Java反射
一、反射的概念
在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;
对于任意一个对象,都能够调用它的任意方法和属性;
这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
这里要特别注意,反射是发生在运行时的一种机制
二、反射的功能
在运行时判断任意一个对象所属的类。
在运行时构造任意一个类的对象。
在运行时判断任意一个类所具有的成员变量和方法。
在运行时调用任意一个对象的成员变量和方法。
生成动态代理。
三、Demo测试
1.先创建一个User类
package com.muerdh.reflect;
/**
* User类
*/
public class User {
// private 修饰的 username
private String username;
// public 修饰的 password
public String password;
// public 修饰的设置 password 的方法
public void setPassword(String password) {
this.password = password;
}
// private 修饰的获取 password 的方法
private String getPassword(){
return password;
}
}
2. 反射获取User类的Class对象
有三种方式:全类名.class 、 对象.getClass() 、 Class.forName(“全类名”)
package com.muerdh.reflect;
/**
* 反射获取User类的Class对象
*/
public class Test1 {
public static void main(String[] args) throws ClassNotFoundException {
/**
* 获取User类的Class对象
*/
//第一种:全类名.class
Class userClass1 = com.muerdh.reflect.User.class;
System.out.println("userClass1 = "+userClass1);
//第二种:对象.getClass();
Class userClass2 = new User().getClass();
System.out.println("userClass2 = "+userClass2);
//第三种:Class.forName("全类名");
Class userClass3 = Class.forName("com.muerdh.reflect.User");
System.out.println("userClass3 = "+userClass3);
}
}
运行结果
userClass1 = class com.muerdh.reflect.User
userClass2 = class com.muerdh.reflect.User
userClass3 = class com.muerdh.reflect.User
3.反射获取类的实例(对象)
package com.muerdh.reflect;
/**
* 反射获取类的实例(对象)
*/
public class Test2 {
public static void main(String[] args) throws IllegalAccessException, InstantiationException {
//获取User类的Class对象
Class userClass = com.muerdh.reflect.User.class;
System.out.println("userClass = "+userClass);
//通过User类的Class对象获取User对象,默认调用的是无参构造方法
User user = (User) userClass.newInstance();
System.out.println("User = " + user);
}
}
运行结果
userClass = class com.muerdh.reflect.User
User = com.muerdh.reflect.User@1b6d3586
4.反射获取类得成员变量(private和public修饰的)
package com.muerdh.reflect;
import java.lang.reflect.Field;
/**
* 反射获取类得成员变量(private和public修饰的)
*/
public class Test3 {
public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchFieldException {
//获取User类的Class对象
Class userClass = com.muerdh.reflect.User.class;
System.out.println("userClass = "+userClass);
//通过User类的Class对象获取User对象,默认调用的是无参构造方法
User user = (User) userClass.newInstance();
System.out.println("User = " + user);
System.out.println("------------------------------------------------------");
/**
* 获取成员变量
*/
//1.获取单个成员变量
//通过User类的Class对象获取User类中的成员变量
Field username = userClass.getDeclaredField("username");
Field password = userClass.getDeclaredField("password");
//设置username成员变量可访问(因为User类中的username属性用的是private修饰符),password是public修饰所以不需要设置
username.setAccessible(true);
//设置username的值
username.set(user,"admin");
password.set(user,"123456");
System.out.println("username = "+username.get(user)+",password = "+password.get(user));
System.out.println("username的数据类型:"+username.getType()+"---------password的数据类型:"+password.getType());
System.out.println("------------------------------------------------------");
//2.获取多个成员变量
//通过User类的Class对象获取User类中的所有成员变量
Field[] userClassDeclaredFields = userClass.getDeclaredFields();
for (int i = 0; i < userClassDeclaredFields.length ; i++) {
Field field = userClassDeclaredFields[i];
//获取成员变量名
System.out.println("成员变量名:"+field.getName());
}
}
}
运行结果
userClass = class com.muerdh.reflect.User
User = com.muerdh.reflect.User@1b6d3586
------------------------------------------------------
username = admin,password = 123456
username的数据类型:class java.lang.String---------password的数据类型:class java.lang.String
------------------------------------------------------
成员变量名:username
成员变量名:password
5.反射获取类中的方法(private和public修饰的)
package com.muerdh.reflect;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
/**
* 反射获取类中的方法(private和public修饰的)
*/
public class Test4 {
public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
//获取User类的Class对象
Class userClass = com.muerdh.reflect.User.class;
System.out.println("userClass = "+userClass);
//通过User类的Class对象获取User对象,默认调用的是无参构造方法
User user = (User) userClass.newInstance();
System.out.println("User = " + user);
System.out.println("------------------------------------------------------");
// setPassword方法
Method setPassword = userClass.getDeclaredMethod("setPassword",String.class);
System.out.println("方法名:"+setPassword.getName());
System.out.println("方法的参数列表的数据类型:"+Arrays.toString(setPassword.getParameterTypes()));
System.out.println("方法参数数量:"+setPassword.getParameterCount());
System.out.println("方法返回值类型:"+setPassword.getGenericReturnType());
//调用setPassword方法,第一个参数为user对象,之后的参数为调用方法所需的参数
setPassword.invoke(user,"123456");
// getPassword方法
Method getPassword = userClass.getDeclaredMethod("getPassword");
//设置getPassword方法可访问(因为User类中的getPassword方法用的是private修饰符),setPassword方法是public修饰所以不需要设置
getPassword.setAccessible(true);
System.out.println("password = "+getPassword.invoke(user));
}
}
运行结果
userClass = class com.muerdh.reflect.User
User = com.muerdh.reflect.User@1b6d3586
------------------------------------------------------
方法名:setPassword
方法的参数列表的数据类型:[class java.lang.String]
方法参数数量:1
方法返回值类型:void
password = 123456
6.反射获取构造方法
package com.muerdh.reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
/**
* 反射获取构造方法
*/
public class Test5 {
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
//获取User类的Class对象
Class userClass = com.muerdh.reflect.User.class;
System.out.println("userClass = "+userClass);
//获取无参构造,有参构造在getConstructor()中加入所需参数即可
Constructor userClassConstructor = userClass.getConstructor();
System.out.println("User的无参构造:"+userClassConstructor);
System.out.println("User的无参构造-方法名:"+userClassConstructor.getName());
System.out.println("User的无参构造-方法的参数列表的数据类型:"+ Arrays.toString(userClassConstructor.getParameterTypes()));
System.out.println("User的无参构造-方法参数数量:"+userClassConstructor.getParameterCount());
//调用无参构造
User user = (User) userClassConstructor.newInstance();
System.out.println("user = " +user);
}
}
运行结果
userClass = class com.muerdh.reflect.User
User的无参构造:public com.muerdh.reflect.User()
User的无参构造-方法名:com.muerdh.reflect.User
User的无参构造-方法的参数列表的数据类型:[]
User的无参构造-方法参数数量:0
user = com.muerdh.reflect.User@1b6d3586
如有错误,欢迎指正;如有侵权,请联系作者。