Java 简单名称和完全限定名称冲突时如何引用类
考虑以下病理学示例:Java 简单名称和完全限定名称冲突时如何引用类,java,language-specifications,Java,Language Specifications,考虑以下病理学示例: class Ideone { static class ArrayList<T> { ArrayList() { System.out.println("!!"); } } static class java { static class util { static class ArrayList<T> { ArrayList() { System.ou
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?
}
}
类表意符{
静态类数组列表{
ArrayList(){
System.out.println(“!!”);
}
}
静态类java{
静态类util{
静态类数组列表{
ArrayList(){
System.out.println(“此处”);
}
}
}
}
公共静态void main(字符串[]args){
新的ArrayList();
新的java.util.ArrayList();
//我可以参考“常用”java.util.ArrayList吗?
}
}
构造函数中创建的两个实例是嵌套类
但是,我怎么能提到我们在同一个班级里都知道和热爱的东西呢?我们不能导入它,也不能使用完全限定名,因为将使用嵌套的类符号
在这种情况下我们能做什么?(除了显而易见的-停止对嵌套类使用这种肆意邪恶的名称)。您尝试过吗
Class cls = ClassLoader.getSystemClassLoader().loadClass("java.util.ArrayList");
List arrayList = cls.newInstance();
我已经很久没有考虑类加载器了,但是IIRC
.loadClass()
会优先尝试从最基本的类加载器加载,真正的java.util
包应该由引导类加载器提供,这使得它比你在应用程序中定义的任何东西都具有更高的优先级。我要冒一个险说,从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;
}
}
输出:
!!
Here
1
2
3
注意:使用此方法,导入
java.util.ArrayList
会很好。但是,如果要调用List List=Idetwo.getList()
在Ideone的主要方法中,您需要导入java.util.*
,因为单个导入将不起作用(有趣的是)。这就是为什么程序包以小写字母开始,而类型以大写字母开始,因为。我认为我从未见过java代码打破这种惯例
但您可以使用内部类型的完全限定名从外部引用它:
com.whatever.bad.project.SomeClass.java.util.ArrayList
当您必须从内部引用外部类型时,您可能可以更改该源文件以符合Java命名准则。如果您已经完成了以下两项工作,则不能再直接引用
Java.util.ArrayList
:
ArrayList
util
中的类ArrayList
隐藏完全限定名java.util.ArrayList
,嵌套在嵌套类java
中List<Integer> al = new AnArrayList<>(); // won't print !! or Here
List al=new AnArrayList();//不会打印!!还是在这里
你有理由相信有解决办法吗?@shmosel并不特别。我只是在做一些容易出错的检查时,想到了一些奇怪的导入案例。我希望看到一位语言架构师回答这个问题。如果您遵循标准,即所有小写的包名和混合大小写的类名,那么这个问题就不会发生。命名约定的存在是有原因的。@Andreas我同意;但我问的是语言允许什么,而不是约定使用什么。很好的尝试,但我说的是“在同一个类中”,而不是“在同一个编译单元中”;)@Andy Turner Darn,错过了;)请参阅我对@Andreas'评论的回复:“我问的是语言允许的内容,而不是惯例使用的内容”。如果您调用loadClass
,而不是findClass
,这应该可以实现。当然,通过使用类似于Stream.of().collect(Collectors.toList())
@AndyTurner的东西,您可以得到一个实际的java.util.ArrayList
,听起来您应该回答自己的问题。我查找了收集器的源代码。toList
,它使用了ArrayList::new
,确认了您的声明。也许吧。这并不是我想问的问题的答案,你能引用这个类型吗,而不是如何得到这个类型的实例。
import java.*;
...
// This doesn't work!
new util.ArrayList<>();
class AnArrayList<T> extends java.util.ArrayList<T> {}
List<Integer> al = new AnArrayList<>(); // won't print !! or Here