目录
1、什么是反射?
2、类类
3、反射实例化
4、反射动态方法调用
5、反射读写属性
1、什么是反射?
Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。反射被视为动态语言的关键。
2、类类
Class.forName(完整类名)、类名.class、对象.getClass
Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。反射被视为动态语言的关键。
Class.forName(完整类名)、类名.class、对象.getClass
编写一个student类
package com.zking.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());
}
}
使用三种类类方法测试
public class Demo {
public static void main(String[] args) throws Exception {
// 1、Class.forName
Class> class1 = Class.forName("com.zking.reflect.Student");
// 2、类.class
Class> class2 = Student.class;
// 3、对象.class
Student stu = new Student();
Class> class3 = stu.getClass();
System.out.println(class1);
System.out.println(class2);
System.out.println(class3);
}
}
运行结果如下:
3、反射实例化
三种实例化方法:getConstructor、getDeclaredConstructor、newlnstance
// 1、Class.forName
Class> class1 = Class.forName("com.zking.reflect.Student");
// 2、类.class
Class> class2 = Student.class;
Constructor> cs=class1.getConstructor();
Student stu1 = (Student) class1.newInstance();
stu1.setSname("zs");
System.out.println(stu1);
强制转换的话要使用泛型
// 1、Class.forName
Class class1 = (Class) Class.forName("com.zking.reflect.Student");
// 2、类.class
Class> class2 = Student.class;
//无参数
Constructor> cs=class1.getConstructor();
Student stu1 = cs.newInstance();
stu1.setSname("zs");
System.out.println(stu1);
//有一个参数
Constructor cs1 = class1.getConstructor(String.class);
Student stu2 = cs1.newInstance("0001");
stu2.setSname("ww");
System.out.println(stu2);
//有两个参数
Constructor cs2 = class1.getConstructor(String.class,String.class);
Student stu3 = cs2.newInstance("0001","ls");
System.out.println(stu3);
Constructor cs3=class1.getDeclaredConstructor(Integer.class);
cs3.setAccessible(true);//暴力反射 既可以获取私有方法也可以获取公有方法
Student stu4 = cs3.newInstance(23);
System.out.println(stu4);
结果如下:
三种实例化方法:getConstructor、getDeclaredConstructor、newlnstance
// 1、Class.forName
Class> class1 = Class.forName("com.zking.reflect.Student");
// 2、类.class
Class> class2 = Student.class;
Constructor> cs=class1.getConstructor();
Student stu1 = (Student) class1.newInstance();
stu1.setSname("zs");
System.out.println(stu1);
强制转换的话要使用泛型
// 1、Class.forName Classclass1 = (Class ) Class.forName("com.zking.reflect.Student"); // 2、类.class Class> class2 = Student.class; //无参数 Constructor> cs=class1.getConstructor(); Student stu1 = cs.newInstance(); stu1.setSname("zs"); System.out.println(stu1); //有一个参数 Constructor cs1 = class1.getConstructor(String.class); Student stu2 = cs1.newInstance("0001"); stu2.setSname("ww"); System.out.println(stu2); //有两个参数 Constructor cs2 = class1.getConstructor(String.class,String.class); Student stu3 = cs2.newInstance("0001","ls"); System.out.println(stu3); Constructor cs3=class1.getDeclaredConstructor(Integer.class); cs3.setAccessible(true);//暴力反射 既可以获取私有方法也可以获取公有方法 Student stu4 = cs3.newInstance(23); System.out.println(stu4);
结果如下:
4、反射动态方法调用
getMethod、getDeclaredMethod
Method method1 = class1.getMethod("hello");
stu4.setSname("zs");
method1.invoke(stu4);//invoke 调用Method类的方法,可以实现动态调用
System.out.println("-------------");
Method method2 = class1.getMethod("hello", String.class);
method2.invoke(stu4, "ww");
System.out.println("-------------");
Method method3 = class1.getDeclaredMethod("add", Integer.class, Integer.class);
method3.setAccessible(true);//会出现不合法访问异常,这时候用暴力反射
int a = (int) method3.invoke(stu4, 1, 2);
System.out.println("add 1,2=" + a);
效果如下:
getMethod、getDeclaredMethod
Method method1 = class1.getMethod("hello");
stu4.setSname("zs");
method1.invoke(stu4);//invoke 调用Method类的方法,可以实现动态调用
System.out.println("-------------");
Method method2 = class1.getMethod("hello", String.class);
method2.invoke(stu4, "ww");
System.out.println("-------------");
Method method3 = class1.getDeclaredMethod("add", Integer.class, Integer.class);
method3.setAccessible(true);//会出现不合法访问异常,这时候用暴力反射
int a = (int) method3.invoke(stu4, 1, 2);
System.out.println("add 1,2=" + a);
效果如下:
5、反射读写属性
getDeclaredField、getDeclaredFields
Field field1 = class1.getField("age");//通过字符串获取属性
field1.set(stu4, 70);
System.out.println(stu4);
Field field2 = class1.getDeclaredField("sname");
field2.setAccessible(true);
field2.set(stu4, "lhl");
System.out.println(stu4);
效果如下:
Field[] field3 = class1.getDeclaredFields();
// 通过循环数值完成动态赋值
for (Field field : field3) {
field.setAccessible(true);
System.out.println(field.get(class1.newInstance()));
}
getDeclaredField、getDeclaredFields
Field field1 = class1.getField("age");//通过字符串获取属性
field1.set(stu4, 70);
System.out.println(stu4);
Field field2 = class1.getDeclaredField("sname");
field2.setAccessible(true);
field2.set(stu4, "lhl");
System.out.println(stu4);
效果如下:
Field[] field3 = class1.getDeclaredFields();
// 通过循环数值完成动态赋值
for (Field field : field3) {
field.setAccessible(true);
System.out.println(field.get(class1.newInstance()));
}



