I want to implement a custom annotation which when used by other classes exposes two methods to them. Something like shown below:
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.TYPE)
public @interface BaseEntity{
public String toString(){ return "Hello" ;}
public String toCustomString() { return "my hello";}
}
Now what I want is whenever any class uses the above annotation. It gets these methods exposed to it by default, something like what Lombok does when we use @Getter
@BaseEntity
public class Person{}
Person p = new Person();
p.toCustomString(); // this should work
While not exactly what you asked, I think you can achieve what you want with a class hierarchy that takes advantage of the annotation:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface BaseEntity {
String string();
String customString();
}
public abstract class AbstractClass {
@Override
public String toString() {
return getClass().getAnnotation(BaseEntity.class).string();
}
public String toCustomString() {
return getClass().getAnnotation(BaseEntity.class).customString();
}
}
And then a concrete subclass:
@BaseEntity(string = "Hello", customString = "my hello")
public class Example extends AbstractClass {
public static void main(String[] args) throws Exception {
Example example = new Example();
System.out.println(example.toString());
System.out.println(example.toCustomString());
}
}
yields:
Hello
my hello
In response to your comment, my real-world solution is to define an annotation and an interface with default methods (which makes a toString() implementation problematic):
@BaseEntity(customString = "my hello")
public class Example implements BaseEntityAnnotated {
public static void main(String[] args) throws Exception {
Example example = new Example();
System.out.println(example.toCustomString());
}
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface BaseEntity {
String customString();
}
public interface BaseEntityAnnotated {
default String toCustomString() {
return this.getClass().getAnnotation(BaseEntity.class).customString();
}
}
I then implement a Processor that enforces an entity annotated with BaseEntity must also implement BaseEntityAnnotated.
I have examples at AntTask, AnnotatedAntTask.getAntTaskName(), and AntTaskProcessor.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With