反射
1:反射是什么?
(1):反射java语言中的一种机制,通过这种机制可以动态的实例化对象、读写属性、调用方法
2:反射三大作用
1 实例化对象
c.newInstance()
Constructor.getConstructor/Constructor.getDeclaredConstructor
注:一定要提供无参构造器
2 动态调用方法
Method m;
m.invoke
3 读写属性
Field set/get
**1:如何获取类对象的三种方式
实体类
package com.Liuyujian;
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());
}
}
(2)三种方式
package com.Liuyujian;
public class Dome1 {
public static void main(String[] args) throws ClassNotFoundException {
//第一种方式:Class.forName("类的全路径名")
Class<?> clz=Class.forName("com.Liuyujian.Student");
//输出结果为:加载进jvm中!
//第二种方式:类名.Class做通用查询
Class<?> clz2=Student.class;
//输出结果为:class com.Liuyujian.Student
//第三种方式:类(Class类类的类对象)实例 .getClass() 做通用的增删改
Student stu=new Student();
Class<?> clz3=stu.getClass();
System.out.println(clz);
//输出结果为:class com.Liuyujian.Student
}
}
2:通过反射进行实例化
package com.Liuyujian;
import java.lang.reflect.Constructor;
public class Dome2 {
public static void main(String[] args) throws Exception {
//一切反射相关的代码都从获得类(java.lang.Class)对象开始
Class clz=Student.class;
//反射调用调用无参构造创建了一个学生对象
Student stu=(Student)clz.newInstance();
//输出结果为:1加载进jvm中!,2: 调用无参构造方法创建了一个学生对象
//要拿到构造器类
Constructor con=clz.getConstructor(String.class);
Student stu=(Student)con.newInstance("s001");
// 输出结果为:1加载进jvm中!,2:调用带一个参数的构造方法创建了一个学生对象
//调用带两个参的的构造方法创建一个学生对象
Constructor con2=clz.getConstructor(String.class,String.class);
Student stu2=(Student)con.newInstance("soo1","zs");
// 输出结果为:1加载进jvm中!,2:调用带两个参数的构造方法创建了一个学生对象
//getConstructor只能寻找public公开的构造器
//getDeclaredConstructor能寻找到任何修饰符修饰的构造器
Constructor con3=clz.getDeclaredConstructor(Integer.class);
//私有的能访问,只能设置为true才能访问,它默认的为false
con3.setAccessible(true);
Student stu3=(Student)con.newInstance(12);
// 输出结果为:1加载进jvm中!,2:调用Student类私有的构造方法创建一个学生对象
}
}
3:反射调用方法
Method m;,m.invoke
package com.Liuyujian;
import java.lang.reflect.Method;
public class Dome3 {
public static void main(String[] args)throws Exception {
//正常调用方法
Student stu=new Student();
// stu.hello();
//输出结果为:
//加载进jvm中!
//调用无参构造方法创建了一个学生对象
//你好!我是null
Class clz=stu.getClass();
Method m=clz.getDeclaredMethod("hello");
m.invoke(stu);
//输出结果为:
//加载进jvm中!
//调用无参构造方法创建了一个学生对象
//你好!我是null
Method m2=clz.getDeclaredMethod("hello",String.class);
m2.invoke(stu,"zs");
//输出结果为:
//加载进jvm中!
//调用无参构造方法创建了一个学生对象
//zs你好!我是null
Method m3=clz.getDeclaredMethod("add",Integer.class,Integer.class);
//私有的能访问,只能设置为true才能访问,它默认的为false
m3.setAccessible(true);
//invoke:如果反射调用的方法是被void所修饰,那么返回的就是null;
//如果反射调用的方法不是被void所修饰,那么返回的就是被调用的方法的返回值;
Object invoke=m3.invoke(stu, 20,5);
System.out.println(invoke);
//输出结果为:
//加载进jvm中!
//调用无参构造方法创建了一个学生对象
//25
}
}
4反射读写属性
Field set/get
反射属性赋值取值
反射能够将jsp传递过来的参数直接封装到实体类中`
package com.Liuyujian;
import java.lang.reflect.Field;
public class Dome4 {
public static void main(String[] args)throws Exception {
Student stu=new Student("soo2","ls");
//他是public公有的所以不用set,get方法
stu.age=22;
// System.out.println(stu.age);
//输出结果为:22
Class clz=stu.getClass();
Field field=clz.getDeclaredField("sid");
field.setAccessible(true);
// field.set(stu, 26);
field.set(stu,"s002");
System.out.println(stu);
System.out.println(field.get(stu));
//输出结果为:
//加载进jvm中!
//调用无参构造方法创建了一个学生对象
//Student [sid=s002, sname=null, age=null]
//s002
Field[] fields = clz.getDeclaredFields();
for (Field field2 : fields) {
field2.setAccessible(true);
System.out.println(field2.getName()+":"+field2.get(stu));
//输出结果为:
//加载进jvm中!
//调用带二个参数的构造方法创建了一个学生对象
//sid:soo2
//sname:ls
//age:22
}
}
}