java反射机制

JAVA反射机制:

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

Java反射机制主要提供了以下功能:

在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。

Java有个Object 类,是所有Java 类的继承根源,其内声明了数个应该在所有Java 类中被改写的方法:hashCode()、equals()、clone()、toString()、getClass()等。其中getClass()返回一个Class 对象。

【Class 类十分特殊。它和一般类一样继承自Object,其实体用以表达Java程序运行时的classes和interfaces,也用来表达enum、array、primitive Java types(boolean, byte, char, short, int, long, float, double)以及关键词void。当一个class被加载,或当加载器(class loader)的defineClass()被JVM调用,JVM 便自动产生一个Class 对象。】

如果您想借由“修改Java标准库源码”来观察Class 对象的实际生成时机(例如在Class的constructor内添加一个println()),这样是行不通的!因为Class并没有public constructor。

Class是Reflection故事起源。针对任何您想探勘的类,唯有先为它产生一个Class 对象,接下来才能经由后者唤起为数十多个的Reflection APIs。Reflection机制允许程序在正在执行的过程中,利用Reflection APIs取得任何已知名称的类的内部信息,包括:package、 type parameters、 superclass、 implemented interfaces、 inner classes、 outer classes、 fields、 constructors、 methods、 modifiers等,并可以在执行的过程中,动态生成instances、变更fields内容或唤起methods。

从Class中获取信息

Class类提供了大量的实例方法来获取该Class对象所对应的详细信息,Class类大致包含如下方法,其中每个方法都包含多个重载版本,因此我们只是做简单的介绍,详细请参考JDK文档

获取类内信息

获取内容 方法签名
构造器 Constructor getConstructor(Class… parameterTypes)
包含的方法 Method getMethod(String name, Class… parameterTypes)
包含的属性 Field getField(String name)
包含的Annotation A getAnnotation(Class annotationClass)
内部类 Class[] getDeclaredClasses()
外部类 Class getDeclaringClass()
所实现的接口 Class[] getInterfaces()
修饰符 int getModifiers()
所在包 Package getPackage()
类名 String getName()
简称 String getSimpleName()
一些判断类本身信息的方法

判断内容 方法签名
注解类型? boolean isAnnotation()
使用了该Annotation修饰? boolean isAnnotationPresent(Class annotationClass)
匿名类? boolean isAnonymousClass()
数组? boolean isArray()
枚举? boolean isEnum()
原始类型? boolean isPrimitive()
接口? boolean isInterface()
obj是否是该Class的实例 boolean isInstance(Object obj)
(1)获取class
java反射机制_第1张图片

主有三种获得class的途径,使用时要注意区别

1、 a,类型.class 如: String.class使用类名加“.class”的方式即会返回与该类对应的Class对象。这个方法可以直接获得与指定类关联的Class对象,而并不需要有该类的对象存在。

2、 b,Class.forName(“类名”);该方法可以根据字符串参数所指定的类名获取与该类关联的Class对象。如果该类还没有被装入,该方法会将该类装入JVM。forName方法的参数是类的完 整限定名(即包含包名)。通常用于在程序运行时根据类名动态的载入该类并获得与之对应的Class对象。

3、 c, obj.getClass();所有Java对象都具备这个方法,该方法用于返回调用该方法的对象的所属类关联的

(2)获取构造方法

Class类提供了四个public方法,用于获取某个类的构造方法:

1、Constructor getConstructor(Class[] params)根据构造函数的参数,返回一个具体的具有public属性的构造函数

2、Constructor getConstructors() 返回所有具有public属性的构造函数数组

3、Constructor getDeclaredConstructor(Class[] params) 根据构造函数的参数,返回一个具体的构造函数(不分public和非public属性)

4、Constructor getDeclaredConstructors() 返回该类中所有的构造函数数组(不分public和非public属性)

1 反射出无参的构造方法并得到对象

  • 注意:
  • 1 在Class.forName()中应该传入含有包名的类全名
  • 2 newInstance()方法的本质是调用类的无参Public构造方法
    /
    String className1=“cn.testreflect.Worker”;
    Class clazz1=Class.forName(className1);
    Object object1=clazz1.newInstance();
    System.out.println(“object1.toString()=”+object1.toString());
    /*
  • 2 反射出带参数的构造方法并得到对象
    */
    String className2=“cn.testreflect.Worker”;
    Class clazz2=Class.forName(className2);
    Constructor constructor1=clazz2.getConstructor(int.class,String.class);
    Object object2=constructor1.newInstance(18,“小明”);
    System.out.println(“object2.toString()=”+object2.toString());
    (3)获取类的成员方法
    与获取构造方法的方式相同,存在四种获取成员方法的方式:
    1、Method getMethod(String name, Class[] params) 根据方法名和参数,返回一个具体的具有public属性的方法
    2、Method[] getMethods() 返回所有具有public属性的方法数组
    3、Method getDeclaredMethod(String name, Class[] params) 根据方法名和参数,返回一个具体的方法(不分public和非public属性)
    4、Method[] getDeclaredMethods() 返回该类中的所有的方法数组(不分public和非public属性)
  • 调用对象的带参数的方法
      */
      String className5=“cn.testreflect.Worker”;
      Class clazz5=Class.forName(className5);
      Method method=clazz5.getMethod(“printMessage”,
    String.class,int.class,int.class);
      Object object5=clazz5.newInstance();
      method.invoke(object5, “周星星”,50,9527);
      } catch (Exception e) {
      System.out.println(e.toString());
      }
    (4)获取类的成员变量(成员属性)

存在四种获取成员属性的方法

1、Field getField(String name) 根据变量名,返回一个具体的具有public属性的成员变量

2、Field[] getFields() 返回具有public属性的成员变量的数组

3、Field getDeclaredField(String name) 根据变量名,返回一个成员变量(不分public和非public属性)

4、Field[] getDelcaredFields() 返回所有成员变量组成的数组(不分public和非public属性)

  • 1 获取类的私有字段
      * 注意:
      * 获取共有字段应调用clazz3.getField(name)方法
      /
      String className3=“cn.testreflect.Worker”;
      Class clazz3=Class.forName(className3);
      Field ageField1=clazz3.getDeclaredField(“age”);
      System.out.println(“ageField1=”+ageField1);
      /
    *
      * 2 获取和更改某个对象的私有字段
      * 即模拟get()和set()方法
      */
      String className4=“cn.testreflect.Worker”;
      Class clazz4=Class.forName(className4);
      Field ageField2=clazz4.getDeclaredField(“age”);
      Object object4=constructor1.newInstance(18,“小明”);
      //取消访问私有字段的合法性检查
      ageField2.setAccessible(true);
      //获取对象的私有字段
      Object ageObject4=ageField2.get(object4);
      System.out.println(“ageObject4=”+ageObject4);
      //再更改对象的私有字段的值
      ageField2.set(object4, 9527);
      //重新获得
      Object ageObject5=ageField2.get(object4);
      System.out.println(“ageObject5=”+ageObject5);

你可能感兴趣的:(javase)