2

On my JRE, the following test passes:

public static @interface Bar {}

@Retention(RetentionPolicy.RUNTIME)
public @interface Foo
{
    Bar value() default @Bar;
}

@Foo
public Object default1;

@Foo
public Object default2;

@Foo(@Bar)
public Object specified;

@Test
public void test() throws NoSuchFieldException, NoSuchMethodException
{
    Foo d1 = getClass().getField("default1").getAnnotation(Foo.class);
    Foo d2 = getClass().getField("default2").getAnnotation(Foo.class);
    Foo s = getClass().getField("specified").getAnnotation(Foo.class);
    Assert.assertSame(d1.value(), d2.value());
    Assert.assertNotSame(d1.value(), s.value());
}

Is the behavior behind both of these assertions specified by Java? Is this a reliable condition to detect when a developer provided a value (albiet one that equals the default)?

Glenn Lane
  • 3,892
  • 17
  • 31
  • [Related?](http://stackoverflow.com/questions/37853188/why-are-annotation-string-values-not-interned) – shmosel Apr 20 '17 at 00:58
  • They're definitely using the same proxies internally to represent default valued annotations, and a different proxy to represent one manually specified. I would say though that this is different than *instances*, since you can't ever *instantiate* an annotation (or interface, for that matter). – Makoto Apr 20 '17 at 01:04
  • @shmosel That was actually quite helpful. The default value for annotations are serialized into the method as `byte[]`. Obviously they're caching an instance, but I can't imagine anyone putting that requirement into a specification. Thanks! – Glenn Lane Apr 20 '17 at 01:55
  • @Makoto You *can* create an instance of an `Annotation`, just like you can create an instance of `java.util.Map`. Obviously we mean we're creating an instance of a class that implements the interface, but the resulting object *is* an instance of that interface. Walk around saying "my method takes one argument: a *proxy* of `java.util.Map`" and you're gonna get weird looks. – Glenn Lane Apr 20 '17 at 02:22

1 Answers1

0

Looking at how default values for annotation members are stored in Oracle's implementation (java.lang.reflect.Method#annotationDefault), it's doubtful implementations would be required to cache a single instance.

Glenn Lane
  • 3,892
  • 17
  • 31