gpt4 book ai didi

枚举值 : passing the annotation instance on to user code 上的 Java 注释

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:12:32 27 4
gpt4 key购买 nike

我们有一个包含很多条目的枚举类型。每个枚举值都有一些 boolean (或其他)属性,在 90% 的情况下大多数具有相同的值。我们最终得到了这样的代码:

enum Foo {
A(true, false, false, true),
B(false, false, false, true),
C(false, false, false, false);

final boolean f1;
final boolean f2;
final boolean f3;
final boolean f4;

Foo(boolean f1, boolean f2, boolean f3, boolean f4) {
this.f1 = f1;
this.f2 = f2;
this.f3 = f3;
this.f4 = f4;
}
}

要编写的代码很多,而且难以阅读(“第三个位置的那个 boolean 值又是什么意思?”)。

这似乎是注释的用例:

@Retention(RetentionPolicy.RUNTIME)
@interface Flags {
boolean f1() default false;
boolean f2() default false;
boolean f3() default false;
boolean f4() default false;
}

enum Foo {
@Flags(f1=true)
A,
@Flags(f4=true)
B,
@Flags()
C;

final boolean f1;
final boolean f2;
final boolean f3;
final boolean f4;

Foo(boolean flag1, boolean f2, boolean f3, boolean f4) {
try {
Flags flags = Objects.requireNonNull(Foo.class.getField(name()).getAnnotation(Flags.class),
"Annotation for '"+getClass().getSimpleName()+"."+name()+"' is missing!");
this.f1 = flags.f1();
this.f2 = flags.f2();
this.f3 = flags.f3();
this.f4 = flags.f4();
} catch (NoSuchFieldException|SecurityException e) {
// should not happen
throw new RuntimeException(e);
}
}
}

但这不能更短吗?

enum Foo {
@Flags(f1=true)
A,
@Flags(f4=true)
B,
@Flags()
C;

final Flags flags;

Foo(boolean flag1, boolean f2, boolean f3, boolean f4) {
try {
this.flags = Objects.requireNonNull(Foo.class.getField(name()).getAnnotation(Flags.class),
"Annotation for '"+getClass().getSimpleName()+"."+name()+"' is missing!");
} catch (NoSuchFieldException|SecurityException e) {
// should not happen
throw new RuntimeException(e);
}
}
}

当然,现在我们必须使用 bar.flags.f1() 而不是 bar.f1()。一个例子:

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Objects;

public class Scratch {

@Retention(RetentionPolicy.RUNTIME)
@interface Flags {
boolean key() default false;

boolean visible() default true;
}

enum Foo {
@Flags(key = true)
A,
@Flags(visible = false)
B;

final Flags flags;

Foo() {
try {
this.flags = Objects.requireNonNull(Foo.class.getField(name()).getAnnotation(Flags.class),
"Annotation for '" + getClass().getSimpleName() + "." + name() + "' is missing!");
} catch (NoSuchFieldException | SecurityException e) {
// Sollte nicht vorkopmmen
throw new RuntimeException(e);
}
}
}

public static void main(String[] args) {
for (Foo bar : Foo.values()) {
System.out.format("%s: key=%-8svisible=%-8s%n", bar.name(), bar.flags.key(), bar.flags.visible());
}
}
}

输出:

A: key=true visible=true

B: key=false visible=false

除了不同的语法,还有什么理由不传递 Annotation 实例吗?或者是否有更优雅的解决方案(不涉及使用框架)?

最佳答案

虽然我没有直接回答您关于注释的问题,但我正在回答您问题的核心(正如您所写:或者是否有更优雅的解决方案(不涉及使用框架) ?)。我不同意这种情况是使用注释的好地方。

我建议您考虑使用更优雅的方式来实现所需的模式:

public enum Foo {
A(FF.F1, FF.F4),
B(FF.F4),
C();

enum FF {
F1, F2, F3, F4;
}

boolean f1;
boolean f2;
boolean f3;
boolean f4;

Foo(FF... flags) {
for (FF ff : flags)
switch (ff) {
case F1:
f1 = true;
break;
case F2:
f2 = true;
break;
case F3:
f3 = true;
break;
case F4:
f4 = true;
break;
}
}
}

或者更简单:

public enum Foo {
A(FF.F1, FF.F4),
B(FF.F4),
C();

enum FF {
F1, F2, F3, F4;
}

boolean[] f = new boolean[FF.values().length];;

Foo(FF... flags) {
for (FF ff : flags) {
f[ff.ordinal()] = true;
}
}
}

关于枚举值 : passing the annotation instance on to user code 上的 Java 注释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41853656/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com