Java reflection annotation class

Java Annotations and Java Reflection — Tutorial

This tutorial describes how to use null annotations to avoid null pointer exceptions and how to define your own annotations and how to use Java reflection to analyze your code with it.

1. Defining the API contract via null annotations

1.1. Eclipse IDE and null annotations

Annotations can be used to provide additional meta information about your API. Eclipse JDT provides the following annotations which can be used:

  • @NonNull : null is not a legal value
  • @Nullable : null value is allowed and must be expected

These annotations can be placed on:

  • Method parameter
  • Method return (syntactically a method annotation is used here)
  • Local variables
  • Fields

You can also specify the default value via the @NonNullByDefault annotation which can be specified for a method, a type or a package (via a file package-info.java). To specify it for a whole package, create the following package-info.java file in your package, for example, com.vogella.test.nullannatations .

@NonNullByDefault package com.vogella.test.nullannatations; import org.eclipse.jdt.annotation.NonNullByDefault;

1.2. Adding support for null annotations

1.2.1. Maven

  org.eclipse.jdt org.eclipse.jdt.annotation 2.0.0 

1.2.2. Gradle

compile 'org.eclipse.jdt:org.eclipse.jdt.annotation:2.0.0'

1.2.3. OSGi

Add an optional dependency to org.eclipse.jdt.annotation in your MANIFEST.MF

1.2.4. Managing the classpath manually

Eclipse provides a quickfix for adding the required dependency. Simple use @NonNull in your code and use Ctrl+1 to add the required dependency.

Читайте также:  Login function with php

1.3. Activating annotation based null pointer access analysis

Select Windows Java Compiler Errors/Warnings and select Enable annotation-based null analysis.

annotationbasednullanalysis10

2. Defining custom annotations

2.1. Define your custom annotation

The Java programming language allows you to define your custom annotations. Annotations are defined via the @interface annotation before the class name. Via @Retention you define if the annotation should be retained at runtime or not. The @Target annotation lets you define where this annotation can be used, e.g., the class, fields, methods, etc.

A typical annotation definition would look like the following.

@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface InstallerMethod  >

You can add additional information, for example you can define that your annotation is a qualifier for the `@Inject`annotation.

@javax.inject.Qualifier @Documented @Target(ElementType.FIELD, ElementType.PARAMETER>) @Retention(RetentionPolicy.RUNTIME) public @interface Checker  >

2.2. Accessing your annotation via Java reflection

To process your annotation you could write your own annotation processor. Typically you use Java reflection for this. Java reflection allows you to analyze a Java class and use the information contained in this class at runtime.

3. Exercise: Define custom annotation and access via reflection

Create a new Java project called com.vogella.annotations . Create the following two classes. The first class defines an annotation and the second class uses this to mark certain methods.

package com.vogella.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(value = ElementType.METHOD) @Retention(value = RetentionPolicy.RUNTIME) public @interface CanRun  >
package com.vogella.annotations; import java.lang.reflect.Method; public class AnnotationRunner  public void method1()  System.out.println("method1"); > @CanRun public void method2()  System.out.println("method2"); > public void method3()  System.out.println("method3"); > @CanRun public void method5()  System.out.println("method4"); > >

Afterwards create the following test class. The main method of this class analyzes the annotations and calls the corresponding methods.

package com.vogella.annotations; import java.lang.reflect.Method; public class MyTest  public static void main(String[] args)  AnnotationRunner runner = new AnnotationRunner(); Method[] methods = runner.getClass().getMethods(); for (Method method : methods)  CanRun annos = method.getAnnotation(CanRun.class); if (annos != null)  try  method.invoke(runner); > catch (Exception e)  e.printStackTrace(); > > > > >

Источник

Java Reflection — Annotations

Using Java Reflection you can access the annotations attached to Java classes at runtime.

What are Java Annotations?

Annotations is a new feature from Java 5. Annotations are a kind of comment or meta data you can insert in your Java code. These annotations can then be processed at compile time by pre-compiler tools, or at runtime via Java Reflection. Here is an example of class annotation:

@MyAnnotation(name=»someName», value = «Hello World») public class TheClass

The class TheClass has the annotation @MyAnnotation written ontop. Annotations are defined like interfaces. Here is the MyAnnotation definition:

@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface MyAnnotation

The @ in front of the interface marks it as an annotation. Once you have defined the annotation you can use it in your code, as shown in the earlier examples.

The two directives in the annotation definition, @Retention(RetentionPolicy.RUNTIME) and @Target(ElementType.TYPE) , specifies how the annotation is to be used.

@Retention(RetentionPolicy.RUNTIME) means that the annotation can be accessed via reflection at runtime. If you do not set this directive, the annotation will not be preserved at runtime, and thus not available via reflection.

@Target(ElementType.TYPE) means that the annotation can only be used ontop of types (classes and interfaces typically). You can also specify METHOD or FIELD , or you can leave the target out alltogether so the annotation can be used for both classes, methods and fields.

Java annotations are explained in more detail in my Java Annotations tutorial.

Class Annotations

You can access the annotations of a class, method or field at runtime. Here is an example that accesses the class annotations:

Class aClass = TheClass.class; Annotation[] annotations = aClass.getAnnotations(); for(Annotation annotation : annotations) < if(annotation instanceof MyAnnotation)< MyAnnotation myAnnotation = (MyAnnotation) annotation; System.out.println("name: " + myAnnotation.name()); System.out.println("value: " + myAnnotation.value()); >>

You can also access a specific class annotation like this:

Class aClass = TheClass.class; Annotation annotation = aClass.getAnnotation(MyAnnotation.class); if(annotation instanceof MyAnnotation)

Method Annotations

Here is an example of a method with annotations:

You can access method annotations like this:

Method method = . //obtain method object Annotation[] annotations = method.getDeclaredAnnotations(); for(Annotation annotation : annotations) < if(annotation instanceof MyAnnotation)< MyAnnotation myAnnotation = (MyAnnotation) annotation; System.out.println("name: " + myAnnotation.name()); System.out.println("value: " + myAnnotation.value()); >>

You can also access a specific method annotation like this:

Method method = . // obtain method object Annotation annotation = method.getAnnotation(MyAnnotation.class); if(annotation instanceof MyAnnotation)

Parameter Annotations

It is possible to add annotations to method parameter declarations too. Here is how that looks:

You can access parameter annotations from the Method object like this:

Method method = . //obtain method object Annotation[][] parameterAnnotations = method.getParameterAnnotations(); Class[] parameterTypes = method.getParameterTypes(); int i=0; for(Annotation[] annotations : parameterAnnotations) < Class parameterType = parameterTypes[i++]; for(Annotation annotation : annotations)< if(annotation instanceof MyAnnotation)< MyAnnotation myAnnotation = (MyAnnotation) annotation; System.out.println("param: " + parameterType.getName()); System.out.println("name : " + myAnnotation.name()); System.out.println("value: " + myAnnotation.value()); >> >

Notice how the Method.getParameterAnnotations() method returns a two-dimensional Annotation array, containing an array of annotations for each method parameter.

Field Annotations

Here is an example of a field with annotations:

You can access field annotations like this:

Field field = . //obtain field object Annotation[] annotations = field.getDeclaredAnnotations(); for(Annotation annotation : annotations) < if(annotation instanceof MyAnnotation)< MyAnnotation myAnnotation = (MyAnnotation) annotation; System.out.println("name: " + myAnnotation.name()); System.out.println("value: " + myAnnotation.value()); >>

You can also access a specific field annotation like this:

Field field = . // obtain method object Annotation annotation = field.getAnnotation(MyAnnotation.class); if(annotation instanceof MyAnnotation)

Источник

Оцените статью