【发布时间】:2020-02-13 17:29:15
【问题描述】:
我正在通过自省解析类定义,并想知道该类是否明确为其某些字段定义了默认值。
class Foo {
private int member = 5; // Init value is 5
}
对比
class Foo {
private int member; // Default value is 0 but no init value defined
}
我可以实例化该类并获取其成员,但我无法区分 显式 初始化的字段,如 private int member = 0; 和 隐式 初始化的字段private int member;(其初始值也是0,只是它没有显式设置)。
我通过getDeclaredFields() 使用自省,这意味着我不能为该字段假设特定类型,所以我不能使用如下注释:
@DefaultValue(5)
private int member;
因为:
public @interface DefaultValue {
Object value() default null; // Error "... only primitive type, String, Class, annotation, enumeration are permitted or 1-dimensional arrays thereof"
}
我正在考虑在这样的注释中使用String(而不是我想使用的Object)然后编写一些deserialize() 方法来解析字符串并检索值,但这似乎有点矫枉过正(如果有更好的方法)并且无法在编译时检查(例如 @DefaultValue("toto") private int member; 会编译但已损坏)。
【问题讨论】:
-
谢谢@Villat,但是当我想知道该字段是否定义了 时,您链接的问题是关于该字段的 current 值是否为默认值明确的值。
-
我不认为这是可能的,一个int类型的类变量会被初始化为0的值,没有办法判断它是否是由你的程序分配的。您可以使用布尔值来跟踪。
-
如果
Object value() default null;是合法的,你仍然没有在编译时检查这个值。这些是完全不相关的问题。无论您使用何种解决方案来声明注释,都没有语言构造来声明注释中指定的值必须与字段的类型匹配。例如,使用int注释值类型的第一个变体,您仍然可以使用@DefaultValue(5) Class<?> field;。 -
@Holger 在我的特殊情况下,我不介意编译时检查(尽管这当然是一个很大的好处),并且使用注释会没有那么优雅,比如说,一个
Field属性给出了默认的初始化值。但正如你所说,没有这样的语言结构,所以我将其作为答案(或者你可以添加它,我会接受)。
标签: java reflection initialization introspection