Java中兄弟类为何可通过点语法引用?如何禁止该行为?
Java静态嵌套类的特殊访问场景解析
一、为什么new Sibling1.Sibling2();能正常运行?
这是Java的限定名称查找规则在起作用:
Sibling1是SomeClass的静态嵌套类,但它自身并没有定义Sibling2内部类;- 当编译器遇到
Sibling1.Sibling2这种写法时,会先在Sibling1内部查找目标类,找不到的话,会自动回溯到Sibling1的外围类(也就是SomeClass)中查找同名静态成员; - 由于
SomeClass中确实存在静态嵌套类Sibling2,编译器会直接把Sibling1.Sibling2解析为SomeClass.Sibling2,因此实例化操作能正常执行。
说白了就是:Java允许通过外围类的任意静态成员作为"跳板",访问该外围类的其他静态成员,哪怕这两个成员之间没有直接包含关系。
二、如何禁止这种写法?
可以通过以下几种方式实现:
1. 在Sibling1内部添加同名私有嵌套类
给Sibling1定义一个私有(或不可实例化)的Sibling2类,让编译器优先匹配Sibling1内部的类,阻断对外部Sibling2的访问:
static class Sibling1 extends AbstractNested { // 私有同名类,直接阻断外部Sibling2的匹配路径 private static class Sibling2 {} }
此时再写new Sibling1.Sibling2()会因为Sibling2是私有类而编译报错。
2. 限制Sibling2的访问修饰符
如果Sibling2不需要在SomeClass外部被访问,可以将其访问权限改为private:
private static class Sibling2 extends AbstractNested {}
不过这种方式只能限制SomeClass外部的访问,在SomeClass内部仍然可以通过Sibling1.Sibling2访问,适合仅需对外限制的场景。
3. 调整Sibling2的嵌套层级
把Sibling2从SomeClass的直接嵌套层级移走,比如放到AbstractNested内部,或者作为独立顶级类:
abstract static class AbstractNested extends SomeClass { static class Sibling2 extends AbstractNested {} } static class Sibling1 extends AbstractNested {}
此时new Sibling1.Sibling2()会直接编译报错,因为Sibling1内部没有Sibling2,而AbstractNested的Sibling2需要通过AbstractNested.Sibling2访问。
内容的提问来源于stack exchange,提问作者Jin Kwon
相关产品推荐
相关产品推荐

