1, the preface

Refers to in the running state of the program, you can construct an object of any class, you can know the class of any object, you can know the member variables and methods of any class, you can call the attributes and methods of any object. Reflection is very powerful, very flexible, and has the following functions in terms of solving things

  • Calling the hidden API
  • Get annotation information
  • Section programming

However, reflection also has disadvantages. When it can be done without reflection, try not to use it for the following reasons:

  1. Performance issues: Java reflection includes some dynamic types, so the Java VIRTUAL machine cannot optimize this dynamic code. Today’s machines are generally fine, and when the number of reflections is low, there is basically no performance impact, right
  2. Security constraints: Using reflection usually requires that the program run without security constraints.
  3. Program robustness: Reflection allows code to perform actions that are not normally allowed, so using reflection can have unintended consequences.

What does reflection involve from a technical point of view?

  1. The related base classes for reflection Class, Field, Method, and Constructor
  2. Generics and their reflection
  3. Reflection of arrays
  4. annotations

2. Base API

An important Class for reflection is Class; A Class is a Class information object that the JVM creates when it needs to load Class information. Each Class in Java corresponds to a Class object in the JVM; Class objects cannot be created by themselves, and a Class corresponds to a unique Class object within the same JVM;

Note: Reflection may not be found by name and will throw an exception

2.1 the Class action

This object is the key entry point for runtime reflection (Java annotator, source phase processing, also has a set of reflection fetch code, which I call static reflection);

General operations of class, including getting, generating instances, getting property methods, and so on

There are three ways to get a Class object

  • When code can refer to a class,

    Class<? > cls = Test.class;Copy the code
  • When class objects can be generated in code

    Class<? > cla = test.getClass();Copy the code
  • There is no class information in the code, you can use the fully qualified name of the class to find, may not find, will throw an exception

    Class<? > lll = Class.forName("com.csu.liutao.Test");Copy the code

Generate the corresponding Class object of Class

	Test tt = (Test) cls.newInstance();
Copy the code

Generating class objects can also be handled using Constructor; Operations on properties and methods are described below

2.2 Attribute Operations

Attribute operations are divided into: obtain, obtain attribute name-value, modify attribute value; Property is operated on by the Class object

Gets the public property of the current class or its parent, grandparent, and so on

 Field[] fields = cls.getFields();
 Field field = cls.getField("name");
Copy the code

Just get all the properties declared by the current class

Field[] fields = cls.getDeclaredFields();
Field field = cls.getDeclaredField("name");
Copy the code

Gets/sets the property value

String name = field.getName();
String value = (String) field.get(test);
field.set(test, "xinde");
Copy the code

One thing to understand; The name of the property is determined after the class is loaded, independent of the object, but the value of the property is initialized after the object is created, dependent on the instance; In the code above, test represents the corresponding real column

Has anyone actually done this and said, hey, my private method can’t get the property value, change the property value; That’s because access to private is restricted, which can be avoided by the following code

field.setAccessible(true);
Copy the code

Static properties do not depend on the instance. Test is passed null

2.3 Method Operation

Method objects are also handled by Class; Common operations: get method, execute method; There are two ways to obtain it

  • Gets all Public methods, including Public methods in inherited classes

      Method[] methods = cls.getMethods();
      Method method = cls.getMethod("hello", new Class[]{String.class});
    Copy the code
  • Just get the declared methods in this class, private or not

      methods = cls.getDeclaredMethods();
      Method method = cls.getDeclaredMethod("hello", new Class[]{String.class});
    Copy the code

When querying by name, the first parameter is the name of the method, and the second parameter is the class array.

When executing a method, it is also necessary to set permission release, and when a static method is used, the first parameter of invoke is passed to null, and the following parameters are method parameters, which are passed all the time

method.setAccessible(true);
method.invoke(test, "getDeclaredMethod invoke hello method");
Copy the code

In annotations, you also get method parameter information and return value information

Return value information

Method.getReturnType(); / / the class information, not including generic Method. The getGenericReturnType (); // Generic informationCopy the code

Request parameter information:

Method.getParameterTypes()); / / class information Method. GetGenericParameterTypes (); / / generics information Method. The getParameters () / / Parameter information, including the type information (Parameter. The getType ()), generic information (Parameter. GetParameterizedType ())Copy the code

Constructor object

The constructor is a special method; General operations: obtaining and generating instances; There are two ways to get it. In the process, you only need to pass in the class array of the parameter column

  • Gets the public constructor for this class

      Constructor[] constructors = cls.getConstructors();
      Constructor constructor = cls.getConstructor(new Class[]{int.class, long.class});
    Copy the code
  • Gets all constructors declared in this class

      constructors = cls.getDeclaredConstructors();
      constructor = cls.getDeclaredConstructor(new Class[]{int.class, long.class});
    Copy the code

If the obtained file is not necessarily public, you need to enable permission restriction. The newInstance method only needs to pass in the construction parameters

	constructor.setAccessible(true);
    constructor.newInstance(5, 10L);
Copy the code

3. Generics and reflection

Reflection is much simpler without generics; But what happens now is that not only do generics exist, but they’re used very widely; So let’s see what generics are

3.1, generics

Generics are parameterized types: suitable for multiple data types to execute the same code; Types in generics are specified at use; Generics are, after all, “templates”;

In Java, generics are only known at run time, and they are just syntactic sugar. The compiled class file has only one and no generic parameters (generic parameters change to upper bounds, default Object). Bridge methods are also generated in generic class inheritance implementations;

public class Temp<T> { T t; public <U> U convert(T t) { return (U) t; } public <U> void set(U u) { t = (T) u; }}Copy the code

This code; Shows the common uses of generics, generic classes, generic methods

In addition to being expressed as a flag, generics can also take the form of wildcards:? ,? extend, ? super

  • ? : Any type;
  • ? Extend: A subclass of a class
  • ? Super: The superclass of a class

Type erasure

And it’s actually pretty easy to understand this, because if I compile the code above, for example; Generics information is certainly stored as well, and the actual Java code can be viewed roughly as follows; The generic parameter is replaced with an upper bound, in this case Object, if? Extend String, that replaces String

public class Temp {
    Object t;
}
Copy the code

Be aware of the following limitations when using generics:

  1. Primitive types cannot be used: only Object and its subclasses due to type erasure
  2. Cannot be instantiated, mainly to prevent type conversion errors
  3. It is not allowed to define static variables, which are initialized before the instance is created without knowing the type of the generic, so no
  4. It’s not covariant, wildcards are covariant, arrays are covariant, that’s what type erasers are; The parameters of a generic type are inheritance, so the two generic classes are also inheritance, which is covariant
  5. Instanceof does not support specific generics and can use generic wildcards. Also because of erasure
  6. You can’t create a concrete class with new; wildcards can; Related to erasure, generic parameters must be known when new objects are created
  7. It is not allowed to define generic exception classes or catch exceptions (throws may)
  8. Method overloading is not allowed

These limitations are basically due to generic erasure, the life cycle of the object created by the class;

3.2 Generics and collections

When wildcards are combined with collections, there are restrictions on adding and fetching:

  1. ? Extends: cannot be added, can only be obtained
  2. ? Super: You can add a class and its subclasses to get Object

3.3 Generics and reflection

Here is how to get generic information; There are four types of generic information:

  1. TypeVariable type:

    T object; // T is of this typeCopy the code
  2. ParameterizedType type:

    The ArrayList < T > list; // ArrayList<T> is of this typeCopy the code

    Class types can be obtained through class methods, erased class types, and generic types

    GetActualTypeArguments () // Generic parameter type, i.e. T getRawType() // erased type, i.e. ArrayListCopy the code
  3. GenericArrayType type

    T[] array; GetGenericComponentType (); // getGenericComponentType();Copy the code
  4. WildcardType type

    ? Extends Number extends Number // This Type gets bounds from class methods: Type[] getUpperBounds(); Type[] getLowerBounds();Copy the code

Get one of the above types by:

The java.lang.class.gettypeparameters () / / Class. The Class generic parameter getComponentType () / / object in the array of generic parameter Method. The getGenericParameterTypes generics () / / all parameters Method. GetGenericReturnType () / / the return value generics. GetGenericType () / / variable generics informationCopy the code

3.4 Arrays and Reflections

I’ve talked a little bit about some of the properties of arrays in reflection, but I’m just going to talk about how reflection can be used to create, add, and get; There are no more operations, the class that does the operation is Array;

create

Object array = Array.newInstance(String.class, 10);
Copy the code

add

Array.set(array, 5, "hello");
Copy the code

To obtain

String str = (String)Array.get(array, 5);
Copy the code

4. Annotations and reflections

This is about runtime annotations; @Retention(retentionPolicy.runtime)

4.1 Introduction to Annotations

Annotations are essentially a special interface that inherits annotations, implemented by dynamic proxy classes generated by the Java runtime.

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Test {
}
Copy the code

It’s essentially defining an interface; The above is explained as follows

  1. At sign interface means this is an annotation interface
  2. @document indicates that the annotation is included in Javadoc
  3. @retention indicates the annotation Retention lifetime. Optional RetentionPolicy parameters include:
    • SOURCE: Annotations are discarded by the compiler
    • CLASS: Annotations are available in the CLASS file, but are discarded by the VM
    • RUNTIME: The VM will retain annotations during RUNTIME, so they can be read by reflection.
  4. @target Where this annotation can be used. Possible ElementType arguments are:
    • CONSTRUCTOR: the declaration of a CONSTRUCTOR
    • FIELD: FIELD declaration (including enum instances)
    • LOCAL_VARIABLE: local variable declaration
    • METHOD: indicates the METHOD declaration
    • PACKAGE: PACKAGE declaration
    • PARAMETER: PARAMETER declaration
    • TYPE: Class, interface (including annotation TYPE), or enum declaration

These annotations, which Java already provides, are called meta-annotations; We define basic Target and Retention as sufficient;

Some other common meta-annotations

  • Override, which means that the current method definition will Override methods in the superclass.
  • @deprecated: The compiler will warn elements that use an annotation for it because the annotation @deprecated is Deprecated code.
  • @suppressWarnings, turn off improper compiler warnings.

4.2 Annotation Acquisition

When using, I see and use only three kinds of annotations: member annotations, method annotations, method parameter annotations; Others are not quite clear, interested in their own understanding;

In addition, the author does not find any difference in methods with Declared, undeclared, or scenes that are undeclared. Leave a message if you know

4.2.1 Member Notes

Notes that look like this

	@IField("ITest-private-field")
    private String first;
Copy the code

The following code can get the annotation class object, you can get the annotation information; These two methods have been tested in the code and the results are consistent;

	Field.getAnnotation(Class)
    Field.getAnnotations()

    Field.getDeclaredAnnotation(Class)
    Field.getDeclaredAnnotations()
Copy the code

4.2.2 Annotation of method parameters

Like this

public void setThird(@IParam("parent_param") String third) {
    this.third = third;
}
Copy the code

The parameter annotation array can be obtained by using the following method: the size of the one-dimensional array is the number of parameters, and the corresponding two-dimensional array is the number of annotations in the parameter

method.getParameterAnnotations()
Copy the code

4.2.3 Method annotations

Notes that look like this

@IMethod("ITest-public-method")
public String getThird() {
    return third;
}
Copy the code

Method annotations can be obtained by using the following method; Act in the same way

Method.getAnnotation(Class);
Method.getDeclaredAnnotation(Class);

Method.getAnnotations();
Method.getDeclaredAnnotations();
Copy the code

4, summary

This article knowledge point is trivial, and the content also belongs to rote memorization; This write down, but also according to the usual use of some + some source code how to use + IDE test verification; I hope you look at the source code, the knowledge points in series, increase the use of more and more skills

Technology changes quickly, but the basic technology, the theoretical knowledge is always the same; The author hopes to share the basic knowledge of common technical points in the rest of his life. If you think the article is well written, please pay attention and like it. If there are mistakes in the article, please give me more advice!