关闭

Java反射总结

162人阅读 评论(3) 收藏 举报
分类:

 学习反射之前说说类的实例化的几种方式:

1、用new语句创建对象,这是最常见的创建对象的方法。

2、通过工厂方法返回对象,如:Stringstr = String.valueOf(23);

3、运用反射手段,调用java.lang.Class或者java.lang.reflect.Constructor类的newInstance()实例方法。如:Objectobj = Class.forName("java.lang.Object").newInstance();

4、调用对象的clone()方法。

5、通过I/O流(包括反序列化),如运用反序列化手段,调用java.io.ObjectInputStream对象的readObject()方法。

       对于通过工厂方法返回对象,虽能实例化,感觉这种方式是对new或者反射的封装。这几种方式我个人常用的new和反射

      比较newInstantan()和new()区别:

      回顾一下类的生命周期:

     


类的生命周期

      使用一个类,肯定离不开JVM。在程序执行中JVM通过装载,链接,初始化这3个步骤完成。

类的装载是通过类加载器完成的,加载器将.class文件的二进制文件装入JVM的方法区,并且在堆区创建描述这个类的java.lang.Class对象。用来封装数据。但是同一个类只会被类装载器装载以前链接就是把二进制数据组装为可以运行的状态。

       链接分为校验,准备,解析这3个阶段 。校验一般用来确认此二进制文件是否适合当前的JVM(版本),准备就是为静态成员分配内存空间。并设置默认值解析指的是转换常量池中的代码作为直接引用的过程,直到所有的符号引用都可以被运行程序使用(建立完整的对应关系)

完成之后,类型也就完成了初始化,初始化之后类的对象就可以正常使用了,直到一个对象不再使用之后,将被垃圾回收。释放空间。

当没有任何引用指向Class对象时就会被卸载,结束类的生命周期

      言归正传,从jvm的角度看,我们使用new的时候,这个要new的类可以没有加载

     但是使用newInstance时候,就必须保证:1、这个类已经加载;2、这个类已经链接了。而完成上面两个步骤的正是class的静态方法forName()方法,这个静态方法调用了启动类加载器(就是加载javaAPI的那个加载器)。

有了上面jvm上的理解,那么我们可以这样说,newInstance实际上是把new这个方式分解为两步,即,首先调用class的加载方法加载某个类,然后实例化。

     这样分步的好处是显而易见的。我们可以在调用class的静态加载方法forName时获得更好的灵活性,提供给了我们降耦的手段。这样在运行时可以动态的加载来实例化我们需要的类。这经常被用在:IOC、反射、面对接口编程 和 依赖倒置 。

各有利弊:

newInstance:弱类型。低效率。只能调用无参构造。

new:强类型。相对高效。能调用任何public构造。

说了这么多,还没谈到反射呢。下面聊聊从几方面聊聊反射,网上的例子很多,大家自愿练习一下。

What:

    JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

Why:

    为什么要用反射机制?直接创建对象不就可以了吗,这就涉及到了动态与静态的概念,

    静态编译:在编译时确定类型,绑定对象,即通过。

    动态编译:运行时确定类型,绑定对象。动态编译最大限度发挥了java的灵活性,体现了多态的应用,有以降低类之间的藕合性。

    一句话,反射机制的优点就是可以实现动态创建对象和编译,体现出很大的灵活性,特别是在J2EE的开发中它的灵活性就表现的十分明显。比如,一个大型的软件,不可能一次就把把它设计的很完美,当这个程序编译后,发布了,当发现需要更新某些功能时,我们不可能要用户把以前的卸载,再重新安装新的版本,假如这样的话,这个软件肯定是没有多少人用的。采用静态的话,需要把整个程序重新编译一次才可以实现功能的更新,而采用反射机制的话,它就可以不用卸载,只需要在运行时才动态的创建和编译,就可以实现该功能。

       它的缺点是对性能有影响。使用反射基本上是一种解释操作,我们可以告诉JVM,我们希望做什么并且它满足我们的要求。这类操作总是慢于只直接执行相同的操作。

How:

    Classc=Class.forName("className");注明:className必须为全名,也就是得包含包名,比如,com.dmsd.demo.Reflect.Person;

    Object obj=c.newInstance();//创建对象的实例

 

总结:

      有了这样的理解,我们再学习IOC、动态代理等知识很有帮助,无非就是在运行时更加需要JVM创建咱们需要的对象。这里用到的就是反射的机制。

      通过反射可以获得类的信息,包括属性、方法等。具有很大的灵活性。但也有不可避免的缺点:使用反射的性能降低、使用反射相对来说不安全,破坏了类的封装性。

参考资料和博客:

java反射机制:http://www.cnblogs.com/jqyp/archive/2012/03/29/2423112.html

java反射详解:http://www.cnblogs.com/rollenholt/archive/2011/09/02/2163758.html

资料:《Java Reflection in Action.pdf》和demo代码(反射和动态代理)

            https://yunpan.cn/cM8FjcU7KUyqb  访问密码 ef05                  

1
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:51127次
    • 积分:3497
    • 等级:
    • 排名:第10225名
    • 原创:66篇
    • 转载:3篇
    • 译文:1篇
    • 评论:791条
    最新评论