5

I was cleaning up code and changing all access to static member such that they are qualified by the class in which they are defined. This, however, lead to the following problem which is puzzling me.

I have a class with a nested class inside. In the annotation on this nested class I refer to a private static final field in the surrounding class. When doing this without qualification (as in the annotation on class D, below) this works. However, when adding the class qualifier (as in the annotation on class C) the compiler tells the field (v below) is not visible.

public class VisibilityTest {

    @interface A {
        int f();
    }

    @A(f = VisibilityTest.v) //fails
    private static class C {
        int c = VisibilityTest.v; //works
    }

    @A(f = v) //works
    private static class D {
        int d = VisibilityTest.v; //works
    }

    private final static int v = 5;

}

In both cases the variable refers to the same field, so why does this happen?

miselico
  • 355
  • 3
  • 9
  • 2
    No idea but interesting, especially because the `OuterClass.privateStaticField` idiom will compile when referenced, say, from within a method of a nested class, which seems inconsistent... – Mena Feb 09 '16 at 14:38
  • Since annotation parameters must be compile-time resolvable (in our case, constant expressions), this seems to be a glitch in the compiler. – biziclop Feb 09 '16 at 14:47
  • what javac version is used? – hahn Feb 09 '16 at 14:49
  • Annotation was introduced much later, it's unclear how it plays out with scoping rules:) There are flaws in spec - [example](http://stackoverflow.com/questions/4800581/static-inner-classes-need-import-for-annotations), and there are understandably bugs in compilers. – ZhongYu Feb 09 '16 at 14:55

2 Answers2

4

This compiles fine with 1.8.0_25 and 1.7.0_45 javac, as it should really. Or both should fail, that would be consistent too.

This seems to be a bug in Eclipse's annotation handling (which is why you can happily reference the same constant from normal code), it was reported quite a long time ago but there hasn't beeen much activity over the last 4 years.

biziclop
  • 48,926
  • 12
  • 77
  • 104
  • I also managed to compile directly with javac without problems. I am indeed using Eclipse, so most likely it is the same bug – miselico Feb 09 '16 at 22:36
  • @miselico Since it's so easy to work around it, I'd expect it to be a pretty long way down the list of bugs to fix. The Eclipse compiler has far bigger problems than this :) – biziclop Feb 09 '16 at 22:41
-2

See How to supply value to an annotation from a Constant java.

Basically you can't. Annotation values must be primitives or Strings. You can't reference a field, private or otherwise.

Community
  • 1
  • 1