当类的简单名称与全限定名称冲突时,如何引用标准java.util.ArrayList?
解决同名嵌套类遮蔽标准库类的问题
嘿,这个场景确实有点棘手——自己的嵌套类把标准库的类给遮蔽了,连全限定名都没法直接用。不过除了改嵌套类名字,还有这几个实用的办法可以试试:
方法一:通过反射动态加载类
你可以用Class.forName()来加载标准的java.util.ArrayList,然后通过反射创建实例。这种方式绕开了编译时的名称遮蔽问题,因为我们是用字符串指定类名,编译器不会把它和嵌套类混淆。
示例代码:
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) throws Exception { new ArrayList<>(); new java.util.ArrayList<>(); // 加载并创建标准java.util.ArrayList实例 Class<?> arrayListClass = Class.forName("java.util.ArrayList"); Object standardList = arrayListClass.getConstructor().newInstance(); System.out.println("标准库实例:" + standardList.getClass().getName()); } }
方法二:借助外部辅助类中转
你可以在同一个项目里创建一个简单的辅助类,让它负责返回标准的java.util.ArrayList,这样在当前类里就可以通过调用辅助类的方法来获取实例,完全不会被嵌套类干扰。
比如先创建这个辅助类:
// 辅助类,放在同一个包下即可 public class CollectionHelper { public static <T> java.util.ArrayList<T> createStandardArrayList() { return new java.util.ArrayList<>(); } }
然后在你的Ideone类里调用:
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<>(); // 通过辅助类获取标准库的ArrayList实例 java.util.ArrayList<String> standardList = CollectionHelper.createStandardArrayList(); System.out.println("标准库实例:" + standardList.getClass().getName()); } }
额外小技巧:利用模块系统(Java 9+)
如果你的项目用了Java 9及以上的模块系统,还可以通过模块的全限定名称来引用,比如java.base/java.util.ArrayList,不过这个方式需要你的代码在模块环境中运行,相对复杂一些,示例代码如下:
// 仅适用于Java 9+模块环境 var standardList = new java.base/java.util.ArrayList<String>();
总结一下,反射方式无需额外类,适合快速临时解决;辅助类方式代码更清晰,适合长期维护的场景;模块方式则是Java 9+的专属方案。
内容的提问来源于stack exchange,提问作者Andy Turner
相关产品推荐
相关产品推荐

