何时初始化静态字段?如果我从不实例化一个类,但是我访问一个静态字段,是否所有静态块和私有静态方法用于实例化那个时刻调用的私有静态字段(按顺序)?
如果我调用静态方法怎么办?它是否也运行所有静态块?方法之前?
这个问题来自我的Java test学习指南.有人能解释一下为什么会这样吗?
这段代码打印出5号而不是12号.你能解释一下原因吗?你能解释为什么如果第二个变量也是12,它会打印出来final,如果它们都不是,那么它会打印出来final吗?
public class Question26 {
public static void main(String[] args) {
System.out.println(Q26.q26.ans);
}
}
class Q26 {
public static Q26 q26 = new Q26();
public int ans;
private static final int var1 = 5;
private static int var2 = 7;
public Q26() {
ans = var1 + var2;
}
}
Run Code Online (Sandbox Code Playgroud) public class Dog {
public static Dog dog = new Dog();
static final int val1 = -5;
static int val2 = 3;
public int val3;
public Dog() {
val3 = val1 + val2;
}
public static void main(String[] args) {
System.out.println(Dog.dog.val3);
}
}
Run Code Online (Sandbox Code Playgroud)
输出是 -5
从这个结果来看,似乎初始化val2是在dog成员完成之前及其实例化.
为什么这个订单是这样的?
当我运行这段代码时答案是1,我认为它将是2.初始化的顺序和每一步中k的值是多少?
public class Test {
static {k = 2;}
static int k = 1;
public static void main(String[] args) {
System.out.println(k);
}
}
Run Code Online (Sandbox Code Playgroud)
编辑1:作为"k设置为默认值"的后续内容,为什么下一个代码不能编译?这是一个错误"无法在定义之前引用字段".
public class Test {
static {System.out.println(k);}
static int k=1;
public static void main(String[] args) {
System.out.println(k);
}
}
Run Code Online (Sandbox Code Playgroud)
编辑2:对于一些我不知道的原因,当^而不是"k"它的"Test.k"时它起作用.
感谢所有的答案.这将是完美的:D
我管理一个开源项目,有一个用户报告了一种情况,根据 Java 的类中静态变量的初始化顺序,我认为这是不可能的。一个的价值static final类变量是不正确,显然是从一个依赖的静态方法的不同结果导致基于其自己的静态最终变量。
我想了解发生了什么,以便找出最佳解决方法。此刻,我很困惑。
我的项目的主要入口点是SystemInfo具有以下构造函数的类:
public SystemInfo() {
if (getCurrentPlatform().equals(PlatformEnum.UNKNOWN)) {
throw new UnsupportedOperationException(NOT_SUPPORTED + Platform.getOSType());
}
}
Run Code Online (Sandbox Code Playgroud)
单独运行时,问题不会重现;但是当作为正在执行的许多测试的一部分运行时,一个更大的构建 ( mvn install) 它始终是可重现的,这意味着问题可能与多线程或多个分叉有关。(澄清:我的意思是同时初始化两个不同类中的静态成员,以及与此过程相关的各种 JVM 内部锁定/同步机制。)
他们收到以下结果:
java.lang.UnsupportedOperationException:不支持操作系统:JNA 平台类型 2
此异常意味着SystemInfo实例化开始时有两件事是正确的:
getCurrentPlatform()是枚举值PlatformEnum.UNKNOWNPlatform.getOSType()是2不过,这种情况应该是不可能的;值 2 将返回 WINDOWS,而 unknown 将返回一个非 2 的值。因为两个变量都是static和final它们永远不应该同时达到这个状态。
我试图自己重现这个并失败了,我依赖于用户在他们的基于 Kotlin(kotest)框架中执行测试的报告。
用户的 MCRE 只需调用此构造函数作为在 Windows 操作系统上运行的大量测试的一部分:
public class StorageOnSystemJava {
public StorageOnSystemJava(SystemInfo info) {
}
}
class StorageOnSystemJavaTest …Run Code Online (Sandbox Code Playgroud)