java - “范围内没有 file1 类型的封闭实例”内部类错误
问题描述
我有一些代码(本质上它导入了这个其他类,它有一个我试图访问的内部类),但它带来了这个错误:
file2.java:5: error: no enclosing instance of type file1 is in scope
public static class file3 extends file2.Inner {
“范围内没有 file1 类型的封闭实例”是什么意思?
这是代码:
package test;
import secret.file1;
public class file2 extends file1 {
public static class file3 extends file2.Inner {
public static void main(String[] args) {
file3 outer = new file3();
System.out.println(outer.x);
}
}
}
file1的代码:
package secret;
public class file1 {
protected class Inner {
public int x = 8;
}
}
解决方案
仅用于教育目的,请勿在实践中使用。
内部类具有这种独特的行为,其中所有构造函数都在第一个位置隐式声明封闭类型的参数。所以,
public class file1 {
public class Inner {
}
}
实际上被编译成类似的东西
public class file1 {
public class Inner {
public Inner(file1 enclosing) {
}
}
}
whereenclosing
实际上是Outer
对其初始化的封闭实例的引用。
new file1().new Inner();
// compiles to something like
file1 enclosing = new file1();
new Inner(enclosing);
请记住,对于常规继承,如果超类声明了一个参数化构造函数(并且没有无参数构造函数),则子类必须使用super(...)
它自己的构造函数来调用它。通过内部类的继承,如果还隐式提供了封闭实例,则可以隐式super(...)
执行该调用。
file3
也就是说,如果实际上也是file1
(或file2
)的内部类,而不是嵌套类,则您的类层次结构将被编译。
public class file2 extends file1 {
public class file3 extends file2.Inner {
}
}
正如我之前所说,file3
将编译为类似
public class file3 extends file2.Inner {
public file3(file2 enclosing) {
super(enclosing); // this is calling the `public Inner(file1)` constructor
}
}
由于“类型的封闭实例在范围内” ,因此该调用将隐式super(..)
完成。file1
但是,由于您的file3
类不是file1
nor的内部类file2
,因此没有隐式封闭file1
实例可以传递给超级构造函数,因此 Java 编译器会产生您看到的错误。
我一直隐含地加粗这个词,试图强调 Java 允许您显式绕过所有这些的事实。此功能是内部类独有的。Java 提供以下语法来声明带有参数(在任何位置)的构造函数,以明确地被视为封闭实例
public static class file3 extends file2.Inner {
public file3(file2 enclosing) {
enclosing.super(); // special syntax
}
// [...]
}
而且,就像常规继承一样,该super(..)
调用必须是构造函数主体中的第一条语句。
然后你的main
方法就变成了
file2 file2 = new file2();
file3 outer = new file3(file2);
System.out.println(outer.x);
file2.Inner
您在其中明确提供(也可以通过)所需的封闭实例null
。
供您参考,还有显式声明我在第二个片段中提到的构造函数的语法,其中参数表示封闭实例
public class file1 {
public class Inner {
public Inner(@SomeAnnotation file1 file1.this) {
}
}
}
这仅在您要注释参数时才真正有用。
这些信息分布在Java 语言规范的第 8 章中,特别是关于“内部类”和“接收器参数”的部分。
推荐阅读
- python - 将数组中的最大值附加到另一个数组时索引错误
- ruby-on-rails - 使用 PSQL 在 Rails 数据库中创建重复索引
- php - 无法在 Wordpress 中获取特定的帖子附件
- javascript - 更改表行中的 [(ngModel)] 值将影响正文中存在的所有行。如何修复它?
- mongodb - 使用副本成员作为独立服务器?MongoDB
- excel - 如何找到工作表中存在的所有值?
- pandas - 在 jupyterlab 中的 pandas df 中呈现超链接
- java - 如何将 JSON 消息转换为具有可为空字段的 avro 模式的有效 JSON?
- stored-procedures - 在我的 MySQL 存储过程中使用事务和更新查询如何确保更新完成
- hibernate - 如何使用 spring-data-jpa 和复合键保存多对多关系