涉及的静态字段的值发生变化后,布尔值保持为false
Boolean value remains false after the value of the static field involved changes
在我的作业中,我必须使用 enum
来制作符合给定标准的 EnumSet
元素。因此,代码需要尽可能灵活,并允许可以应用于 enum
.
中声明的对象的任何条件。
我一直在测试,我的代码涉及将 enum
的末尾放入静态上下文中,以便可以将 boolean
应用于它们,然后循环遍历每个在 enum
中声明对象以查看它们是否符合条件。但出于某种原因,当静态字段的值符合条件时,boolean
的状态不会更改为 true
。
这是我的代码:
public class test {
// enumeration of persons by age and sex
enum Name {
Adam("Male", 17),
Amy("Female", 24),
Boris("Male", 12),
Bella("Female", 16);
final String _sex;
final int _age;
// static variants to "turn" values to the static context
volatile static String sex = "";
volatile static int age = 0;
Name(String sex, int age) {
_sex = sex;
_age = age;
}
}
public static void main(String[] args) {
// creating a set of people older than 17
EnumSet<Name> set = makeSet(Name.age >= 17);
System.out.print(set.toString());
}
static EnumSet<Name> makeSet(boolean query) {
EnumSet<Name> set = EnumSet.noneOf(Name.class);
for (Name element : Name.values()) {
// this is the "turning" of the values to the static context
Name.sex = element._sex;
Name.age = element._age;
// PROBLEM LIES HERE
// the query remains false, even when age is above 17
if (query) {
set.addAll(EnumSet.of(element));
}
}
return set;
}
}
将静态字段更改为 volatile
也无法解决问题,因此我认为这不是缓存问题。
那么,为什么布尔值不更新?有解决办法吗?
您面临的问题是 predicate
(Name.age >= 17
) 在函数调用时被检查:
当您调用 makeSet(Name.age >= 17)
时,实际发生的是 predicate
returns 一个布尔值,在检查 returns false
时,因此 false
被解析为函数。
@Turing85 在评论中回答
出现问题是因为 boolean
正在按值传递。
使用 Predicate
而不是 boolean
解决了这个问题,因为对象引用将被传递,允许在调用 makeSet()
方法后更改值。
此外,这消除了将 enum
的决赛带入静态上下文的需要。
这是我的代码:
public class test {
// enumeration of persons by age and sex
enum Name {
Adam("Male", 17),
Amy("Female", 24),
Boris("Male", 12),
Bella("Female", 16);
final String sex;
final int age;
Name(String sex, int age) {
this.sex = sex;
this.age = age;
}
}
public static void main(String[] args) {
// creating a set of people older than 17
EnumSet<Name> set = makeSet(query -> query.age >= 17);
System.out.print(set.toString());
}
static EnumSet<Name> makeSet(Predicate<Name> query) {
EnumSet<Name> set = EnumSet.noneOf(Name.class);
for (Name element : Name.values()) {
// PROBLEM FIXED
if (query.test(element)) {
set.addAll(EnumSet.of(element));
}
}
return set;
}
}
在我的作业中,我必须使用 enum
来制作符合给定标准的 EnumSet
元素。因此,代码需要尽可能灵活,并允许可以应用于 enum
.
我一直在测试,我的代码涉及将 enum
的末尾放入静态上下文中,以便可以将 boolean
应用于它们,然后循环遍历每个在 enum
中声明对象以查看它们是否符合条件。但出于某种原因,当静态字段的值符合条件时,boolean
的状态不会更改为 true
。
这是我的代码:
public class test {
// enumeration of persons by age and sex
enum Name {
Adam("Male", 17),
Amy("Female", 24),
Boris("Male", 12),
Bella("Female", 16);
final String _sex;
final int _age;
// static variants to "turn" values to the static context
volatile static String sex = "";
volatile static int age = 0;
Name(String sex, int age) {
_sex = sex;
_age = age;
}
}
public static void main(String[] args) {
// creating a set of people older than 17
EnumSet<Name> set = makeSet(Name.age >= 17);
System.out.print(set.toString());
}
static EnumSet<Name> makeSet(boolean query) {
EnumSet<Name> set = EnumSet.noneOf(Name.class);
for (Name element : Name.values()) {
// this is the "turning" of the values to the static context
Name.sex = element._sex;
Name.age = element._age;
// PROBLEM LIES HERE
// the query remains false, even when age is above 17
if (query) {
set.addAll(EnumSet.of(element));
}
}
return set;
}
}
将静态字段更改为 volatile
也无法解决问题,因此我认为这不是缓存问题。
那么,为什么布尔值不更新?有解决办法吗?
您面临的问题是 predicate
(Name.age >= 17
) 在函数调用时被检查:
当您调用 makeSet(Name.age >= 17)
时,实际发生的是 predicate
returns 一个布尔值,在检查 returns false
时,因此 false
被解析为函数。
@Turing85 在评论中回答
出现问题是因为 boolean
正在按值传递。
使用 Predicate
而不是 boolean
解决了这个问题,因为对象引用将被传递,允许在调用 makeSet()
方法后更改值。
此外,这消除了将 enum
的决赛带入静态上下文的需要。
这是我的代码:
public class test {
// enumeration of persons by age and sex
enum Name {
Adam("Male", 17),
Amy("Female", 24),
Boris("Male", 12),
Bella("Female", 16);
final String sex;
final int age;
Name(String sex, int age) {
this.sex = sex;
this.age = age;
}
}
public static void main(String[] args) {
// creating a set of people older than 17
EnumSet<Name> set = makeSet(query -> query.age >= 17);
System.out.print(set.toString());
}
static EnumSet<Name> makeSet(Predicate<Name> query) {
EnumSet<Name> set = EnumSet.noneOf(Name.class);
for (Name element : Name.values()) {
// PROBLEM FIXED
if (query.test(element)) {
set.addAll(EnumSet.of(element));
}
}
return set;
}
}