Introduction to the reflection mechanism and application scenarios of Java learning
- 2020-05-17 05:30:36
- OfStack
Preface:
Recently, the company is carrying out business componentization process, in which the routing implementation USES the reflection mechanism of Java. Since it has been used, I want to learn and summarize 1 well. In fact, both the previous version of EventBus 2.x, Retrofit and the early annotation framework of View all more or less use the reflection mechanism of Java.
What is the Java reflection mechanism?
JAVA reflection mechanism is in the running state, for any one class, can know all the attributes and methods of this class; For any one object, you can call any one of its methods. This ability to dynamically fetch and dynamically call methods on an object is called Java's reflection mechanism.
What does the reflection mechanism provide?
Determines which class any one object belongs to at run time Construct the object of any one class at runtime. Determine the member variables and methods of any one class at run time. Call methods on any one object at run time; Generate dynamic proxy;
Java reflection mechanism class:
java.lang.Class; // class
java.lang.reflect.Constructor;// A constructor
java.lang.reflect.Field; // class
java.lang.reflect.Method;// Methods of a class
java.lang.reflect.Modifier;// Access permissions
Java reflection mechanism implementation:
1.) acquisition of class objects
// The first 1 Kind of way Through object getClass methods
Person person = new Person();
Class<?> class1 = person.getClass();
// The first 2 Kind of way Through the class class attribute
class1 = Person.class;
try {
// The first 3 Kind of way through Class Class static methods -- forName() To implement the
class1 = Class.forName("com.whoislcj.reflectdemo.Person");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
2.) get the summary information of the class object
boolean isPrimitive = class1.isPrimitive();// Determine if it is the base type
boolean isArray = class1.isArray();// Determine if it is a collection class
boolean isAnnotation = class1.isAnnotation();// Determines if it is an annotation class
boolean isInterface = class1.isInterface();// Determine if it is an interface class
boolean isEnum = class1.isEnum();// Determines if it is an enumeration class
boolean isAnonymousClass = class1.isAnonymousClass();// Determines whether an anonymous inner class is present
boolean isAnnotationPresent = class1.isAnnotationPresent(Deprecated.class);// Determines whether it is modified by an annotation class
String className = class1.getName();// To obtain class The name Contains the package name path
Package aPackage = class1.getPackage();// To obtain class The package information
String simpleName = class1.getSimpleName();// To obtain class The name of the class
int modifiers = class1.getModifiers();// To obtain class Access permissions
Class<?>[] declaredClasses = class1.getDeclaredClasses();// The inner class
Class<?> declaringClass = class1.getDeclaringClass();// Outside class
3.) get the properties, methods, constructors, etc. of class object
Field[] allFields = class1.getDeclaredFields();// To obtain class All properties of the object
Field[] publicFields = class1.getFields();// To obtain class The object's public attribute
try {
Field ageField = class1.getDeclaredField("age");// To obtain class Specify the attributes
Field desField = class1.getField("des");// To obtain class The specified public attribute
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
Method[] methods = class1.getDeclaredMethods();// To obtain class All declaration methods of the object
Method[] allMethods = class1.getMethods();// To obtain class All methods of the Includes methods of the parent class
Class parentClass = class1.getSuperclass();// To obtain class The parent class of the object
Class<?>[] interfaceClasses = class1.getInterfaces();// To obtain class All interfaces of the object
Constructor<?>[] allConstructors = class1.getDeclaredConstructors();// To obtain class All declaration constructors of the object
Constructor<?>[] publicConstructors = class1.getConstructors();// To obtain class object public The constructor
try {
Constructor<?> constructor = class1.getDeclaredConstructor(new Class[]{String.class});// Gets the specified declaration constructor
Constructor publicConstructor = class1.getConstructor(new Class[]{});// Gets the specified declared public The constructor
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
Annotation[] annotations = class1.getAnnotations();// To obtain class All annotations of the object
Annotation annotation = class1.getAnnotation(Deprecated.class);// To obtain class Object specified annotation
Type genericSuperclass = class1.getGenericSuperclass();// To obtain class Object of the immediate superclass Type
Type[] interfaceTypes = class1.getGenericInterfaces();// To obtain class Object of all interfaces type A collection of
4.) class object is generated dynamically
// The first 1 Kind of way Class The object newInstance() Method to generate
Object obj = class1.newInstance();
// The first 2 Kind of way The object gets the corresponding Constructor Object and pass through the Constructor The object's newInstance() Method to generate
Constructor<?> constructor = class1.getDeclaredConstructor(new Class[]{String.class});// Gets the specified declaration constructor
obj = constructor.newInstance(new Object[]{"lcj"});
5.) call functions dynamically
try {
// Generate a new object: with newInstance() methods
Object obj = class1.newInstance();
// Determine whether the object is Person A subclass of
boolean isInstanceOf = obj instanceof Person;
// The first thing you need to do is get the one that corresponds to this method Method object
Method method = class1.getDeclaredMethod("setAge", new Class[]{int.class});
// Calls the specified function and passes the arguments
method.invoke(obj, 28);
method = class1.getDeclaredMethod("getAge");
Object result = method.invoke(obj, new Class[]{});
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
6.) get generic types through reflection
For example, the following structure
//People class
public class People<T> {}
//Person Class inheritance People class
public class Person<T> extends People<String> implements PersonInterface<Integer> {}
//PersonInterface interface
public interface PersonInterface<T> {}
Gets the generic type
Person<String> person = new Person<>();
// The first 1 Kind of way Through object getClass methods
Class<?> class1 = person.getClass();
Type genericSuperclass = class1.getGenericSuperclass();// To obtain class Object of the immediate superclass Type
Type[] interfaceTypes = class1.getGenericInterfaces();// To obtain class Object of all interfaces Type A collection of
getComponentType(genericSuperclass);
getComponentType(interfaceTypes[0]);
getComponentType implementation
private Class<?> getComponentType(Type type) {
Class<?> componentType = null;
if (type instanceof ParameterizedType) {
//getActualTypeArguments() Returns the value that represents the actual type parameter of this type Type An array of objects.
Type[] actualTypeArguments = ((ParameterizedType) type).getActualTypeArguments();
if (actualTypeArguments != null && actualTypeArguments.length > 0) {
componentType = (Class<?>) actualTypeArguments[0];
}
} else if (type instanceof GenericArrayType) {
// said 1 An element type is a parameterized type or an array type of a type variable
componentType = (Class<?>) ((GenericArrayType) type).getGenericComponentType();
} else {
componentType = (Class<?>) type;
}
return componentType;
}
6.) get annotation information through reflection mechanism
The emphasis here is on obtaining the annotation information of Method as an example
try {
// The first thing you need to do is get the one that corresponds to this method Method object
Method method = class1.getDeclaredMethod("jumpToGoodsDetail", new Class[]{String.class, String.class});
Annotation[] annotations1 = method.getAnnotations();// Get all method annotation information
Annotation annotation1 = method.getAnnotation(RouterUri.class);// Gets the specified annotation information
TypeVariable[] typeVariables1 = method.getTypeParameters();
Annotation[][] parameterAnnotationsArray = method.getParameterAnnotations();// Get all the parameter annotation information
Class<?>[] parameterTypes = method.getParameterTypes();// Get all the parameters class type
Type[] genericParameterTypes = method.getGenericParameterTypes();// Gets all the parameters type type
Class<?> returnType = method.getReturnType();// Gets the return type of the method
int modifiers = method.getModifiers();// Gets access to a method
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
Application scenarios of reflection mechanism:
Reverse code, such as decompile Frameworks that combine annotations, such as Retrofit Pure reflection mechanism application framework such as EventBus 2.x Dynamically generate a class framework such as Gson
Advantages and disadvantages of reflection mechanism:
Advantages: runtime type determination, dynamic class loading, dynamic proxy using reflection.
Cons: performance is a problem, reflection is equivalent to a series 1 explain operation, notifying jvm what to do, performance is much slower than direct java code.
Conclusion:
The reflection mechanism of Java is rarely used in the normal business development process, but it is widely used in the construction of some basic frameworks. Today, I have simply summarized and learned 1. There are still a lot of unknown knowledge to be used and supplemented later.