Explain Java reflection operation in detail

Special invited author of enjoying learning class: Dream chasing youth
Reprint, please state the source!

In the process of java development, some frameworks such as Spring and SpringMvc are often used to simplify the development operation. In web development, we can use SpringMvc to quickly convert the request parameters and entities. When using database operation, we can use Mybatis/hibernate and other frameworks to realize the conversion operation between entities and db, This is the operation realized by using the reflection mechanism of Java, so there will be a place for reflection in the advanced journey of Java. Let's learn about the classes and methods related to java reflection in detail

Where is reflection suitable

First of all, let's think about a question. Where is reflection suitable for use? In terms of function, reflection seems to be omnipotent. We can use almost all classes, all attributes, methods and structures, but let's think carefully. In actual development, not all scenes need to use reflection to obtain attributes or methods for operation, but more use examples xxx mode operation. When these operations are repeated many times, we often consider optimizing the code, reducing code redundancy and improving reuse, such as entity construction, assignment and other operations. At this time, it is often where we need to reuse most, so we can generally think that reflection is mainly used in the process of entity operation. In the process of general data operation, our entities generally know and depend on the corresponding data type, such as:

1. Create objects according to the type new

2. Define variables according to the type. The type may be a basic type or a reference type, class or interface

3. Pass the object of the corresponding type to the method

4. Access the properties of the object and call methods according to the type

The above operations are the most common and difficult to reuse and optimize in the process of data operation. If reflection is used in the operation here, you can dynamically operate instances of different types. By calling the reflection entry Class, you can obtain the corresponding attributes, structures and methods to complete the corresponding operation. So let's start from the Class entry

Get Class

When we have studied the principle of class and inheritance implementation, we all know that each loaded class has a corresponding class information in memory, and each Object has a reference to its class. The class in which the class information is stored is Java lang.Class. In the base class Object of all classes, there is a local method that can quickly obtain the class Object

public final native Class<?> getClass()

You can see that the returned type is class <? >, This is the information of the current class, but the subclass of the base class is not clear, so the specific type is returned in the form of template

The getClass method can be used not only in the class, but also for the interface. Of course, the interface has no specific implementation, so it cannot be an instance of the interface Get by getClass. At this time, we need to call the built-in Class attribute quick get type:

Class<Comparable> cls = Comparable.class;

In java, there are some special types, such as basic type and void type. This type cannot directly create an instance. If you want to obtain a class, the same way as the interface is as follows:

//It can be seen here that the class of the basic type is the corresponding packaging type
Class<Integer> intCls = int.class;
Class<Byte> byteCls = byte.class;
Class<Character> charCls = char.class;
Class<Double> doubleCls = double.class;
//Void is also a special type, which returns the corresponding wrapper class void
Class<Void> voidCls = void.class;

As a special implementation class in java, array and enumeration obtain special class types. Array has dimension characteristics, so the obtained class types also have dimensions, that is, one one-dimensional array and two-dimensional arrays. Each dimension has corresponding different types, and the enumerated class is each subset defined therein, as follows:

String[] strArr = new String[10];
int[][] twoDimArr = new int[3][2];
int[] oneDimArr = new int[10];
Class<? extends String[]> strArrCls = strArr.getClass();
Class<? extends int[][]> twoDimArrCls = twoDimArr.getClass();
Class<? extends int[]> oneDimArrCls = oneDimArr.getClass();

After obtaining the Class object in the above way, we can learn a lot of information about the type, and based on this information, we can obtain the detailed information we want, which can be roughly divided into the following categories, including name information, field information, method information, method of creating object, construction information and type information, Next, we will learn the contents related to these types of information

Class name information

In the development process, after obtaining the Class, we often need to obtain the corresponding Class name for operations, such as comparing the Class name and excluding the Class name. In the Class class, the following methods are provided to obtain the relevant information of the Class name:

public String getName()
public String getSimpleName()
public String getCanonicalName()
public Package getPackage()

It can be seen here that four different class names can be obtained respectively. What are the differences in the specific contents obtained? Let's first look at a list of table information:

It can be seen that the Class name information obtained by different types of classes through the four methods is completely different, so why is there such a big difference? Here we need to pay attention to:

getName()

The getname () method obtains the standard class name information, that is, the name information corresponding to the real type in Java (the real class name information of the JVM), Here we can see that the result of getName() of the array is [i]. It needs to be explained here that [represents an array and is related to the dimension. If it is a two-dimensional array, it will be [[, and the following I is the abbreviation of the real type of int type in Java. The abbreviated names of the classes corresponding to the eight basic types are as follows:

Basic typeReal class name abbreviation
booleanZ
byteB
charC
doubleD
floatF
intI
longJ
shortS

Another thing to note here is that if it is an array referencing type objects, there will be a semicolon at the end of the real Class name of Class;

getSimpleName()

The getSimpleName() method is implemented by jdk to quickly obtain the path abbreviation of the real Class name of the current Class, that is, the Class name without package name

getCanonicalName()

The getCanonicalName() method obtains the complete pseudo Class name in java, that is, the complete name of the package name + getSimpleName() name. The Class name obtained by this method is relatively friendly

getPackage()

getPackage() is a method implemented by default in java that can be used to quickly obtain the package name of the current Class. This method only returns the front of the Class path (package name), excluding the Class name

Class field information

After obtaining the name information of Class, we begin to focus on how to obtain Class attribute information through Class. We know that both static and instance variables defined in the Class are called fields. In the Class class, they are represented by Field, which is located in Java Under the lang.reflect package, and in the Class class, there are the following methods to obtain Field information:

public Field[] getFields()
public Field[] getDeclaredFields()
public Field getField(String name)
public Field getDeclaredField(String name)

It can be seen that it is mainly divided into two types: one returns field array and the other returns specific fields. See the functions of these two types of methods respectively:

getFields()/getDeclaredFields()

getFields()/getDeclaredFields() methods return all fields in the current Class, including those from the parent Class. However, there are certain differences between the two methods. getFields() method can only return non private fields, while getDeclaredFields() method returns all fields, including private fields, Of course, the setAccessible method is also needed

getField(String name)/getDeclaredField(String name)

Both getField(String name)/getDeclaredField(String name) methods obtain the corresponding field information through the field name. Through naming, it is not difficult to find that, similar to the previous group, the getField(String name) method can only find the field information of the current name from all non private fields, Getdeclaraedfield (string name) is to find the field information of the corresponding name from all fields

Common methods of operating Field

Through the above four methods, we can easily obtain the corresponding Field information in the Class. Next, we can complete the operations we need as long as we operate and process these information. The common methods of operating Field are as follows:

public String getName()
public boolean isAccessible()
public void setAccessible(boolean flag)
public Object get(Object obj)
public void set(Object obj, Object value)

getName()

The getName() method can be seen by naming. This method can get the Field name of the current Field

isAccessible()

isAccessible() method we introduced in the above getdeclaraedfields() method. If you need to obtain private fields, you need the support of setAccessible method. This method can obtain whether you can obtain the support of setAccessible method, that is, whether you can obtain private fields

setAccessible(boolean flag)

setAccessible(boolean flag) is to set the Boolean value to confirm whether to check the private Field in the current reflection to obtain the Field. If it is set to true, it will not be checked. Reflection can obtain the private Field. If it is set to false, it will check the private Field. Reflection cannot obtain the private Field

get(Object obj)/set(Object obj, Object value)

We are all familiar with the get(Object obj)/set(Object obj, Object value) method. This opposite law is to set / obtain the corresponding value for the current Field

Other methods

In addition to the above common methods, some other methods of operating Field may be used in the development process. When used in combination, more flexible Field operations can be realized. The methods are as follows:

//Returns the modifier of the current field -- public, private, etc
public int getModifiers()
//Returns the type of the current field -- String, etc
public Class<?> getType()
//Gets / assigns the field value of the base type through the current method
public void setBoolean(Object obj, boolean z)
public boolean getBoolean(Object obj)
public void setDouble(Object obj, double d)
public double getDouble(Object obj)
//Get the annotation on the current field. When using frameworks such as jpa or mybatis plus, some annotations will be added to the field
public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
public Annotation[] getDeclaredAnnotations()

Class method information

After obtaining the Field information, we often need to operate the method, such as calling xx method to realize some functions. At this time, we need to obtain the method information, and there are many methods to operate the method information in Class, which are common as follows:

Get all non private methods, including the non private methods of the parent class
public Method[] getMethods()
//Gets all methods, including private methods and non private methods of the parent class
public Method[] getDeclaredMethods()
//Find the methods with the same name and parameter list from all public methods of the current Class (including non private methods of the parent Class)
//If not found, NoSuchMethodException will be thrown
public Method getMethod(String name, Class<?>... parameterTypes)
//Find the method with the same name and parameter list from all methods of the current Class, including the non private methods of the parent Class. If it is not found, NoSuchMethodException will be thrown
public Method getDeclaredMethod(String name, Class<?>... parameterTypes)

When we get the Method object through the above Method, we can operate the object to complete the Method method call, etc., and the Method information includes the following contents:

//Gets the name of the current Method
public String getName()
//Whether to ignore the inspection mechanism and allow private methods to be called. If set to true, the inspection will be ignored and private methods will be called. If set to false, the inspection mechanism will be used and private methods will not be operated
public void setAccessible(boolean flag)
//Call the current method of the specified obj instance object, and call the correct method according to the parameters
public Object invoke(Object obj, Object... args) throws
IllegalAccessException, Illegal-ArgumentException, InvocationTargetException

Reflection creation instance and construction method

After we get the field information and method information, we can basically operate these to complete many common functions here, but in addition, we will encounter frequent operations of constructing instances in daily development. If only we can reflect and create instances, the Class provides the method of constructing instances and the construction method of operating classes, As follows:

//Gets the list of all public constructor methods of the current Class
public Constructor<?>[] getConstructors()
//Get the list of all construction methods in the current Class, including private construction methods
public Constructor<?>[] getDeclaredConstructors()
//Find the non private construction methods that meet the current requirements according to the parameter list. If not, throw NoSuchMethodException
public Constructor<T> getConstructor(Class<?>... parameterTypes)
//Find the matching methods in all current constructions according to the parameter list. If not, throw NoSuchMethodException
public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)

By calling the obtained construction method, we can complete the loading and construction of class instances. Similarly, we can also use the following methods to quickly build class instances:

public T newInstance() throws InstantiationException, IllegalAccessException

Take a simple example:

Map<String,Integer> map = HashMap.class.newInstance();//Pass class <? > Newinstance build class instance
map.put("hello", 123);

Type information and declaration information of Class

Through the above learning, we have learned that Class is a magical existence, which can not only obtain names, but also operate fields and methods. Then we can't help wondering whether the type represented by Class is an ordinary Class, an internal Class, a basic type or an array? In fact, Class is a collection of types. The type of each Class depends on the original type. The Class method also provides the following methods to help judge the type information of Class, as follows:

//Is the Class type an array
public native boolean isArray() 
Class Is the basic data type--Packaging
public native boolean isPrimitive() 
//Is the Class type an interface
public native boolean isInterface()
//Whether Class type is enumeration
public boolean isEnum() 
//Whether Class type is annotation type
public boolean isAnnotation() 
//Is the Class type an anonymous inner Class
public boolean isAnonymousClass() 
//Whether the Class type is a member Class, and the Class defined outside the method
public boolean isMemberClass()
//Whether the Class type is a local Class, that is, the Class defined in the method, and the non anonymous inner Class
public boolean isLocalClass() 

In addition to the type information of Class itself, we can also obtain the declaration information, parent Class, interface and other information of Class according to the following methods:

//Gets the modifier of the current class
public native int getModifiers()
//Gets the parent type information of the current class
public native Class<? super T> getSuperclass()
//Get all the interface information implemented by the current class
public native Class<?>[] getInterfaces();
//Gets the annotation information array of the current class declaration
public Annotation[] getDeclaredAnnotations()
//Get all annotation information in the current class
public Annotation[] getAnnotations()
//Find the corresponding annotation information according to the complete class name of the annotation
public <A extends Annotation> A getAnnotation(Class<A> annotationClass)

Reflection of arrays and enumerations

In the process of using reflection, in addition to daily operations, sometimes we need to do some reflection operations for the Class of Array and enumeration types, and the operation of Array types often needs the help of Java The operation of Array Class under lang.reflect package is completed. The main methods are as follows:

//Create an array with element type and element length specified
public static Object newInstance(Class<?> componentType, int length)
//Create a multi-dimensional array. Dimensions can be passed continuously to represent different dimensions
public static Object newInstance(Class<?> componentType, int... dimensions)
//Gets the value of the corresponding index of the specified array
public static native Object get(Object array, int index)
//The value assigned to the corresponding index of the specified array
public static native void set(Object array, int index, Object value)
//Get array length
public static native int getLength(Object array)

It should be noted that in the Array class, arrays are represented by Object instead of Object [], which is designed to facilitate the processing of various types of arrays, because in java, arrays such as int [], String [], etc. can not be converted to Object [], but can be converted to Object, for example:

int[] intArr = (int[])Array.newInstance(int.class, 10);
String[] strArr = (String[])Array.newInstance(String.class, 10);

In addition to array types, in development, especially when encountering fixed constant types, we often choose to use enumeration classes to implement operations. However, in reflection, when we need to find enumeration types, Class class provides the following methods to obtain all constants defined in our enumeration classes, so as to realize enumeration related reflection operations

//Gets all defined enumeration constants of the current enumeration type Class
public T[] getEnumConstants()

last

Authoritative guide - the first Docker book

Lead the installation, deployment, management and expansion of Docker, let it go through the whole development life cycle from test to production, and have an in-depth understanding of what scenarios Docker is suitable for. In addition, this authoritative guide to Docker introduces the basic knowledge of its components, and then uses Docker to build containers and services to complete various tasks: using Docker to establish a test environment for new projects, demonstrating how to integrate Docker using continuously integrated workflow, how to build application services and platforms, how to use Docker's API, and how to expand Docker.

It includes nine chapters: introduction, installing Docker, getting started with Docker, using Docker image and warehouse, using Docker in testing, using Docker to build services, using Fig to configure Docker, using Docker API, getting help and improving Docker.

About the "K8S+Docker learning guide" strongly recommended by Ali - "in simple terms, Kubernetes: Theory + practice" and "authoritative guide - the first Docker book", after reading, it is described in two words: love, love!

If you love too, Click here to download the "K8S+Docker" learning guide for free

4842690)]

[external chain picture transferring... (IMG vlagohcm-1623644842691)]

[external chain picture transferring... (img-5z4QwTiU-1623644842693)]

[external chain picture transferring... (img-mG43iLUo-1623644842693)]

About the "K8S+Docker learning guide" strongly recommended by Ali - "in simple terms, Kubernetes: Theory + practice" and "authoritative guide - the first Docker book", after reading, it is described in two words: love, love!

If you love too, Click here to download the "K8S+Docker" learning guide for free

Keywords: Java Interview Programmer

Added by y4m4 on Sun, 30 Jan 2022 02:09:24 +0200