java - 从匿名类内部访问变量

标签 java class anonymous-class

我有一个匿名类,我想从匿名类访问外部类的一些变量。问题是,当我尝试访问它时,它的值始终与初始化时相同,即使我正在另一个匿名类上更改它的值。

这是修剪后的代码

public class WeaponCircle extends Entity {
    public static int TAG = gWorld.getNextTag();
    float power=99; // <<<--the variable
    public WeaponCircle(final gWorld world) {
        super(world);
        this.tag = TAG;

        setGroups(Scene.SLOWABLE);

        addMechanism(new IntervalMechanism(this,10) {
            @Override
            public void init() {
                super.init();
                    world.worldrenderer.setWorldShader("punchShockWave");
                    world.worldrenderer.getShader("punchShockWave").getShader().setUniformf("screenSize",  Tools.tempVec2.set(Gdx.graphics.getWidth(),Gdx.graphics.getHeight()));
                    power=4;
            }
            @Override
            public void die() {
                super.die();
                world.worldrenderer.setClearWorldShader();
            }
            @Override
            public void tick() {//this is called every frame
                if(power>0)power-=0.1f*Director.delta;
                Tools.con("debug0:"+power);    //<<--------------------debug0 ,prints correct value
            }
        });

        addMechanism(new MovementMechanism(this));

        addMechanism(new SpriteMechanism(this,"sprites/sprites.png",714,284,1,235,235,gWorld.RENDER_LAYER4));

        world.worldrenderer.addShader("punchShockWave", new Shader("shaders/default.ver","shaders/punch_shock_wave.frag",Shader.SCENE_SHADER));
        world.worldrenderer.getShader("punchShockWave").setListener(new ShaderParrametersListener(this) {
            @Override
            public void setParameters(Shader shader) {//called every frame
                WeaponCircle wc=(WeaponCircle)entity;//entity is the object that i passed in the constractor
                /*irrelevant code*/
                Tools.con("debug1:"+wc.power);  //<<--------------------debug1 ,prints always 99
                Tools.con("debug2:"+power);   //<<--------------------debug2 ,prints always 99
                /*irrelevant code*/
            }
        });
    }
}

ShaderParrametersListener(它是 Shader 类中的静态类)

public abstract static class ShaderParrametersListener{
    public Entity entity;
    abstract public void setParameters(Shader shader);
    public ShaderParrametersListener(){};
    public ShaderParrametersListener(Entity entity){this.entity=entity;}
}

我的实体系统基于匿名类,到目前为止我没有遇到任何问题,如果我再使用 1 个 IntervlMechanism 并从那里打印 power 变量,我将获得正确的值。这只发生在 ShaderParrametersListener 类中。

最佳答案

我认为您的问题是您在构造函数中使用了 this 关键字。请参阅Java - Leaking this in constructor .

正如链接的答案所说,

"An object is considered to be completely initialized when its constructor finishes. A thread that can only see a reference to an object after that object has been completely initialized is guaranteed to see the correctly initialized values for that object's final fields". No such guarantee if you leak this to another thread in the constructor! Also 'at the end of the constructor' may be reordered by the VM."

我的猜测是,world.worldrenderer.getShader("punchShockWave").setListener其他线程,现在可以访问未完全构造的对象。

我建议在构造函数完成后找到一种方法来调用上述 setListener 方法。

更新我发现power字段不是final,因此这可能使我的假设无效,因为链接的问题似乎表明此问题仅适用于final字段;但是,我仍然会尝试等到构造函数完成后再将 this 传递给另一个对象。也许尝试一下,看看是否修复了错误。

关于java - 从匿名类内部访问变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24584369/

相关文章:

php - fatal error : Function name must be a string in.。 PHP错误

actionscript-3 - Flex 4 两个类在一个文件中

java - 我的代码是否创建Java接口(interface)的对象?

java - 如何替换以特定字符开头和结尾的所有子字符串?

java - 从 jar 执行中获取 Java 覆盖率

java - 在jsp文件中动态创建url

java - 无法调用匿名类方法

java - 如何在 Android 中将 TextView 放置在 LinearLayout 的上边缘?

C 数据类型创建

java - 从匿名类调用新定义的方法