Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 匿名类变量_Java - Fatal编程技术网

Java 匿名类变量

Java 匿名类变量,java,Java,今天我在尝试匿名课程。当我执行System.out.println(super.x)时,它打印12,当我使用System.out.println(x)时它打印4。我想super.x会打印4,不知道是否有人可以向我解释为什么会这样 public class AnonClass { private int x = 1; public AnonClass(int x) { this.x = x; } public static void main(

今天我在尝试匿名课程。当我执行
System.out.println(super.x)时
,它打印12,当我使用
System.out.println(x)时它打印4。我想
super.x
会打印4,不知道是否有人可以向我解释为什么会这样

public class AnonClass {

    private int x = 1;

    public AnonClass(int x) {
        this.x = x;
    }

    public static void main(String[] args) {
        AnonClass test = new AnonClass(4);
        test.testMethod();
    }

    public void testMethod() {

        AnonClass anon = new AnonClass(12) {
            {
                System.out.println(super.x); //Prints 12
                System.out.println(x); //prints 4
            }
        };

    }
}

当您在
类AnonClass
中定义这样的匿名类时:

AnonClass anon =
    new AnonClass(12) {
      {
        System.out.println(super.x); //Prints 12
        System.out.println(x); //prints 4
      }
    };
编译器将创建类似以下内容的类:

class AnonClass$1 extends AnonClass {
  final AnonClass enclosed;

  AnonClass$1(AnonClass enclosed, int x) {
    super(x);
    System.out.println(super.x);
    System.out.println(enclosed.x);
    this.enclosed = enclosed;
  }
}
然后像这样调用它:

AnonClass anon = new AnonClass$1(this, 12);
请注意,超构造函数(
super(x);
)的调用发生在实例初始值设定项的内容之前(即
System.out.println
行)

因此,超级构造函数将字段
AnonClass.x
初始化为12,然后通过
System.out.println(super.x)将其值打印为
12

然后,
System.out.println(x)
实际上引用了
AnonClass
的封闭实例中的
x
,其值为4

它不再次打印
12
的原因是
x
private
;正如书中所说:

声明为私有的类的成员不会被该类的子类继承


因此,没有
类$1.x
可打印;名为
x
的范围中唯一的标识符是
AnonClass.x

这里有两个类:普通类
AnonClass
和匿名类
AnonClass$1
扩展
AnonClass

这两个类都有
x
字段

您还有两个对象:一个是在
main
方法中实例化的
AnonClass
类型,使用
x=4
;另一个是在
testMethod()中实例化的
AnonClass$1
类型,使用
x=12

打印
super.x
的值时,访问第二个对象的
x
字段;但是
x
的值属于第一个对象,因为您的类不是
静态的
,并且包含对外部类实例的隐式引用


参考资料:

我认为
super
只用于继承。“我想不是。”宪兵,你为什么这么想?匿名类从它们扩展的类继承而来。@AndyTurner好吧,我想我对Java的知识太多了。。。肤浅的。我无法理解这一切。java规范的哪一部分说匿名类中的非限定标识符解析为封闭类而不是匿名超类?我本以为会出现“模棱两可”的编译错误。这确实是一个有趣的问题——也是不使用双大括号初始化的另一个原因。请在实例初始值设定项中参考关于变量分辨率的JLS。下面是回答我问题的提示,我想:如果您从字段
x
中删除
private
,则
super.x
x
都指超级实例。只有当
x
private
时,非限定的
x
才会引用封闭实例。这很有趣,它似乎在私有时增加了封装级别,在公共时允许共享。