什么是反射

    • Java反射机制是在运行状态中
    • 对于任意一个类,都能知道这个类的所有属性和方法
    • 对于任何一个对象,都能够调用它的任何一个方法和属性
    • 这样动态获取新的类以及动态调用对象方法的功能就叫做反射

    Class类

    • Class可以说是反射能够实现的基础。
    • class关键字是在声明java类是使用的;而Class是java JDK提供的一个类,完整路径为java.lang.Class
    • 对于每一种类,Java虚拟机都会初始化一个Class类型的实例,每当我们编写并且编译一个新创建的类就会产生一个对应Class对象,并且Class对象会被保存在同名.class文件里。
    • 每当new一个新对象或者引用静态成员变量时,JVM中的类加载器系统会将对应的Class对象加载到JVM中,然后再根据这个类型信息相关的Class对象创建我们需要的实例对象或者提供静态变量的引用值。
      构造器是私有的,只有JVM才可以调用获赠构造函数创建Class的对象
    • 每个class(class是小写,代表普通类),无论创建多少个实例对象,在JVM中都对应同一个Class对象。
    • Class是反射能够实现的基础另一个原因:Java反射包java.lang.reflect中的所有类都没有public构造方法,要想获得这些类实例,只能通过Class类获取。另言之如果想使用反射,必须得获得Class对象。

      1. private Class(ClassLoader loader) {
      2. classLoader = loader;
      3. }
    • 通过已有的类得到一个Class对象的几种方式:
      1.通过对象实例获取对应Class对象Object.getClass(),基本类型无法使用该方法 ```java //Returns the Class for String Class c = “foo”.getClass();

    enum E { A, B } //Returns the Class corresponding to the enumeration type E. Class c = A.getClass();

    byte[] bytes = new byte[1024]; //Returns the Class corresponding to an array with component type byte. Class c = bytes.getClass();

    Set s = new HashSet(); //Returns the Class corresponding to java.util.HashSet. Class c = s.getClass();

    1. - 2.通过类的类型获取Class对象,基本类型同样可以使用这种方法
    2. ```java
    3. //The `.class` syntax returns the Class corresponding to the type `boolean`.
    4. Class c = boolean.class;
    5. //Returns the Class for String
    6. Class c = String.class;
    • 3.通过类的全限定名获取Class对象,基本类型无法使用此方法 ```java Class c = Class.forName(“java.lang.String”);//通过Class.forName()方法加载的类,采用的是系统类加载器 //对于数组比较特殊 Class cDoubleArray = Class.forName(“[D”); //相当于double[].class

    Class cStringArray = Class.forName(“[[Ljava.lang.String;”); //相当于String[][].class

    1. - 4.基本类型和void类型的包装类可以使用TYPE字段获取
    2. ```java
    3. Class c = Double.TYPE; //等价于 double.class.
    4. Class c = Void.TYPE;//void

    Member

    java.lang.reflect.Member有三个实现类,对应Java中的操作基本中构造函数,变量和方法。
    java.lang.reflect.Field :对应类变量
    java.lang.reflect.Method :对应类方法
    java.lang.reflect.Constructor :对应类构造函数

    突破java的权限检测
    java.lang.reflect.AccessibleObject
    AccessibleObject为我们提供了一个方法 setAccessible(boolean flag),该方法的作用就是可以取消 Java 语言访问权限检查。所以任何继承AccessibleObject的类的对象都可以使用该方法取消 Java 语言访问权限检查。
    所以任何继承AccessibleObject的类的对象都可以使用该方法取消 Java 语言访问权限检查。(final类型变量也可以通过这种办法访问)

    1. public final class Field extends AccessibleObject implements Member

    FieldMethodConstructor都是继承AccessibleObject

    反射缺点

    • 性能问题。因为反射是在运行时而不是在编译时,所有不会利用到编译优化,同时因为是动态生成,因此,反射操作的效率要比那些非反射操作低得多。
    • 安全问题。使用反射技术要求程序必须在一个没有安全限制的环境中运行。如果一个程序必须在有安全限制的环境中运行,如Applet,那么这就是个问题了。
    • 代码问题。由于反射允许代码执行一些在正常情况下不被允许的操作(比如访问私有的属性和方法),所以使用反射可能会导致意料之外的副作用--代码有功能上的错误,降低可移植性。反射代码破坏了抽象性,因此当平台发生改变的时候,代码的行为就有可能也随着变化。