我有一个类似的课程:
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 检查或切换语句,因为这是在游戏循环中进行的。
任何建议赞赏
答案 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
允许您更改该对象的状态。当你将一个像这样的对象传递给方法时,它会按值传递。这意味着创建了另一个引用,但它指向堆上的同一个对象(参见下图)。
答案 1 :(得分:0)
您可以使用AtomicBoolean
,它将具有传递引用语义。