目录
1.什么是反射?
反射java语言中的一种机制,通过这种机制可以动态的实例化对象,读写属性,调用方法。
2.类类
类类的获取方式
1.类.class
Class clz1 = Student.class;
2.类实例.getClass
Student stu = new Student();
Class clz2 = stu.getClass();
3.Class.forName("类的全路径名")
Class clz3 = Class.forName("类的全路径名");
结果:
3.反射实例化
1.无参数 共有的构造方法
2.有参数 共有的构造方法
拿到构造器对象 三个点代表:可以传n个参数---->拿到参数为String的构造器对象
3.有多个参数共有的构造方法
4.私有的构造方法
getConstructor只能获取共有的构造方法,要获取私有的构造方法要用getDeclaredConstructor
代码如下:
package com.xbb.reiflect;
import java.lang.reflect.Constructor;
/**
* 反射实例化
* 1.无参数 共有的构造方法
* 2.有参数 共有的构造方法
* 3.有多个参数共有的构造方法
* 4.私有的构造方法
* @author Administrator
*
*/
public class Demo2 {
public static void main(String[] args) throws Exception{
Student stu1 = new Student();
Student stu2 = new Student("s001");
Student stu3 = new Student("s001", "哈哈");
/**
* 反射方式
*/
//获取类类
Class<? extends Student> class1 = stu1.getClass();
//默认调用无参共有的构造函数
// 1.无参数 共有的构造方法
Student stu4 = class1.newInstance();
//2.有参数 共有的构造方法
//拿到构造器对象 三个点代表:可以传n个参数---->拿到参数为String的构造器对象
Constructor<? extends Student> c1 = class1.getConstructor(String.class);
Student stu5 = c1.newInstance("s001");
//3.有多个参数共有的构造方法
Constructor<? extends Student> c2 = class1.getConstructor(String.class,String.class);
Student stu6 = c2.newInstance("s001","嘿嘿");
//4.私有的构造方法
//getConstructor只能获取共有的构造方法,要获取私有的构造方法要用getDeclaredConstructor
Constructor<? extends Student> c3 = class1.getConstructor(Integer.class);
//打开访问权限
c3.setAccessible(true);
Student stu7 = c3.newInstance(12);
}
}
4.反射动态方法调用
1.调用无参的 共有的方法
Object invoke = m1.invoke(clz.newInstance());
第一个参数:类实例 第二个参数:方法的实际参数
2.调用1个有参的共有方法
3.调用私有的方法
私有的必须要打开访问权限:
m3.setAccessible(true);
package com.xbb.reiflect;
import java.lang.reflect.Method;
/**
* 反射动态调用方法
* 1.调用无参的 共有的方法
* 2.调用1个有参的共有方法
* 3.调用私有的方法
* @author Administrator
*
*/
public class Demo3 {
public static void main(String[] args) throws Exception{
/**
* 1.先拿到类类
* 2.拿到方法对象
* 3.调用对应的方法
*/
//1.先拿到类类
Class <Student> clz = Student.class;
//name:方法名 方法对应的参数
Method m1 = clz.getMethod("hello");
//调用对应的方法对象
//第一个参数:类实例 第二个参数:方法的实际参数
Object invoke = m1.invoke(clz.newInstance());
System.out.println(invoke);
//2.调用1个有参的共有方法
Method m2 = clz.getMethod("hello", String.class);
Object invoke2 = m2.invoke(clz.newInstance(), "张三");
System.out.println(invoke2);
// 3.调用私有的方法
Method m3 = clz.getDeclaredMethod("add", Integer.class);
//打开访问权限
m3.setAccessible(true);
Object invoke3 = m3.invoke(clz.newInstance(), 5,5);
System.out.println(invoke3);
}
}
5.反射读写属性
如果没有学反射我们编码会较为复杂可能也会出现错误
下面是用反射编码:
package com.xbb.reiflect;
import java.lang.reflect.Field;
/**
* 反射读写属性
* @author Administrator
*
*/
public class Demo4 {
public static void main(String[] args) throws Exception{
Student stu = new Student("s003","麻子");
stu.age = 20;
//要求:要拿到这个学生所有的属性及属性值
System.out.println("age:"+stu.age);
System.out.println("sname:"+stu.getSname());
System.out.println("sid:"+stu.getSid());
/*
* 上述代码存在的问题:
* 1.要先知道类有哪些属性
* 2.如果该类属性较多?
*
*/
//一切反射从类类开始
Class<? extends Student> class1 = stu.getClass();
//拿到当前类的所有属性对象
Field[] fields = class1.getDeclaredFields();
System.out.println(fields.length);
//循环中的f代表每一个属性对象
for (Field f : fields) {
//打开访问权限
f.setAccessible(true);
//通过属性对象拿到属性名称
System.out.println(f.getName());
//拿到当前的属性对象的属性值
System.out.println(f.get(stu));
}
}
}
注意:一定要打开访问权限,不然会报错