JAVA第十一课 反射、XML

第十课

  • 反射
    • 反射相关的主要API
    • Class类
      • class类理解
    • 获取Class类的实例(四种方法)
    • 使用反射能获取什么
      • 所有的结构
      • 指定的结构

反射

  • Reflection(反射)是被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内
    部属性及方法。 
  • 加载完类之后,在堆内存的方法区中就产生了一个Class类型的对象(一个类只有一个Class对象),这个对象就包含了完整的类的结构信息。我们可以通过这个对象看到类的结构。这个对象就像一面镜子,透过这个镜子看到类的结构,所以,我们形象的称之为:反射
  1. 动态语言
    一类在运行时可以改变其结构的语言:例如新的函数、对象、甚至代码可以
    被引进,已有的函数可以被删除或是其他结构上的变化。通俗点说就是在运
    行时代码可以根据某些条件改变自身结构。
    主要动态语言:Object-C、C#、JavaScript、PHP、Python、Erlang。
  2. 静态语言
    与动态语言相对应的,运行时结构不可变的语言就是静态语言。如Java、C、C++。
    Java不是动态语言,但Java可以称之为“准动态语言”。即Java有一定的动态性我们可以利用反射机制、字节码操作获得类似动态语言的特性。Java的动态性让编程的时候更加灵活!

反射相关的主要API

java.lang.Class:代表一个类 

  • java.lang.reflect.Method:代表类的方法
  • java.lang.reflect.Field:代表类的成员变量
  • java.lang.reflect.Constructor:代表类的构造器

Class类

在Object类中定义了以下的方法,此方法
将被所有子类继承:
public final Class getClass()
以上的方法返回值的类型是一个Class类,
此类是Java反射的源头,实际上所谓反射
从程序的运行结果来看也很好理解,即:
可以通过对象反射求出类的名称。

class类理解

对象照镜子后可以得到的信息:某个类的属性、方法和构造器、某个类到底实现了哪些接口。对于每个类而言,JRE 都为其保留一个不变的 Class 类型的对象。一个 Class 对象包含了特定某个结构(class/interface/enum/annotation/primitivetype/void/[])的有关信息。 

  1. Class本身也是一个类
  2. Class 对象只能由系统建立对象
  3. 一个加载的类在 JVM 中只会有一个Class实例
  4. 一个Class对象对应的是一个加载到JVM中的一个.class文件
  5. 每个类的实例都会记得自己是由哪个 Class 实例所生成
  6. 通过Class可以完整地得到一个类中的所有被加载的结构
  7. Class类是Reflection的根源,针对任何你想动态加载、运行的类,唯有先获得相应的Class对象

获取Class类的实例(四种方法)

  1. 前提:若已知具体的类,通过类的class属性获取,该方法最为安全可靠,程序性能最高
    实例:Class clazz = String.class;
  2. 前提:已知某个类的实例,调用该实例的getClass()方法获取Class对象
    实例:Class clazz = student.getClass();
  3. 前提:已知一个类的全类名,且该类在类路径下,可通过Class类的静态方法forName()获取,可能抛出ClassNotFoundException
    实例:Class clazz = Class.forName(“java.lang.String”);
  4. 其他方式(不做要求)
    ClassLoader cl = this.getClass().getClassLoader();
    Class clazz4 = cl.loadClass(“类的全类名”);

哪些类型可以有Class对象?
(1)class: 外部类,成员(成员内部类,静态内部类),局部内部类,匿名内部类
(2)interface:接口
(3)[]:数组
(4)enum:枚举
(5)annotation:注解@interface
(6)primitive type:基本数据类型
(7)void

使用反射能获取什么

所有的结构

  1. 实现的全部Interface接口
     public Class[] getInterfaces()
    确定此对象所表示的类或接口实现的接口。
  2. 所继承的Superclass父类
     public Class getSuperclass()
    返回表示此 Class 所表示的实体(类、接口、基本类型)的父类的Class。
  3. 全部的Constructor构造器
  • public Constructor[] getConstructors()
    返回此 Class 对象所表示的类的所有public构造方法。
  • public Constructor[] getDeclaredConstructors()
    返回此 Class 对象表示的类声明的所有构造方法。
  • Constructor类中的方法:
     取得修饰符: public int getModifiers();
     取得方法名称: public String getName();
     取得参数的类型:public Class[] getParameterTypes();
  1. 全部的Method方法
  • public Method[] getDeclaredMethods()
    返回此Class对象所表示的类或接口的全部方法
  • public Method[] getMethods()
    返回此Class对象所表示的类或接口的public的方法
  • Method类中的方法:
     public Class getReturnType()取得全部的返回值
     public Class[] getParameterTypes()取得全部的参数
     public int getModifiers()取得修饰符
     public Class[] getExceptionTypes()取得异常信息
  1. 全部的Field属性
  • public Field[] getFields()
    返回此Class对象所表示的类或接口的public的Field。 
  • public Field[] getDeclaredFields()
    返回此Class对象所表示的类或接口的全部Field。 * * Field方法中方法:
     public int getModifiers() 以整数形式返回此Field的修饰符
     public Class getType() 得到Field的属性类型
     public String getName() 返回Field的名称。
  1. Annotation注解
     get Annotation(Class annotationClass)
     getDeclaredAnnotations()
  2. 泛型相关
    获取父类泛型类型:Type getGenericSuperclass()
    泛型类型:ParameterizedType
    获取实际的泛型类型参数数组:getActualTypeArguments()
  3. 类所在的包 Package getPackage()

指定的结构

  1. 调用指定的Method方法
    通过反射,调用类中的方法,通过Method类完成。步骤:
    1.通过Class类的getMethod(String name,Class…parameterTypes)方法取得一个Method对象,并设置此方法操作时所需要的参数类型。
    2.之后使用Object invoke(Object obj, Object[] args)进行调用,并向方法中传递要设置的obj对象的参数信息。
//invoke()方法的说明
//Object invoke(Object obj, Object … args)
//说明:
// *Object 对应原方法的返回值,若原方法无返回值,此时返回null
// *若原方法若为静态方法,此时形参Object obj可为null
// *若原方法形参列表为空,则Object[] args为null
// *若原方法声明为private,则需要在调用此invoke()方法前,显式调用
//方法对象的setAccessible(true)方法,将可访问private的方法。
  1. 调用指定Field属性

在反射机制中,可以直接通过Field类操作类中的属性,通过Field类提供的set()和get()方法就可以完成设置和取得属性内容的操作。

  • public Field getField(String name) 返回此Class对象表示的类或接口的指定的public的Field。 
  • public Field getDeclaredField(String name)返回此Class对象表示的类或接口的指定的Field。 
  • 在Field中:
     public Object get(Object obj) 取得指定对象obj上此Field的属性内容
     public void set(Object obj,Object value) 设置指定对象obj上此Field的属性内容
setAccessible()方法的说明
Method和Field、Constructor对象都有setAccessible()方法。  
setAccessible()启动和禁用访问安全检查的开关。 
*参数值为true则指示反射的对象在使用时应该取消Java语言访问检查。 
*提高反射的效率。如果代码中必须用反射,而该句代码需要频繁的被调用,那么请设置为true。使得原本无法访问的私有成员也可以访问
*参数值为false则指示反射的对象应该实施Java语言访问检查。

你可能感兴趣的:(JAVA第十一课 反射、XML)