How do you know if a class is an annotation - java

how to juge a class is an annotation,
How do you know if a class is an annotation
Is there a good Samaritan out there,,,,,,,
how to juge a class is an annotation

If you have the source code: an annotation is declard as
#interface MyAnnotation { /* ... */ }
If you have some class object:
// Class<?> myClass = MyAnnotation.class;
if (myClass.isAnnotation()) { /* ... */ }

Maybe you can like this:
if(class.hasMethodAnnotation(Annotation.class)){}

Maybe you can do like this;
if (MyExampleClass.class.isAnnotationPresent(MyExampleAnnotation.class)) {
}

Related

Creating Dynamic Advice by Passing in Strategies to Aspect

I am trying to make my advice more dynamic based on the class/method it is providing advice for. Looking for something like this pseudoish code:
class Activity
private TheAdviceStrategyInterface activityAdviceStrategy = new ActivityAdviceStrategy();
#Entity(adviceStrategy = activityAdviceStrategy)
public void doSomething(ActivityInput ai) { ... }
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.METHOD)
public #interface Entity {
public TheAdviceStrategyInterface adviceStrategy();
}
#Aspect
public class TheAdvice {
#Around("#annotation(entity)")
public Object doStuff (ProceedingJoinPoint pjp, Entity entity) {
...
TheAdviceStrategyInterface theStrat = entity.adviceStrategy();
....
}
}
But of course we can not have Objects or Interfaces as annotation parameters.
Any "advice" on how I can implement this? I basically want one Aspect annotation to handle very similar situations, with a slight difference depending on which class is using the annotation.
But of course we can not have Objects or Interfaces as Annotation
parameters. Any "advice" on how I can implement this?
1- Create a String parameter in the Entity interface to represent the possible strategies:
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.METHOD)
public #interface Entity {
public String adviceStrategy();
}
2- Create a class that implements the factory pattern, for instance:
public class TheAdviceStrategyFactory {
//use getShape method to get object of type shape
public TheAdviceStrategyInterface getStrategy(String strategy){
if(strategy == null){
return null;
}
if(strategy.equalsIgnoreCase("Strategy1")){
return new TheAdviceStrategy1();
} else if(strategy.equalsIgnoreCase("Strategy2")){
return new TheAdviceStrategy2();
return null;
}
}
with the Classes TheAdviceStrategy1 and TheAdviceStrategy2 implementing the interface TheAdviceStrategyInterface.
Take advantage of both in the advice:
#Aspect
public class TheAdvice {
#Around("#annotation(entity)")
public Object doStuff (ProceedingJoinPoint pjp, Entity entity) {
...
TheAdviceStrategyFactory factory = new TheAdviceStrategyFactory();
TheAdviceStrategyInterface theStrat = factory.getStrategy(entity.adviceStrategy());
....
}
}

Have a common base type for all my custom annotations

So, I have created several custom annotations:
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.METHOD)
public #interface Foo {
}
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.METHOD)
public #interface Bar {
}
Those annotations are used in my functions:
public class Worker {
#Foo
public void doTaskOne() {...}
#Bar
public void doTaskX() {...}
...
}
I want to use java reflection to check if certain annotation is declared in one method.
for (Method m : methods) {
if (m.isAnnotationPresent(Foo.class)) {
...
} else if (m.isAnnotationPresent(Bar.class)) {
...
}
}
The problem is that since in Java, custom annotation #interface is not able to be extended. I mean this is illegal:
public #interface Bar extends MyBaseAnnotation{
}
That's I am not able to have a base #interface for all my custom annotation class Foo and Bar. So, if I have a new custom annotation created, I need to add more else if condition in above method checking code, which sucks! Is there anyway to get rid of this problem? What I want to achieve is to generalize my method checking code to :
for (Method m : methods) {
if (m.isAnnotationPresent(MyBaseAnnotation.class)) {
...
}
}
How to achieve it?
You can annotate your custom annotations with a base custom annotation, like composed annotations do.
Instead of:
public #interface Bar extends MyBaseAnnotation{
}
use:
#MyBaseAnnotation
public #interface Bar {
}
Assuming that
#Parent
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.METHOD)
#interface Foo {}
#Parent
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.METHOD)
#interface Bar {}
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.ANNOTATION_TYPE)
#interface Parent {}
and there is a method
public static boolean isAnnotationPresent(Method method, Class<? extends Annotation> parentAnnotation) throws NoSuchMethodException {
for (Annotation methodAnnotation : method.getDeclaredAnnotations()) {
if (methodAnnotation.annotationType().isAnnotationPresent(parentAnnotation)) {
return true;
}
}
return false;
}
you can do
isAnnotationPresent(m, Parent.class)
You got it right: there is no inheritance between annotation types in Java. You could make your own rules, though. By saying "if annotation B has annotation A over it, then B extends A", you define the rule that you will follow while using reflection.

Java Type Use annotation - How to read them

I'm using custom type use annotation. I can't read them from an object like any other regular annotation:
public class TestingAnnotations {
public static void main(final String[] args) {
final #CustomAnnotation TypeAnnotated b = new #CustomAnnotation TypeAnnotated();
System.out.println(b.getClass().getAnnotation(CustomAnnotation.class)); //<-- prints null :(
}
}
#Target({ElementType.TYPE_USE, ElementType.TYPE})
#Retention(RetentionPolicy.RUNTIME)
#interface CustomAnnotation {
}
class TypeAnnotated {
}
So, how can I check b instance is annotated?
Thanks
you are actually not annotating the class.... a class is annotated when it looks like:
#CustomAnnotation
class TypeAnnotated {
}
after that you will get the annotation doing:
TypeAnnotated b = new TypeAnnotated();
System.out.println(b.getClass().getAnnotation(CustomAnnotation.class));
It looks like you actually want a local variabel annotation
#Target({ElementType.TYPE_USE, ElementType.LOCAL_VARIABLE})
public #interface CustomAnnotation {
}
Then this compiles just fine:

creating custom annotation and using it in java?

I have written below the Custom Annotation.
#Target(ElementType.METHOD)
#Retention(RetentionPolicy.RUNTIME)
public #interface MyAnnotation {
String value();
}
and am using the annotation as below.
#MyAnnotation("someValue")
public void someMethod(){
}
above code is working fine without any issues.
But in the annotation class, value() method name i have to reanme. Can i do as below?
#Target(ElementType.METHOD)
#Retention(RetentionPolicy.RUNTIME)
public #interface MyAnnotation {
String name();
}
I tried doing but eclipse is giving the compilation error.
- The attribute value is undefined for the annotation type
MyAnnotation
- The annotation #MyAnnotation must define the attribute
name
Any reason?
Use it like this :
#MyAnnotation(name="someValue")
public void someMethod(){
}
because by default annotation has value method so if you specify like this
#MyAnnotation("someValue")
public void someMethod(){
}
it will by default take it as value="someValue"

Java Annotations not working

I'm trying to use Java annotations, but can't seem to get my code to recognize that one exists.
What am I doing wrong?
import java.lang.reflect.*;
import java.lang.annotation.*;
#interface MyAnnotation{}
public class FooTest
{
#MyAnnotation
public void doFoo()
{
}
public static void main(String[] args) throws Exception
{
Method method = FooTest.class.getMethod( "doFoo" );
Annotation[] annotations = method.getAnnotations();
for( Annotation annotation : method.getAnnotations() )
System.out.println( "Annotation: " + annotation );
}
}
You need to specify the annotation as being a Runtime annotation using the #Retention annotation on the annotation interface.
i.e.
#Retention(RetentionPolicy.RUNTIME)
#interface MyAnnotation{}
Short answer: you need to add #Retention(RetentionPolicy.RUNTIME) to your annotation definition.
Explanation:
Annotations are by default not kept by the compiler. They simply don't exist at runtime. This may sound silly at first, but there are lots of annotations that are only used by the compiler (#Override) or various source code analyzers (#Documentation, etc).
If you want to actually USE the annotation via reflection like in your example, you'll need to let Java know that you want it to make a note of that annotation in the class file itself. That note looks like this:
#Retention(RetentionPolicy.RUNTIME)
public #interface MyAnnotation{}
For more information, check out the official docs1 and especially note the bit about RetentionPolicy.
Use #Retention(RetentionPolicy.RUNTIME)
Check the below code. It is working for me:
import java.lang.reflect.*;
import java.lang.annotation.*;
#Retention(RetentionPolicy.RUNTIME)
#interface MyAnnotation1{}
#Retention(RetentionPolicy.RUNTIME)
#interface MyAnnotation2{}
public class FooTest {
#MyAnnotation1
public void doFoo() {
}
#MyAnnotation2
public void doFooo() {
}
public static void main(String[] args) throws Exception {
Method method = FooTest.class.getMethod( "doFoo" );
for( Annotation annotation : method.getAnnotations() )
System.out.println( "Annotation: " + annotation );
method = FooTest.class.getMethod( "doFooo" );
for( Annotation annotation : method.getAnnotations() )
System.out.println( "Annotation: " + annotation );
}
}

Categories

Resources