java - 传递和设置 boolean 值 - Java/Android

标签 java android enums boolean pass-by-value

我有一个像这样的类(class):

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

还有其他方法可以实现这一目标吗?

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

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

任何建议表示赞赏

最佳答案

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

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

public class BooleanWrapper {

    private boolean value;

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

    public boolean get() {
        return value;
    }
}

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

那么你的代码将变成:

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 可以让您更改该对象的状态。当您将一个像这样的对象传递给该方法时,它是按值传递的。这意味着创建了另一个引用,但它指向堆上的同一个对象(见下图)。

enter image description here

关于java - 传递和设置 boolean 值 - Java/Android,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31810572/

相关文章:

java - 是否可以禁用 JSpinner 向下箭头按钮?如何?

java - 使用 Realm 支持枚举?

java - 如何使用 ints 而不是 Enumerator.value 初始化枚举器数组

java - 使用WebFlux时如何使用HTTP DELETE发送正文?

java - 如何在Java中多次打印一个对象?

java - Jpa条件,将枚举类型转换为字符串

android - 如何 fork 整个 Android 操作系统的代码?

android - Firebase 查询 : equalTo on a list

java - Android 从 drawable 释放内存

c - C 中枚举类型变量的用途