Java reflection Exploration

Source: Internet
Author: User

Java reflection Exploration

 

Abstract: This article provides a detailed description of the reflection mechanism in Java, and describes how to generate objects, call functions, obtain fields, and set fields through reflection. Finally, some common reflection examples are provided.

I. Reflection

(1) Concepts

Reflection meaning: You can get a running Java object.
(2) Functions
1) determine the class to which any object belongs at runtime
2) construct the object of any class at runtime
3) determine the member variables and methods of any class at runtime.
4) Call methods of any object at runtime
(3) Java reflection class
1) Class: it indicates the classes and interfaces in the running Java application.
2) Field: Provides attribute information about the class or interface and dynamic access permissions to it.
3) Constructor: Provides information about a single Constructor of a class and its access permissions.
4) Method: Provides information about a Method in a class or interface.
Note: The Class is the most important function Class in Java reflection. It is required to obtain the object information (including methods, attributes, constructor methods, and access permissions ).

(4) three methods for getting a class

 

Dog dog = new Dog (); Class
 DogClass = dog. getClass (); Class
 DogClass1 = Dog. class; Class
 DogClass2 = Class. forName (com. lin. Dog); // note that an exception should be added and thrown.

 

(5) Key Methods

 

Method keywords

Description

GetDeclaredMethods ()

Get all methods

GetReturnType ()

Obtain the method replacement type

GetParameterTypes ()

Obtain the input parameter type of the method.

GetDeclaredMethod (method name, parameter type. class ,......)

Obtain a specific method

 

 

Constructor keywords

Description

GetDeclaredConstructors ()

Obtain all constructor Methods

GetDeclaredConstructor (parameter type. class ,......)

Obtain a specific Constructor

 

 

Parent class and parent interface

Description

GetSuperclass ()

Obtain a class of parent class

GetInterfaces ()

Obtain an implemented Interface


 

(6) Some different functions

Public Method [] getMethods () returns all public (public) methods of a class, including the public methods of its inherited class, and of course the methods of its Implemented interfaces.

Public Method [] getDeclaredMethods () indicates all methods declared by classes or interfaces, including public, protected, default (Package) Access, and private methods, but not inherited methods. Of course, it also includes the methods of the interfaces It implements.

GetFields () obtains all the public fields of a class, including the parent class.

GetDeclaredFields () obtains all declarative fields of a class, including public, private, and proteced,
But does not include the declarative fields of the parent class.

Here is an example:

Animal Interface

 

package com.lin;public interface Aminal {public String eat(String obj);public int run(int obj);}

Implementation class:

 

 

 
Package com. lin; import java. util. jar. attributes. name; public class Dog implements Aminal {private String name; private int age; public Dog () {// constructor stub automatically generated by TODO} public Dog (String name, int age) {this. name = name; this. age = age;} public Dog (String name) {this. name = name; this. age = 10;} private void sleep (int x) {System. out. println (name + sleep + x + minutes);} public String getName () {return name;} public void setName (String name) {this. name = name;} public int getAge () {return age;} public void setAge (int age) {this. age = age ;}@ Override public String eat (String obj) {System. out. println (name + eat + obj); return null ;}@ Override public int run (int obj) {System. out. println (run, speed: + obj); return 0 ;}@ Override public String toString () {return dog name: + name + dog age: + age ;} private static void play () {System. out. println (play with your dog );}}

Let's take a look at their respective calls:

 

 

Package com. lin; import java. lang. reflect. method; public class ReflectLearning {public static void main (String [] args) throws ClassNotFoundException {Dog = new dog (); System. out. println (dog. getClass (); System. out. println (dog. getClass (). getName (); Class
 DogClass = dog. getClass (); Class
 DogClass1 = Dog. class; Class
 DogClass2 = Class. forName (com. lin. dog); Method [] methods1 = dogClass. getMethods (); System. out. println (============================== get the method through getMethods start ================== ======= ); for (Method method: methods1) {System. out. println (method);} System. out. println (============================== get the method end through getMethods ================ ======= ); method [] methods2 = dogClass. getDeclaredMethods (); System. out. println (============================== get the method through getDeclaredMethods ======= ); for (Method method: methods2) {System. out. println (method);} System. out. println (============================== get the method end through getDeclaredMethods ================ ======== );}}

Here is the result:

 

GetMethods Method

GetDeclareMethos method:

From the above, we can see that getMethods () returns all public (public) methods of a class, including the public methods of its inherited class, and of course the methods of its Implemented interfaces. GetDeclaredMethods () indicates all methods declared by classes or interfaces, including public, protected, default (Package) Access, and private methods, but not inherited methods. Of course, it also includes the methods of the interfaces It implements.


2. Call constructor through reflection

(1) list all constructors:

 

Constructor
 [] Constructors = dogClass. getConstructors (); System. out. println (=================================list all Constructors ======== ); for (Constructor
 Constructor: constructors) {System. out. println (constructor);} System. out. println (=================================list all Constructors ======== );
Output result:

 

(2) generate objects through reflection

 

System. out. println (============================== generate an object through newInstance, there must be a default constructor =========================); Dog dog1 = (Dog) dogClass. newInstance (); dog1.setName (DOG 1); dog1.setAge (7); System. out. println (dog1); System. out. println (=============================== passed newInstance (parameter) method 1: generate the object =======================); Dog dog2 = (Dog) constructors [0]. newInstance (DOG 2); System. out. println (dog2); System. out. println (=============================== passed newInstance (parameter) method 2: generate an object =========================); Constructor con1 = dogClass. getConstructor (new Class [] {String. class, int. class}); // This statement mainly refers to Dog dog3 = (Dog) con1.newInstance (new Object [] {Dog 3, 14}); System. out. println (dog3 );
Output result:

 

As shown above, getConstructor (new Class [] {xxxx. class, yyy. class}), and then use con1.newInstance (new Object [] {xxxxx ,...}); the method is the most flexible. You can automatically find the corresponding constructor to call according to the type and number of input parameters. The second method requires an array of constructor functions, and you need to know which constructor corresponds. The first method is to call a constructor without parameters.

 

3. Call common and static functions through reflection

(1) obtain some basic information about the function.

 

Class
 DogClass = Dog. class; Method [] methods = dogClass. getDeclaredMethods (); for (Method method: methods) {System. out. println (function name: + method. getName () + function type: + method. getModifiers () + function return: + method. getReturnType () + number of function parameters: + method. getParameterCount ());}
Output result:

 

The table corresponding to the function type is as follows:
PUBLIC: 1
PRIVATE: 2
PROTECTED: 4
STATIC: 8
FINAL: 16
SYNCHRONIZED: 32
VOLATILE: 64
TRANSIENT: 128
NATIVE: 256
INTERFACE: 512
ABSTRACT: 1024
STRICT: 2048

(2) method call

This is the current dog method:

 

Package com. lin; import java. util. jar. attributes. name; public class Dog implements Aminal {private String name; private int age; public Dog () {// constructor stub automatically generated by TODO} public Dog (String name, int age) {this. name = name; this. age = age;} public Dog (String name) {this. name = name; this. age = 10;} private void sleep (int x) {System. out. println (name + sleep + x + minutes);} public String getName () {return name;} public void setName (String name) {this. name = name;} public int getAge () {return age;} public void setAge (int age) {this. age = age ;}@ Overridepublic String eat (String obj) {System. out. println (name + eat + obj); return null ;}@ Overridepublic int run (int obj) {System. out. println (run, speed: + obj); return 0 ;}@ Overridepublic String toString () {return dog name: + name + dog age: + age ;} private static void play () {System. out. println (play with your dog );}}

Call process of different methods:

 

 

// Call the private Method method1 = dogClass. getDeclaredMethod (sleep, int. class); // do not use getMethod. It can only obtain the public method Dog dog1 = (Dog) dogClass. getConstructor (new Class [] {String. class }). newInstance (new Object [] {DOG 1}); method1.setAccessible (true); // This method1.invoke (dog1, 12) must be added to the private method ); // call the Private Static Method method2 = dogClass. getDeclaredMethod (play); // do not use getMethod. It can only get the public method method2.setAccessible (true); // you must add this method to the private method. 2. invoke (dogClass. newInstance (); // call the public Method method3 = dogClass. getMethod (eat, String. class); // you can also use getDeclaredMethodDog dog3 = new Dog (Dog 3, 45); method3.invoke (dog3, Apple ~);

Output result:

 

The difference between getMethod and getDeclaredMethod must be remembered here, And setAccessible (true) must be added before calling a private method. No error will be reported!

4. Obtain and set field values through reflection

(1) how to obtain class attributes through reflection
A) Class. getDeclaredField (String name );
Returns a Field object that reflects the declared fields specified by the Class object or interface.
B) Class. getDeclaredFields ();
Returns an array of the Field object. These objects reflect all fields declared by the Class object or interface.
C) Class. getField (String name );
Returns a Field object that reflects the specified public member fields of the Class or interface represented by this Class object.
D) Class. getField ();
Returns an array containing some Field objects, which reflect all accessible public fields of the Class or interface represented by this Class object.

(2) Change the attributes

Dog dog1 = new Dog (Dog 1, 12); System. out. println (dog1); Class
 DogClass = dog1.getClass (); Field field1 = dogClass. getDeclaredField (name); // Note: getField can only obtain the public field field1.setAccessible (true); // you must set the Accessible to true System first. out. println (original dog name: + field1.get (dog1); field1.set (dog1, dog 2); System. out. println (dog1 );

Output result:

 

It is worth noting that the Accessible must be set to true before obtaining the private attribute.

 

5. common tools for reflection

(1) bean replication tool

Here, you can use the copyProperties () method in commons-beanutils to better understand reflection.

1. base class of toString

 

Package com. lin; import java. lang. reflect. field; import java. text. simpleDateFormat; import java. util. date;/*** bean base type * @ author lin **/public class BaseBean {public String toString () {StringBuffer sb = new StringBuffer (); simpleDateFormat sdf = new SimpleDateFormat (yyyy-MM-dd HH: mm: ss); Class
 Cls = this. getClass (); Field [] fields = cls. getDeclaredFields (); sb. append (cls. getName () + {); for (Field field: fields) {try {field. setAccessible (true); sb. append (field. getName (); sb. append (=); sb. append (field. get (this); sb. append ();} catch (Exception e) {e. printStackTrace () ;}} sb. append (}); return sb. toString ();}}

2. bean replication tool

 

 

Package com. lin; import java. lang. reflect. field; import java. lang. reflect. invocationTargetException; import java. lang. reflect. method;/*** copy the property value of a JavaBean style object to the same name attribute of another object (if there is no property of the same name, it will not be copied) **/public class BeanCopy {private static String GET = get; private static String SET = set; /***** @ param source * @ param target * @ throws Exception */public static void copy (Object source, Object target) {Class
 SourceClz = source. getClass (); Class
 TargetClz = target. getClass (); // obtain all attributes (including private attributes) of the Class represented by the Class object Field [] sourceFields = sourceClz. getDeclaredFields (); if (sourceFields. length = 0) {sourceFields = sourceClz. getSuperclass (). getDeclaredFields ();} int len = sourceFields. length; for (int I = 0; I <len; I ++) {String fieldName = sourceFields [I]. getName (); Field targetField = null; // obtain the attribute fieldName of the class characterized by the targetClz object. If it does not exist, enter the next loop try {targetField = targetClz. getDeclaredField (fieldName);} catch (NoSuchFieldException e) {try {targetField = targetClz. getSuperclass (). getDeclaredField (fieldName);} catch (NoSuchFieldException e1) {e1.printStackTrace ();} catch (SecurityException e1) {e1.printStackTrace () ;}} if (targetField = null) {continue ;} // determine whether the sourceClz field type is the same as the targetClz field type if (sourceFields [I]. getType () = targetField. getType () {// get the name of the GET and set methods corresponding to the attribute name String getMethodName = get + fieldName. substring (0, 1 ). toUpperCase () + fieldName. substring (1); String setMethodName = SET + fieldName. substring (0, 1 ). toUpperCase () + fieldName. substring (1); // obtain the Method object Method getMethod; Method setMethod; try {getMethod = sourceClz from the Method name. getDeclaredMethod (getMethodName, new Class [] {}); // The catch (NoSuchMethodException e) {getMethod = sourceClz. getSuperclass (). getDeclaredMethod (getMethodName, new Class [] {});} try {setMethod = targetClz. getDeclaredMethod (setMethodName, sourceFields [I]. getType (); // The set method is not empty.} catch (NoSuchMethodException e) {setMethod = targetClz. getSuperclass (). getDeclaredMethod (setMethodName, sourceFields [I]. getType ();} // call the getMethod method of the source Object result = getMethod. invoke (source, new Object [] {}); // call the setMethod method setMethod of the target Object. invoke (target, result);} catch (SecurityException e) {e. printStackTrace ();} catch (NoSuchMethodException e) {e. printStackTrace ();} catch (IllegalArgumentException e) {e. printStackTrace ();} catch (IllegalAccessException e) {e. printStackTrace ();} catch (InvocationTargetException e) {e. printStackTrace () ;}} else {continue ;}}}}
Usage:

 

Create two classes:

 

package com.lin;import java.util.Date;public class Car extends BaseBean{private String name;private String id; private Boolean sellFlag;private int age;private double maxSpeed;private double minSpeed;private int driverPeople;private Date date;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getId() {return id;}public void setId(String id) {this.id = id;}public Boolean getSellFlag() {return sellFlag;}public void setSellFlag(Boolean sellFlag) {this.sellFlag = sellFlag;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public double getMaxSpeed() {return maxSpeed;}public void setMaxSpeed(double maxSpeed) {this.maxSpeed = maxSpeed;}public double getMinSpeed() {return minSpeed;}public void setMinSpeed(double minSpeed) {this.minSpeed = minSpeed;}public int getDriverPeople() {return driverPeople;}public void setDriverPeople(int driverPeople) {this.driverPeople = driverPeople;}public Date getDate() {return date;}public void setDate(Date date) {this.date = date;}}

Another:

 

 

Package com. lin; import java. util. date; public class Bus extends BaseBean {private String name; private String id; private Boolean sellFlag; private int age; private double maxSpeed; private double minSpeed; private long driverPeople; // different from the car type private int driverYear; // car does not have this private Date; public String getName () {return name;} public void setName (String name) {this. name = name;} public String getId () {return id;} public void setId (String id) {this. id = id;} public Boolean getSellFlag () {return sellFlag;} public void setSellFlag (Boolean sellFlag) {this. sellFlag = sellFlag;} public int getAge () {return age;} public void setAge (int age) {this. age = age;} public double getMaxSpeed () {return maxSpeed;} public void setMaxSpeed (double maxSpeed) {this. maxSpeed = maxSpeed;} public double getMinSpeed () {return minSpeed;} public void setMinSpeed (double minSpeed) {this. minSpeed = minSpeed;} public long getDriverPeople () {return driverPeople;} public void setDriverPeople (long driverPeople) {this. driverPeople = driverPeople;} public int getDriverYear () {return driverYear;} public void setDriverYear (int driverYear) {this. driverYear = driverYear;} public Date getDate () {return date;} public void setDate (Date date) {this. date = date ;}}

Call:

 

 

Public static void test5 () {Car car = new Car (); car. setAge (12); car. setDriverPeople (4); car. setId (YU1234); car. setMaxSpeed (13.66); car. setMinSpeed (1.09); car. setName (car); car. setSellFlag (false); car. setDate (new Date (); Bus bus = new Bus (); BeanCopy. copy (car, bus); System. out. println (car); System. out. println (bus );}

Apart from two different fields, all other fields have been copied, which is often used in DTO, VO, and DOMAIN object conversion.
(2) String object conversion to bean Tool

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.