preface

Annotations are the metadata of the source code and, more generally, tags in the code. Annotations have the following characteristics:

  1. An annotation is an accessory that depends on other elements (packages, classes, methods, attributes, and so on).
  2. Annotations are not useful by themselves, but are parsed by an external program when appropriate.

What are annotations?

  1. According to the source points
    • JDK comes with annotations such as @Override, @deprecated, @Suppresswornings.
    • Third party annotations.
    • Custom annotations.
  2. Divided by life cycle
    • SOURCE: only exists in the SOURCE code, compiled into the class file does not exist.
    • Class: Exists in source code and in Class files.
    • RUNTIME: Annotations are reserved for RUNTIME.

What is a meta-annotation?

Meta-annotations are the annotations used to form annotations and include the following:

  1. @Retention: Specifies the Annotation lifecycle. The value passed in is an enumeration type. The optional values are:
    • RetentionPolicy.SOURCE
    • RetentionPolicy.CLASS
    • RetentionPolicy.RUNTIME
  2. @target: specifies which elements of the program can be modified by the Annotation. The value passed in is of type ElemetType[] and can be:
    • ElementType.CONSTRUCTOR: a constructor
    • ElementType.FIELDAttributes:
    • ElementType.LOCAL_VARIABLE: local variable
    • ElementType.METHODMethod:
    • ElementType.PACKAGE: package
    • ElementType.PARAMETERParameters:
    • ElementType.TYPE: classes, interfaces (including annotation types and enum declarations)
  3. @Documented: Annotations with this modifier will be extracted into a document by the Javadoc tool. With this annotation, @Retention must be set toRetentionPolicy.RUNTIME 。
  4. @Inherited: Inherited.

How do I customize annotations?

Custom annotations need to be noted:

  1. Use the @interface keyword definition.

  2. Automatically inherit the Java. Lang. The annotation. The annotation interface.

  3. The types of configuration parameters can only be the eight basic types: String, Class, enum, Annotation, and corresponding array types.

  4. The syntax format of the configuration parameter declaration is as follows ([] indicates that it can be omitted) :

    Type variable name () [default default];Copy the code
  5. If there is only one configuration parameter, the parameter name must be value.

  6. If the defined annotation contains configuration parameters, then when using the annotation, you must specify the parameter value in the form “Parameter name = parameter value”. If there is only one parameter, write the parameter value directly. If the parameter has a default value in the definition, you can specify no value, but you must specify a value if there is no default value.

  7. Annotations without members are tags, and those with members are metadata.

Custom annotation instances (definition and usage)

Reference code:

(1) Test01. Java

import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; Public class Test01 {@info (name =" ",address=" ") public void Test01 (){} @one ("value") public void test02(){} @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE,ElementType.METHOD}) @interface Info { String name(); String address(); int age()default 18; } @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.METHOD}) @interface One{ String value(); }}Copy the code

# # reflection

What is reflection?

Reflection refers to an application that uses the reflection API to obtain internal information about any class at runtime and use this internal information to manipulate the internal properties and methods of the corresponding object.

Any class, the first time it is used, is loaded by the JVM into the method area of heap memory. When a Class is successfully loaded by the JVM, a corresponding Class object (only one Class object per Class) is generated in the method area. This Class object contains all the structural information of the loaded Class.

How do I get a class object?

(1) The class attribute

Each class has a class static property, which is the class object corresponding to the class.

1 Class<Person> cl1 = Person.class; 

Copy the code

(2) The getClass() method of the Object

1 Person p1 = new Person();
2 Class<Person> cl2 = (Class<Person>) p1.getClass(); 

Copy the code

(3) Through the Class forName() method

1 try { 2 Class cl3 = Class.forName("com.llm.hkl.Person"); 3 } catch (ClassNotFoundException e) { 4 e.printStackTrace(); 5}Copy the code

(4) Through the ClassLoader class (not commonly used)

1 ClassLoader cl = Person.class.getClassLoader(); 2 try { 3 Class cl4 = cl.loadClass("com.llm.hkl.Person"); 4 } catch (ClassNotFoundException e) { 5 e.printStackTrace(); 6}Copy the code

How to use reflection?

The basic uses of reflection include creating objects, setting properties, and calling methods. Most get methods on a Class object have Declared and none.

  1. Declared: public modifiers are allowed only, including the current class and all its parents.
  2. Declared: all (including private) of the current class are obtained but not its parent.

Reflection examples:

Person class and annotation class (ready) :

import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @info (name = "张三", habbit = "张三") public class Person {@filed ("张三") private String name; public String habbit; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getHabbit() { return habbit; } public void setHabbit(String habbit) { this.habbit = habbit; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", habbit='" + habbit + '\'' + ", age=" + age + '}'; } private String say(String STR) {String str1 = name + "" + STR; System.out.println(str1); return str1; } public void eat(String food) {system.out.println (name + "eat" + food); } public Person() { } public Person(String name, String habbit, int age) { this.name = name; this.habbit = habbit; this.age = age; } private Person(String name, String habbit) { this.name = name; this.habbit = habbit; } @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD, ElementType.TYPE}) @interface Info { String name(); String habbit(); int age() default 18; } @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) @interface Filed{ String value(); }}Copy the code

Reflect usage 1 (to get basic information about a class) :

Get the name of the class get the properties of the class get the values of the specified properties Get the methods of the class get the specified methods get the constructor get the specified constructor

Class<? > person = Class.forName("Person"); / / get the name of the class System. Out. Println (" < -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- get the name of the class -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - > "); String name = person.getName(); System.out.println(name); / / get the attributes of a class System. Out. Println (" < -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- get the attributes of a class -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - > "); / / only public System. Out. Println (" < -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- the getFields -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- > "); Field[] fields = person.getFields(); for (Field field : fields) { System.out.println(field); } System.out.println("<-----------------getDeclaredFields----------------->"); Field[] declaredFields = person.getDeclaredFields(); for (Field declaredField : declaredFields) { System.out.println(declaredField); } / / for specified attribute's value System. Out. The println (" < -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- get the class specified properties -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- > "); Field name1 = person.getDeclaredField("name"); System.out.println(name1); / / get the method of the System. The out. Println (" < -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- get a class method -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- > "); / / only public System. Out. Println (" < -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- getMethods -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- > "); Method[] methods = person.getMethods(); for (Method method : methods) { System.out.println(method); } System.out.println("<-----------------getDeclaredMethods----------------->"); Method[] declaredMethods = person.getDeclaredMethods(); for (Method declaredMethod : declaredMethods) { System.out.println(declaredMethod); } / / for specified method System. Out. Println (" < -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- get the specified method -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- > "); Method say = person.getDeclaredMethod("say",String.class); System.out.println(say); / / get the constructor System. Out. Println (" < -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- get the constructor of a class -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- > "); System.out.println("<-----------------getConstructors----------------->"); / / only public Constructor <? >[] constructors = person.getConstructors(); for (Constructor<? > constructor : constructors) { System.out.println(constructor); } System.out.println("<-----------------getDeclaredConstructors----------------->"); Constructor<? >[] declaredConstructors = person.getDeclaredConstructors(); for (Constructor<? > declaredConstructor : declaredConstructors) { System.out.println(declaredConstructor); } / / get the constructor of the specified System. Out. The println (" < -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- get the constructor of the class to specify -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- > "); Constructor<? > declaredConstructor = person.getDeclaredConstructor(String.class, String.class, int.class); System.out.println(declaredConstructor);Copy the code

Reflect usage 2 (create and manipulate objects) :

Reflection creates an object by calling the no-parameter constructor by using the parameter constructor by setting public properties by reflection by setting private properties by reflection calling a method by reflection calling a private method

Class<? > person = Class.forName("Person"); / / reflection way to create objects System. Out. Println (" < -- -- -- -- -- reflection way to create objects -- -- -- -- -- > "); Person instance01 = (Person) person.newInstance(); System.out.println(instance01); / / calls a no-parameter constructor to create objects System. Out. The println (" < -- -- -- -- -- call a no-parameter constructor to create objects -- -- -- -- -- > "); Constructor<? > noneConstructor = person.getDeclaredConstructor(); Person instance02 = (Person) noneConstructor.newInstance(); System.out.println(instance02); / / calls have involved the constructor to create objects System. Out. The println (" < -- -- -- -- -- call have join the constructor to create objects -- -- -- -- -- > "); Constructor<? > constructor = person.getDeclaredConstructor(String.class, String.class, int.class); Person instance03 = (Person) constructor. NewInstance (" 对 方 ", "对 方 ", 18); System.out.println(instance03); / / call private constructor to create the object System. Out. The println (" < -- -- -- -- -- call private constructor to create objects -- -- -- -- -- > "); java.lang.reflect.Constructor<? > privateConstructor = person.getDeclaredConstructor(String.class, String.class); privateConstructor.setAccessible(true); The Object instance04 = privateConstructor. NewInstance (" zhang ", "programming"); System.out.println(instance04); / / set the public property by reflection System. Out. The println (" < -- -- -- -- -- by reflecting set public properties -- -- -- -- -- > "); Field habbit = person.getDeclaredField("habbit"); Habbit. set(instance01, "programming "); System.out.println(instance01); / / set the private property through reflection System. Out. The println (" < -- -- -- -- -- by reflecting set private properties -- -- -- -- -- > "); Field name = person.getDeclaredField("name"); name.setAccessible(true); Name. Set (instance01, "zhang SAN "); System.out.println(instance01); / / by reflection calls public methods System. Out. The println (" < -- -- -- -- -- by reflecting tuning utility method -- -- -- -- -- > "); Method eat = person.getDeclaredMethod("eat", String.class); Eat. Invoke (instance01, "rice"); / / by reflection calls a private method System. Out. The println (" < -- -- -- -- -- by reflection calls a private method -- -- -- -- -- > "); Method say = person.getDeclaredMethod("say", String.class); say.setAccessible(true); Say. Invoke (instance01, "ha ha");Copy the code

Reflect usage 3 (to get generic information) :

Java introduced generics by using the mechanism of generic erasure. Generics in Java are only used by the compiler Javac to ensure data security and avoid casting problems. However, once compilation is complete, all types related to generics are erased. To manipulate these types by reflection,Java adds ParameterizedType, GenericArrayTypeType Variable, and WildcardType to represent types that cannot be grouped into a class class but are named the same as the original type.

ParameterizedType: specifies a ParameterizedType. For example, Collection< String>

GenericArrayType: Indicates the type of an array whose element type is a parameterized type or type variable

TypeVariable: is a common parent interface for variables of various types

WildcardType: indicates a WildcardType expression

import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.List; import java.util.Map; public class Test03 { public void test01(Map<String, Person> map, List<Person> list) { System.out.println("test01"); } public Map<String, Person> test02(){ System.out.println("test02"); return null; } public static void main(String[] args) throws Exception { Class<Test03> test03 = Test03.class; System.out.println("<--------test01---------->"); Method test01 = test03.getDeclaredMethod("test01", Map.class, List.class); Type[] genericParameterTypes = test01.getGenericParameterTypes(); for (Type genericParameterType : genericParameterTypes) { System.out.println(genericParameterType); if (genericParameterType instanceof ParameterizedType) { Type[] actualTypeArguments = ((ParameterizedType) genericParameterType).getActualTypeArguments(); for (Type actualTypeArgument : actualTypeArguments) { System.out.println(actualTypeArgument); } } } System.out.println("<--------test02---------->"); Method test02 = test03.getDeclaredMethod("test02"); Type genericReturnType = test02.getGenericReturnType(); System.out.println(genericReturnType); if (genericReturnType instanceof ParameterizedType) { Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments(); for (Type actualTypeArgument : actualTypeArguments) { System.out.println(actualTypeArgument); }}}}Copy the code

Running results:

Reflect usage 4:

Gets annotations on a class gets annotations on a property Gets annotations on a method

Class<? > person = Class.forName("Person"); System. The out. Println (" < -- -- -- -- -- -- -- -- -- -- get class notes -- -- -- -- -- -- -- -- -- -- -- -- -- > "); Info annotation = person.getannotation (info.class); System.out.println(annotation.name()); System.out.println(annotation.habbit()); System.out.println(annotation.age()); System. Out. Println (" < -- -- -- -- -- -- -- -- -- -- gets an attribute on the annotation -- -- -- -- -- -- -- -- -- -- -- -- -- > "); Field name = person.getDeclaredField("name"); Person.Filed file = name.getAnnotation(Person.Filed.class); String value = file.value(); System.out.println(value); // The method of obtaining...Copy the code

Running results:

The last

You can leave a comment below to discuss what you don’t understand. You can also pay attention to my private letter and ask me. I will answer it after I see it. Also welcome everyone to pay attention to my public account: the future is bright, immediately gold nine silver ten job-hunting interview season, sorted out more than 1000 nearly more than 500 pages of PDF document Java interview questions in it, to help you realize your dream BAT! Articles will be updated in it, and sorted data will be placed in it. Thank you for watching, think the article is helpful to you remember to pay attention to me a thumb-up support!