所涉及的静态字段的值发生变化后,布尔值仍为false

问题描述

在我的作业中,我必须使用 enum 来制作符合给定条件的 EnumSet 元素。因此,代码需要尽可能灵活,并允许可应用于 enum 中声明的对象的任何条件。

我一直在测试,我的代码涉及将 enum 的 finals 放入静态上下文中,以便可以将 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 也不能解决问题,因此我认为这不是缓存问题。 那么,为什么布尔值不更新?有解决办法吗?

提前致谢!

解决方法

在@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;
    }
}