I am getting null pointer exception while executing following method. I have debugged and found that cons.getAnnotation(MyAssessment.class); is returning null. Plese help
import java.lang.annotation.*;
import java.lang.reflect.*;
enum GradeLevel { POOR, AVERAGE, GOOD, VERYGOOD, EXTRAORDINARY }
#interface MyAssessment {
GradeLevel score();
}
public class Problem {
#MyAssessment(score=GradeLevel.GOOD)
public Problem(){
System.out.println("This is a constuructor");
}
public static void main(String... args){
try {
Class c = new Problem().getClass();
Constructor cons = c.getDeclaredConstructor();
MyAssessment an = (MyAssessment) cons.getAnnotation(MyAssessment.class);
System.out.println("YOUR SCORE IS : " + an.score());
}
catch(NoSuchMethodException nsme) {
System.out.println("Constructor thrown exception");
}
}
}
Annotations are not by default available at runtime. You need to annotate your annotation :P
#Retention(RetentionPolicy.RUNTIME)
#interface MyAssessment {
You can also add a #Target of say CONSTRUCTOR to say it should only appear on constructors.
You need to annotate your annotation with:
#Retention(RetentionPolicy.RUNTIME)
You can change the Retention Policy of your annotation. Using #Retention.
Related
Is there a way by which I can set the id inside annotated method...
Annotation class:
import java.lang.annotation.*;
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.METHOD)
public
#interface MyAnnotation {
int id();
}
//Set id at runtime
public class A {
#MyAnnotation(id = ? )
public void method1() {
// I want to set the id here for my annotation...
}
}
Yes, but it's a bit unintuitive. You'll have to edit its bytecode using a tool like JavaAssist.
Here is an article describing what you're after.
This is the first time I am trying to write a custom annotations in java.
I am not sure whether it is possible or not but wanted to give it a try before approaching another solution.
So here is the scenario, I have a lots of method that sends the data out from the application to a device. I have a requirement to log all these data in database.
I would like to create an annotation for this so that I can write the code in the annotation to log the data in database and then annotation all the methods with this annotation.
I can modify the code to log into the database but in that case I have to go in each method and place my code at correct place inorder to log them into database.
This is the reason I am looking for annotation based approach.
Is it possible what I am looking for or am I asking more.
Any pointers will be appreciated or If someone has different approach for my solution that will be really help full.
Instead of writing your own Annotations and processing them, have a look at what Spring provides, e.g. Interceptors:
Interceptors vs Aspects in Spring?
You can try below approach
package annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
#Target(ElementType.METHOD)
#Retention(RetentionPolicy.RUNTIME)
#interface Todo {
public enum Priority {LOW, MEDIUM, HIGH}
String logInfo() default "Logging...";
Priority priority() default Priority.LOW;
}
package annotation;
public class BusinessLogic {
public BusinessLogic() {
super();
}
public void compltedMethod() {
System.out.println("This method is complete");
}
#Todo(priority = Todo.Priority.HIGH)
public void notYetStartedMethod() {
// No Code Written yet
}
#Todo(priority = Todo.Priority.MEDIUM, logInfo = "Inside DAO")
public void incompleteMethod1() {
//Some business logic is written
//But its not complete yet
}
#Todo(priority = Todo.Priority.LOW)
public void incompleteMethod2() {
//Some business logic is written
//But its not complete yet
}
}
package annotation;
import java.lang.reflect.Method;
public class TodoReport {
public TodoReport() {
super();
}
public static void main(String[] args) {
Class businessLogicClass = BusinessLogic.class;
for(Method method : businessLogicClass.getMethods()) {
Todo todoAnnotation = (Todo)method.getAnnotation(Todo.class);
if(todoAnnotation != null) {
System.out.println(" Method Name : " + method.getName());
System.out.println(" Author : " + todoAnnotation.logInfo());
System.out.println(" Priority : " + todoAnnotation.priority());
System.out.println(" --------------------------- ");
}
}
}
}
I want to create custom annotation in java for DirtyChecking. Like I want to compare two string values using this annotation and after comparing it will return a boolean value.
For instance: I will put #DirtyCheck("newValue","oldValue") over properties.
Suppose I made an interface:
public #interface DirtyCheck {
String newValue();
String oldValue();
}
My Questions are:
Where I make a class to create a method for comparison for two string values? I mean, how this annotation notifies that this method I have to call?
How to retreive returning values of this method ?
First you need to mark if annotation is for class, field or method. Let's say it is for method: so you write this in your annotation definition:
#Target(ElementType.METHOD)
#Retention(RetentionPolicy.RUNTIME)
public #interface DirtyCheck {
String newValue();
String oldValue();
}
Next you have to write let's say DirtyChecker class which will use reflection to check if method has annotation and do some job for example say if oldValue and newValue are equal:
final class DirtyChecker {
public boolean process(Object instance) {
Class<?> clazz = instance.getClass();
for (Method m : clazz.getDeclaredMethods()) {
if (m.isAnnotationPresent(DirtyCheck.class)) {
DirtyCheck annotation = m.getAnnotation(DirtyCheck.class);
String newVal = annotation.newValue();
String oldVal = annotation.oldValue();
return newVal.equals(oldVal);
}
}
return false;
}
}
Cheers,
Michal
To answer your second question: your annotation can't return a value. The class which processes your annotation can do something with your object. This is commonly used for logging for example.
I'm not sure if using an annotation for checking if an object is dirty makes sense except you want to throw an exception in this case or inform some kind of DirtyHandler.
For your first question: you could really spent some effort in finding this yourself. There are enough information here on stackoverflow and the web.
CustomAnnotation.java
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
#Target(ElementType.METHOD)
#Retention(RetentionPolicy.RUNTIME)
public #interface CustomAnnotation {
int studentAge() default 21;
String studentName();
String stuAddress();
String stuStream() default "CS";
}
How to use the field of Annotation in Java?
TestCustomAnnotation.java
package annotations;
import java.lang.reflect.Method;
public class TestCustomAnnotation {
public static void main(String[] args) {
new TestCustomAnnotation().testAnnotation();
}
#CustomAnnotation(
studentName="Rajesh",
stuAddress="Mathura, India"
)
public void testAnnotation() {
try {
Class<? extends TestCustomAnnotation> cls = this.getClass();
Method method = cls.getMethod("testAnnotation");
CustomAnnotation myAnno = method.getAnnotation(CustomAnnotation.class);
System.out.println("Name: "+myAnno.studentName());
System.out.println("Address: "+myAnno.stuAddress());
System.out.println("Age: "+myAnno.studentAge());
System.out.println("Stream: "+myAnno.stuStream());
} catch (NoSuchMethodException e) {
}
}
}
Output:
Name: Rajesh
Address: Mathura, India
Age: 21
Stream: CS
Reference
I'm trying to find all fields annotated with a custom annotation, but it doesn't seem to detect it. The same code works fine for standard annotations, such as #Deprecated.
Minimal code to reproduce:
public class MyClass {
public #interface MyAnnotation {}
#MyAnnotation Object someObject;
#MyAnnotation #Deprecated Object someDeprecatedObject;
#Deprecated Object aThirdObject;
public static void main(String[] args) {
Class<?> cls = MyClass.class;
for (Field field : cls.getDeclaredFields()) {
System.out.print(field.getName());
for (Annotation a : field.getDeclaredAnnotations())
System.out.print(" " + a);
System.out.println();
}
}
}
Output:
someObject
someDeprecatedObject #java.lang.Deprecated()
aThirdObject #java.lang.Deprecated()
#Deprecated comes up, but #MyAnnotation doesn't! Help!
By default, annotations are not kept at runtime and so cannot be reflected upon. You need to declare your annotation like this to ensure it exists at runtime:
#Retention(RetentionPolicy.RUNTIME)
public #interface MyAnnotation {
}
Here is a test class:
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
public class TestAnnotations {
#interface Annotate{}
#Annotate public void myMethod(){}
public static void main(String[] args) {
try{
Method[] methods = TestAnnotations.class.getDeclaredMethods();
Method m = methods[1];
assert m.getName().equals("myMethod");
System.out.println("method inspected ? " + m.getName());
Annotation a = m.getAnnotation(Annotate.class);
System.out.println("annotation ? " + a);
System.out.println("annotations length ? "
+ m.getDeclaredAnnotations().length);
}
catch(Exception e){
e.printStackTrace();
}
}
}
Here is my output :
method inspected ? myMethod
annotation : null
annotations length : 0
What I am missing to make annotations visible through reflection ?
Do I need an annotation processor even for just checking their presence ?
In order to access an annotation at runtime, it needs to have a Retention policy of Runtime.
#Retention(RetentionPolicy.RUNTIME) #interface Annotate {}
Otherwise, the annotations are dropped and the JVM is not aware of them.
For more information, see here.