2

我试图找出为什么下面的代码会出错,有人可以解释一下吗?这是一堂课

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 类型的封闭实例来限定分配(例如 xnew A(),其中 x 是 A 的实例)。”

4

7 回答 7

2

鉴于BextendsAA包含一个内部类B,我怀疑存在混淆的空间(对于编译器和程序员)。

该行:

B b = new B();

是模棱两可的。这是哪个B?正如在别处指出的那样,内部类 B 需要一个包含的实例A,所以我怀疑你的意思是B外部类。

编辑:你的错误

“没有 A 类型的封闭实例是可访问的。必须使用 A 类型的封闭实例来限定分配(例如 xnew A(),其中 x 是 A 的实例)。”

证实了这一点。我想你想要xyz.B并且应该适当地确定范围。

于 2012-08-02T13:42:55.780 回答
1

尝试指定封闭范围:

B b = new A.B();

或者

B b = new xyz.B();
于 2012-08-02T13:43:29.057 回答
1

如果你 make public class B static,它会像写的那样工作。

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

于 2012-08-02T13:45:41.760 回答
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");
    }
}
于 2012-08-23T11:20:30.980 回答
0

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

如果第二个外部类具有不同的名称,您实际上会得到相同的错误。因此,明显的命名冲突是一个红鲱鱼。尽管这本身就是不对两个类使用相同名称的一个很好的理由——它在试图理解错误时会引起混淆。

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

public class A {
   public static class B {

   }
}

关于静态与非静态嵌套类的一些相关讨论在这里

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

于 2012-08-02T13:51:41.943 回答
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 的封闭实例来限定分配(例如 xnew A(),其中 x 是 A 的实例)。

于 2012-08-02T13:49:04.817 回答
0

您的类B extends A 继承了该类A.B,并且表达式new B()引用了该内部类。因此它要求一个封闭的实例。您必须明确地使用包名称来限定您提到的两个B,或者,更好的是,首先避免这种命名混乱

于 2012-08-02T14:07:58.707 回答