JAVA Annotations and Reflections

Keywords: Java Attribute jvm Spring

Annotations to JAVA

What is annotation?

Annotations are still very popular at present, and Sprinng, which we often use, uses annotations. Adding annotations can make the code concise, easy to read and use.

  1. First, let's look at our own meta-annotations in java, under the java.lang.annotation package, where @Native@Repeatable is not a meta-annotation (meta-annotation is annotation for new annotations)
Annotation name explain
@Target Indicates where the annotation can be used, and possible ElementType parameters are: CONSTRUCTOR: Constructor's declaration FIELD: Domain declaration (including enum instances) LOCAL_VARIABLE: Local variable declaration METHOD: Method declaration PACKAGE: Package declaration PARAMETER: Parameter declaration TYPE: Class, Interface (including annotation types) or enum declaration
@Retention Indicates at what level the annotation information needs to be saved. Optional Retention Policy parameters include: SOURCE: Annotations will be discarded by the compiler CLASS: Annotations are available in the class file, but RUNTIME: VM will retain annotations during operation, so annotation information can be read through reflection mechanism.
@Document Include annotations in Javadoc
@Inherited Allow subclasses to inherit annotations from parent classes
  1. What can new annotations do?
    Create a comment for MyAnnotation.Class
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
//@ Inherited allows subclasses to inherit annotations from parent classes
//@ Documented includes annotations in <u>Javadoc</u>.
//@ At what level do Retention annotations hold annotations that can be used in reflection mechanisms
//@ Where can annotations created by Target be used (methods, classes, etc.)
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface MyAnnotation {
}

New class Atest.Class to use annotations

@MyAnnotation
public class Atest {
    private int number;
    private String name;
    public int getNumber() {
        return number;
    }
    public void setNumber(int number) {
        this.number = number;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString(){
       return Atest.class.toString();
    }
    Atest(){}
}

Create a new Btest.Class to test annotations, using reflection

public class Btest {
  public static void main(String[] args) throws {
        Atest atest = new Atest();
        Class<?> clazz = atest.getClass();
        //Determine whether a class has annotations
        if(clazz.isAnnotationPresent(MyAnnotation.class)) {
            System.out.println("Annotated");
            System.out.println(clazz.newInstance().toString());
        }
}

Display results:

Annotated
class test.Atest

If @Retention(RetentionPolicy.RUNTIME) is changed to @Retention(RetentionPolicy.SOURCE) for meta-annotations of annotations, JVM cannot recognize annotations and generally uses runtime state.
To sum up, what's the use of annotations? A series of operations can be performed at JVM runtime, reflections can be used together, and annotated classes can be retrieved for related processing. Annotations in Spring are used in this way. Make some of the work we can do ourselves to get the framework done.

Class object

An important part of Java's reflection mechanism is to obtain Class objects. Class objects describe information about classes. Class members, methods, annotations and so on can be obtained by obtaining Class formation.

Three methods to obtain Class objects:

  1. Class.forName("Class Path");
  2. Class name. getClass();
  3. new Class().class();

So, what can you do with the class class class you get?
The construction method, general method, and members of the corresponding class can be obtained.

Constructor constructors = clazz.getConstructor(null);//Get the constructor
Field[] fields = clazz.getDeclaredFields();//Get all the fields it defines
Method[] methods = clazz.getDeclaredMethods();//Get all the methods it defines

There are many ways:
getName(): Gets the full name of the class.
getFields(): Gets the properties of the public type of the class.
getDeclaredFields(): Gets all attributes of the class. Including private declarations and inheritance classes
getMethods(): A method for obtaining the public type of a class.
getDeclaredMethods(): Get all the methods of the class. Including private declarations and inheritance classes
getMethod(String name, Class[] parameterTypes): Gets the specific method of the class, the name parameter specifies the name of the method, and the parameterTypes parameter specifies the parameter type of the method.
getConstructors(): Gets the construction method of the public type of the class.
getConstructor(Class[] parameterTypes): Gets the specific constructor of the class, and the parameterTypes parameter specifies the parameter type of the constructor.
newInstance(): Creates an object of this class through its parametric-free constructor.

reflex

JAVA reflection mechanism is in the running state, ** for any entity class, all attributes and methods of this class can be known; for any object, any method and attributes can be invoked; ** This function of dynamic acquisition of information and dynamic invocation of object methods is called the reflection mechanism of Java language.

Reflection mechanism can break the restriction of access rights of classes, run private methods and access to modify private attributes.
When executing private methods and accessing private attributes, you need to add a method.setAccessible(true); break the restrictions on access rights

Create a new Ctest class with private methods and private attributes

public class Ctest {
	private int code;
	private String name;
	Ctest(int code,String name) {
		this.code = code;
		this.name = name;
	}
	private String printCtest(){
		return "hello"+name + code;
	}
}

Access in class Btest:

public class Btest {

	public static void main(String[] args){
		
		Atest atest = new Atest();
		Class<?> clazz = atest.getClass();
		Field[] fields = clazz.getDeclaredFields();
		//Determine whether a class has annotations
		if(clazz.isAnnotationPresent(MyAnnotation.class)) {
			System.out.println("Annotated");
			
			System.out.println(clazz.newInstance().toString());
		}
		
        Ctest c = new Ctest(1,"htx");
        Class<?> cclazz = Ctest.class;//Get the class object
        Field[] files = cclazz.getDeclaredFields();//Method attributes for obtaining all rights
        Method[] methods = cclazz.getDeclaredMethods();//Method of obtaining all rights
        for(Method method : methods){
        	System.out.println("Method" + method.getName());
        }
        for(Field file: files){
        	System.out.println("attribute" + file);
        }
        try {
            //modify attribute
        	Field field = cclazz.getDeclaredField("name");
        	field.setAccessible(true);
        	System.out.println("The attribute values before modification are:" + field.get(c).toString()); 
        	field.set(c,"world");
        	System.out.println("The modified attribute values are:" + field.get(c).toString()); 
        	//Execution method
            Method method = cclazz.getDeclaredMethod("printCtest");
            method.setAccessible(true);
			Object temp = method.invoke(c);
			System.out.println("Execution method" + temp.toString());
		} catch (Exception e) {
			e.printStackTrace();
		}        
	}
}
The output results are as follows:
Method printCtest
 Attribute private int test.Ctest.code
 Attribute private java.lang.String test.Ctest.name
 The attribute value before modification is: htx
 The modified attribute value is:world.
Execution method helloworld1

Conclusion:

  1. Annotations and reflections are commonly used with each other, and Spring's object injection is implemented in this way.
  2. Using reflection can break the original access restrictions, but improper use will also affect the speed of operation. Reflection can modify the attributes of an object and execute its methods. You can also get all the information about the class.

Posted by Lyleyboy on Thu, 09 May 2019 22:58:38 -0700