标签:reflect 元素 efi c++ 导入 否则 字节 示例 初始化
概念
Java语言允许通过程序化的方式间接对Class的对象实例操作,Class文件由类装载器装载后,在JVM中将形成一份描述Class结构的元信息对象,通过该元信息对象可以获知Class的结构信息,如构造函数、属性和方法等
示例讲解
编写一个简单示例开始探访Java反射机制的征程,通过比较传统方法以及反射机制创建类实例的不同,来介绍Java反射机制的原理:
public class Car { private String brand; private String color; private int maxSpeed; //1.默认构造函数 public Car(){} //2.带参构造函数 public Car(String brand,String color,int maxSpeed){ this.brand = brand; this.color = color; this.maxSpeed = maxSpeed; } //3.输出文字 public void introduce() { System.out.println("brand:"+brand+";color:"+color+";maxSpeed:"+maxSpeed); } public String getBrand() { return brand; } public void setBrand(String brand) { this.brand = brand; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } public int getMaxSpeed() { return maxSpeed; } public void setMaxSpeed(int maxSpeed) { this.maxSpeed = maxSpeed; } }
1. 构造函数方法:Car car = new Car(“红旗轿车”, “黑色”, “180”);
2. Set方法:Car car = new Car(); car.setBrand(“红旗轿车”);
ReflectTest类
public class ReflectTest { public static Car initByDefaultConst() throws Throwable { //1.通过类装载器获取Car类对象 ClassLoader loader = Thread.currentThread().getContextClassLoader(); Class clazz = loader.loadClass("com.jike.spring.chapter03.reflect.Car"); //2.获取类的默认构造器对象并实例化Car Constructor cons = clazz.getDeclaredConstructor((Class[])null); Car car = (Car)cons.newInstance(); //3.通过反射方法设置属性 Method setBrand = clazz.getMethod("setBrand",String.class); setBrand.invoke(car,"奔驰"); Method setColor = clazz.getMethod("setColor",String.class); setColor.invoke(car,"黑色"); Method setMaxSpeed = clazz.getMethod("setMaxSpeed",int.class); setMaxSpeed.invoke(car,200); return car; } public static Car initByParamConst() throws Throwable{ //1.通过类装载器获取Car类对象 ClassLoader loader = Thread.currentThread().getContextClassLoader(); Class clazz = loader.loadClass("com.jike.spring.chapter03.reflect.Car"); //2.获取类的带有参数的构造器对象 Constructor cons = clazz.getDeclaredConstructor(new Class[]{String.class,String.class,int.class}); //3.使参数的构造器对象实例化Car Car car = (Car)cons.newInstance(new Object[]{"宝马","红色",180}); return car; } public static void main(String[] args) throws Throwable { Car car1 = initByDefaultConst(); Car car2 = initByParamConst(); car1.introduce(); car2.introduce(); } }
以上便是利用java反射机制来获取class类以及方法。
ClassLoade
类装载器就是寻找类的字节码文件并构造出类在JVM内部表示的对象组件,主要工作由ClassLoader及其子类负责,ClassLoader是一个重要的Java运行时系统组件,它负责在运行时查找和装入Class字节码文件。
工作机制
在java中把一个类装载到java虚拟机中需要经过以下步骤
链接:执行校验,准备和解析步骤。校验主要是检查载入class文件数据的正确性;准备主要是给类的静态变量分配存储空间;解析主要是将符号引用转换成直接引用
Jvm在运行时会产生三个classloader:根装载器、扩展类装载器(EXTClassloader)、系统类装载器(APPClassloader),其中根装载器不是classloader的子类,由于是使用c++来编写的,所以在java中看不到。根装载器来负责加载JRE的核心类库。Extclassloader与APPclassloader都是classloader的子类。extclassLoader负责装载JRE扩展目录ext中的jar类包,而APPClassloader则负责装载classPath路径下的类包。根装载器是extclassloader的父装载器,而extclassloader是APPclassloader的父装载器。在默认情况下,使用APPclassloader装载应用程序。
重要方法
Class loadClass(String name)
Name:指定类装载器需要装载类的名字,必须要使用全限定名。在初始化类之前,应考虑进行类解析。但并不是所有的类都需要解析,如果java虚拟机只需要知道该类是否存在,或找出该类的超类,则不需要解析
Class defineClass(String name, byte[]b, int off,int len)
将类文件的字节数组来转换成java虚拟机内部的java.lang.class对象。字节数组可从本地文件系统,或者是远程网络获取;name为完全限定名
Class findSystemClass(String name)
从本地文件系统载入class文件,若本地没有该class文件,则会抛出异常,这个方法是java虚拟机默认使用的装载机制
Class findLoadedClass(String name)
调用该方法来查看classloader是否已装入到某个类当中,如果已经装入,则返回java.lang.class对象,否则返回null值,如果强行装载已经存在的类,则会抛出链接错误。
ClassLoader getParent()
获取类装载器的父装载器,除根装载器外,所有的类装载器都有且仅有一个父装载器。可以编写自己的第三方装载器,以实现特殊的需求。类文件被装载并解析之后,在java虚拟机内相应拥有一个对应的java.lang.class类型属性。该类的对象实例则拥有指向这个类描述对象的引用,而类描述对象又拥有指向关联classloader类。每一个类在java虚拟机中都拥有一个对应的java.lang.class对象,它提供了对结构信息的描述。数组、枚举、注解以及基本的java类型。
Java反射机制
Class反射对象描述类语义结构,可以从Class对象中获取构造函数,成员变量,方法等类元素的反射对象,并以编程的方式通过这些反射对象对目标类对象进行操作。这些反射对象类在java.reflect包中定义,下面是最主要的三个反射类
1.Class getReturnType()
2.Class[] getParameterTypes()
3.Class[] getExceptionTypes()
4.Annotation[][] getParameterAnnotations()
与IOC关系
在Spring中,通过IOC可以将实现类、参数信息等配置在其对应的配置文件中,那么当需要更改实现类或参数信息时,只需要修改配置文件即可,我们还可以对某对象所需要的其它对象进行注入,这种注入都是在配置文件中做的。
Spring的IOC的实现原理利用的就是Java的反射机制,Spring的工厂类会帮我们完成配置文件的读取、利用反射机制注入对象等工作,我们可以通过bean的名称获取对应的对象。
标签:reflect 元素 efi c++ 导入 否则 字节 示例 初始化
原文地址:http://www.cnblogs.com/xiaobaizhiqian/p/7755293.html