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