考虑以下病理示例:
class Ideone {
static class ArrayList<T> {
ArrayList() {
System.out.println("!!");
}
}
static class java {
static class util {
static class ArrayList<T> {
ArrayList() {
System.out.println("Here");
}
}
}
}
public static void main(String[] args) {
new ArrayList<>();
new java.util.ArrayList<>();
// Can I refer to the "usual" java.util.ArrayList?
}
}
在构造函数中创建的两个实例是嵌套类。
但我怎么能参考 java.util.ArrayList
我们都知道并喜欢同一个班级?我们无法导入它,也不能使用完全限定名,因为将使用嵌套类符号。
在这种情况下我们能做些什么? (除了明显的 - 停止使用嵌套类的这些肆无忌惮的邪恶名称)。
你不能再直接参考了 java.util.ArrayList
如果你已经完成了你做过的两件事:
- 隐藏简单名称
ArrayList
在范围内使用静态嵌套类。
- 隐藏完全限定名称
java.util.ArrayList
一堂课 ArrayList
嵌套在类中 util
,嵌套在嵌套类中 java
。
您甚至无法“拆分”导入以尝试使用“部分限定”导入。
import java.*;
...
// This doesn't work!
new util.ArrayList<>();
您可以 import java.*;
,但那是毫无价值的;没有定义类 java
直接打包。
但是,您可以参考该课程 java.util.ArrayList
间接的,因为它不是 final
。超出了班级的范围 Ideone
,声明一个具有不同名称的子类。
class AnArrayList<T> extends java.util.ArrayList<T> {}
然后你可以将该类和程序引用到界面:
List<Integer> al = new AnArrayList<>(); // won't print !! or Here
我要走出去,说不可能从内部引用它 Ideone
。我看到的唯一解决方案是创建另一个类 Idetwo
(这是一个巢穴 Ideone
(即它驻留在同一个文件中))并返回一个 java.util.ArrayList
从那里用于 Ideone
:
import java.util.ArrayList;
class Ideone {
...
}
class Idetwo {
static ArrayList<Integer> getList() {
ArrayList<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
return list;
}
}
而你只是改变你的 Ideone
的主要方法是:
public static void main(String[] args) throws Exception {
new Ideone.ArrayList<>();
new Ideone.java.util.ArrayList<>();
Idetwo.getList().forEach(System.out::println);
}
输出:
!!
Here
1
2
3
注意:使用此方法,导入 java.util.ArrayList
会很好的。但是,如果你打电话 List<Integer> list = Idetwo.getList();
内 Ideone
的主要方法,你需要导入 java.util.*
,因为个别进口不起作用(有趣)。
你有没有尝试过
Class cls = ClassLoader.getSystemClassLoader().loadClass("java.util.ArrayList");
List arrayList = cls.newInstance();
自从我考虑过类加载器以来,已经很长时间了,但IIRC .loadClass()
将优先尝试从最基本的类加载器和真实加载 java.util
package应该由bootstrap类加载器提供,它提供的优先级高于您在应用程序中定义的任何内容。
这就是为什么包以小写字母开头,以及大写字母的类型,因为 第一版java的官方代码约定。我不认为我见过java代码打破了这个惯例。
但是你可以使用它的完全限定名称从外部引用内部类型:
com.whatever.bad.project.SomeClass.java.util.ArrayList
当您必须从内部引用外部类型时,您可以更改该源文件以符合Java命名准则。