1 反射
在 java 中有一句名言,“万物皆对象“。相对浅显的理解, 程序员 是通过Class类,创建对象,然后调用对象的方法进行逻辑操控。通常我们用到new 创建对象,然后调用对象的方法。那么有没有其他的方式获取对象呢?或者如果当前我们仅仅知道class的全路径,有没有办法获取创建对象呢?或者说你是如何在java程序中链接数据库驱动的呢?针对以上的问题,避让不开的就是java反射。
1.1Java程序的三个阶段
我们知道程序从编写到执行可以分为三个阶段,
第一阶段 源码阶段
Person.java – javac .exe->Person.class
第二阶段 加载阶段
Person.class -ClassLoader-> Class<Person>
第三阶段 执行阶段
Person p = new Person();
1.2java反射机制
反射:光从物质A到物质B,再返回给物质A的现象叫做反射。
机制:工作原理。
那么,什么是java的 反射机制 呢?
在java的程序执行阶段,利用java的反射API,获取类Person的Class<?>对象,初始化对象Person,调用具体Person的方法和属性,这种在运行期间调用ClassLoader加载到 jvm 并且获取类成员变量、方法的过程就是java的反射机制。
1.3 java对象创建两种方式
程序样例:
Person类 package com.guozijie.reflection;
public class Person { private String name = “guozijie” ; public int age = 18;
public void sayHello(){ System. out .println( “my name is ” + name + ” And age is ” + age ); } } 反射测试类 普通new 方式 package com.guozijie.reflection;
public class ReflectTest { public static void main(String args [] ) throws Exception { Person p1 = new Person(); p1.sayHello(); } } 输出结果: my name is guozijie And age is 18 反射方式 package com.guozijie.reflection;
import java.lang.reflect.Method;
public class ReflectTest { public static void main(String args [] ) throws Exception{ // Person p1 = new Person(); // p1.sayHello();
Class cls = Class. forName ( “com.guozijie.reflection.Person” ); Object o = cls.newInstance(); Method m = cls.getMethod( “sayHello” ) ; m. invoke (o);
} }
输出结果 my name is guozijie And age is 18 |
1.4创建对象方式的快慢比较
再来比较两种方式的执行速度快慢
package com.guozijie.reflection;
import java.lang.reflect.Method;
public class ReflectTest { public static void main(String args [] ) throws Exception{
long s = System. currentTimeMillis ();
for ( int i =0;i<200000;i++){ Person p1 = new Person(); p1.sayHello(); } long e = System. currentTimeMillis ();
System. out .println( “p1耗时:” +(e-s));
s = System. currentTimeMillis (); for ( int i =0;i<200000;i++){ Class cls = Class. forName ( “com.guozijie.reflection.Person” ); Object o = cls.newInstance(); Method m = cls. getMethod ( “sayHello” ) ; m.invoke(o); } e = System. currentTimeMillis (); System. out .println( “p2耗时:” +(e-s)); } } 结果: p1耗时:3 p2耗时:362 |
1.5 为什么有反射
通过1.4比较结果,发现通过new 创建对象和通过反射创建对象,两个相差巨大,那为什么还会有反射这门技术呢?
1. 反射是框架设计的灵魂,而框架是一个半成品,可以简化代码开发,提高开发速度。
2. 使用反射技术可以赋予JVM动态编译的能力,在程序的执行阶段可以动态的获取已知类的信息,从而初始化对象。
3. 增强代码的灵活性,结合设计模式使用特点非常明显。
4.反射是针对 字符串 进行编程而new是针对对象编程。
1.6 类加载的基本流程
加载-链接-初始化
1.6.1 加载,将 class文件 加载到内存中使用ClassLoader加载器,
1.6.2 链接-验证 验证类是否正确,格式,内容,语法,符号引用是否存在对应的直接引用
链接-准备 初始化静态成员
链接-解析 将符号引用替换成直接引用
1.6.3 初始化 初始化用户自定义的静态变量成员。
前两个阶段是jvm自动进行控制,程序员并不能干预,而最后一个阶段是程序员参与的 静态变量 初始化。