Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Annotate class with inner class

I create my enums through reflection, for that I add to each enum an inner class which implements the abstract factory. Now I want to access this inner class in order to invoke the method:

@Factory(FooFactory.class)
public enum Foo {

     FOO, BAR;

     public class FooFactory implements AbstractFactory<Foo> {

          public Foo create(String value) {
               return valueOf(value.toUpperCase());
          }
     }
}

The definition of @Factory is:

@Retention(RetentionPolicy.RUNTIME)
public @interface Factory {

        Class<?> value();
}

With this, however, I receive the following error:

Class cannot be resolved to a type FooFactory.java

When I try @Factory(Foo$FooFactory.class) I receive the error:

The nested Foo$FooFactory cannot be referneced using its binary name.

So is it even possible to reference a nested class?

like image 697
Konrad Reiche Avatar asked Aug 24 '12 21:08

Konrad Reiche


3 Answers

From the comments... apparently

@Factory(Foo.FooFactory.class)

was needed.

like image 188
Charlie Avatar answered Oct 01 '22 05:10

Charlie


You're using a non-static nested class, which is scoped to the individual instances of the enum.

Instead, you need a static nested class, like so:

public static class FooFactory implements AbstractFactory<Foo> {

      public static Foo create(String value) {
           return valueOf(value.toUpperCase());
      }
 }

However, all of this is redundant: you can simply call Foo.valueOf(value) to achieve this goal. I don't see any value added here (no pun intended).

Factory.java

import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
public @interface Factory {
        Class<?> value();
}

FooEnum.java

@Factory(FooEnum.FooFactory.class)
public enum FooEnum {
    FOO, BAR;
    public static class FooFactory  {

          public static FooEnum create(String value) {
               return valueOf(value.toUpperCase());
          }
     }
}

FooEnumMain.java

public class FooEnumMain {
    public static void main(String[] args) {
        FooEnum f = FooEnum.FooFactory.create("foo");
        System.out.println(f);
    }
}
like image 43
corsiKa Avatar answered Oct 01 '22 05:10

corsiKa


At the point when your annotation is presented, FooFactory is undefined, so the full path needs to be specified:

@Factory(Foo.FooFactory.class)
like image 45
Reimeus Avatar answered Oct 01 '22 06:10

Reimeus