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

时间:2015-08-04 13:25:06

标签: java android enums boolean pass-by-value

我有一个类似的课程:

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类中,我检查每个tick的成就状态,并根据需要对它们进行操作(假设所有方法都有效并定义 - 这是为了提供问题所需的代码)。 .....

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,但是,它不会影响最初发送到方法中的实际布尔值(尽管如此) see在我的'Achievements'课程中定义。我猜这是因为Java是Pass by Value,因此,创建一个仅在方法内有效的变量的本地副本。我也尝试过使用布尔(包装类),但得到了相同的结果。

实现此目的的其他方法?

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

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

任何建议赞赏

2 个答案:

答案 0 :(得分: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允许您更改该对象的状态。当你将一个像这样的对象传递给方法时,它会按值传递。这意味着创建了另一个引用,但它指向堆上的同一个对象(参见下图)。

enter image description here

答案 1 :(得分:0)

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