1.1反射出现的原因和作用
当我们在使用开源项目中的类的时候,我们只能看到.class文件,这个类中的成员变量、构造函数、成员方法这些我们都无法去知道,但是我们还是想使用这个类我们该怎么办呢?反射的出现就解决了这个问题。
2.1反射的机制
java反射机制是在运行的字节码文件中获取这个类中所有的属性和方法。
- 对于任意一个对象,都能够调用它的任意一个方法
3.1 字节码对象是用来描述什么的?
用来描述.class文件的。面向对象阶段的时候讲过java中描述事物都是通过类的形式, 而字节码文件也可以看做为一种事物, 如何描述这种事物? 上面说过类中有是三个东西,这里不再赘述
4.1获取字节码文件的三种方法
1.对象名.getCalss(); // 此方法来自于Object 对象已经存在的情况下, 可以使用这种方式
创建一个Student类
private String name="xiaolai";
private int age=10;
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
public Student() {
}
public String getName() {
return name;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
创建测试类Test
public class Test {
public static void main(String[] args) throws ClassNotFoundException {
Student str=new Student();
Class class1 = str.getClass();
}
2.类名.class // 类名.class这是一个静态的属性, 只要知道类名, 就可以获取
Class class2=Clazz.class;
3.Class.forName(“com.itheima_0Student”); // 通过Class类中的静态方法, 指定字符串, 该字符串是类的全类名(包名+类名) 此处将会抛出异常都系 ClassNotFoundException 防止传入错误的类名
Class class3=Class.forName("com.itheima01.Student");
这个方法的灵活性比较高所以在开发的过程中使用的频率也就很高了
5.1反射是怎样操作字节码文件的
- 反射操作构造方法
- 反射操作成员变量
- 反射操作成员方法
java虚拟机jvm会把类文件转化为字节码文件,这个过程不是瞎搞的,是直接把字节码文件分三个区一个地方叫Constructor 这个地方放构造方法类,第二个地方叫Field 这个地方放成员变量类 第三个地方叫method。(这里使用封装的思想把东西分好类让人使用的时候非常舒服)下面代码演示了整个反射的工作流程
//拿到类的字节码文件,反射能够把类中的成员变量,成员方法,构造方法分好类
Class clazz=Class.forName("com.itheima02.Demo1");//这个就返回了三个类封装好的对象
//通过不同的方法调用不同的类中的不同的方法返回的值就是一个对象了
Constructor cl = clazz.getConstructor(String.class,int.class);
//获取学生对象
Object obj = cl.newInstance("xiaohong",19);
System.out.println(obj);
Constructor c2=clazz.getConstructor();
Object obj1=c2.newInstance();
System.out.println(obj1);
Field field = clazz.getDeclaredField("name");//获取成员变量
field.setAccessible(true);//加权限
Object f=field.get(obj);
System.out.println(f);
Object f1=field.get(obj1);
System.out.println(f1);
Object obj3=c2.newInstance();
field.set(obj3, "wangwu");
Object f2=field.get(obj3);
System.out.println(f2);
反射到这里基本结束,然后如果想更深入的学习一下,可以查看BeanUtils的实现方式,这个是阿帕奇公司给的一个类,你可以自己动手实现里面的
1.static void setProperty(Object bean, String name, Object value) 2.static String getProperty(Object bean, String name)
3.static void populate(Object bean, Map properties)
这三个方法。它们就是使用了反射机制