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

Passing and setting booleans - Java/Android

提问人:Zippy 提问时间:8/4/2015 最后编辑:Valery ViktorovskyZippy 更新时间:9/18/2015 访问量:109

问:

我有一个这样的课程:

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
}

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

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,但是,它不会影响最初发送到该方法的实际布尔值(如您所见,该布尔值在我的“Achievements”类中定义)。我猜这是因为 Java 是按值传递的,因此正在创建仅在方法内有效的变量的本地副本。我也尝试过使用布尔值(包装类),但得到了相同的结果。

其他方法可以做到这一点吗?

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

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

任何建议都值得赞赏

Java Android 枚举布尔 传递

评论


答:

0赞 Kevin Herron 8/4/2015 #1

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

1赞 darijan 8/4/2015 #2

这都是因为出于安全原因,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;
    }
}

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

然后,您的代码将变为:

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

Java 是按值传递的:

当你传递时,你肯定会通过值传递它,而它是一个基元类型。当你传递时,你会认为它是一个对象,你可以改变它的状态,但实际上你不能,因为它是作为一个不可变的对象实现的(如前所述)。您只需阅读 的代码即可确认这一点。booleanBooleanBooleanjava.lang.Boolean

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

enter image description here

评论

0赞 wastl 8/4/2015
这不会编译,因为您重新分配了最终值。
0赞 darijan 8/4/2015
是的,错误地写了最后。删除了它。
0赞 Zippy 8/4/2015
很好的答案@darijan,我刚刚在我的项目中实现了它 - 干杯!