【问题标题】:Java import wildcard accessibility for nested static classes嵌套静态类的 Java 导入通配符可访问性
【发布时间】:2021-05-25 19:32:34
【问题描述】:

Java 可访问性(或者可能是作用域)在类型导入多级嵌套类方面是如何工作的?一个例子:

ClassA.java:

package com.oracle.javatests;

public class ClassA {

    public static class NestedAA {
        public void printSomething() {
            System.out.println("inside " + this.getClass().getName());
        }
        
        public static class NestedAB{
            public void printSomethingAB() {
                System.out.println("inside " + this.getClass().getName());  
            }
        }
    }
    
    public void printSomething() {
        System.out.println("inside " + this.getClass().getName());
    }
}

Main.java

package com.oracle.javatests;

import com.oracle.javatests.ClassA.*;
// import com.oracle.javatests.ClassA.NestedAA.*; // Adding this will resolve NestedAB

public class Main {

    public static void main (String[] args){
        ClassA objA = new ClassA();
        objA.printSomething();
        
        NestedAA nestedAA = new NestedAA(); // Ok
        NestedAB nestedAB = new NestedAB(); // Compiler error- NestedAB cannot be resolved to a type
    }
}

使用通配符时,import 语句不会导入 NestedAB 类型。一个可能类似的question 引导我查看Java 规范表,其中阐明了Type-Import-on-Demand Declarations

type-import-on-demand 声明允许所有可访问的类型 根据需要导入的命名包或类型。

对该问题的公认答案意味着按需导入声明不是递归的。推理可能是 Java 认为的“命名类型的所有可访问类型”和general concept of packages,但我没有将这些点联系起来,也没有理解可访问类型对于嵌套类的含义。

请任何人帮忙解释一下类型导入和可访问性在 java 中是如何工作的(同时忽略通配符导入的有争议的使用)

【问题讨论】:

  • 如果你想访问一个内部类,你需要能够访问外部类和内部类。
  • 好的,但是为什么导入通配符语句不能一样呢?
  • 类需要可以通过 import 语句访问,但这不是问题,因为类和内部类是公共的。问题是导入是非递归的。因此,您要么需要导入 ClassA.NestedAA.NestedAB,要么需要指定 new NestedAA.NestedAB()。
  • P.S.但是,在外部类中导入(甚至使用)嵌套超过 1 级的类是非常罕见的。
  • 谢谢。我想了解导入是否设计为非递归的,因为我能找到的任何文档中都没有明确提到这一点。或者,它是否受到 java 的范围或包“安全”或其他东西的限制。我同意,内部类非常罕见,而且绝对不是故意设计的。在我们的用例中,这是由于解析一个非常大的 xsd 而每个新类型都被解析为一个内部类导致在某些情况下超过 10 级嵌套的结果。

标签: java javac inner-classes language-concepts javaimports


【解决方案1】:

听不懂。 import static com.foo.bar.*;import static com.foo.bar.[everything you can imagine here but without dots] 完全相同。

换句话说,在您的示例中,使用import static pkg.ClassA.*;,您可以只编写不带限定符的NestedAA,这样就可以了,因为import static pkg.ClassA.NestedAA; 本来可以做到这一点。

不能NestedAB unqualified 并期望它起作用;除了 * (不包括点)之外,没有任何东西可以编写,因此,星号导入也不会使其正常工作。

【讨论】:

  • 谢谢。很明显 java 不接受这个……我想知道为什么。
最近更新 更多