基本概述:JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
要让Java程序能够运行,就得让Java类被Java虚拟机加载。Java类如果不被Java虚拟机加载就不能正常运行。正常情况下,我们运行的所有的程序在编译期时候就已经把那个类被加载了。
Java的反射机制是在编译时并不确定是哪个类被加载了,而是在程序运行的时候才加载、探知、自审。使用的是在编译期并不知道的类。这样的编译特点就是java反射。
反射机制的作用:
-
反编译:.class-->.java
-
通过反射机制访问java对象的属性,方法,构造方法等;
-
在运行时判断任意一个对象所属的类;
-
在运行时构造任意一个类的对象;
-
在运行时判断任意一个类所具有的成员变量和方法;
-
在运行时调用任意一个对象的方法;
-
生成动态代理。
假如有两个程序员,一个程序员在写程序的时需要使用第二个程序员所写的类,但第二个程序员并没完成他所写的类。那么第一个程序员的代码是不能通过编译的。此时,利用Java反射的机制,就可以让第一个程序员在没有得到第二个程序员所写的类的时候,来完成自身代码的编译。
Java的反射机制它知道类的基本结构,这种对Java类结构探知的能力,我们称为Java类的“自审”。如eclipse中,一按点,编译工具就会自动的把该对象能够使用的所有的方法和属性全部都列出来,供用户进行选择。这就是利用了Java反射的原理,是对我们创建对象的探知、自审。
在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理
Class类
要正确使用Java反射机制就得使用java.lang.Class这个类。它是Java反射机制的起源。当一个类被加载以后,Java虚拟机就会自动产生一个Class对象。通过这个Class对象我们就能获得加载到虚拟机当中这个Class对象对应的方法、成员以及构造方法的声明和定义等信息。
jdbc中有一行代码:Class.forName('com.mysql.jdbc.Driver.class').newInstance();这句话是生成驱动对象实例,也就是反射,现在很多框架都用到反射机制,hibernate,struts都是用反射机制实现的。
获得Class对象的5种方式:
1."Object.getClass()": 如果一个类的对象可用,则最简单的获得 Class 的方法是使用 Object.getClass()、 当然,此方式只对引用类型有效。
2.".class"------------- : 如果类型可用但没有对象,则可以在类型后加上 ".class" 来获得 Class 对象。这也是使原始类型获得 Class 对象最简单的方式:
3."Class.forName()"---: 如果知道类的全名,则可以使用静态方法 Class.forName() 来获得 Class 对象,它不能用在原始类型上,但是可以用在原始类型数组上。 ( 注:此方式会抛出 ClassNotFoundException 异常 )
4." 包装类的 TYPE 域 "-----: 每一个原始类型和 void 都有包装类。利用其 TYPE 域就可以获得 Class 对象。
5." 以 Class 为返回值的方法 ": 如获取内部类的 getDeclaredClasses() 方法,此时返回一个对象数组
反射机制的优缺点?
静态编译:在编译时确定类型,绑定对象,即通过
动态编译:运行时确定类型,绑定对象。动态编译最大限度的发挥了java的灵活性,体现了多态的应用,有利于降低类之间的耦合性。
它的缺点是对性能有影响。使用反射基本上是一种解释操作,我们可以告诉JVM,我们希望做什么并且它满足我们的要求。这类操作总是慢于只直接执行相同的操作。
Java语言反射提供一种动态链接程序组件的多功能方法。它允许程序创建和控制任何类的对象,无需提前硬编码目标类。这些特性使得反射特别适用于创建以非常普通的方式与对象协作的库。Javareflection 非常有用,它使类和数据结构能按名称动态检索相关信息,并允许在运行着的程序中操作这些信息。