Konrad Reiche
Konrad Reiche

Reputation: 29483

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?

Upvotes: 6

Views: 5361

Answers (3)

Reimeus
Reimeus

Reputation: 159754

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

@Factory(Foo.FooFactory.class)

Upvotes: 3

Charlie
Charlie

Reputation: 7349

From the comments... apparently

@Factory(Foo.FooFactory.class)

was needed.

Upvotes: 9

corsiKa
corsiKa

Reputation: 82559

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);
    }
}

Upvotes: 4

Related Questions