Java 是否将最终参数复制到隐藏变量中?

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++]; }

这是从JPL复制的(见下面的注释),我添加了import和main()

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());
}
}
我的问题是:

  • 调用iter.hasNext()时,iter如何知道objs的含义?它没有显式保存在实例中。从讨论中看,它似乎是隐式复制并保存在iter实例中的。你能证实一下吗?我找不到推荐人

  • 如果第一个为真(保存了最后一个参数),那么依赖这种隐式保存是否被认为是一种良好的编程实践?很抱歉,如果它在Java规范中,那么我的第二个Q是不相关的,但是再一次-我没有找到它


  • 结果是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;