将值传递给超构造函数时无法从静态上下文访问字段
Cannot access field from static context when passing value to superconstructor
我遇到了一个非常奇怪的编译时错误:
class Super {
Super(int[] array) {
}
}
class Sub extends Super {
private final int number = 1;
Sub() {
super(new int[] { number }); //error
}
}
我得到的错误是
Cannot access field from static context
我的问题
静态上下文在哪里?似乎 static 甚至不会在这里发挥作用。
我偶然发现了这个试图回答别人问题的问题;发现我莫名其妙的错误。有人可以解释静态上下文在哪里吗?
您的字段 number
应该是静态的,以便您可以在构造函数调用中使用它。否则你会得到 cannot reference number before supertype constructor has been called
因为在调用父 class.
的构造函数之前无法访问该字段
因此您的代码应如下所示:
class Super {
Super(int[] array) {
}
}
class Sub extends Super {
private static final int number = 1;
Sub() {
super(new int[] { number }); //error
}
}
问题是,super
必须在子类中执行任何其他操作之前调用。这意味着 number
在调用时未初始化,因此您不能将其传递给 super。
至于和"static context"有什么关系,我也不清楚。
An explicit constructor invocation statement in a constructor body may not refer to any instance variables or instance methods or inner classes declared in this class or any superclass, or use this
or super
in any expression; otherwise, a compile-time error occurs.
在 super
调用时 Sub
的实例尚不存在
尝试运行以下程序。
public class Main {
public static class Super
{
Super(int number) {
System.out.println("A");
}
}
public static class Sub extends Super {
private final Thing thing = new Thing();
Sub() {
super(3);
System.out.println("B");
}
}
public static final class Thing {
Thing() {
System.out.println("C");
}
}
public static void main(String[] args) {
new Sub();
}
}
输出A、C、B。先运行Super
的构造函数,然后初始化Sub
的实例字段thing
。最后 Sub
构造函数中跟随 super
的行被执行。
当您尝试引用 number
时,字段 number
尚未初始化并且没有 Sub
实例。错误消息可能更有帮助。在 IntelliJ 上,我得到 "Cannot reference Sub.number before supertype constructor has been called"。
classes 的加载是从子 class(如果它有 main 方法或由其他 class 加载)到基础 class 但 初始化以相反的顺序发生(基础class将首先初始化)。 base class 初始化已经完成,那时你的数字字段将不存在,因为它是实例变量。
你可以让它 static(class variable) 加载得更早,如果它的 final 那么编译器会做一个在编译时 常量池 中的条目 only.so JVM 将能够获取其值。
我遇到了一个非常奇怪的编译时错误:
class Super {
Super(int[] array) {
}
}
class Sub extends Super {
private final int number = 1;
Sub() {
super(new int[] { number }); //error
}
}
我得到的错误是
Cannot access field from static context
我的问题
静态上下文在哪里?似乎 static 甚至不会在这里发挥作用。
我偶然发现了这个试图回答别人问题的问题;发现我莫名其妙的错误。有人可以解释静态上下文在哪里吗?
您的字段 number
应该是静态的,以便您可以在构造函数调用中使用它。否则你会得到 cannot reference number before supertype constructor has been called
因为在调用父 class.
因此您的代码应如下所示:
class Super {
Super(int[] array) {
}
}
class Sub extends Super {
private static final int number = 1;
Sub() {
super(new int[] { number }); //error
}
}
问题是,super
必须在子类中执行任何其他操作之前调用。这意味着 number
在调用时未初始化,因此您不能将其传递给 super。
至于和"static context"有什么关系,我也不清楚。
An explicit constructor invocation statement in a constructor body may not refer to any instance variables or instance methods or inner classes declared in this class or any superclass, or use
this
orsuper
in any expression; otherwise, a compile-time error occurs.
在 super
调用时 Sub
的实例尚不存在
尝试运行以下程序。
public class Main {
public static class Super
{
Super(int number) {
System.out.println("A");
}
}
public static class Sub extends Super {
private final Thing thing = new Thing();
Sub() {
super(3);
System.out.println("B");
}
}
public static final class Thing {
Thing() {
System.out.println("C");
}
}
public static void main(String[] args) {
new Sub();
}
}
输出A、C、B。先运行Super
的构造函数,然后初始化Sub
的实例字段thing
。最后 Sub
构造函数中跟随 super
的行被执行。
当您尝试引用 number
时,字段 number
尚未初始化并且没有 Sub
实例。错误消息可能更有帮助。在 IntelliJ 上,我得到 "Cannot reference Sub.number before supertype constructor has been called"。
classes 的加载是从子 class(如果它有 main 方法或由其他 class 加载)到基础 class 但 初始化以相反的顺序发生(基础class将首先初始化)。 base class 初始化已经完成,那时你的数字字段将不存在,因为它是实例变量。
你可以让它 static(class variable) 加载得更早,如果它的 final 那么编译器会做一个在编译时 常量池 中的条目 only.so JVM 将能够获取其值。