Java内部类(不是静态的)

时间:2013-12-07 21:08:09

标签: java

我对这个话题有疑问:
内部类的实例每次都需要内部类的guest类的相同类型的对象。例如:

public class GuestClass {

    class innerClass {
    }

    public static void main(String[] args) {
        innerClass test = new innerClass(); //does not work because 
                                            //I need a object of type GuestClass
        GuestClass iNeedYou = new GuestClass();
        innerClass nestClassObj = iNeedYou.new innerClass(); //it works 
    }
}
好的,很清楚 innerClass对象现在也指向一个GuestClass对象(iNeedYou)
现在来问我的问题:
一个匿名的班级也是一个内部阶级的权利? 但有一些区别:
答:我不知道这个对象的类型
B.它实现了一个界面。

但它仍然是内部类(anonymus但内部)的对象

事实上,如果我这样做:

public class GuestClass {
    private int numb = 100;

    class innerClass {
    }

    public void createAnAnonymusObject () {
        myInterface myAnObj = new myInterface(){
        int a, b;

        @Override
        public void print() {
            System.out.println(numb); //it works
        }};
        myAnObj.print(); 
    }

    public static void main(String[] args) {                                   
        GuestClass iNeedYou = new GuestClass();
        iNeedYou.createAnAnonymusObject();  
    }
}

有效,因为匿名内部对象指向外部对象...所以我可以看到变量麻木。

但为什么会这样呢?

public static void main(String[] args) {
    myInterface myAnObj = new myInterface(){ //why does it work? in this case   
                                             //where is the outer object?
    int a, b;

    @Override
    public void print() {

    }};     
}

如果匿名类是内部类,为什么它不需要外部对象?

2 个答案:

答案 0 :(得分:1)

你基本上在这里问两个问题。

为什么非静态嵌套类需要封闭实例?

因为假定它可以访问外部类的所有非静态成员。即使您实际上没有使用其中任何一个,编译器也无法推断非静态嵌套类可以在静态上下文中安全使用。您必须明确标记static以允许此操作。

在此代码段中创建的匿名类的封闭对象的位置和内容是什么?

public class OuterClass {

  private int nonStaticMember;

  private static int staticMember;

  public static void main(String[] args) {
    MyInterface myAnObj = new MyInterface(){ //why it works ?? in this case   
                                             //where is the outer object?

    @Override
    public void print() {
       //nonStaticMember is not visible in this scope
       //staticMember is visible in this scope
    }};     
  }
}

在这种情况下,您的匿名类具有无封闭实例。它是在main方法的静态上下文中创建的。您可以实例化MyInterface,因为所有接口都是隐式静态的,即使在另一个类中定义也是如此。这就是界面完全可见的原因。另一方面,OuterClass的所有非静态成员都不在此范围内,因此您可以保证不使用其中任何一个。{1}}。这就是为什么不需要引用封闭对象的原因。实际上,这包含在语言规范中。

看看这个Java Language Standard excerpt

  

让C成为实例化的类,让我成为实例   创建。如果C是内部类,那么我可能会立即拥有   封闭实例。 i的直接封闭实例(§8.1.3)   确定如下。

     

如果C是匿名类,则:

     
      
  • 如果类实例创建表达式出现在静态上下文中   (§8.1.3),然后我没有立即封闭的实例。

  •   
  • 否则,i的直接封闭实例就是这个。

  •   
     

(...)

我只引用了此用例中最相关的部分。随意深入潜入它。

答案 1 :(得分:1)

public class Anonymous2 {
    private int numb = 100;

    public static void main(String[] args) {
        MyInterface myAnObj = new MyInterface(){ //why it works ?? in this case   
                                                 //where is the outer object?
        int a, b;

        @Override
        public void print() {
            System.out.println(numb); 
        }};     
    }
}

interface MyInterface {
    public void print();
}

编译:

C:\JavaTools>javac Anonymous2.java
Anonymous2.java:11: error: non-static variable numb cannot be referenced from a static context
            System.out.println(numb);
                               ^
1 error

可以看出,OP声称编译的代码不会。所以整个问题都无关紧要。