Error message here!

Hide Error message here!

忘记密码?

Error message here!

请输入正确邮箱

Hide Error message here!

密码丢失?请输入您的电子邮件地址。您将收到一个重设密码链接。

Error message here!

返回登录

Close

Introduction to Java reflect

Ao Yin 2021-01-13 16:29:36 阅读数:17 评论数:0 点赞数:0 收藏数:0

Reflection mechanism means that in the running state of a program , For any class , Can know all the properties and methods of this class ; For any object , Can call any of its methods and properties ; This dynamic access to information and the function of dynamically calling methods of objects namely Java The reflection mechanism of .
Java The reflection mechanism mainly provides the following functions :

  • At run time, determine the class that any object belongs to ;
  • Construct an object of any class at run time ;
  • Determine the member variables and methods of any class at run time ;
  • Call the method of any object at run time ;
  • Generate dynamic agents .
    Java The classes related to reflection mechanism mainly include java.lang In bag Class Classes and java.lang.reflect In bag Constructor class 、Field class 、Method Classes and Parameter class .

Class object

Class Class is a special class , It's the basis of the reflex mechanism ,Class Class represents the running Java A class or interface in a program , That is, when any class is loaded , About to class .class file ( Bytecode file ) While reading into memory , Automatically create a java.lang.Class object .Class Class has no public constructor , The object is JVM When loading a class, by calling defineClass() Method to create , So you can't explicitly create a Class object . Through this Class object , To get other information about the object .
Java Will be .class When a bytecode file is loaded ,JVM Will produce a java.lang.Class The object represents the .class Bytecode file , From the Class You can get a lot of basic information about the class from the object , This is the reflection mechanism . So to complete the reflection operation , We must first understand Class class .
from Class Class source code comments :

/*
* Instances of the class {@code Class} represent classes and
* interfaces in a running Java application. An enum is a kind of
* class and an annotation is a kind of interface. Every array also
* belongs to a class that is reflected as a {@code Class} object
* that is shared by all arrays with the same element type and number
* of dimensions. The primitive Java types ({@code boolean},
* {@code byte}, {@code char}, {@code short},
* {@code int}, {@code long}, {@code float}, and
* {@code double}), and the keyword {@code void} are also
* represented as {@code Class} objects.
*/

You know , Any data type ( Including basic data types ) as well as void, stay JVM in , All are Class object .

Use of reflection

Post code directly :

Reflection basic usage example class :

package main.basics.reflect;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Properties;
public class ReflectDetails {
/**
* obtain Class Three ways of objects
* 1 Object ——> getClass();
* 2 Any data type ( Including basic data types ) There is one. “ static state ” Of class attribute
* 3 adopt Class Class static methods :forName(String className)( Commonly used )
*
* During operation , One class , only one Class Object generation .
* There are three ways to use the third one , And the third way is usually the way that most scenarios require
* For the first way , Now that all the objects are there, reflection is meaningless .
* The second way is to import the package of the class , Too much dependence , Compiling error will be reported if package is not imported .
* For the third , The input of string parameters can be directly transferred to or read from the configuration file or database , It's also flexible in configuration .
*/
public void getClassMsg(){
// The first way to get Class object
Student stu1 = new Student();// this new Produce a Student object , One Class object .
Class stuClass = stu1.getClass();// obtain Class object
System.out.println(stuClass.getName());
System.out.println(void.class);
System.out.println(int.class);
// The second way to get Class object
Class stuClass2 = Student.class;
System.out.println(stuClass == stuClass2);// Judge the first way to get Class Whether the object and the second method are the same
// The third way to get Class object
try {
Class stuClass3 = Class.forName("main.basics.reflect.Student");// Note that this string must be a real path , It's the classpath with the package name , Package name . Class name
System.out.println(stuClass3 == stuClass2);// Judge whether the three ways get the same Class object
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* adopt Class Object can get the : Construction method 、 Member variables 、 Member method ; And visit members ;
* 1. Get construction method :
* 1). Batch method :
* public Constructor[] getConstructors(): all " public " Construction method
* public Constructor[] getDeclaredConstructors(): Get all the construction methods ( Including private ownership 、 The protected 、 Default 、 public )
* 2). Get a single method , And call :
* public Constructor getConstructor(Class... parameterTypes): Get a single " public " Construction method :
* public Constructor getDeclaredConstructor(Class... parameterTypes): obtain " Some construction method " It can be private , Or protected 、 Default 、 public ;
*
* Call constructor :
* Constructor-->newInstance(Object... initargs)
*/
public void getConstructors() throws Exception{
//1. load Class object
Class clazz = Class.forName("main.basics.reflect.Student");
//2. Get all public constructor methods
System.out.println("********************** All public construction methods *********************************");
Constructor[] conArray = clazz.getConstructors();
for(Constructor c : conArray){
System.out.println(c);
}
System.out.println("************ All the construction methods ( Include : private 、 The protected 、 Default 、 public )***************");
conArray = clazz.getDeclaredConstructors();
for(Constructor c : conArray){
System.out.println(c);
}
System.out.println("***************** Get public 、 The construction method without parameters *******************************");
Constructor con = clazz.getConstructor(null);
//1、 Because it is a construction method without parameters, the type is a null, It's ok if you don't write : What we need here is a parameter type , Remember it's the type
//2、 The class object that describes the parameterless constructor is returned .
System.out.println("con = " + con);
// Call constructor
Object obj = con.newInstance();
// System.out.println("obj = " + obj);
// Student stu = (Student)obj;
System.out.println("****************** Get private constructor , And call *******************************");
con = clazz.getDeclaredConstructor(char.class);
System.out.println(con);
// Call constructor
con.setAccessible(true);// Violent visits ( Ignore access modifiers )
obj = con.newInstance(' male ');
}
/**
* Get the member variable and call :
*
* 1. In bulk
* 1).Field[] getFields(): Get all " Public field "
* 2).Field[] getDeclaredFields(): Get all fields , Include : private 、 The protected 、 Default 、 public ;
* 2. Get a single :
* 1).public Field getField(String fieldName): Get a " public " Field ;
* 2).public Field getDeclaredField(String fieldName): Get a field ( It can be private )
*
* Set the value of the field :
* Field --> public void set(Object obj,Object value):
* Parameter description :
* 1.obj: The object of the field to be set ;
* 2.value: The value to set for the field ;
*/
public void getFields() throws Exception{
//1. obtain Class object
Class stuClass = Class.forName("main.basics.reflect.Student");
//2. Get field
System.out.println("************ Get all public fields ********************");
Field[] fieldArray = stuClass.getFields();
for(Field f : fieldArray){
System.out.println(f);
}
System.out.println("************ Get all fields ( Including private ownership 、 The protected 、 default )********************");
fieldArray = stuClass.getDeclaredFields();
for(Field f : fieldArray){
System.out.println(f);
}
System.out.println("************* Get public fields ** And call ***********************************");
Field f = stuClass.getField("name");
System.out.println(f);
// Get an object
Object obj = stuClass.getConstructor().newInstance();// produce Student object --》Student stu = new Student();
// Set values for fields
f.set(obj, " Lau Andy ");// by Student Object name Attribute assignment --》stu.name = " Lau Andy "
// verification
Student stu = (Student)obj;
System.out.println(" Verify name :" + stu.name);
System.out.println("************** Get private fields **** And call ********************************");
f = stuClass.getDeclaredField("phoneNum");
System.out.println(f);
f.setAccessible(true);// Violent reflex , Remove private restrictions
f.set(obj, "18888889999");
System.out.println(" Verification phone :" + stu);
}
/**
* Get member methods and call :
*
* 1. In bulk :
* public Method[] getMethods(): Get all " Public methods ";( Methods that contain the parent class also contain Object class )
* public Method[] getDeclaredMethods(): Get all member methods , Including private ( Does not include inherited )
* 2. Get a single :
* public Method getMethod(String name,Class<?>... parameterTypes):
* Parameters :
* name : Method name ;
* Class ... : Paramedic Class Type object
* public Method getDeclaredMethod(String name,Class<?>... parameterTypes)
*
* Calling method :
* Method --> public Object invoke(Object obj,Object... args):
* Parameter description :
* obj : The object to call the method ;
* args: Arguments passed when calling a method ;
*
*
* thus it can be seen :
* m = stuClass.getDeclaredMethod("show4", int.class);// Call the development method ( All including private ),
* You need to pass in two parameters , The first is the name of the method called , The second is the parameter type of the method , Remember it's the type .
* System.out.println(m);
* m.setAccessible(true);// Remove private restrictions
* Object result = m.invoke(obj, 20);// Two parameters are required , One is the object to call ( Get reflection ), One is the argument
* System.out.println(" Return value :" + result);//
*/
public void getMethodsMsg() throws Exception{
//1. obtain Class object
Class stuClass = Class.forName("main.basics.reflect.Student");
//2. Get all public methods
System.out.println("*************** Get all ” public “ Method *******************");
stuClass.getMethods();
Method[] methodArray = stuClass.getMethods();
for(Method m : methodArray){
System.out.println(m);
}
System.out.println("*************** Get all the ways , Including private *******************");
methodArray = stuClass.getDeclaredMethods();
for(Method m : methodArray){
System.out.println(m);
}
System.out.println("*************** To obtain public ownership show1() Method *******************");
Method m = stuClass.getMethod("show1", String.class);
System.out.println(m);
// Instantiate a Student object
Object obj = stuClass.getConstructor().newInstance();
m.invoke(obj, " Lau Andy ");
System.out.println("*************** Get private show4() Method ******************");
m = stuClass.getDeclaredMethod("show4", int.class);
System.out.println(m);
m.setAccessible(true);// Remove private restrictions
Object result = m.invoke(obj, 20);// Two parameters are required , One is the object to call ( Get reflection ), One is the argument
System.out.println(" Return value :" + result);
}
/**
* obtain main Method
*/
public void reflectMain(){
try {
//1、 obtain Student Bytecode of object
Class clazz = Class.forName("main.basics.reflect.Student");
//2、 obtain main Method
Method methodMain = clazz.getMethod("main", String[].class);// The first parameter : Method name , The second parameter : Type of method parameter ,
//3、 call main Method
// methodMain.invoke(null, new String[]{"a","b","c"});//java.lang.IllegalArgumentException: argument type mismatch
// The first parameter , object type , Because the way is static Static , So for null Sure , The second parameter is String Array ,
/* start-up Java programmatic main The argument to the method is an array of strings ,
according to jdk1.5 The grammar of , The entire array is a parameter , And in accordance with jdk1.4 The grammar of , Each element in the array corresponds to a parameter ,
When passing an array of strings as a parameter to invoke When the method is used ,javac According to jdk1.4 The syntax for processing ,
because jdk1.5 Be sure to be compatible with jdk1.4 The grammar of , That is to break up the array into several separate parameters ,
So there will be the above exception .
Since the string array will be unpacked into object parameters , So let's put another coat on the outside of this string ,
When unpacking, just remove the outer layer , The string array can be passed as a single parameter */
// It's going to be new String[]{"a","b","c"} Split into 3 Objects ... So we need to turn it around .
methodMain.invoke(null, (Object)new String[]{"a","b","c"});// Mode one
// methodMain.invoke(null, new Object[]{new String[]{"a","b","c"}});// Mode two
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Read configuration file
*/
public void readProperties() {
Properties pro = new Properties();// Get the object of the configuration file
try {
FileReader in = new FileReader("HelloJava\\resources\\pro.properties");// Get input stream
pro.load(in);// Load the stream into the profile object
in.close();
// Get by reflection Class object
Class stuClass = Class.forName(pro.getProperty("className"));
//2 obtain show() Method
Method m = stuClass.getMethod(pro.getProperty("methodName"));
//3. call show() Method
m.invoke(stuClass.getConstructor().newInstance());
/**
* demand :
* When we upgrade this system , Don't Student class , And need to write a new Student2 Class time of ,
* All you need to do is change pro.properties The content of the document can be . The code doesn't have to change at all
*/
} catch (IOException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* Breaking generics
*/
public void reflectGeneric() {
ArrayList<String> strList = new ArrayList<>();
strList.add("aaa");
strList.add("bbb");
// strList.add(100);
// obtain ArrayList Of Class object , Reverse call add() Method , Add data
Class listClass = strList.getClass(); // obtain strList Bytecode of object object
try {
Method m = null;
// obtain add() Method
m = listClass.getMethod("add", Object.class);
// call add() Method
m.invoke(strList, 100);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
// Ergodic set
for(Object obj : strList){
System.out.println(obj);
}
}
/**
* Destroy a single case , And a single example of preventing damage
*/
public void reflectSingleton() {
SingletonStudent singletonStudent = SingletonStudent.getInstance();
SingletonStudent2 singletonStudent_2 = SingletonStudent2.getInstance();
try {
Constructor constructor = singletonStudent.getClass().getDeclaredConstructor();
constructor.setAccessible(true);
SingletonStudent singletonStudent1 = (SingletonStudent) constructor.newInstance();
SingletonStudent singletonStudent2 = (SingletonStudent) constructor.newInstance();
System.out.println(singletonStudent.hashCode());
System.out.println(singletonStudent1.hashCode());
System.out.println("----------------------------------");
Constructor constructor2 = singletonStudent_2.getClass().getDeclaredConstructor();
constructor2.setAccessible(true);
SingletonStudent2 singletonStudent_21 = (SingletonStudent2) constructor2.newInstance();
SingletonStudent2 singletonStudent_22 = (SingletonStudent2) constructor2.newInstance();
System.out.println(singletonStudent_22.hashCode());
System.out.println(singletonStudent_21.hashCode());
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}

Test with singleton class 1:

package main.basics.reflect;
public class SingletonStudent {
private static SingletonStudent ourInstance = new SingletonStudent();
public static SingletonStudent getInstance() {
return ourInstance;
}
private SingletonStudent() {
}
}

Test with singleton class 2:

package main.basics.reflect;
public class SingletonStudent2 {
private static int count = 0;
private static SingletonStudent2 ourInstance = null;
public static SingletonStudent2 getInstance() {
if (null == ourInstance) {
ourInstance = new SingletonStudent2();
}
return ourInstance;
}
private SingletonStudent2() {
synchronized (SingletonStudent2.class) {
if (count > 0) {
throw new RuntimeException(" Cannot create instance ");
}
count++;
}
}
}

Common classes for testing 1:

package main.basics.reflect;
public class Student {
//--------------- Construction method -------------------
//( Default constructor )
Student(String str){
System.out.println("( Default ) Construction method of s = " + str);
}
// Nonparametric construction method
public Student(){
System.out.println(" Called public 、 The parameterless construction method executes ...");
}
// There's a way to construct parameters
public Student(char name){
System.out.println(" full name :" + name);
}
// There are several construction methods of parameters
public Student(String name ,int age){
System.out.println(" full name :"+name+" Age :"+ age);// There's something wrong with the efficiency of this implementation , Solve later .
}
// Protected construction methods
protected Student(boolean n){
System.out.println(" Protected construction methods n = " + n);
}
// Private constructor
private Student(int age){
System.out.println(" Private construction method Age :"+ age);
}
//********** Field *************//
public String name;
protected int age;
char sex;
private String phoneNum;
//************** Member method ***************//
public void show(){
System.out.println("is show()");
}
public void show1(String s){
System.out.println(" Called : public ,String Parametric show1(): s = " + s);
}
protected void show2(){
System.out.println(" Called : The protected , Non parametric show2()");
}
void show3(){
System.out.println(" Called : default , Non parametric show3()");
}
private String show4(int age){
System.out.println(" Called , Private , And it has a return value of ,int Parametric show4(): age = " + age);
return "abcd";
}
public String getPhoneNum() {
return phoneNum;
}
public void setPhoneNum(String phoneNum) {
this.phoneNum = phoneNum;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + ", sex=" + sex
+ ", phoneNum=" + phoneNum + "]";
}
//**************main Method ***************//
public static void main(String[] args) {
System.out.println("main Method executed ...");
}
}

Common classes for testing 2:

package main.basics.reflect;
public class Student2 {
public void show2(){
System.out.println("is show2()");
}
}

The configuration file :

className = main.basics.reflect.Student
methodName = show

Test class :

package main.basics.reflect;
public class Test {
public static void main(String[] args) {
ReflectDetails details = new ReflectDetails();
details.getClassMsg();
try {
details.getConstructors();
details.getFields();
details.getMethodsMsg();
details.reflectMain();
details.readProperties();
details.reflectGeneric();
details.reflectSingleton();
} catch (Exception e) {
e.printStackTrace();
}
}
}

Output results :

 Called public 、 The parameterless construction method executes ...
main.basics.reflect.Student
void
int
true
true
********************** All public construction methods *********************************
public main.basics.reflect.Student(java.lang.String,int)
public main.basics.reflect.Student()
public main.basics.reflect.Student(char)
************ All the construction methods ( Include : private 、 The protected 、 Default 、 public )***************
private main.basics.reflect.Student(int)
protected main.basics.reflect.Student(boolean)
public main.basics.reflect.Student(java.lang.String,int)
main.basics.reflect.Student(java.lang.String)
public main.basics.reflect.Student()
public main.basics.reflect.Student(char)
***************** Get public 、 The construction method without parameters *******************************
con = public main.basics.reflect.Student()
Called public 、 The parameterless construction method executes ...
****************** Get private constructor , And call *******************************
public main.basics.reflect.Student(char)
full name : male
************ Get all public fields ********************
public java.lang.String main.basics.reflect.Student.name
************ Get all fields ( Including private ownership 、 The protected 、 default )********************
public java.lang.String main.basics.reflect.Student.name
protected int main.basics.reflect.Student.age
char main.basics.reflect.Student.sex
private java.lang.String main.basics.reflect.Student.phoneNum
************* Get public fields ** And call ***********************************
public java.lang.String main.basics.reflect.Student.name
Called public 、 The parameterless construction method executes ...
Verify name : Lau Andy
************** Get private fields **** And call ********************************
private java.lang.String main.basics.reflect.Student.phoneNum
Verification phone :Student [name= Lau Andy , age=0, sex= , phoneNum=18888889999]
*************** Get all ” public “ Method *******************
public static void main.basics.reflect.Student.main(java.lang.String[])
public java.lang.String main.basics.reflect.Student.toString()
public void main.basics.reflect.Student.show1(java.lang.String)
public void main.basics.reflect.Student.show()
public java.lang.String main.basics.reflect.Student.getPhoneNum()
public void main.basics.reflect.Student.setPhoneNum(java.lang.String)
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
*************** Get all the ways , Including private *******************
public static void main.basics.reflect.Student.main(java.lang.String[])
public java.lang.String main.basics.reflect.Student.toString()
public void main.basics.reflect.Student.show1(java.lang.String)
private java.lang.String main.basics.reflect.Student.show4(int)
public void main.basics.reflect.Student.show()
protected void main.basics.reflect.Student.show2()
void main.basics.reflect.Student.show3()
public java.lang.String main.basics.reflect.Student.getPhoneNum()
public void main.basics.reflect.Student.setPhoneNum(java.lang.String)
*************** To obtain public ownership show1() Method *******************
public void main.basics.reflect.Student.show1(java.lang.String)
Called public 、 The parameterless construction method executes ...
Called : public ,String Parametric show1(): s = Lau Andy
*************** Get private show4() Method ******************
private java.lang.String main.basics.reflect.Student.show4(int)
Called , Private , And it has a return value of ,int Parametric show4(): age = 20
Return value :abcd
main Method executed ...
Called public 、 The parameterless construction method executes ...
is show()
aaa
bbb
100
2133927002
1836019240
----------------------------------
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at main.basics.reflect.ReflectDetails.reflectSingleton(ReflectDetails.java:313)
at main.basics.reflect.Test.main(Test.java:34)
Caused by: java.lang.RuntimeException: Cannot create instance
at main.basics.reflect.SingletonStudent2.<init>(SingletonStudent2.java:17)
... 6 more
Process finished with exit code 0
Copyright statement
In this paper,the author:[Ao Yin],Reprint please bring the original link, thank you