gpt4 book ai didi

java - 是否可以知道注释方法是否被覆盖( boolean 值)?

转载 作者:行者123 更新时间:2023-11-30 05:38:25 26 4
gpt4 key购买 nike

我在网上尝试了很多方法,但似乎没有什么对我有用。我想知道注释方法是否已被 @Overriden(与其 default 具有相同的值)。

看一下这个例子:

public class AnnoTest {

@Anno
private String something;

public static void main(String[] args) throws NoSuchFieldException, SecurityException, NoSuchMethodException {
Field field = AnnoTest.class.getDeclaredField("something");
field.setAccessible(true);
boolean isDefault= field.getAnnotation(Anno.class).annotationType().getDeclaredMethod("include").isDefault();
System.out.println(isDefault); //returns false

}

@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.FIELD })
public @interface Anno {
boolean include() default false;
}
}

由于某种原因它返回 false。当我将其更改为:

@Anno(include = false)
private String something;

它再次返回false。有没有办法知道该值是否已在注释中声明?

我知道我可以比较默认值和当前值,但它对我不起作用。我想知道是否已宣布。

<小时/>

换句话说,我需要某种神奇的 boolean 值来执行以下操作:

@Anno
private String something;

返回false

@Anno(include = true)
private String something;

返回true

@Anno(include = false)
private String something;

返回true

<小时/>

这样做的原因是我希望添加一个名为“parent”的方法(到我的注释中)。当父级(字符串)已被声明为注释时,该字段将继承名为parent的字段的注释。看一下这个例子:

public class AnnoTest {

@Anno(include = false)
private Something something = new Something();

@Anno(parent = "something")
private Something somethingElse = new Something();

public static void main(String[] args) throws NoSuchFieldException, SecurityException, NoSuchMethodException {
AnnoTest test = new AnnoTest();

Field somethingField = AnnoTest.class.getDeclaredField("something");
somethingField.setAccessible(true);

Field somethingElseField = AnnoTest.class.getDeclaredField("somethingElse");
somethingField.setAccessible(true);

Anno anno = somethingElseField.getAnnotation(Anno.class);

if (anno.parent().equals("something")) {
boolean include = somethingField.getAnnotation(Anno.class).include();
test.somethingElse.isIncluded = include;
}

//If not declared it will return true, which it should be false, because "something" field has it false.
boolean include = somethingElseField.getAnnotation(Anno.class).include();
//if somethingElse has declared "include", dominate the value, else keep it from the parent
test.somethingElse.isIncluded = include;

}

public class Something {
boolean isIncluded;
}

@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.FIELD })
public @interface Anno {
boolean include() default false;

String parent() default "";
}
}

最佳答案

反射 API 不允许查询注释值是已显式指定还是仅默认。

通常的解决方法是指定一个默认值,头脑清醒的人不会明确指定该值,然后检查该值。例如,JPA uses "" 为此目的。

可以尝试一下

Boolean value() default null;

但是正如您在评论中正确指出的那样,java不支持Boolean注释值,仅支持boolean注释值。您可以改用具有 3 个值的枚举,但这对您的用户来说可能会造成负担。

这就剩下了黑暗魔法:你可以自己解析类文件。这可行,因为类文件仅列出指定的注释属性,如以下 javap 输出所示:

给定

@Anno(false)
public void foo()

我们得到

Constant pool:
...
#16 = Utf8 Lstackoverflow/Anno;
#17 = Utf8 value
#18 = Integer 0

public void foo();
descriptor: ()V
flags: ACC_PUBLIC
RuntimeVisibleAnnotations:
0: #16(#17=Z#18)

但给定

@Anno()
public void foo() {

我们得到

Constant pool:
...
#16 = Utf8 Lstackoverflow/Anno;

public void foo();
descriptor: ()V
flags: ACC_PUBLIC
RuntimeVisibleAnnotations:
0: #16()

也就是说,即使您设法做到这一点,您也可能会让您的用户感到惊讶并使他们的工具感到困惑。例如,IDE 很可能会将默认值的显式分配标记为冗余。

如果可能的话,我会更改您的注释,这样您就不必区分是否已显式指定 boolean 值。

关于java - 是否可以知道注释方法是否被覆盖( boolean 值)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56184789/

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