反射笔记-----------------------------
1.反射基本概念:
01.定义:
反射是指在程序运行期间,能够观察和修改类或者类的对象的属性和行为的特性!
02.作用:
001.在运行期间获取类的修饰符,包名,类名,实现的接口,继承的父类。
002.在运行期间获取类的所有属性名,修饰符,属性类型。
003.在运行期间获取所有方法,方法的返回值类型,方法名,方法参数数量,方法参数类型。
004.在运行期间加载类的方法。
03.java反射API常用的类
001.java.lang.Class
002.java.lang.reflect.Method
003.java.lang.Constructor
004.java.lang.Filed
005.java.lang.Modifier
2.例子
01.使用java反射获取类的信息
001.父类代码
package cn.pb.bean;
/**
* 父类
*
* @author Administrator
*
*/
public class FatherTest {
private String teststr = "测试用";
public String getTeststr() {
return teststr;
}
public void setTeststr(String teststr) {
this.teststr = teststr;
}
}
002.子类代码
package cn.pb.bean;
/**
* 测试类 人类 继承了父类
*/
import java.io.Serializable;
public class Person extends FatherTest implements Serializable {
private int id;
private String name;
private String address;
private String message;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Person() {
super();
}
public Person(int id, String name, String address, String message) {
super();
this.id = id;
this.name = name;
this.address = address;
this.message = message;
}
}
003.测试类代码:
package cn.pb.test;
/**
* 测试类 通过反射获取类的信息
*
* @author Administrator
*
*/
public class GetClassInfo {
public void test(String className) throws Exception {
// 获取Person类对象 传递的className为类的全类名
Class clazz = Class.forName(className);
// 获取类在的包名 clazz.getSimpleName():获取类名
Package pkg = clazz.getPackage();
System.out.println(clazz.getSimpleName() + "定义在" + pkg.getName()
+ "包中!");
System.out.println("*********************");
// 获取此对象所表示的实体(类,接口,基本类型或者void)的超类Class
// 如果此对象是一个Object类,一个接口,一个基本类型或void,它的超类返回Null
// 如果此对象是一个数组类,返回表示Object类的Class对象
Class superClass = clazz.getSuperclass();
System.out.println(clazz.getSimpleName() + "的超类是"
+ superClass.getName());
System.out.println("*********************");
// 获取Person类所实现的接口
// 如果Person类没有实现任何接口,返回一个长度为0的数组
// 如果Person类是一个基本类型或者是void,那么也返回一个长度为0的数组
Class[] interfaces = clazz.getInterfaces();
System.out.println("所实现的接口有:");
for (Class c : interfaces) {
System.out.println(c.getName());
}
System.out.println("******************");
}
public static void main(String[] args) throws Exception {
GetClassInfo getClassInfo = new GetClassInfo();
getClassInfo.test("cn.pb.bean.Person");
}
}
02.使用java反射获取类的构造函数的参数列表,并通过构造函数实例化类
001.父类代码
package cn.pb.bean;
/**
* 父类
*
* @author Administrator
*
*/
public class FatherTest {
private String teststr = "测试用";
public String getTeststr() {
return teststr;
}
public void setTeststr(String teststr) {
this.teststr = teststr;
}
}
002.子类代码
package cn.pb.bean;
/**
* 测试类 人类 继承了父类
*/
import java.io.Serializable;
public class Person extends FatherTest implements Serializable {
private int id;
private String name;
private String address;
private String message;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Person() {
super();
System.out.println("通过无参构造实例化Person对象");
}
public Person(int id, String name, String address, String message) {
super();
this.id = id;
this.name = name;
this.address = address;
this.message = message;
System.out.println("通过有参构造实例化Person对象");
}
@Override
public String toString() {
return "Person [id=" + id + ", name=" + name + ", address=" + address
+ ", message=" + message + "]";
}
}
003.测试代码
package cn.pb.test;
import java.lang.reflect.Constructor;
/**
* 使用java反射获取类的构造函数的参数列表,并通过构造函数实例化类
*
* @author Administrator
*
*/
public class GetClassConstructorInfo {
/**
* 通过反射实例化类的对象
*
* @throws Exception
*/
public void test1() throws Exception {
// 参数calssName,为类的全类名
Class clazz = Class.forName("cn.pb.bean.Person");
// 通过clazz.newInstance()方法,获取类的实例
Object obj = clazz.newInstance();
System.out.println("通过反射实例化的对象:" + obj);
}
/**
* 通过反射获取类的构造函数
*
* @throws Exception
*/
public void test2() throws Exception {
// 参数calssName,为类的全类名
Class clazz = Class.forName("cn.pb.bean.Person");
// 获取类的构造函数,返回类的所有公共的构造函数
Constructor[] constructors = clazz.getConstructors();
System.out.println(clazz.getSimpleName() + "类的公共的构造函数以及构造函数的参数列表类型:");
for (Constructor constructor : constructors) {
System.out.println("构造函数的名称为:" + constructor.getName());
// 获取构造函数的所有参数
Class[] params = constructor.getParameterTypes();
if (params.length == 0) {
System.out.println("此构造函数没有参数!");
} else {
System.out.println("该构造函数的参数列表为:【");
for (int i = 0; i < params.length; i++) {
if (i != 0) {
System.out.println(",");
}
System.out.println(params[i].getName());
}
System.out.println("】");
}
}
// 获取无参构造,如果参数为空,则获取无参构造
Constructor constructor = clazz.getConstructor();
// 通过无参构造方法获取类的实例
Object obj = constructor.newInstance();
System.out.println("通过无参构造实例化的对象为:" + obj);
/**
* 获取有参构造 这个方法只能获得公共的有参构造 想要获取私有的构造方法 可以使用
* clazz.getDeclaredConstructor(int.class, String.class, String.class,
* String.class);方法
*/
Constructor constructor2 = clazz.getConstructor(int.class,
String.class, String.class, String.class);
Object obj2 = constructor2.newInstance(12, "xiix", "hah", "wawa");
System.out.println("通过有参构造实例化的 对象为:" + obj2);
}
public static void main(String[] args) throws Exception {
GetClassConstructorInfo test = new GetClassConstructorInfo();
// test.test1();
test.test2();
}
}
03.使用java反射获取类的所有方法的信息,并调用类的setter方法进行属性的赋值
001.父类代码
package cn.pb.bean;
/**
* 父类
*
* @author Administrator
*
*/
public class FatherTest {
private String teststr = "测试用";
public String getTeststr() {
return teststr;
}
public void setTeststr(String teststr) {
this.teststr = teststr;
}
}
002.子类代码
package cn.pb.bean;
/**
* 测试类 人类 继承了父类
*/
import java.io.Serializable;
public class Person extends FatherTest implements Serializable {
private int id;
private String name;
private String address;
private String message;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Person() {
super();
System.out.println("通过无参构造实例化Person对象");
}
public Person(int id, String name, String address, String message) {
super();
this.id = id;
this.name = name;
this.address = address;
this.message = message;
System.out.println("通过有参构造实例化Person对象");
}
@Override
public String toString() {
return "Person [id=" + id + ", name=" + name + ", address=" + address
+ ", message=" + message + "]";
}
}
003.测试代码
package cn.pb.test;
/**
* 使用java反射获取类的所有方法的信息,并调用类的setter方法进行属性的赋值
*/
import java.lang.reflect.Method;
public class GetClassMethodsInfo {
/**
* 调用类的setter方法进行属性的赋值
*
* @param className
* 类的全类名
* @param propName
* 属性名
* @param propType
* 属性类型
* @param propValue
* 属性值
* @throws Exception
*/
public void invokeSetter(String className, String propName,
String propType, Object propValue) throws Exception {
// 通过反射获取类的实例
Class clazz = Class.forName(className);
Object obj = clazz.newInstance();
// 将传过来的属性名 转换成set方法
String methodName = "set" + propName.substring(0, 1).toUpperCase()
+ propName.substring(1);
// 根据set方法名和参数列表获取set方法
Method method = clazz.getDeclaredMethod(methodName,
Class.forName(propType));
// 如果需要可以设置setAccessible方法,设置为可以访问
// method.setAccessible(true);
// 调用方法并传参 参数为:方法所属的对象和方法的参数
method.invoke(obj, propValue);//
System.out.println("通过set方法给类的属性赋值:" + obj);
}
/**
* 使用java反射获取类的所有方法的信息
*/
public void showMethods() throws Exception {
Method[] methods;
// 获取Person类中的所有的方法,不包括继承的类的方法
// 如果该类或接口没有生命任何方法,或者此Class 对象表示一个基本数据类型,一个数组类或void
// 那么返回一个长度为0的数组
methods = Class.forName("cn.pb.bean.Person").getDeclaredMethods();
System.out.println("******展示方法信息********");
for (Method method : methods) {
System.out.println("方法名:" + method.getName());
System.out.println("方法返回值类型:" + method.getReturnType().getName());
// 获取方法的参数列表
Class[] params = method.getParameterTypes();
if (params.length == 0) {
System.out.println("该方法没有参数!");
} else {
System.out.println("该方法的参数列表为:【");
for (int i = 0; i < params.length; i++) {
if (i != 0) {
System.out.println(",");
}
System.out.println(params[i].getName());
}
System.out.println("】");
}
// 获取方法所属的类或接口的class对象
Class declaringClass = method.getDeclaringClass();
System.out.println("方法声明在:" + declaringClass.getName() + "中!");
// 获取方法抛出的异常的类型,即throws子句中声明的异常
Class[] exceptions = method.getExceptionTypes();
if (exceptions.length > 0) {
System.out.println("该方法抛出的异常有:【");
for (int i = 0; i < exceptions.length; i++) {
if (i != 0) {
System.out.println(",");
}
System.out.println(exceptions[i].getName());
}
System.out.println("】");
}
System.out.println("***********************");
}
}
public static void main(String[] args) throws Exception {
GetClassMethodsInfo test = new GetClassMethodsInfo();
// test.invokeSetter("cn.pb.bean.Person", "name", "java.lang.String",
// "zhangsan");
test.showMethods();
}
}
04.使用java反射获取类的所有属性的名称和类型,并为其中一个属性赋值
001.父类代码
package cn.pb.bean;
/**
* 父类
*
* @author Administrator
*
*/
public class FatherTest {
private String teststr = "测试用";
public String getTeststr() {
return teststr;
}
public void setTeststr(String teststr) {
this.teststr = teststr;
}
}
002.子类代码
package cn.pb.bean;
/**
* 测试类 人类 继承了父类
*/
import java.io.Serializable;
public class Person extends FatherTest implements Serializable {
private int id;
private String name;
private String address;
private String message;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Person() {
super();
System.out.println("通过无参构造实例化Person对象");
}
public Person(int id, String name, String address, String message) {
super();
this.id = id;
this.name = name;
this.address = address;
this.message = message;
System.out.println("通过有参构造实例化Person对象");
}
@Override
public String toString() {
return "Person [id=" + id + ", name=" + name + ", address=" + address
+ ", message=" + message + "]";
}
}
003.测试代码
package cn.pb.test;
import java.lang.reflect.Field;
/**
* 使用java反射获取类的所有属性的名称和类型,并为其中一个属性赋值
*
* @author Administrator
*
*/
public class GetClassFieldsInfo {
/**
* 使用java反射获取类的所有属性的名称和类型
*
* @throws Exception
*/
public void showFields() throws Exception {
Field[] fields;
// 获取Person类中的所有字段,但不包括继承的字段
// 如果该类或接口不声明任何字段,或者此Class 对象表示一个基本数据类型,一个数组类或void
// 那么返回一个长度为0的数组
fields = Class.forName("cn.pb.bean.Person").getDeclaredFields();
// 遍历
System.out.println("**********字段展示***********");
for (Field field : fields) {
System.out.println("字段名:" + field.getName());
System.out.println("字段类型:" + field.getType().getName());
System.out.println("********************");
}
}
/**
* 通过使用反射操作person类的字段 使用java反射获取类的对象的实例,并为其中一个属性赋值
*/
public void accessField() throws Exception {
// 通过反射加载一个Person实例
Class clazz = Class.forName("cn.pb.bean.Person");
Object obj = clazz.newInstance();
// 通过getDeclaredField("address")方法 获取类的指定字段
Field address = clazz.getDeclaredField("address");
// address字段为private,这里已经超出其访问范围,不能直接访问
// 通过setAccessable方法,设定为可以访问
address.setAccessible(true);
System.out.println("赋值前的address:" + address.get(obj));
// 为address属性赋值
address.set(obj, "北大青鸟");
System.out.println("赋值之后的address:" + address.get(obj));
}
public static void main(String[] args) throws Exception {
GetClassFieldsInfo test = new GetClassFieldsInfo();
test.showFields();
test.accessField();
}
}

浙公网安备 33010602011771号