mardi 23 juin 2020

Java Reflection with Annotation Class not working

I'm pretty experienced with Java, however a novice to using Reflection and Annotation classes, which I'm trying to learn for fun. To get some practice, I made an Identifiable class which is designed to add several helpful methods to any class it inherits.

Here is the full class:

abstract class Identifiable<T, K extends Comparable<K>> implements Comparable<Identifiable<T, K>> {

    @Retention(RetentionPolicy.RUNTIME)
    public @interface Identifier { }

    private static Method getMethodAnnotatedWith(final Class<?> type) {
        return Arrays.stream(type.getDeclaredMethods())
                .filter(m -> m.isAnnotationPresent(Identifier.class))
                .findFirst()
                .orElse(null);
    }

    private K id;

    @SuppressWarnings("unchecked")
    public Identifiable(Class<T> clazz) {
        var m = getMethodAnnotatedWith(clazz);
        if (m == null) throw new IllegalArgumentException(
            clazz.toString() + " does not have a method annotated by @Identifier"
        );

        try {
            id = (K) m.invoke(this);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public int compareTo(@NotNull Identifiable<T, K> i) {
        return id.compareTo(i.id);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Identifiable<?, ?> that = (Identifiable<?, ?>) o;
        return id == that.id;
    }

    @Override
    public int hashCode() {
        return Objects.hash(id);
    }
}

And here is how I am trying to design it to work:

class Foo extends Identifiable<Foo, Integer> {
    private final int i;

    Foo(int i) {
        super(Foo.class);
        this.i = i;
    }

    @Identifier
    int getI() {
        return i;
    }
}

However, id is always 0 for some reason, so I'm not sure if it's a problem with my Identifier annotation class or the way I'm using reflection. I'm pretty sure it's the latter since while debugging, I found that it is able to access the method with the annotation. Any help would be appreciated, thanks!





Aucun commentaire:

Enregistrer un commentaire