【问题标题】:Get field initialization value获取字段初始化值
【发布时间】: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


【解决方案1】:

来自@Holger's comment:这是不可能的,即使有注释。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-27
    • 1970-01-01
    • 1970-01-01
    • 2013-10-22
    • 1970-01-01
    • 1970-01-01
    • 2011-07-18
    • 1970-01-01
    相关资源
    最近更新 更多