尝试访问继承字段时发生NullPointerException
在尝试访问父类中的重写变量时,我正在获取NPE
java.lang.NullPointerException: Attempt to get length of null array at app.deadmc.materiallivewallpaper.model.Square.<init>(Square.kt:29) at app.deadmc.materiallivewallpaper.model.Cube.<init>(Cube.kt:8) at app.deadmc.materiallivewallpaper.renderer.MaterialRenderer.onSurfaceCreated(MaterialRenderer.kt:40) at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1548) at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1286)
我将展示简化的代码,以解决未知的问题
我有一个绘画广场的课
open class Square(renderer: ReadyRenderer) { val COORDS_PER_VERTEX = 3 open val triangleCoords = floatArrayOf( //first triangle -1.0f, 1.0f, 0.0f, -1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 0.0f, //second triangle -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 0.0f) private val vertexCount:Int = triangleCoords.size / COORDS_PER_VERTEX init { val bb = ByteBuffer.allocateDirect( triangleCoords.size * 4) //other code } }
广场正常工作,但现在我想绘制立方体,所以我只是从方形继承,并添加更多的坐标
open class Cube(renderer: ReadyRenderer):Square(renderer) { val size = 1.0f override val triangleCoords = floatArrayOf( //front side // Triangle 1 -size, size, size, // top-left -size, -size, size, // bottom-left size, -size, size, // bottom-right // Triangle 2 size, -size, size, // bottom-right size, size, size, // top-right -size, size, size, // top-left //and then back side, left, top, right with same way ) }
似乎逻辑,对吗? 所有的变量都有价值,NPE应该没有地方。
但是当我尝试创建Cube的实例
val cube = Cube(this@MaterialRenderer)
我在这一行捕获了Square类中的NullPointerException:
private val vertexCount:Int = triangleCoords.size / COORDS_PER_VERTEX
即使我直接分配价值
private val vertexCount:Int = 2
在这一行,我将在init块内的Square类中获得NPE:
val bb = ByteBuffer.allocateDirect( triangleCoords.size * 4)
所以我有两个问题:
1.我该如何修复它,仍然使用继承?
来自“简明英汉词典”它真的应该这样工作吗
如果你看着编辑器,它实际上警告你在构造函数中使用非final属性。 发生这种情况是因为在创建Cube
,首先需要创建一个Square
。 Square
创建时, Cube
不被初始化。 ( triangleCoords
为null)因此, triangleCoords.size
会抛出异常。
我怎样才能解决它,仍然使用继承?
你应该把它作为参数传递。
open class Square(protected val triangleCoords: FloatArray = floatArrayOf( //first triangle -1.0f, 1.0f, 0.0f, -1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 0.0f, //second triangle -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 0.0f)) { val COORDS_PER_VERTEX = 3 private val vertexCount: Int = triangleCoords.size / COORDS_PER_VERTEX init { val bb = ByteBuffer.allocateDirect( triangleCoords.size * 4) //other code } } open class Cube(val size: Float = 1.0f) : Square(floatArrayOf( //front side // Triangle 1 -size, size, size, // top-left -size, -size, size, // bottom-left size, -size, size, // bottom-right // Triangle 2 size, -size, size, // bottom-right size, size, size, // top-right -size, size, size, // top-left //and then back side, left, top, right with same way )) { }
如果你觉得这很丑,你可以编写一个工厂方法,并通过参数传递给一个私有的构造函数。
它真的应该这样工作吗?
是