Java 是否将最终参数复制到隐藏变量中?
这是从JPL复制的(见下面的注释),我添加了import和main()Java 是否将最终参数复制到隐藏变量中?,java,parameters,local,final,Java,Parameters,Local,Final,这是从JPL复制的(见下面的注释),我添加了import和main() import java.util.*; /** *@摘自Arnold,Gosling,Holmes的“Java编程语言” *(5.3.本地内部类) */ 公共类地方性课程{ 公共静态迭代器演练(最终对象[]objs){ 类Iter实现迭代器{ 私人int pos=0; @凌驾 公共布尔hasNext(){ 返回(位置=对象长度) 抛出新的NoTouchElementException(); 返回objs[pos++]; }
import java.util.*;
/**
*@摘自Arnold,Gosling,Holmes的“Java编程语言”
*(5.3.本地内部类)
*/
公共类地方性课程{
公共静态迭代器演练(最终对象[]objs){
类Iter实现迭代器{
私人int pos=0;
@凌驾
公共布尔hasNext(){
返回(位置<对象长度);
}
@凌驾
public Object next()抛出NoTouchElementException{
如果(位置>=对象长度)
抛出新的NoTouchElementException();
返回objs[pos++];
}
@凌驾
公共空间删除(){
抛出新的UnsupportedOperationException();
}
}
返回新的Iter();
}
公共静态void main(字符串[]args){
Object[]objects=新对象[5];
迭代器iter=漫游(对象);
while(iter.hasNext())
System.out.println(iter.next());
}
}
我的问题是:
结果是5个null,我没有初始化数组的元素 由于
objs
是匿名类封闭范围内的最后一个变量,因此它被类“捕获”,其生存期至少与该类一样长。规格不是很清楚,但这一行暗示了它:
通常,任何作用域都会继承其父作用域;内部类略有不同,因为它只继承其父局部作用域的最终成员,以及其封闭类的所有作用域
这是工厂方法的一种常见模式,尤其是在处理异步代码时,该代码涉及需要封闭状态的侦听器。由于
objs
是匿名类封闭范围内的最终变量,它被类“捕获”,其生存期至少与类一样长。规格不是很清楚,但这一行暗示了它:
通常,任何作用域都会继承其父作用域;内部类略有不同,因为它只继承其父局部作用域的最终成员,以及其封闭类的所有作用域
这是工厂方法的一种常见模式,尤其是在处理异步代码时,该代码涉及需要封闭状态的侦听器。以下是该命令生成的内容
javap -private -c LocalInnerClassAppl\$1Iter
-
pkg
是我复制您的类来编译它的包
Compiled from "LocalInnerClassAppl.java"
class pkg.LocalInnerClassAppl$1Iter extends java.lang.Object implements java.util.Iterator{
private int pos;
private final java.lang.Object[] val$objs;
pkg.LocalInnerClassAppl$1Iter(java.lang.Object[]);
Code:
0: aload_0
1: aload_1
2: putfield #14; //Field val$objs:[Ljava/lang/Object;
5: aload_0
6: invokespecial #16; //Method java/lang/Object."<init>":()V
9: aload_0
10: iconst_0
11: putfield #19; //Field pos:I
14: return
public boolean hasNext();
Code:
0: aload_0
1: getfield #19; //Field pos:I
4: aload_0
5: getfield #14; //Field val$objs:[Ljava/lang/Object;
8: arraylength
9: if_icmpge 14
12: iconst_1
13: ireturn
14: iconst_0
15: ireturn
public java.lang.Object next() throws java.util.NoSuchElementException;
Code:
0: aload_0
1: getfield #19; //Field pos:I
4: aload_0
5: getfield #14; //Field val$objs:[Ljava/lang/Object;
8: arraylength
9: if_icmplt 20
12: new #31; //class java/util/NoSuchElementException
15: dup
16: invokespecial #33; //Method java/util/NoSuchElementException."<init>":()V
19: athrow
20: aload_0
21: getfield #14; //Field val$objs:[Ljava/lang/Object;
24: aload_0
25: dup
26: getfield #19; //Field pos:I
29: dup_x1
30: iconst_1
31: iadd
32: putfield #19; //Field pos:I
35: aaload
36: areturn
public void remove();
Code:
0: new #35; //class java/lang/UnsupportedOperationException
3: dup
4: invokespecial #37; //Method java/lang/UnsupportedOperationException."<init>":()V
7: athrow
}
从“LocalInnerClassAppl.java”编译而来
类pkg.LocalInnerClassAppl$1Iter扩展了java.lang.Object实现了java.util.Iterator{
私人国际邮政局;
private final java.lang.Object[]val$objs;
pkg.localinerclassappl$1Iter(java.lang.Object[]);
代码:
0:aload_0
1:aload_1
2:putfield#14;//Field val$objs:[Ljava/lang/Object;
5:aload_0
6:invokespecial#16;//方法java/lang/Object。”“:()V
9:aload_0
10:iconst_0
11:putfield#19;//字段位置:I
14:返回
公共布尔hasNext();
代码:
0:aload_0
1:getfield#19;//字段位置:I
4:aload_0
5:getfield#14;//Field val$objs:[Ljava/lang/Object;
8:排列长度
9:if_icmpge 14
12:iconst_1
13:我轮到你了
14:iconst_0
15:我轮到你了
public java.lang.Object next()抛出java.util.NoSuchElementException;
代码:
0:aload_0
1:getfield#19;//字段位置:I
4:aload_0
5:getfield#14;//Field val$objs:[Ljava/lang/Object;
8:排列长度
9:if_icmplt 20
12:new#31;//类java/util/NoSuchElementException
15:dup
16:invokespecial#33;//方法java/util/NoSuchElementException。“”:()V
19:athrow
20:aload_0
21:getfield#14;//Field val$objs:[Ljava/lang/Object;
24:aload_0
25:dup
26:getfield#19;//字段位置:I
29:dup_x1
30:iconst_1
31:iadd
32:putfield#19;//字段位置:I
35:aaload
36:areturn
删除公共空间();
代码:
0:new#35;//类java/lang/UnsupportedOperationException
3:dup
4:invokespecial#37;//方法java/lang/UnsupportedOperationException。“”:()V
7:athrow
}
如您所见,编译器生成的字段private final java.lang.Object[]val$objs;
和构造函数localinerclassappl$1Iter(java.lang.Object[])
。我认为这基本上回答了第一个问题
对于第二个问题,这实际上取决于您是否需要多次实例化该类,还是只需实例化一次就可以完成,这取决于您应该决定是否将其设置为本地/匿名。如果它最适合您的情况,那么它很可能是一种好的做法。Foll这是命令产生的结果
javap -private -c LocalInnerClassAppl\$1Iter
-
pkg
是我复制您的类来编译它的包
Compiled from "LocalInnerClassAppl.java"
class pkg.LocalInnerClassAppl$1Iter extends java.lang.Object implements java.util.Iterator{
private int pos;
private final java.lang.Object[] val$objs;
pkg.LocalInnerClassAppl$1Iter(java.lang.Object[]);
Code:
0: aload_0
1: aload_1
2: putfield #14; //Field val$objs:[Ljava/lang/Object;
5: aload_0
6: invokespecial #16; //Method java/lang/Object."<init>":()V
9: aload_0
10: iconst_0
11: putfield #19; //Field pos:I
14: return
public boolean hasNext();
Code:
0: aload_0
1: getfield #19; //Field pos:I
4: aload_0
5: getfield #14; //Field val$objs:[Ljava/lang/Object;
8: arraylength
9: if_icmpge 14
12: iconst_1
13: ireturn
14: iconst_0
15: ireturn
public java.lang.Object next() throws java.util.NoSuchElementException;
Code:
0: aload_0
1: getfield #19; //Field pos:I
4: aload_0
5: getfield #14; //Field val$objs:[Ljava/lang/Object;
8: arraylength
9: if_icmplt 20
12: new #31; //class java/util/NoSuchElementException
15: dup
16: invokespecial #33; //Method java/util/NoSuchElementException."<init>":()V
19: athrow
20: aload_0
21: getfield #14; //Field val$objs:[Ljava/lang/Object;
24: aload_0
25: dup
26: getfield #19; //Field pos:I
29: dup_x1
30: iconst_1
31: iadd
32: putfield #19; //Field pos:I
35: aaload
36: areturn
public void remove();
Code:
0: new #35; //class java/lang/UnsupportedOperationException
3: dup
4: invokespecial #37; //Method java/lang/UnsupportedOperationException."<init>":()V
7: athrow
}
从“LocalInnerClassAppl.java”编译而来
类pkg.LocalInnerClassAppl$1Iter扩展了java.lang.Object实现了java.util.Iterator{
私人国际邮政局;
private final java.lang.Object[]val$objs;
pkg.localinerclassappl$1Iter(java.lang.Object[]);
代码:
0:aload_0
1:aload_1
2:putfield#14;//Field val$objs:[Ljava/lang/Object;
5:aload_0
6:特别是#16;