问题描述
在枚举中使用修饰符 static
和 final
声明 EnumSet 是否有意义?还是多余的?
示例:
public enum guitar {
STRATOCASTER,LES_PAUL,CLASSIC;
private static final EnumSet electrics = EnumSet.of(STRATOCASTER,LES_PAUL);
}
谢谢!
解决方法
在带有修饰符的枚举中声明一个 EnumSet 是有意义的 静态和最终?还是多余的?
不,它们不是多余的。考虑以下示例,其中可以设置 nonElectrics
,因为它不是 final
。
import java.util.EnumSet;
enum Guitar {
STRATOCASTER,LES_PAUL,CLASSIC;
private static final EnumSet<Guitar> electrics = EnumSet.of(STRATOCASTER,LES_PAUL);
static EnumSet<Guitar> nonElectrics = EnumSet.of(CLASSIC);
public static EnumSet<Guitar> getNonElectrics() {
return nonElectrics;
}
public static void setNonElectrics(EnumSet<Guitar> nonElectrics) {
Guitar.nonElectrics = nonElectrics;
}
public static EnumSet<Guitar> getElectrics() {
return electrics;
}
public boolean isElectronics() {
return electrics.contains(this);
}
}
public class Main {
public static void main(String[] args) {
System.out.println(Guitar.STRATOCASTER.isElectronics());
System.out.println(Guitar.CLASSIC.isElectronics());
EnumSet<Guitar> electrics = EnumSet.of(Guitar.STRATOCASTER,Guitar.LES_PAUL);
Guitar.setNonElectrics(electrics);
System.out.println(Guitar.getNonElectrics());
}
}
,
这不是多余的,枚举类中的字段不是静态的或最终的。 但是,您不能从其他类调用非静态枚举的字段。
,tl;博士
static final public Set ELECTRICS = Set.of( STRATOCASTER,LES_PAUL ) ;
详情
关于您的代码:
private static final EnumSet electrics = EnumSet.of(STRATOCASTER,LES_PAUL);
private
private
正如所写,不需要 private
。
如果标记为 private
,则其他代码将无法访问此集合。所以它没有任何意义。
static
是的,static
是合适的。枚举定义了其类的特定数量的命名实例。当类在运行时首次加载时,实例化会自动发生。所以每个枚举对象都是一个单独的对象。不需要每个人都有自己的一套。该集合是不变的,因此只需通过将其标记为 static
来定义该集合的单个实例。
这使得语法更加清晰,因为我们不涉及任何枚举对象的名称。示例代码:
Set < Guitar > guitars = Guitar.ELECTRICS ;
或者:
Guitar.ELECTRICS.stream.forEach( System.out::println ) ;
final
是的,如果该集合在此应用的整个运行过程中保持不变,请将其标记为 final
。标记为 final
可防止将任何其他集合分配给该字段。
EnumSet
➠ Set
关于第一个 EnumSet
,将其简化为 Set
。
通常最好承诺一个更通用的超类或接口,而不是将自己锁定在特定的具体类中。
electrics
➠ ELECTRICS
名称 electrics
应该全部大写,如果您打算将此设置固定不变。按照惯例,Java 中的常量以全部大写命名。所以,ELECTRICS
。
集合的复数命名
很高兴您将 ELECTRICS
命名为复数。这个名字表明它是一个集合而不是一个单一的枚举对象。
Set.of
用于不可修改的集合
对于第二个EnumSet
,一般使用EnumSet
是处理枚举对象的正确选择。 EnumSet
类针对枚举进行了高度优化,从而在使用很少内存的情况下实现了非常快的性能。
但这里的问题是 EnumSet
是可变的。我希望您不希望任何错误的代码在您的集合中添加或删除元素。
所以我们想要一个不可变的集合。 Java 通过 unmodifiable set 方法提供 Set.of…
。
在幕后,这些方法可以自由地使用它们想要的任何具体类,因此可以在选择底层类时自由地进行优化。所以你最终可能会得到一个像 EnumSet
这样高效的具体类。但这并不是最重要的,因为在这种情况下,不变性胜过性能。
解决方案代码
所以我会把这段代码写成:
static final public Set ELECTRICS = Set.of( STRATOCASTER,LES_PAUL ) ;
第三方库中明确不可变的集合
使用 Set.of
的替代方法是向您的项目添加一个库,该库提供不变性作为其集合数据类型的显式部分。可能是 Eclipse Collections 或 Google Guava。
至于冗余,请参阅正确的 Answer by Live and Let Live。