Kotlin/Java,在方法调用时尚未初始化字符串数组
在我的一个程序中,我得到了一个空异常,调试代码时我发现这是因为我的一个(): 在后续()中需要时尚未初始化: 如果我把它移进去:Kotlin/Java,在方法调用时尚未初始化字符串数组,java,exception,null,kotlin,Java,Exception,Null,Kotlin,在我的一个程序中,我得到了一个空异常,调试代码时我发现这是因为我的一个(): 在后续()中需要时尚未初始化: 如果我把它移进去: fun initializePrograms(gl: GL3) { val FRAGMENTS = arrayOf("phong-lighting", "phong-only", "blinn-lighting", "blinn-only") ... } 那么一切都好了。。为什么? Ps:同样的代码和行为在java中也是一样的 编辑:不要混淆,ini
fun initializePrograms(gl: GL3) {
val FRAGMENTS = arrayOf("phong-lighting", "phong-only", "blinn-lighting", "blinn-only")
...
}
那么一切都好了。。为什么?
Ps:同样的代码和行为在java中也是一样的
编辑:不要混淆,init
不是类init
,它扩展了方法
Edit2:initializePrograms()
不会从超级构造函数调用。它是从哪个重写调用的,它应该是从另一个线程开始调用的 理由
如果在超类构造函数中调用方法initializePrograms
,则崩溃是一种预期行为。类的属性是在构造对象之后初始化的,所以在构造对象之前它们是未初始化的
在这种情况下,因为arrayOf
函数是一个内联函数,所以它在反编译类上清晰可见:
public final class Test {
@NotNull
private final String[] FRAGMENTS;
...
public Test() {
super();
String[] elements$iv = new String[]{"phong-lighting", "phong-only", "blinn-lighting", "blinn-only"};
Object[] var4 = (Object[])elements$iv;
this.FRAGMENTS = (String[])var4;
}
}
请注意Test
类的构造函数以及调用super()
后如何初始化属性
请注意,如果要使用not inline函数初始化该属性(例如,listOf
),则初始化将与声明结合在一起,但实际上是相同的,只是没有那么明确。在Java中,此字段也将在构造函数完成后初始化
public final class Test {
@NotNull
private final List FRAGMENTS = CollectionsKt.listOf(new String[]{"phong-lighting", "phong-only", "blinn-lighting", "blinn-only"});
...
}
解决方案
最有可能的是,您试图实现的(考虑到所有caps片段)是将其声明为一个静态字段。在Kotlin中,您可以通过将其嵌套在特定类中的伴生对象中来实现这一点
class Test {
...
companion object {
val FRAGMENTS = arrayOf("phong-lighting", "phong-only", "blinn-lighting", "blinn-only")
}
}
然后,正如您在反编译类上看到的,它被声明为静态字段,并在static
块中初始化:
public final class Test {
@NotNull
private static final String[] FRAGMENTS;
...
static {
String[] elements$iv = new String[]{"phong-lighting", "phong-only", "blinn-lighting", "blinn-only"};
FRAGMENTS = (String[])((Object[])elements$iv);
}
}
类方法不是在超级构造函数中调用的吗?如果是,那么原因是超级构造函数是在属性初始化之前被调用的。是的,我认为是这样,并检查了它,但我认为不是这样。这对我来说有点神秘。我对Kotlin不太了解,你能在方法之外用关键字(私有或公共)识别变量,看看它是否有效吗?@hotkey不,它不起作用。initializePrograms()
从init(GL3 gl)
调用,它覆盖Framework.init(GL3 gl)
从Framework.init(GLAutoDrawable autoDrawable)
调用,从Animator
开始调用一次,应该是另一个线程。@在youngChoung中,您可以查看并行java代码(在括号中引用)
class Test {
...
companion object {
val FRAGMENTS = arrayOf("phong-lighting", "phong-only", "blinn-lighting", "blinn-only")
}
}
public final class Test {
@NotNull
private static final String[] FRAGMENTS;
...
static {
String[] elements$iv = new String[]{"phong-lighting", "phong-only", "blinn-lighting", "blinn-only"};
FRAGMENTS = (String[])((Object[])elements$iv);
}
}