开发者

Static inner classes need import for annotations

So I was doing some jUnit testing and wanted to write distinct classes that had similar functionality but were small enough to write within a single class. Regardless of the decision for design it brought me to a compiler error I am not sure what the rules are for what I saw.

You can imagine it would look something like

package foo;

@RunWith(Suite.class)
@SuiteClasses({ TestClassOne.class, TestClassTwo.class })
public class TestSuite{

   @RunWith(SpringJUnit4ClassRunner.class)
   public static class TestClassOne{

   }

   @RunWith(SpringJUnit4ClassRunner.class)
   pub开发者_开发技巧lic static class TestClassTwo{

   }
}

Now when the compiler kicks it it will say TestClassOne cannot be resolved to a type. There is an easy way to resolve this. It would require an explict import of the static class for instance.

import foo.TestSuite.TestClassOne; 
import foo.TestSuite.TestClassTwo; 

My question is, can anyone explain what compiler rules or reasons there may be for the annotations to not be able to see the class static inner class. Keep in mind a package private class is seen fine and compiles without an import.


This is an interesting one. According to [1], the scope of the name "TestClassOne" is "the entire body of" class "TestSuite".

Is the annotation in "the body of" TestSuite? Apparently not. But that's not very fair. The scope rule was defined before annotation was introduced. I don't see any problem if a class annotation is considered in the scope of the class. They are very intimate anyway.

Another question is how come simple name "TestSuite" can be referenced in the annotation? It turns out the spec covers this one. Annotation is a modifier, which is part of the type declaration, and "The scope of a top level type is all type declarations in the package".

However it is possible that the spec got it right by accident. The rules were defined before annotation was introduced, and remain the same afterwards. So although it covers the case in technicality, it could be an accident. This is not to doubt the brain power of language designers - the whole spec is just too damn complex.

[1] http://java.sun.com/docs/books/jls/third_edition/html/names.html#6.3


You don't need to import the inner class, you could access them using

TestSuite.TestClassOne

The details can be found in JLS, but my simple rule is: An import a.b.c.d.e allows you to use e instead of the fully qualified name. It doesn't allow you to use f.


Just an additional info: it's necessary to import inner classes not only when using annotations, but also when using it as a parametric type, which is very annoying.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜