O、附:测试类
package cn.xiyou.reflect;
/**
* 测试类
* @author XIAO
*/
public class Person {
public String name;
public int age;
private String address;//私有变量
//空参构造方法
public Person() {
System.out.println("空参数构造方法");
}
//私有的构造方法
@SuppressWarnings("unused")
private Person(String name, int age){
this.name = name;
this.age = age;
System.out.println("带有String,int的构造方法");
}
//普通带参构造方法
public Person(String name) {
this.name = name;
System.out.println("带有String的构造方法");
}
public Person(String name, int age, String address){
this.name = name;
this.age = age;
this.address = address;
System.out.println("带有String, int, String的构造方法");
}
//成员方法
//没有返回值没有参数的方法
public void method1(){
System.out.println("没有返回值没有参数的方法");
}
//没有返回值,有参数的方法
public void method2(String name){
System.out.println("没有返回值,有参数的方法 name= "+ name);
}
//有返回值,没有参数
public int method3(){
System.out.println("有返回值,没有参数的方法");
return 123;
}
//有返回值,有参数的方法
public String method4(String name){
System.out.println("有返回值,有参数的方法");
return "哈哈" + name;
}
//私有方法
@SuppressWarnings("unused")
private void method5(){
System.out.println("私有方法");
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", address=" + address+ "]";
}
}
一、获取构造方法
1.获取public修饰的空参
构造方法
//获取public修饰的空参构造方法
Constructor<?> con = c.getConstructor();
System.out.println(con);//public cn.xiyou.reflect.Person()
//获取所有public修饰的空参构造方法
Constructor<?>[] cons = c.getConstructors();
for (int i = 0; i < cons.length; i++) {
System.out.println(cons[i]);
}
//运行结果:
/*
public cn.xiyou.reflect.Person(java.lang.String,int,java.lang.String)
public cn.xiyou.reflect.Person(java.lang.String)
public cn.xiyou.reflect.Person()
*/
2.获取public修饰的带参
构造方法
//获取带参构造函数(例1)
Constructor<?> cc = c.getConstructor(String.class);
System.out.println(cc);//public cn.xiyou.reflect.Person(java.lang.String)
//获取带参构造函数(例2)
Constructor<?> ccc = c.getConstructor(String.class, int.class, String.class);
System.out.println(ccc);//public cn.xiyou.reflect.Person(java.lang.String,int,java.lang.String)
3.获取所有构造方法(含private修饰的
)
//获取声明的空参构造方法(包含私有空参构造函数)
Constructor<?> con2 = c.getDeclaredConstructor();
System.out.println(con2);//public cn.xiyou.reflect.Person()
//获取所有声明的空参构造方法(包含私有空参构造函数)
Constructor<?>[] cons2 = c.getDeclaredConstructors();
for (int i = 0; i < cons2.length; i++) {
System.out.println(cons2[i]);
}
/*
public cn.xiyou.reflect.Person(java.lang.String,int,java.lang.String)
private cn.xiyou.reflect.Person(java.lang.String,int)
public cn.xiyou.reflect.Person(java.lang.String)
public cn.xiyou.reflect.Person()
*/
二、使用构造方法创建实例
//使用装载当前类的类装载器来装载指定的类
Class<?> c = Class.forName("cn.xiyou.reflect.Person");
/**
* 获取普通构造函数
*/
Constructor<?> con = c.getConstructor(String.class, int.class, String.class);
Object obj = con.newInstance("李小璐", 30, "北京");//通过构造方法,创建对象
System.out.println(obj);
/*运行结果:
带有String, int, String的构造方法
Person [name=李小璐, age=30, address=北京]
*/
/**
* 获取私有构造函数
*/
Constructor<?> con2 = c.getDeclaredConstructor(String.class, int.class);
con2.setAccessible(true);//暴力访问
Object obj2 = con2.newInstance("赵薇", 21);//通过构造方法,创建对象
System.out.println(obj2);
/*运行结果:
带有String,int的构造方法
Person [name=赵薇, age=21, address=null]
*/
三、操作属性
1.获取属性
//获取普通属性
Field agef = c.getField("age");
System.out.println(agef);//public int cn.xiyou.reflect.Person.age
//获取私有属性
Field addressf= c.getDeclaredField("address");
System.out.println(addressf);//private java.lang.String cn.xiyou.reflect.Person.address
//获取所有属性(含private属性)
Field[] fields = c.getDeclaredFields();
for (Field field : fields) {
System.out.println(field);
}
/*
public java.lang.String cn.xiyou.reflect.Person.name
public int cn.xiyou.reflect.Person.age
private java.lang.String cn.xiyou.reflect.Person.address
*/
2.获取属性值
//1.使用装载当前类的类装载器来装载指定的类
Class<?> c = Class.forName("cn.xiyou.reflect.Person");
//2.获取带参构造方法
Constructor<?> con = c.getConstructor(String.class);
//3.通过构造方法,创建对象
Object obj = con.newInstance("李小璐");
//获取非私有变量(例1)
Field namef = c.getField("name");
System.out.println(namef.get(obj));//李小璐
//获取非私有变量(例2)
Field agef = c.getField("age");
System.out.println(agef.get(obj));//0
//获取私有变量
Field addf = c.getDeclaredField("address");//私有变量
addf.setAccessible(true);//暴力访问
System.out.println(addf.get(obj));//null
//重新设置变量值
agef.set(obj, 13);
addf.set(obj, "陕西");
//重新获取属性值
System.out.println("==============");
System.out.println(namef.get(obj));//李小璐
System.out.println(agef.get(obj));//13
System.out.println(addf.get(obj));//陕西
四、操作成员方法
1.获取成员方法
//使用装载当前类的类装载器来装载指定的类
Class<?> c = Class.forName("cn.xiyou.reflect.Person");
//1.获取空参方法
Method m1 = c.getMethod("method1");
System.out.println(m1);//public void cn.xiyou.reflect.Person.method1()
//2.获取带参方法
Method m4 = c.getMethod("method4", String.class);
System.out.println(m4);
//运行结果:public java.lang.String cn.xiyou.reflect.Person.method4(java.lang.String)
//3.获取所有方法
Method[] ms = c.getDeclaredMethods();
for (Method m : ms) {
System.out.println(m);
}
/*运行结果:
public java.lang.String cn.xiyou.reflect.Person.toString()
public void cn.xiyou.reflect.Person.method1()
public java.lang.String cn.xiyou.reflect.Person.method4(java.lang.String)
private void cn.xiyou.reflect.Person.method5()
public void cn.xiyou.reflect.Person.method2(java.lang.String)
public int cn.xiyou.reflect.Person.method3()
*/
2.反射调用普通
成员方法
//1.使用装载当前类的类装载器来装载指定的类
Class<?> c = Class.forName("cn.xiyou.reflect.Person");
//2.获取带参构造方法
Constructor<?> con = c.getConstructor(String.class, int.class, String.class);
//3.通过构造方法,创建对象
Object obj = con.newInstance("小明", 23, "哈尔滨");
//4.获取指定的方法(普通方法:有返回值,有参数的方法)
Method m4 = c.getMethod("method4", String.class);
//5.执行找到的方法
Object o = m4.invoke(obj, "haha");//o为返回值
System.out.println(o);//哈哈haha
3.反射调用私有
成员方法
//1.使用装载当前类的类装载器来装载指定的类,因为class.forName(String name)方法内部调用了Class.forName(className,true,this.getClass().getClassLoader())方法
Class<?> c = Class.forName("cn.xiyou.reflect.Person");
//2.获取带参构造方法
Constructor<?> con = c.getConstructor(String.class, int.class, String.class);
//3.通过构造方法,创建对象
Object obj = con.newInstance("小明", 23, "哈尔滨");
//4.获取指定的方法(private方法)
Method m5 = c.getDeclaredMethod("method5");
//5.开启暴力访问
m5.setAccessible(true);
//6.执行找到的方法
m5.invoke(obj);
五、应用:反射忽略泛型,实现ArrayList<Integer>
添加任意类型的元素
//0.初始化list集合
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(new Integer(30));
list.add(new Integer("12345"));
list.add(123);
//list.add("哈哈");//因为有泛型类型的约束,不支持
System.out.println(list);//[30, 12345, 123]
//1.使用装载当前类的类装载器来装载指定的类
Class<?> c = Class.forName("java.util.ArrayList");
//2.获取add()方法
Method addMethod = c.getMethod("add", Object.class);
//3.执行add()方法
addMethod.invoke(list, "哈哈");
System.out.println(list);//[30, 12345, 123, 哈哈]