java 反射

来源:互联网 发布:周星驰 电视剧 知乎 编辑:程序博客网 时间:2024/05/02 02:22

----------- android培训java培训、java学习型技术博客、期待与您交流! ------------

Java反射

一、反射的概念
       反射的引入:
       Object obj = new Student();
       若程序运行时接收到外部传入的一个对象,该对象的编译类型是Object,但程序又需要调用该对象运行类型的方法:
      1.若编译和运行类型都知道,使用 instanceof判断后,强转。
      2.编译时根本无法预知该对象属于什么类,程序只能依靠运行时信息来发现对象的真实信息, 这时就必须使用反射了。
      3.要是想得到对象真正的类型,就得使用反射。
什么是反射机制? 
        简单的来说,反射机制指的是程序在运行时能够获取自身的信息。在java中,只要给定类的名字,那么就可以通过反射机制来获得类的所有信息。
反射机制的优点与缺点: 
        为什么要用反射机制?直接创建对象不就可以了吗,这就涉及到了动态与静态的概念, 
     静态编译:在编译时确定类型,绑定对象,即通过。 
     动态编译:运行时确定类型,绑定对象。动态编译最大限度发挥了java的灵活性,体现了多态的应用,有以降低类之间的藕合性。 
     一句话,反射机制的优点就是可以实现动态创建对象和编译,体现出很大的灵活性,特别是在J2EE的开发。
它的缺点是对性能有影响。使用反射基本上是一种解释操作,我们可以告诉JVM,我们希望做什么并且它满足我们的要求。这类操作总是慢于只直接执行相同的操作。

二、获得Class对象
如何得到各个字节码对应的实例对象?
       每个类被加载后,系统会为该类生成对应的Class对象,通过Class对象可以访问到JVM中的这个类,
3种方式:
       1、调用某个类的class属性获取Class对象,如Date.class会返回Date类对应的Class对象(其实就是得到一个类的一份字节码文件);
       2、使用Class类的forName(String className)静态方法,className表示全限定名;如String的全限定名:java.lang.String;
       3、调用某个对象的getClass()方法。该方法属于Object类;
Class<?> clz = new Date().getClass();

三、九个预定义Class对象
       基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void通过class属性也表示为 Class 对象;
       Class类中boolean isPrimitive() :判定指定的 Class 对象是否表示一个基本类型。//primitive 原始的;
       包装类和Void类的静态TYPE字段;
       Integer.TYPE == int.class ;  
       Integer.class == int.class;  
 数组类型的Class实例对象:
Class<String[]> clz = String[].class;
        数组的Class对象如何比较是否相等? 数组的维数和数组的类型;
Class类中 boolean isArray() :判定此 Class 对象是否表示一个数组类型。

五、Class中得到构造方法Constructor、方法Method、字段Field
常用方法:
Constructor类用于描述类中的构造方法:
 Constructor<T> getConstructor(Class<?>... parameterTypes)
返回该Class对象表示类的指定的public构造方法;
 Constructor<?>[] getConstructors()
返回该Class对象表示类的所有public构造方法;
 Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)//declared 公开的;
返回该Class对象表示类的指定的构造方法,和访问权限无关;
 Constructor<?>[] getDeclaredConstructors()
返回该Class对象表示类的所有构造方法,和访问权限无关;
Method类用于描述类中的方法:
 Method getMethod(String name, Class<?> ... parameterTypes)
返回该Class对象表示类和其父类的指定的public方法;
 Method[] getMethods(): 
返回该Class对象表示类和其父类的所有public方法;
 Method getDeclaredMethod(String name, Class<?>... parameterTypes)
返回该Class对象表示类的指定的方法。和访问权限无关,但不包括继承的方法;
 Method[] getDeclaredMethods(): 获得类所有的方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法;
六、利用反射创建对象
创建对象:
      1、使用Class对象的newInstance()方法创建该Class对象的实例,此时该Class对象必须要有无参数的构造方法。
      2、使用Class对象获取指定的Constructor对象,再调用Constructor的newInstance()方法创建对象类的实例,此时可以选择使用某个构造方法。如果这个构造方法被私有化起来,那么必须先申请访问,将可以访问设置为true;
       七、使用反射调用方法
        每个Method的对象对应一个具体的底层方法。获得Method对象后,程序可以使用Method里面的invoke方法来执行该底层方法。
       Object invoke(Object obj,Object ... args):obj表示调用底层方法的对象,后面的args表示传递的实际参数。
       如果底层方法是静态的,那么可以忽略指定的 obj 参数。该参数可以为 null,想想为什么?
       //静态方法,不需创建对象,所以这里会是null
       如果底层方法所需的形参个数为 0,则所提供的 args 数组长度可以为 0 或 null。
       不写,null,或 new Object[]{}
       若底层方法返回的是数组类型,invoke方法返回的不是底层方法的值,而是底层方法的返回类型;

 

0 0