在注释之间共享一个 "configuration"
Sharing a "configuration" between annotations
我想在多个带注释的 class 之间共享一个共同的“配置”。我最初的方法是将注释指向 class 然后扩展配置 class:
@MyAnnotation(config = SharedConfig.class)
class A {}
@MyAnnotation(config = SharedConfig.class)
class B {}
class SharedConfig extends BaseConfig{
public SharedConfig(){
super("abc",123)
}
}
我最初的做法是在注释处理过程中找到 SharedConfig 类型并实例化它以找出实际配置。问题是我无法在实际处理过程中实例化 SharedConfig class...
知道如何实现吗?
确实,您无法实例化配置 class。但是您 可以 做的是查询配置 class.
上的注释
因此,您可以想象以下系统:
旧方法:
@Movie(
name = "A Few Good Men",
director = @Director(lastName = "Reiner", firstName = "Rob"),
releaseYear = 1992,
liked = true)
public class Foo {}
@Movie(
name = "A Few Good Men",
director = @Director(lastName = "Reiner", firstName = "Rob"),
releaseYear = 1992,
liked = true)
public class Bar {}
新方式:
@Movie(
name = "A Few Good Men",
director = @Director(lastName = "Reiner", firstName = "Rob"),
releaseYear = 1992)
public class Placeholder {
// This class serves solely as a place to store the above annotation.
private Placeholder() {}
}
@Movie(
config = Placeholder.class,
liked = true)
public class Foo {}
@Movie(
config = Placeholder.class,
liked = false)
public class Bar {}
您的规则大概是采用实际 class 上明确设置的任何内容,如果没有明确设置但有 'config' class 设置,则来自该配置 class 注释的值被采用。
不幸的是,当 Foo
被定义为 @interface Foo {String value() default "";}
时,没有(非 hacky)方法来区分 @Foo
和 @Foo(value="")
- 即没有区分与给定 anno 参数的默认值相同的值的显式设置的方法,因此您实际上不能使用 'if you do not explicitly set it, then this defaulting mechanism applies' 作为注释中的概念。因此,'use the defaulting mechanism' 必须基于实际值 - 您需要 'stand-in' 值表示:“从配置继承”。不幸的是,这意味着布尔值已经过时了。您可以改用枚举。
这是一个例子:
public enum LikeStatus {
LIKED, DISLIKED, INHERIT;
}
// target classes/types
public @interface Movie {
Class<?> config() default Object.class;
LikeStatus liked default LikeStatus.INHERIT;
int releaseYear() default 0;
Director director() default @Director(lastName = "", firstName = "")
String name() default "";
}
现在你需要编写一些代码来了解默认值并采取相应的行动(因此,如果 name()
returns 是一个空字符串,这意味着你应该检查 config
class 用于 Movie
注释并获取其 name
。同样适用于发行年份 0、名字和姓氏均为空白的导演等。
我想在多个带注释的 class 之间共享一个共同的“配置”。我最初的方法是将注释指向 class 然后扩展配置 class:
@MyAnnotation(config = SharedConfig.class)
class A {}
@MyAnnotation(config = SharedConfig.class)
class B {}
class SharedConfig extends BaseConfig{
public SharedConfig(){
super("abc",123)
}
}
我最初的做法是在注释处理过程中找到 SharedConfig 类型并实例化它以找出实际配置。问题是我无法在实际处理过程中实例化 SharedConfig class...
知道如何实现吗?
确实,您无法实例化配置 class。但是您 可以 做的是查询配置 class.
上的注释因此,您可以想象以下系统:
旧方法:
@Movie(
name = "A Few Good Men",
director = @Director(lastName = "Reiner", firstName = "Rob"),
releaseYear = 1992,
liked = true)
public class Foo {}
@Movie(
name = "A Few Good Men",
director = @Director(lastName = "Reiner", firstName = "Rob"),
releaseYear = 1992,
liked = true)
public class Bar {}
新方式:
@Movie(
name = "A Few Good Men",
director = @Director(lastName = "Reiner", firstName = "Rob"),
releaseYear = 1992)
public class Placeholder {
// This class serves solely as a place to store the above annotation.
private Placeholder() {}
}
@Movie(
config = Placeholder.class,
liked = true)
public class Foo {}
@Movie(
config = Placeholder.class,
liked = false)
public class Bar {}
您的规则大概是采用实际 class 上明确设置的任何内容,如果没有明确设置但有 'config' class 设置,则来自该配置 class 注释的值被采用。
不幸的是,当 Foo
被定义为 @interface Foo {String value() default "";}
时,没有(非 hacky)方法来区分 @Foo
和 @Foo(value="")
- 即没有区分与给定 anno 参数的默认值相同的值的显式设置的方法,因此您实际上不能使用 'if you do not explicitly set it, then this defaulting mechanism applies' 作为注释中的概念。因此,'use the defaulting mechanism' 必须基于实际值 - 您需要 'stand-in' 值表示:“从配置继承”。不幸的是,这意味着布尔值已经过时了。您可以改用枚举。
这是一个例子:
public enum LikeStatus {
LIKED, DISLIKED, INHERIT;
}
// target classes/types
public @interface Movie {
Class<?> config() default Object.class;
LikeStatus liked default LikeStatus.INHERIT;
int releaseYear() default 0;
Director director() default @Director(lastName = "", firstName = "")
String name() default "";
}
现在你需要编写一些代码来了解默认值并采取相应的行动(因此,如果 name()
returns 是一个空字符串,这意味着你应该检查 config
class 用于 Movie
注释并获取其 name
。同样适用于发行年份 0、名字和姓氏均为空白的导演等。