为什么我不能在扩展类中创建一个与内部类同名的对象

时间:2012-08-02 13:39:42

标签: java

我试图找出下面代码为什么会出错,有人可以解释一下。 这是一个班级

package abc;

public class A {
   public class B {

   }
}

现在我尝试创建一个B类

package xyz;
import abc.*;


public class B extends A{
    public static void main(String[] args) {
        B b = new B (); // this line gives error. Can you please explain
    }
}

请考虑B类扩展A是默认包意味着

import abc.*;


public class B extends A{
    public static void main(String[] args) {
        B b = new B (); // this line gives error. Can you please explain 
                          // I am try to create "B" class object which extends A 
                         //.. not the B inner class 
    }
}

在eclipse中显示的错误是:“不能访问类型A的封闭实例。必须使用类型A的封闭实例限定分配(例如x.new A(),其中x是A的实例。”

7 个答案:

答案 0 :(得分:2)

鉴于B扩展A,而A包含内部类B,我怀疑存在混淆的余地(对于编译器和程序员而言)。

该行:

B b = new B();

含糊不清。 哪个 B是这个?正如其他地方所指出的,内部类B需要一个包含A的实例,所以我怀疑你的意思是B外部类。

编辑:您的错误

  

“无法访问类型A的封闭实例。必须符合条件   使用类型A的封闭实例进行分配(例如x.new A()其中   x是A)的一个实例。“

证实了这一点。我认为你想要xyz.B并且应该适当地调整范围。

答案 1 :(得分:1)

尝试指定封闭范围:

B b = new A.B();

B b = new xyz.B();

答案 2 :(得分:1)

如果您制作public class B static,它将按照书面形式运作。

否则,您不能从类A的实例外部创建类B的实例,因为非静态内部类需要指向其外部类的“this”(在B中,您可以编写this.A,这实际上是指封闭的A)。

答案 3 :(得分:0)

当我在Eclipse中创建以下内容时:

package com.example;

public class A {
    class B {
    }
}

package com.example;

import com.example.A.B;

public class B extends A {

    public static void main(String[] args) {
        B b = new B();
    }
}

正如您所见,Eclipse会导入类A.B。如果没有导入,则会注意到以下错误:

无法访问类型A的封闭实例。必须使用类型A的封闭实例限定分配(例如x.new A(),其中x是A的实例。)

答案 4 :(得分:0)

当我尝试编译此代码时所得到的错误(减去包规范,因为它们似乎无关紧要)是“非静态变量,这不能从静态上下文引用”。所以,问题是在静态方法main()中你试图访问非静态的东西,我猜这是内部类B的定义。

如果第二个外部类具有不同的名称,则实际上会出现相同的错误。所以明显的命名冲突是一个红色的鲱鱼。虽然这本身就是不为两个类使用相同名称的好理由 - 但在尝试理解错误时会引起混淆。

如果我将内部类的声明更改为静态,则会解决错误。

public class A {
   public static class B {

   }
}

静态与非静态嵌套类的一些相关讨论是here

但这可能不是正确的解决办法。它表明main()中的代码引用了B内部类,而不是包含该方法的B类。你真的想要哪一个?显然,我建议为这两个类使用不同的名称以避免混淆。如果你想在main()中创建一个包含该方法的类的实例,那么使用该类的唯一名称将解决你的问题。

答案 5 :(得分:0)

您的班级B extends A 继承了班级A.B ,而表达式new B()指的是该班级。因此它要求一个封闭的实例。您必须明确限定B提及包名称,或者更好,首先避免此类命名混乱

答案 6 :(得分:0)

我找到了这个解决方案,通过反射你可以创建B类(B扩展A类)对象。

import java.lang.reflect.Method;

import abc.*;

public class B extends A{
    public static void main(String[] args) {
        //B b = new B(); // this line gives error. Can you please explain 
                          // I am try to create "B" class object which extends A 
                         //.. not the B inner class
     try{
      Class c = Class.forName("B"); //class B extends A
      Method  m=c.getMethod("print", null);
      m.invoke(c.newInstance(), null);
     }catch(Exception e){
      e.printStackTrace();
     }
    }

    public void print(){
     System.out.println("Printed");
    }
}