Java内部类与其他顶级类同名

时间:2011-05-05 12:43:40

标签: java inner-classes naming

我有关于Java内部类的问题。

有没有办法从顶级类Main访问顶级类A来定义内部类A?

以下是演示此问题的示例代码:

class A {   // Outer Class A
  { 
    System.out.println("A outer");
  }
}

class B {   // Outer Class B
  { 
    System.out.println("B outer"); 
  }
}

public class Main { 
  class A {  // Inner Class A
    {
      System.out.println("A inner");
    }
  }

  public void newA() {      
    class A {   // Local Class A
      { 
        System.out.println("A local");
      }
    }
    new A();
  }

  public static void main(String[] args) {
    new Main().newA();  // prints "A local"
    new Main().new A(); // prints "A inner"
    //new A();    // compiler error: No enclosing instance of type Main is Accessible.
    new B();      // but this works and prints "B outer" 
  }
}

6 个答案:

答案 0 :(得分:9)

使用完全限定的类名:

new com.mypackage.A();

答案 1 :(得分:4)

如果你的课程是在课程中,我希望这是实现这一目标的最简单方法。我不相信Java的C#global::有任何等价物来强迫这类事情。

最终,我只是尝试更改类名,以避免问题首先发生。这通常比使用变通方法更好。

答案 2 :(得分:4)

您应该为两个A提供不同的包名称,以便它们显然是不同的类型,然后您可以用它们的全名来引用它们。

例如:

my.package.for.toplevel.A outerA = new my.package.for.toplevel.A(); // prints "A outer"
                                                                    // if this is the
                                                                    // package

或者甚至更好,为两个不同的类使用两个不同的名称。

答案 3 :(得分:3)

内部类的名称被称为影响顶级类的名称。顶级类不能在内部类的范围内通过其简单名称引用;顶级类只能通过限定名称引用。

如果顶级类在默认包中(在这种情况下,它的规范名称与其简单名称相同),您仍然可以通过反射访问它。

答案 4 :(得分:1)

是的,只需使用包或避免从一开始就命名它们。我想知道你有什么理由将它们命名为相同的吗?

为了解释你的错误,它来自于它试图访问内部A的事实,但由于该类未被声明为静态并且没有可用的主实例,因此它无法创建非静态内部A需要引用父主实例。

答案 5 :(得分:0)

假设类在默认包中。要解决这种情况下的命名冲突,需要重命名冲突的类或使用命名包。然后使用FQCN解决问题。