目录
一:什么是反射:反射是java语言中的一种机制,通过这个机制可以动态的实例化对象,读写属性,调用方法。
举例解释:
框架:反射+设计模式 组合而成的一个半成品
半成品就是 合成后的火药
反射+设计模式:合成火药的过程
二:类类
Class.forName(完整类名)
类名.Class
对象.getClass()
package zhouj.com;
import com.mysql.jdbc.Driver;
/**
* 类类的获取方式
* 获取到student的类类
* 1.类.class
* 2.类实例.getClass
* 3.Class.froName("类的全路径名");
* @author zjjt
*
*/
public class Demo1 {
public static void main(String[] args) throws Exception {
// 类.class
Class clz1 = Student.class;
// 确定本工程有这个类
// Student stu=new Student();
// 本工程没有这个类也可以编译通过
// Object newInstance=Class.froName("zhouj.com.Student");
// 2.类实例.getClass
Student stu = new Student();
Class clz2 = stu.getClass();
// 3.Class.froName("类的全路径名");
Class clz3 = Class.forName("zhouj.com.Student");
// Driver
}
}
三:反射实例化
getConstructor
getDeclaredConstructor
newInstance
package zhouj.com;
import java.lang.reflect.Constructor;
/**
* 反射实例化
* 1.无参数 共有的构造方法
* 2.有参数 共有的构造方法
* 3.有多个参数 共有的构造方法
* 4.私有的构造方法
*
* @author zjjt
*
*/
public class Demo2 {
public static void main(String[] args) throws Exception {
Student stu1=new Student();
Student stu2=new Student("s002");
Student stu3 = new Student("s001","张三");
/*-----------------以下均为反射的方式实例化对象-------------------*/
// 获取类类
Class<? extends Student> clz1 = stu1.getClass();
// 默认就是调用无参 共有的构造函数
// 1.无参数 共有的构造方法
Student stu4 = clz1.newInstance();
// 2.有参数 共有的构造方法
// 拿到构造器对象 三个 ,代表可以传1个2个...n个参数-->拿到一个参数为String的构造器对象
Constructor<? extends Student> c1 = clz1.getConstructor(String.class);
Student stu5 = c1.newInstance("s001");
// 3.有多个参数 共有的构造方法 拿到两个参数的构造器对象
Constructor<? extends Student> c2 = clz1.getConstructor(String.class,String.class);
Student stu6 = c2.newInstance("s001","李四");
// 4.私有的构造方法
// getConstructor只能获取共有的构造方法, 要获取私有的构造器要用:getDeclaredConstructor
Constructor<? extends Student> c3 = clz1.getDeclaredConstructor(Integer.class);
// 打开访问权限
c3.setAccessible(true);
Student stu7 = c3.newInstance(18);
}
}
四:反射动态方法调用
getMethod
getDeclaredMethod
package zhouj.com;
import java.lang.reflect.Method;
/**
* 反射动态调用方法
* 1.调用无参的 共有的方法
* 2.调用有参的 共有的方法
* 3.调用2个有参的 共有的方法
* 4,调用私有的方法
* @author zjjt
*
*/
public class Demo3 {
public static void main(String[] args) throws Exception {
/**
* 1,先拿到类类
* 2.先拿到方法对象
* 3.调用对应的方法
*
*/
Class<Student> clz=Student.class;
// name:方法名 parameterTypes:方法对应的参数
Method m1 = clz.getMethod("hello");
// 3.调用对应的方法
// 第一个参数:哪一个类实例 第二个参数:方法的实际参数
// invoke 这个方法调用的返回值就是方法对象本身的返回值Hello的返回值
Object invoke = m1.invoke(clz.newInstance());
System.out.println(invoke);
// 调用1个参数的 共有方法
Method m2 = clz.getMethod("hello", String.class);
Object invoke2 = m2.invoke(clz.newInstance(), "张三");
System.out.println(invoke2);
// 2.调用私有的方法
Method m3 = clz.getDeclaredMethod("add", Integer.class,Integer.class);
m3.setAccessible(true);
Object invoke3 = m3.invoke(clz.newInstance(), 5,5);
System.out.println(invoke3);
}
}
五:反射读写属性
getDeclaredField
getDeclaredFields
package zhouj.com;
import java.lang.reflect.Field;
/**
* 反射读写属性
* @author zjjt
*
*/
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("sis:"+stu.getSid());
/*
* 上述代码存在的问题
* 1.你要先知道这个类有哪些属性
* 2.假设studnet有30个属性呢?
*
*/
// 一切反射从类类开始
Class<? extends Student> clz = stu.getClass();
// 当前类的所有属性对象
Field[] fields = clz.getDeclaredFields();
System.out.println(fields.length);
// for循环中的f代表每一个属性对象
for (Field f : fields) {
// 打开访问权限
f.setAccessible(true);
// 通过属性对象拿到属性名称
System.out.println(f.getName());
// 拿到当前的属性对象的属性值
System.out.println(f.get(stu));
}
}
}