目录
思维导图:
一、什么是反射
反射java语言中的一种机制,通过这种机制可以动态的读写属性,实例化对象,调用方法
二, 类类
类类的获取方法
1.类.class
2.类实例.getClass()
3.Class.forName("类的全路径名")
例:
代码如下:
package com.heminjie.reflect;
public class Student {
private String sid;
private String sname;
public Integer age;
static{
System.out.println("加载进jvm中!");
}
public Student() {
super();
System.out.println("调用无参构造方法创建了一个学生对象");
}
public Student(String sid) {
super();
this.sid = sid;
System.out.println("调用带一个参数的构造方法创建了一个学生对象");
}
public Student(String sid, String sname) {
super();
this.sid = sid;
this.sname = sname;
System.out.println("调用带二个参数的构造方法创建了一个学生对象");
}
@SuppressWarnings("unused")
private Student(Integer age) {
System.out.println("调用Student类私有的构造方法创建一个学生对象");
this.age = age;
}
public String getSid() {
return sid;
}
public void setSid(String sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public void hello() {
System.out.println("你好!我是" + this.sname);
}
public void hello(String name) {
System.out.println(name + "你好!我是" + this.sname);
}
@SuppressWarnings("unused")
private Integer add(Integer a, Integer b) {
return new Integer(a.intValue() + b.intValue());
}
}
1.类.class---------------》student.class
2.类实例.getClass()----------------->student.class
3.Class.forName("类的全路径名")---------------》Class.forName("com.ruojuan.aa.Student")
以上完整代码如下
package com.heminjie.reflect;
import java.sql.Driver;
import javafx.scene.control.SplitPane.Divider;
/**
* 类类的获取方式
* 获取student的类类
* 1.类.class
* 2.类类例.getClass()
* 3.Class.forName("类的全路径名")
* @author Administrator
*
*/
public class Demo1 {
public static void main(String[] args) throws Exception {
// 类.class
Class clz1 = Student.class;
// 2.类实例.getClass()
Student stu = new Student();
Class clz2 = stu.getClass();
// 3.Class.forName("类的全路径名")
Class clz3 = Class.forName("com.heminjie.reflect.Student");
}
}
三,反射实例化
返实例化
1.newInstance()
2.getConstructor()
3.getDeclaredConstructor()
1.newInstance()
2.getConstructor()
3.getDeclaredConstructor()
这点一定要打开权限,不打开就会报错
我们现在要打开权限
以上完整代码
package com.heminjie.reflect;
import java.lang.reflect.Constructor;
/**
* 反射实例化
* 1.无参数 共有的构造方法
* 2.有参数 共有的构造方法
* 3.有多个参数 共有的构造方法
* 4.私有的构造方法
* @author Administrator
*
*/
public class Demo2 {
public static void main(String[] args) throws Exception, IllegalAccessException {
Student stu1 = new Student();
Student stu2 = new Student("s001");
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);
}
}
四,反射动态方法调用
1.getMethod ();
2.getDeclaredMethod();
例:
1.getMethod ();
调用有参
2.getDeclaredMethod();
完整代码:
package com.heminjie.reflect;
import java.lang.reflect.Method;
/**
* 反射调用方法
* 1.调用无参 共有方法
* 2.调用一个有参的 共有方法
* 3.调用2个有参的 共有方法
* 4.调用私有方法
* @author Administrator
*
*/
public class Demo3 {
public static void main(String[] args) throws Exception {
/**
* 1.拿到类类
* 2.拿到方法对象
* 3.调用对应的方法
*/
// 1,先拿到类类
Class<Student> clz = Student.class;
// name方法名 parameterTypes:指的是方法对应的参数
Method m1 = clz.getMethod("hello");
// 3.调用对应的方法
// 第一个参数,那个类实例 第二个参数:方法调用时的实参
// m1.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);
// 调用私有方法
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.heminjie.reflect;
import java.lang.reflect.Field;
/**
* 反射读写属性
* @author Administrator
*
*/
public class Demo4 {
public static void main(String[] args) throws Exception, IllegalAccessException {
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.假设student有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));
}
}
}
今天就分享到这里了,谢谢大家