传递和设置布尔值 - Java/Android

Posted

技术标签:

【中文标题】传递和设置布尔值 - Java/Android【英文标题】:Passing and setting booleans - Java/Android 【发布时间】:2015-10-26 22:25:25 【问题描述】:

我有这样的课:

public class Achievements()

    boolean score100_Earned_Offline;
    boolean score1000_Earned_Offline;

    final String score100 = "xxxxxxxxxx" //where xxxxxxxxxx would be replaced with the achievement's Google Play Games ID
    final  String score1000 = "xxxxxxxxxx" //where xxxxxxxxxx would be replaced with the achievement's Google Play Games ID

在我的 Game 类中,我会检查每个刻度的成就状态,并在必要时对它们采取行动(假设所有方法都是有效且已定义的 - 这已被削减以提供问题所需的代码).. .....

public class Game()

    public void checkAchievements(Achievements achievements)

        if (score>=100)
            unlockAchievement(achievements.score100, achievements.score100_Earned_Offline);     
        

        if (score>1000)
            unlockAchievement(achievements.score100, achievements.score1000_Earned_Offline);  
        
    

    public void unlockAchievement(String achievementToUnlock, boolean thisAchievementOfflineFlag)

        //If user is signed in, then we are ready to go, so go ahead and unlock the relevant achievement....
        if (checkSignedIn())
            Games.Achievements.unlock(getApiClient(), achievementToUnlock);
        //Otherwise, I want to do is set the relevant flag to true so it can be checked when the user does eventually log in
        else
            thisAchievementOfflineFlag=true;
        
    

按值传递

在 'unlockAchievement' 方法中,如果用户未登录,布尔值 'thisAchievementOfflineFlag' 会设置为 true,但是,它不会影响最初发送到方法中的实际布尔值(您可以请参阅在我的“成就”类中定义)。我猜这是因为 Java 是按值传递的,因此创建了仅在方法内部有效的变量的本地副本。我也尝试过使用 Boolean(包装类),但得到了相同的结果。

其他方式来实现这一点?

我目前已经设置好了,所以我可以将每个成就定义为一个枚举,这样每个成就都有自己的布尔标志副本。但是,我知道不建议在 android 中使用枚举,所以如果我缺少更好的方法,我宁愿避免使用它们。

请注意,我不想使用 if 检查或 switch 语句,因为这是在游戏循环中进行的。

任何建议表示赞赏

【问题讨论】:

【参考方案1】:

这都是因为出于安全原因,Java 的 Boolean(也例如 String)实现是不可变的。你可以在这里看到它:http://www.explain-java.com/is-string-mutable-in-java-why-wrapper-classes-immutable-in-java/

您可以通过为该布尔值引入对象包装器来解决您的问题:

public class BooleanWrapper 

    private boolean value;

    public void set(boolean value) 
        this.value = value;
    

    public boolean get() 
        return value;
    

现在,此对象引用将按值传递,但仍将指向 上的同一 BooleanWrapper 对象。您可以简单地使用 getter 和 setter 来更改内部布尔值。

那么你的代码会变成:

public void unlockAchievement(String achievementToUnlock, BooleanWrapper thisAchievementOfflineFlag)
    if (checkSignedIn())
        Games.Achievements.unlock(getApiClient(), achievementToUnlock);
    else 
        thisAchievementOfflineFlag.set(true);
    


Java 是按值传递的:

当您传递boolean 时,您肯定会按值传递它,而它是原始类型。当你传递Boolean 时,你会认为它是一个对象并且你可以改变它的状态,但实际上你不能因为Boolean 被实现为一个不可变 对象(如前所述)。你可以通过阅读java.lang.Boolean的代码来确认这一点。

但是,如果您创建自己的包装类,并且在某种意义上,您可以控制是否以不可变或可变的方式实现它。 BooleanWrapper 我写的让你改变那个对象的状态。当你将一个像this这样的对象传递给方法时,它是按值传递的。这意味着创建了另一个引用,但它指向堆上的同一个对象(见下图)。

【讨论】:

这不会编译,因为您重新分配了最终值。 是的,最后写错了。删除它。 很好的答案@darijan,我刚刚在我的项目中实现了它——干杯!【参考方案2】:

您可以使用 AtomicBoolean,它具有传递引用语义。

【讨论】:

以上是关于传递和设置布尔值 - Java/Android的主要内容,如果未能解决你的问题,请参考以下文章

如何将管道中的布尔参数值传递给下游作业?

通过 Ajax 将布尔值传递给 asp.net api 控制器

Opengl顶点着色器为每个顶点设置布尔值(glVertexAttribPointer)

java布尔值在被调用方法中没有改变[重复]

JSON 序列化程序 - 当布尔值设置为 false 时,前端缺少键

通过 PHP GET 传递布尔值