Java全限定名继承ArrayList后用简名实例化编译报错疑问
Java全限定名与import语句使用差异问题
复现场景
Case 1 编译报错示例
代码内容:
class A extends java.util.ArrayList { public static void main(String[] args) { ArrayList a=new ArrayList(); } }
编译抛出错误:
cannot find symbol Symbol:class ArrayList location:class A
Case 2 编译通过示例
代码内容:
class A extends java.util.ArrayList { }
该段代码可正常编译通过。
核心疑问
若如case1所示无法直接使用ArrayList简名创建实例,那么通过全限定名继承ArrayList的作用是什么?
解答
要搞懂这个现象,首先得明确Java里两个语法的作用边界,二者的作用完全不重叠:
- 代码中书写全限定名(比如
extends java.util.ArrayList)属于单点类型声明:仅在当前书写全路径的位置,告诉编译器需要引用的具体类型,这个动作不会把对应类型的简名注入到当前类文件的命名空间,作用域仅限当前这一行代码。 import语句的作用才是全局简名导入:书写import java.util.ArrayList之后,整个Java文件的所有位置都可以直接用ArrayList这个简名指代对应类型,不用每次书写完整全路径。
两个case的编译结果逻辑非常清晰:
- Case2能正常编译,是因为
extends后面写了全限定名,编译器已经明确识别A的父类是java.util.ArrayList,整个类里没有其他无法识别的类型引用,自然编译通过。这时候A作为ArrayList子类的身份是完全生效的:它继承了ArrayList所有非私有方法、属性,多态逻辑也正常运行,完全可以正常实例化A、调用ArrayList的所有方法,比如:
整个过程根本不需要在代码里书写public static void main(String[] args) { A a = new A(); a.add("测试元素"); System.out.println(a.get(0)); // 正常运行,输出"测试元素" }ArrayList这个简名,自然不需要额外导入。 - Case1报错和用全限定名继承ArrayList没有任何关系:在main方法里直接写
ArrayList的时候,编译器会在当前命名空间匹配对应类型——既没有写import导入ArrayList简名,当前类名是A不是ArrayList,同包下也没有自定义的ArrayList类,当然会报找不到符号。哪怕前面用全限定名做了继承,也不会自动完成简名导入的动作。
用全限定名书写继承关系的实际作用主要覆盖两个场景:
- 避免命名冲突:比如代码里同时要用到
java.util.Date和java.sql.Date这种同名类,只能import其中一个,另一个不管是声明变量还是做继承,都需要写全限定名,没必要为了继承特意调整导包逻辑产生冲突。 - 减少无意义导包:如果整个类里只有extends这一处用到某个父类,类内部的方法、属性定义全程不会直接提到父类的简名,那直接在extends后面写全限定名即可,省得单独加一行import,代码功能完全不受影响。
内容的提问来源于stack exchange,提问作者veerraju annamdevula
相关产品推荐
相关产品推荐

