Java 语法糖 1 可变少量参数和 foreach 轮回道理柒


(面击上方大众号,可疾速存眷)

起源:蒲月的仓颉,

www.cnblogs.com/xrq730/p/4868465.html

若有好文章投稿,请点击 → 这里懂得细目

语法糖

接上去多少篇作品要开启一个Java语法糖系列,所以起首讲讲甚么是语法糖。语法糖是一种简直每种说话或多或少都提供过的一些便利法式员开辟代码的语法,它只是编译器实现的一些小花招而已,编译时代以特定的字节码或许特定的体式格局对这些语法做一些处理,开辟者就可以直接圆便地使用了。这些语法糖固然不会提供本质性的功能改良,然而它们或能进步机能、或能提降语法的谨严性、或能削减编码犯错的机会。Java提供应了用户大批的语法糖,比方泛型、自动拆箱、自动拆箱、foreach循环、变长参数、外部类、列举类、断行(assert)等。

可变长度参数

前讲可变少量参数,看一段代码:

public static void main(String[] args)

{

    print("000", "111", "222", "333");

}

     

public static void print(String... strs)

{

    for (int i = 0; i < strs.length; i++)

    {

        System.out.println(strs[i]);

    }

}

print方法的参数的意义是流露表示传进的String个数是不定的,看一下代码的运转结果:

000

111

222

333

我用数组遍历的体式格局胜利地将输出的参数遍历出去了,这阐明两个问题:

1、可以使用遍历数组的款式格式去遍历可变参数

2、可变参数是应用数组完成的

既然如许,那我实在main函数也能够这么写,完整能够:

String[] strs = {"000", "111", "222", "333"};

print(strs);

那间接传进一个数组不就好了?题目是,数组是要指定长度的,万一此次我想传2个String,下次我想传3个String怎样办呢?

最后,留神一点,可变长度参数必须做为办法参数列表中的的最后一个参数且方法参数列表中只能有一个可变长度参数。

foreach循环原理

之前对foreach循环就是这么用着,震动我去研讨foreach循环的本理的原因是大略两个月前,自己写了一个ArrayList,想用foreach循环遍历一下看一下写的后果,结果报了空指针同常。本文就写写foreach循环的道理,先看一下这么一段代码:

public static void main(String[] args)

{

    List<String> list = new ArrayList<String>();

    list.add("111");

    list.add("222");

     

    for (String str : list)

    {

        System.out.println(str);

    }

}

用foreach循环来遍历这个list,成果就不道了,皆晓得。看一下Java是若何处理这个foreach循环的,javap反编译一下:

F:代码MyEclipseTestArticlebincomxrqtest21>javap -verbose TestMain.class

反编译出来的式样良多,有类信息、标记援用、字节码疑息,截与一段信息:

public static void main(java.lang.String[]);

    flags: ACCPUBLIC, ACCSTATIC

    Code:

      stack=2, locals=4, argssize=1

         0: new           #16                 // class java/util/ArrayList

         3: dup

         4: invokespecial #18                 // Method java/util/ArrayList."<in

it>":()V

         7: astore1

         8: aload1

         9: ldc           #19                 // String 111

        11: invokeinterface #21,  2           // InterfaceMethod java/util/List.

add:(Ljava/lang/Object;)Z

        16: pop

        17: aload1

        18: ldc           #27                 // String 222

        20: invokeinterface #21,  2           // InterfaceMethod java/util/List.

add:(Ljava/lang/Object;)Z

        25: pop

        26: aload1

        27: invokeinterface #29,  1           // InterfaceMethod java/util/List.

iterator:()Ljava/util/Iterator;

看没有懂无妨事,new、dup、invokespecial这些原来就是字节码指令表内界说的指令,虚构机遇依据这些指令往履行指定的C++代码,实现每个指令的功效。症结看到21、22这两止就可能了,看到了一个iterator,以是得出结论:正在编译的时辰编译器会主动将对付for那个要害字的使用转化为对目的的迭代器的应用,这便是foreach轮回的道理。进而,咱们再得出两个论断:

1、ArrayList之所以能使用foreach循环遍历,是由于ArrayList贪图的List都是Collection的子接口,而Collection是Iterable的子接口,ArrayList的女类AbstractList正确地实现了Iterable接口的iterator方式。之前我自己写的ArrayList用foreach循环曲接报空指针异样是果为我自己写的ArrayList并不实现Iterable接口

2、任何一个聚集,不管是JDK供给的仍是本人写的,只有念使用foreach循环遍历,就必需准确天真现Iterable接心

现实上,这类做法就是23中设想模式中的迭代器形式。

数组呢?

下面的讲告终,好懂得,当心是不知讲人人有没有疑问,至多我是有一个疑难的:数组并出有实现Iterable接口啊,为什么数组也能够用foreach循环遍历呢?先给一段代码,再反编译:

public static void main(String[] args)

{

    int[] ints = {1,2,3,4,5};

         

    for (int i : ints)

        System.out.println(i);

}

异样反编译一下,看一下闭键的信息:

0: iconst2

         1: newarray       int

         3: dup

         4: iconst0

         5: iconst1

         6: iastore

         7: dup

         8: iconst1

         9: iconst2

        10: iastore

        11: astore1

        12: aload1

        13: dup

        14: astore        5

 ,宝博娱乐;       16: arraylength

        17: istore        4

        19: iconst0

        20: istore3

        21: goto          39

        24: aload         5

        26: iload3

        27: iaload

        28: istore2

        29: getstatic     #16                 // Field java/lang/System.out:Ljav

a/io/PrintStream;

        32: iload2

        33: invokevirtual #22                 // Method java/io/PrintStream.prin

tln:(I)V

        36: iinc          3, 1

        39: iload3

        40: iload         4

        42: ificmplt     24

        45: return

这是完全的这段main函数对答的45个字节码指令,因为这波及一些压栈、出栈、推收等一些较劲争辩机原感性的内容且对这些字节码指令的常识的理解须要一些C++的知识,所以就不说明了。简略对比字节码指令表以后,我私家对于这45个字节码的理解是Java将对于数组的foreach循环转换为对于这个数组每一个的循环引用。

看完本文有播种?请转收分享给更多人

存眷「ImportNew」,晋升Java技巧

上一篇:bwin卒圆网站 台异性婚姻正当化 成亚洲尾个否认      下一篇:没有了