传递和设置布尔值 - Java/Android
Passing and setting booleans - Java/Android
我有一个 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
}
在我的游戏 class 中,我每次检查成就的状态并在必要时像这样对它们采取行动(假设所有方法都是有效的和定义的 - 这被削减以提供必要的代码问题)......
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' class 中定义)。我猜这是因为 Java 是按值传递的,因此创建了仅在方法内部有效的变量的本地副本。我也尝试过使用 Boolean(包装器 class)但得到了相同的结果。
其他实现方法?
我目前已经设置好了,所以我可以将每个成就定义为一个枚举,这样每个成就都会有自己的布尔标志副本。但是,我知道不建议在 Android 中使用枚举,因此如果我遗漏了更好的方法,我宁愿避免使用它们。
请注意,我不想使用 if 检查或 switch 语句,因为这是在游戏循环中发生的.
感谢任何建议
您可以使用 AtomicBoolean
,它将具有传递引用语义。
这都是因为 Java 出于安全原因,布尔值(也例如字符串)的实现是 不可变的 。你可以在这里看到它: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
被实现为一个 immutable 对象(如前所述)。您可以通过阅读 java.lang.Boolean
的代码来确认这一点。
但是,如果您创建自己的包装器 class,从某种意义上说,您可以控制以不可变或可变方式实现它。 BooleanWrapper
我写的可以让你改变那个对象的状态。当您将像这样的对象传递给方法时,它是按值传递的。这意味着创建了另一个引用,但它指向堆上的同一个对象(见下图)。
我有一个 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
}
在我的游戏 class 中,我每次检查成就的状态并在必要时像这样对它们采取行动(假设所有方法都是有效的和定义的 - 这被削减以提供必要的代码问题)......
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' class 中定义)。我猜这是因为 Java 是按值传递的,因此创建了仅在方法内部有效的变量的本地副本。我也尝试过使用 Boolean(包装器 class)但得到了相同的结果。
其他实现方法?
我目前已经设置好了,所以我可以将每个成就定义为一个枚举,这样每个成就都会有自己的布尔标志副本。但是,我知道不建议在 Android 中使用枚举,因此如果我遗漏了更好的方法,我宁愿避免使用它们。
请注意,我不想使用 if 检查或 switch 语句,因为这是在游戏循环中发生的.
感谢任何建议
您可以使用 AtomicBoolean
,它将具有传递引用语义。
这都是因为 Java 出于安全原因,布尔值(也例如字符串)的实现是 不可变的 。你可以在这里看到它: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
被实现为一个 immutable 对象(如前所述)。您可以通过阅读 java.lang.Boolean
的代码来确认这一点。
但是,如果您创建自己的包装器 class,从某种意义上说,您可以控制以不可变或可变方式实现它。 BooleanWrapper
我写的可以让你改变那个对象的状态。当您将像这样的对象传递给方法时,它是按值传递的。这意味着创建了另一个引用,但它指向堆上的同一个对象(见下图)。