Java基础----反射

来源:互联网 发布:pop ssl 端口 编辑:程序博客网 时间:2024/05/17 04:39
Java语言允许通过程序化的方式间接对Class进行操作,Class文件由类装载器装载后,在JVM中将形成一份描述Class结构的元信息对象,通过该元信息对象可以获知Class的结构信息:如构造函数、属性和方法等。Java允许用户借由这个Class相关的元信息对象间接调用Class对象的功能。

有如下Person类,通过反射获取关于Person的结构信息

package kay.reflect;/** * Created by kay on 2016/12/6. */public class Person {    private String name;    private int age;    public Person() {    }    public Person(String name, int age) {        this.name = name;        this.age = age;    }    public void sayHi(){        System.out.println("Hi, My name is "+name+", and age is "+age);    }       //省略getter、setter}

反射获取Person类的结构信息:

package kay.reflect;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.Method;/** * Created by kay on 2016/12/6. */public class ReflectTest {    public static void main(String[] args) throws Throwable{        Class clazz = Class.forName("kay.reflect.Person");        //获取构造函数        Constructor constructor = clazz.getDeclaredConstructor(null);        //实例化Person对象        Person person = (Person) constructor.newInstance();        //得到setName方法对象,并调用设置属性        Method method=clazz.getDeclaredMethod("setName",String.class);        method.invoke(person,"Kay");        System.out.println("----------反射获取--------------");        System.out.println(clazz.getName());        System.out.println("方法:");        Method[] methods=clazz.getDeclaredMethods();        for (Method m: methods){            System.out.println(m);        }        Field[] fields=clazz.getDeclaredFields();        System.out.println("字段:");        for (Field f : fields) {            System.out.println(f);        }    }}

打印结果:
这里写图片描述

可以看到,通过反射我们用编程的方式操作Class对象获取到了Person的信息(包括它的私有成员,也可以访问),反射机制为动态的加载类提供了方便,如果有一个类的完全限定名和它的class文件,则完全可以在需要的时候实例化该类为我们所用。比如,使用JDBC的时候,先加入jar包,然后通过反射加载驱动类。

ClassLoader

ClassLoader将Class加载到JVM中,JVM提供三层ClassLoader,分别是Bootstrap ClassLoader,ExtClassLoader,AppClassLoader。除JVM默认的三个ClassLoader以外,可以编写自己的第三方类装载器,以实现一些特殊的需求。类文件被装载并解析后,在JVM内将拥有一个对应的java.lang.Class类描述对象,该类的实例都拥有指向这个类描述对象的引用,而类描述对象又拥有指向关联ClassLoader的引用
当Java程序需要使用某个类时,JVM会确保这个类已经被加载、连接、初始化。连接包括验证、准备、解析3个步骤。

  1. 加载:查找并加载类的二进制数据
  2. 连接:
    a.验证:确保被加载类的正确性
    b.准备:为类的静态变量分配内存,并将其初始化为默认值
    c.解析:把类中的符号引用转换为直接引用
  3. 初始化:给类的静态变量赋予正确的初始值

Java反射

Java反射的包在java.lang.reflect
主要类为如下,可以访问关于类的结构信息
这里写图片描述
在访问private、protected成员变量和方法时必须通过setAccessible(boolean access)方法取消Java语言检查,否则将抛出异常。

0 0