目录:
- 什么是反射
- 类类
- 反射实例化
- 反射动态方法调用
- 反射读写属性
先上思维导图:
一,什么是反射
反射是java语言的一种机制,利用反射机制动态的实例化对象(构造函数)、读写属性、调用方法。
二,类类(所有类的实例)
这里我用student类给大家举例:
package com.whw.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());
}
}
如何得到类对象(一切反射相关的代码都从获得类对象开始)三种获取方式:
- Class.forName(完整类名)(最常用)
- 类名.class
- 对象名.getClass()
如下代码:
package com.whw.reflect;
/**
* 获得类类的三种方法
* 1.Class.forName
* 2.类.class
* 3.类类的类对象的类实例.getClass
* @author zjjt
*
*/
public class Demo01 {
public static void main(String[] args) throws Exception {
//Student.class
Class stuClz1 = Class.forName("com.whw.reflect.Student");
//通用查询
Class stuClz2 = Student.class;
//通用增删改
Class stuClz3 = new Student().getClass();
//获取全限定名
System.out.println(stuClz1.getName());
//获取包名
System.out.println(stuClz1.getSimpleName());
//获取类名
System.out.println(stuClz1.getPackage());
}
}
运行结果:
三,反射实例化
- class.newInstance()反射实例化对象
- class.getConstrutor()和class.getDeclaredConstrutor() 同为获取单个构造的方法
- 区别:class.getDeclaredConstrutor()包括私有、受保护、默认、公有的方法
- 如果是有参构造,需要在括号里写上参数类型
- 调用私有的方法,需打开访问权限:setAccessible(true)
如下代码:
package com.whw.reflect;
import java.lang.reflect.Constructor;
/**
* 反射实例化
* @author zjjt
* */
public class Demo02 {
public static void main(String[] args) throws Exception {
Class<Student> stuClz1 = (Class<Student>) Class.forName("com.whw.reflect.Student");
Student stu1 = (Student) stuClz1.newInstance();
stu1.hello();
//反射调用有参构造器
//getDeclaredConstructor和getConstructor的区别
Constructor<Student> c1 = stuClz1.getConstructor(String.class);
Student s1 = c1.newInstance("s001");
Constructor<Student> c2 = stuClz1.getConstructor(String.class,String.class);
Student s2 = c2.newInstance("s002","zs");
Constructor<Student> c3 = stuClz1.getDeclaredConstructor(Integer.class);
c3.setAccessible(true);
Student s3 = c3.newInstance(18);
}
}
运行结果:
四, 反射动态方法调用
- class.getMethod() 获取单个公有方法
- class.getMethod()和class.getDeclaredMethod() 同为获取单个方法
- 区别:class.getDeclaredMethod() 包括私有、受保护、默认、公有
- 调用方法:invoke(对象名,有参传值)
- 参数1:类实例,在这里指的是Student类实例
- 参数2:当前被调用的方法,传递的参数值
代码如下:
package com.whw.reflect;
import java.lang.reflect.Method;
/**
* 反射动态方法调用
* @author zjjt
*
*/
public class Demo03 {
public static void main(String[] args) throws Exception {
Class<Student> stuClz1 = (Class<Student>) Class.forName("com.whw.reflect.Student");
Student s1 = stuClz1.newInstance();
/**invoke:
参数1:类实例,在这里是student类实例
参数2:当前被调用的方法,传递的参数值
invoke的返回值,就是被反射调用的方法的返回值,如果被调用的方法返回值是void,则返回null*/
Method m1 = stuClz1.getDeclaredMethod("hello");
System.out.println(m1.invoke(s1));
Method m2 = stuClz1.getDeclaredMethod("hello", String.class);
System.out.println(m2.invoke(s1, "zs"));
Method m3 = stuClz1.getDeclaredMethod("add", Integer.class,Integer.class);
m3.setAccessible(true);
System.out.println(m3.invoke(s1, 10,5));
}
}
运行结果:
五,反射读写属性
-
getDeclaredField(获取单个对)
-
getDeclaredFields(获取所有对象)
代码如下:
package com.whw.reflect;
import java.lang.reflect.Field;
/**
* 反射读写属性
* @author zjjt
*
*/
public class Demo04 {
public static void main(String[] args) throws Exception {
Class<Student> stuClz1 = (Class<Student>) Class.forName("com.whw.reflect.Student");
Student s1 = stuClz1.newInstance();
Field f = stuClz1.getDeclaredField("sname");
f.setAccessible(true);
//反射属性
f.set(s1, "zs");
System.out.println(s1.getSname());
//反射读属性
System.out.println(f.get(s1));
//比较oop与反射读取属性值的方法
Student st=new Student("s002","ls");
st.age = 19;
System.out.println(st.getSid());
System.out.println(st.getSname());
System.out.println(st.age);
//反射获取该对象所有的属性值
Field[] fs = stuClz1.getDeclaredFields();
for (Field fd : fs) {
fd.setAccessible(true);
System.out.println(fd.getName()+":"+fd.get(st));
}
}
}
运行结果:
到这里就结束了,有不对或补充的地方欢迎大家评论,谢谢!