1

I'm parsing class definitions through introspection and would like to know whether the class has explicitly defined a default value for some of its fields.

class Foo {
    private int member = 5; // Init value is 5
}

vs.

class Foo {
    private int member; // Default value is 0 but no init value defined
}

I could instanciate the class and get its members, but I wouldn't be able to distinguish between explicitly-initialized fields like private int member = 0; from implicitly-initialized like private int member; (which initial value is also 0, except that it was not explicitly set).

I'm using introspection through getDeclaredFields() which means I can't assume a specific type for the field, so I can't use an annotation like:

@DefaultValue(5)
private int member;

Because:

public @interface DefaultValue {
    Object value() default null; // Error "... only primitive type, String, Class, annotation, enumeration are permitted or 1-dimensional arrays thereof"
}

I was thinking about using a String in such annotation (instead of the Object I wanted to use) then code some deserialize() method to parse the string and retrieve the value, but it seems like an overkill (if there are nicer ways) and cannot be checked at compile time (e.g. @DefaultValue("toto") private int member; would compile but is broken).

Matthieu
  • 2,736
  • 4
  • 57
  • 87
  • You can take a look here: https://stackoverflow.com/questions/7223482/java-how-can-i-with-reflection-check-if-a-field-is-initialized-or-is-default-val – Villat Oct 16 '19 at 23:06
  • Thanks @Villat, but the question you linked is about whether the field's *current* value is the default value, when I want to know whether the field has defined an *explicit* value. – Matthieu Oct 17 '19 at 03:56
  • I don't think that is possible, an int type class variable will be initalized to the value of 0, there is no way to tell if it is assigned by your program or not. You CAN use a boolean to keep track. – XzibitGG Oct 18 '19 at 21:08
  • 2
    If `Object value() default null;` was legal, you still hadn’t compile-time checking of the value. These are entirely unrelated problems. Whatever solution you use to declare the annotation, there is no language construct to declare that the value specified in the annotation must match the type of the field. E.g., with the first variant using an `int` annotation value type, you still could do `@DefaultValue(5) Class> field;`. – Holger Jul 30 '20 at 11:22
  • @Holger in my particular case, I didn't mind the compile-time checking (though it would have been a great bonus of course), and using an annotation would have been less elegant than having, say, a `Field` attribute giving the default initialization value. But as you said, there is no such language construct so I'll just have that as an answer (or you can add it and I'll accept). – Matthieu Jul 30 '20 at 16:29

1 Answers1

1

From @Holger's comment: it is not possible, even with annotations.

Matthieu
  • 2,736
  • 4
  • 57
  • 87