当前位置: 首页 > 知识库问答 >
问题:

为什么这个私有浮动字段变为零?

马淳
2023-03-14

我有一些奇怪的行为,我正努力向自己解释。浮点字段,称为“文本缩放”,变为零。

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

有谁能帮我理解这里可能发生的事情吗?为什么这个浮动会变成零,除非我把它设为最终值?这里有我不熟悉的Java ism吗?唯一的解释是否在其他地方的代码中有些模糊?

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?!
    }
}

共有2个答案

简滨海
2023-03-14

我期望duUpdateGeometryTenture()是从超级类的构造函数调用的。当您这样做时,您将在子类的构造函数完成之前访问它,并且不会设置所有字段。

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

梁丘伟
2023-03-14

在方法中设置断点。是从超级构造函数调用的吗?如果是这样,该字段在该点上不初始化,因为超级构造函数在子类的字段初始化之前被调用。

如果将字段声明为final,编译器可能会将字段访问替换为常量表达式,这将使其正常工作

 类似资料:
  • 问题内容: 在大学里学习时,我不得不做一些难看的Java基础知识,例如不使用封装就可以工作,同一类中的主要方法等。(我不想在Java样式指南上展开讨论,我只是想澄清一下,我不会在大学以外写这样的东西) 我偶然发现了一种我无法向自己解释的行为: 为什么这段代码可以编译并正确运行?我怎么可能访问私有字段?由于主类位于同一类中,因此行为异常? 问题答案: 由于静态方法是类的成员,因此可以访问中的任何私有

  • 约书亚·布洛赫在高效的Java中写道: 请注意,非零长度数组总是可变的,因此类具有公共静态最终数组字段或返回此类字段的访问器是错误的。如果类具有这样的字段或访问器,客户端将能够修改数组的内容。这是安全漏洞的常见来源: 请注意,许多IDE生成的访问器会返回对私有数组字段的引用,这恰恰导致了这个问题。有两种方法可以解决这个问题。您可以将公共数组设为私有,并添加公共不可变列表: 或者,可以将数组设为私有

  • 问题内容: 最近,我观察到在Java中访问priavte字段的意外行为。考虑以下示例,该示例说明了该行为: 为什么我可以访问类的其他对象的私有字段的内法(第二种情况)? 问题答案: 私有字段保护一个类,而不是实例。主要目的是允许一个类独立于其API实现。在它们之间隔离实例,或从相同类的静态代码中保护实例的代码都不会带来任何好处。

  • 问题内容: 我有这段简单的代码。 当我运行上面的代码时,该对象被打印为null。(我得到 “ Object = null” ) 令人惊讶的是,在类Y中,当我删除null声明时 打印对象的实际值。 类似于( “ Object = java.lang.Object@3cd1a2f1” )之 类的现象为何被观察到?“这个”指的是什么?如果仅声明对象,则将其初始化为null,那么为什么会有这种异常行为呢?

  • 令牌“if”的语法错误(应在此令牌之后 谢谢你的建议!

  • 问题内容: 为什么Java有瞬态字段? 问题答案: 在中关键字用于指示字段不应该是系列化的一部分(这意味着保存,像一个文件)的过程。 从Java语言规范,Java SE 7中版,第8.3.1.3节。transient领域: 可以标记变量transient以指示它们不是对象持久状态的一部分。 例如,你可能具有从其他字段派生的字段,并且仅应以编程方式进行操作,而不要通过序列化来保持状态。 这是一个包含