[英]Passing and setting booleans - Java/Android
我有一个像这样的课程:
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中使用枚举,因此,如果缺少更好的方法,我宁愿避免使用它们。
请注意,我不想,如果支票或switch语句,因为这是发生在一个游戏循环使用。
任何建议表示赞赏
这是因为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
可让您更改该对象的状态。 当您将一个这样的对象传递给方法时,它会按值传递。 这意味着将创建另一个引用,但它指向堆上的同一对象(请参见下图)。
您可以使用AtomicBoolean
,它具有按引用传递的语义。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.