- 前言
- 一、类类
- 二、反射实例化
- 三、反射动态方法调用
- 四、反射读写属性
什么反射:反射是java语言中的一种机制,通过这种机制可以动态的实例化对象、读写属性、调用方法
一、类类获取类类的三种方式
1.类.Class
2.类实例.getClass
3.Class.forName(“类的全路径名”)
下面展示 如何获取类类的三种方式代码。
package com.yzp.reflect;
import com.mysql.jdbc.Driver;
public class YzpDemo1 {
public static void main(String[] args) throws Exception {
//反射是java语言中的一种机制,通过这种机制可以动态的实例化对象、读写属性、调用方法
//1 、类.Class
Class clz1 = YzpStudent.class;
//确定本工程有这个类
// YzpStudent stu = new YzpStudent();
//本工程没有这个类,也可以编译通过,运行报错
// Object newInstance = Class.forName("com.yzp.reflect.YzpStudent").newInstance();
//2、类实例.getClass
YzpStudent stu = new YzpStudent();
Class extends YzpStudent> clz2 = stu.getClass();
// 3、 Class.forName("类的全路径名");
Class> clz3 = Class.forName("com.yzp.reflect.YzpStudent");
// Driver
// java.sql.Driver
// Driver driver = new com.mysql.jdbc.Driver();
// Driver driver = new com.oracle.jdbc.Driver();
// Driver driver = Class.forName(com.mysql.jdbc.Driver)
}
}
二、反射实例化
1.无参数 共有的构造方法
2.有参数 共有的构造方法
3.有多个参数 共有的构造方法
4.私有的构造方法
下面展示 反射实例化的代码。
package com.yzp.reflect;
import java.lang.reflect.Constructor;
public class YzpDemo2 {
public static void main(String[] args) throws Exception {
YzpStudent stu1 = new YzpStudent();
YzpStudent stu2 = new YzpStudent("s001");
YzpStudent stu3 = new YzpStudent("s001","猪崽");
//获取类类
Class extends YzpStudent> clz1 = stu1.getClass();
//默认就是调用无参 共有的构造函数
//1.无参数 共有的构造方法
YzpStudent stu4 = clz1.newInstance();
// 2.有参数 共有的构造方法
// 拿到构造器对象 三个.代表可以传1个2个N个参数 -->拿到一个参数为string的构造器对象
Constructor extends YzpStudent> c1 = clz1.getConstructor(String.class);
YzpStudent stu5 = c1.newInstance("s001");
// 3.有多个参数 共有的构造方法 拿到有两个参数的构造器对象
Constructor extends YzpStudent> c2 = clz1.getConstructor(String.class,String.class);
YzpStudent stu6 = c2.newInstance("s001","猪崽");
// 4.私有的构造方法
// getConstructor只能获取共有的构造方法,要获取私有的构造器getDeclaredConstructor
Constructor extends YzpStudent> c3 = clz1.getDeclaredConstructor(Integer.class);
//打开访问权限
c3.setAccessible(true);
YzpStudent stu7 = c3.newInstance(18);
}
}
三、反射动态方法调用
1.调用无参的 共有方法
2.2.调用1个有参的 共有方法
3.调用私有方法
下面展示 反射动态方法的调用代码。
package com.yzp.reflect;
import java.lang.reflect.Method;
public class YzpDemo3 {
public static void main(String[] args) throws Exception {
//先拿到类类
Class clz = YzpStudent.class;
//name:方法名 parameterTypes:方法对应的参数
Method m1 = clz.getMethod("hello");
// 3.调用对应的方法
//obj:指的是那个类实例 第二个参数:指的是方法调用时的实参
//m1.invoke这个方法调用的返回值就是方法对象本身的返回值 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,Integer.class);
//打开权限
m3.setAccessible(true);
Object invoke3 = m3.invoke(clz.newInstance(), 5,5);
System.out.println(invoke3);
}
}
四、反射读写属性
我们应该如何读写一个未知的类里面的属性:首先应该获取类类,然后读写出这个类的属性
下面展示 反射读写属性代码。
package com.yzp.reflect;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
public class YzpDemo4 {
public static void main(String[] args) throws Exception {
YzpStudent stu = new YzpStudent("s003","猪崽");
stu.age=20;
//需求,要拿到这个学生所有的属性及属性值
System.out.println("age:"+stu.age);
System.out.println("sname:"+stu.getSname());
System.out.println("sid:"+stu.getSid());
//一切反射从类开始
Class extends YzpStudent> 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));
//拿到当前的属性的修饰符
System.out.println("修饰符:"+Modifier.toString(f.getModifiers()));
}
}
}



