reflex
What is reflection
Oracle's official interpretation of reflection:
Through reflection, we can get the member and member information of each type in the program or assembly at run time. The type of general objects in the program is determined at compile time, and Java reflection mechanism can dynamically create objects and call their properties. The type of such objects is unknown at compile time. Therefore, we can create objects directly through reflection mechanism, even if the type of this object is unknown at compile time.
The core of reflection
The core of Java reflection mechanism is to dynamically load classes and obtain class details when the program is running, so as to operate the properties and methods of classes or objects. The essence is that after the JVM obtains the class object, it decompiles it through the class object to obtain various information of the object
java is compiled and then executed. Load the required classes from. java file - >. Class file - > through the class loading mechanism, and the unused classes will not be loaded into the JVM. Through reflection, you can dynamically create objects and call their properties at run time, without knowing who the running objects are at compile time in advance.
Using the reflection mechanism, you can dynamically obtain the information of the current class, such as method information, annotation information, method parameters, attributes, etc
Advantages and disadvantages of reflection mechanism
A private property / method is defined in a class, but all properties can be accessed by using reflection, which will crack the private property
1. Advantages: obtain various contents of classes at run time and decompile them. For Java, a language that compiles first and then runs, it is convenient for us to create flexible code. These codes can be matched at run time without linking source code between components, making it easier to realize object-oriented.
2. Disadvantages:
(1) Reflection consumes some system resources, so if you don't need to create an object dynamically, you don't need to use reflection
(2) Reflection can ignore permission checking when calling methods, which may break encapsulation and lead to security problems
Application scenario of reflection
Decompile:. Class -- >. Java
1. Access the properties, methods and construction methods of java objects through reflection mechanism
2. JDBC load driver connection class.forname
Class.forName("com.mysql.jdbc.Driver"); // Dynamic loading mysql driver
3. Spring container framework IOC instantiation object
<bean id="usr" class="com.ylc.UserEntity" />
4. Custom annotation takes effect (reflection + Aop)
5. Third party core framework mybatis orm
Use of reflection technology
Class represents the entity of a class and represents classes and interfaces in running Java applications
The Field class represents the member variables of the class (member variables are also called class properties)
The Method class represents the Method of the class
Constructor class represents the construction method of class
1.getField, getMethod and getCostructor methods can obtain the domain, method and constructor with the specified name.
2. The getfields, getMethods and getconstructors methods can obtain the public fields, methods and constructor arrays provided by the class, including the common members of the superclass.
3. The getdeclatedfields, getDeclatedMethods and getDeclaredConstructors methods can obtain all the fields, methods and constructors declared in the class, including private and protected members, but excluding members of the superclass.
The reflection mechanism creates objects in three ways
-
Get the class through the new object
UserEntity userEntity = new UserEntity(); Class userClass = userEntity.getClass(); // The default execution is a parameterless constructor UserEntity user2 = (UserEntity) userClass.newInstance(); System.out.println(user2==userEntity);//false
-
Get class directly
Class userClass = UserEntity.class; UserEntity user2 = (UserEntity) userClass.newInstance(); System.out.println(user2);
-
Get class by full class name (common)
Class<?> aClass = Class.forName("com.ylc.entity.UserEntity"); UserEntity user3 = (UserEntity) aClass.newInstance(); System.out.println(user3);
During operation, only one Class object is generated for a Class
Reflection execution constructor
non-parameter constructor
Class<?> userClass = Class.forName("com.ylc.entity.UserEntity"); UserEntity userEntity1 = (UserEntity) userClass.newInstance(); System.out.println(userEntity1);
Parameterized constructor
Class<?> userClass = Class.forName("com.ylc.entity.UserEntity"); Constructor<?> declaredConstructor1 = userClass.getDeclaredConstructor(String.class, Integer.class); UserEntity ylc = (UserEntity)declaredConstructor1.newInstance("ylc", 22); System.out.println(ylc.toString());
Reflection traverses attributes and assigns values
Reflection performs assignment to public attributes
The getFields method can only access public properties of a class
Class<?> userClass = Class.forName("com.ylc.entity.UserEntity"); Field[] fields = userClass.getFields(); for (Field field : fields) { System.out.println(field); }
Reflection performs assignment to private attributes
Getdeclaraedfields can access all properties of the class
Class<?> userClass = Class.forName("com.ylc.entity.UserEntity"); Field[] fields = userClass.getDeclaredFields(); for (Field field : fields) { System.out.println(field); }
Attribute assignment by reflection
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException { Class<?> userClass = Class.forName("com.ylc.entity.UserEntity"); UserEntity userEntity = (UserEntity)userClass.newInstance(); //Properties found Field pubUserName = userClass.getDeclaredField("pubUserName"); //Specifies which userEntity object to assign a value to pubUserName.set(userEntity,"ylc"); System.out.println(userEntity.pubUserName); }
This is to assign a value to the public attribute. By default, you can only access the public attribute. If you want to access the private attribute, an error will be reported
Reflection does not have permission to access private properties. If you need access, you need to set the permission setAccessible
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException { Class<?> userClass = Class.forName("com.ylc.entity.UserEntity"); UserEntity userEntity = (UserEntity)userClass.newInstance(); Field pubUserName = userClass.getDeclaredField("userName"); //Set permissions pubUserName.setAccessible(true); pubUserName.set(userEntity,"ylc"); System.out.println(userEntity.getUserName()); }
Reflection call method
Reflection calls public methods
Class<?> aClass = Class.forName("com.ylc.entity.UserEntity"); UserEntity userEntity = (UserEntity) aClass.newInstance(); Method mayikt = aClass.getDeclaredMethod("mayikt"); //Execution method mayikt.invoke(userEntity);
Reflection calls private methods. You need to turn on the access permission, otherwise you can't access it
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException { Class<?> userClass = Class.forName("com.ylc.entity.UserEntity"); UserEntity o = (UserEntity)userClass.newInstance(); Method method = userClass.getMethod("HelloWorld"); Object invoke = method.invoke(o); }
userName.setAccessible(true);
Reflection calls method pass parameters
private Integer sum(Integer a, Integer b) { return a + b; }
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException { Class<?> userClass = Class.forName("com.ylc.entity.UserEntity"); UserEntity o = (UserEntity)userClass.newInstance(); //Call method to pass parameters Method method = userClass.getDeclaredMethod("sum",Integer.class,Integer.class); method.setAccessible(true); Integer result = (Integer)method.invoke(o,1,2); System.out.println(result); }
Cross generic checking by reflection
Generic validation is performed at compile time. Adding an int type will result in an error
After the compiler compiles, the class file can be cracked by reflection in the program
ArrayList<String> arrayList = new ArrayList<>(); arrayList.add("ylc"); Class<? extends ArrayList> aClass = arrayList.getClass(); Method addMethod = aClass.getDeclaredMethod("add", Object.class); addMethod.invoke(arrayList, 1); System.out.println(arrayList);
annotation
Annotation concept
Annotations are used to add additional information to class declarations. They can be marked on classes, fields, methods, etc. the compiler, JVM and developers can get the annotation information through reflection, and then do some related processing
Common notes
@Override can only be marked on the method that the child class overrides the parent class. It has the function of prompting
@The Deprecated annotation is used to indicate obsolete methods or classes
@SuppressWarnings("unchecked") are marked on the classes and methods that the compiler considers to be problematic to cancel the warning prompt of the compiler. The warning types include serial, unchecked, unused and all
Meta annotation
Meta annotations are used to specify some features of new annotations when declaring new annotations
@Target specifies the location of the new annotation, such as class, field, method, etc. the values include ElementType.Method, etc
@Target({ElementType.METHOD,ElementType.TYPE,ElementType.FIELD})
@Retention specifies when the information of the new annotation will be retained. The values include RetentionPolicy.RUNTIME, etc
@Inherited specifies that the new annotation can be inherited by the child class when it is marked on the parent class
Annotated Target
TYPE: Declaration of classes, interfaces (including annotation types) and enumerations
FIELD: FIELD declaration (including enumeration constants)
METHOD: METHOD declaration
PARAMETER: PARAMETER declaration
CONSTRUCTOR: CONSTRUCTOR declaration
LOCAL_VARIABLE: local variable declaration
ANNOTATION_TYPE: annotation type declaration
PACKAGE: PACKAGE declaration
TYPE_PARAMETER: type parameter declaration, introduced by Java se 8, can be applied to the generic declaration of classes
TYPE_USE: introduced by JavaSE8, this type includes type declaration and type parameter declaration
Get annotation information
Annotation method
@DiyName private void HelloWorld() { System.out.println(" ...ylc....."); }
Custom annotation
@Target({ElementType.METHOD,ElementType.TYPE,ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Inherited public @interface DiyName { }
Gets the annotation on the current method
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException { Class<?> userClass = Class.forName("com.ylc.entity.UserEntity"); Object o = userClass.newInstance(); Method diyMethod = userClass.getDeclaredMethod("HelloWorld"); DiyName diyName = diyMethod.getDeclaredAnnotation(DiyName.class); System.out.println(diyName); }