涉及的静态字段的值发生变化后,布尔值保持为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;
    }
}