4

我有一些奇怪的行为,我正在努力向自己解释。一个名为“textureScale”的浮点字段变为零。

如果某些代码正在更改值,则可以解释这一点。但是,我希望能够通过将其设置为“私有最终浮点数”来导致构建失败,或者至少是运行时异常——然后任何改变值的东西都会失败。但如果我这样做,代码根本不会失败——它工作得很好!

任何人都可以帮助我理解这里可能发生的事情 - 为什么这个浮点数会变为零,除非我将它设置为最终值?这里有我不熟悉的 Java 主义吗?唯一的解释是其他地方的代码有些晦涩难懂吗?

public class TexturedBox extends Box {
    // This field becomes 0.0?
    private float textureScale = 1.0f;

    public TexturedBox(Vector3f center, float x, float y, float z) {
        super(center, x, y, z);
    }

    @Override
    protected void duUpdateGeometryTextures() {
        FloatBuffer buf = BufferUtils.createFloatBuffer(24);

        buf.clear();

        // All the values in these puts are "zero" - since textureScale is now zero?
        buf.put(textureScale * 2f * xExtent); buf.put(0);
        buf.put(0); buf.put(0);
        buf.put(0); buf.put(textureScale * 2f * yExtent);
        buf.put(textureScale * 2f * xExtent); buf.put(textureScale * 2f * yExtent);
        // ... and more puts just like that ...

        buf.flip();

        setBuffer(Type.TexCoord, 2, buf);

        System.out.println(textureScale);
        // ^ This outputs zero
        // ... unless I set textureScale to final - then everything works?!
    }
}
4

2 回答 2

10

Set a breakpoint in the method. Is it called from the super constructor? If so, the field is not initialized at that point, because the super-constructor is called before the field initialization of the subclass.

If you declare the field final, the compiler may replace the field access with a constant expression, which will make it work

于 2013-10-08T20:18:01.617 回答
5

我希望这duUpdateGeometryTextures()是从您的超类的构造函数中调用的。执行此操作时,您将在子类的构造函数完成之前访问子类,并且不会设置所有字段。

在您的情况下,在调用 super之后设置非最终字段。最终字段实际上是静态字段并首先被初始化。

于 2013-10-08T20:20:07.520 回答