zoukankan      html  css  js  c++  java
  • Java反射机制的简单学习

    今天看了一下Java的反射机制,就此记录一下。

    首先,我们要先了解一下什么是反射?

    •   反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。
    •   JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制

    Java反射的应用

    •   Spring框架 
    •   Hibernate框架:关联映射等
    •   白盒测试   

    Java反射相关API

      java.lang包下

        -Class<T>:表示一个正在运行的 Java 应用程序中的类和接口,是Reflection的起源

      java.lang.reflect包下

        -Field 类:代表类的成员变量(也称类的属性)

        -Method 类 : 代表类的方法

        -Array 类 : 提供了动态创建数组,以及访问数组的元素的静态方法

    反射的类类型:Class

    假设我们有一个Role类

     1 package _Venom_.reflection;
     2 
     3 public class Role {
     4     
     5     private String name;
     6     private String type;
     7     
     8     //Constructors
     9     public Role(){
    10         System.out.println("Constructor Role() is invoking!");
    11     }
    12     
    13     private Role(String _name){
    14         this.name = _name;
    15         System.out.println("Constructor Role(String _name) is invoking!");
    16     }
    17 
    18     
    19     //get and set method
    20     public String getName() {
    21         return name;
    22     }
    23 
    24     public void setName(String name) {
    25         this.name = name;
    26     }
    27 
    28     public String getType() {
    29         return type;
    30     }
    31 
    32     public void setType(String type) {
    33         this.type = type;
    34     }
    35 
    36     //override the toString method to show the class
    37     @Override
    38     public String toString() {
    39         // TODO Auto-generated method stub
    40         return "This is a role called " + this.name;
    41     }
    42     
    43 }

    我们可以通过以下方式得到类类型。

    获取方式

    说明

    示例

    object.getClass()

    每个对象都有此方法

    获取指定实例对象的Class

    List list = new ArrayList();

    Class listClass = list.getClass();

    class. getSuperclass()

    获取当前Class的继承类Class

    List list = new ArrayList();

    Class listClass = list.getClass();

    Class superClass = listClass. getSuperclass();

    Object.class

    .class直接获取

    Class listClass = ArrayList.class;

    Class.forName(类名)

    用Class的静态方法,传入类的全称即可

    try {

    Class c = Class.forName("java.util.ArrayList");

    } catch (ClassNotFoundException e) {

    e.printStackTrace();

    }

    Primitive.TYPE

    基本数据类型的封装类获取Class的方式

    Class longClass = Long.TYPE;

    Class integerClass = Integer.TYPE;

    Class voidClass = Void.TYPE;


    Class class1 = Role.class; try { Class class2 = Class.forName("_Venom_.reflection.Role"); } catch (ClassNotFoundException e1) { // TODO Auto-generated catch block e1.printStackTrace(); }

    通过类类型的newInstance方法来创建一个实例。如下

    Object obj = class1.newInstance();

    但是,我们通常的做法是通过Constructor类来获取类的构造方法,然后再通过Constructor类的newInstance方法来创建实例。

    获取类的构造器

    Constructor类:

    •   public Constructor<?>[] getConstructor()   返回类中的所有public构造器集合,默认构造器的下标为0
    •   public Constructor<T> getConstructor(Class<?>...parameterTypes) 返回指定的public构造器,参数为构造器参数类型集合
    •      public  Constructor<?>[] getDeclaredConstructor() 返回类中所有的构造器,包括私有
    • public Constructor<T> getDeclaredConstructor(Class<?>...parameterTypes) 返回任意指定的构造器
    Class class1 = Role.class;
            try {
                Class class2 = Class.forName("_Venom_.reflection.Role");
            } catch (ClassNotFoundException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            
            /**
             * 获取构造方法Constructor
             * getConstructor() only for public 
             * getDeclaredConstructor() global access all
             * */
            Constructor constructor = null;
            //指定参数列表获取特定的方法
            try {
           //1 constructor
    = class1.getDeclaredConstructor(new Class[]{String.class}); //设置可访问的权限 不设置会报IllegalAccessException异常 constructor.setAccessible(true); } catch (NoSuchMethodException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } Object obj = null; try { obj = constructor.newInstance(new Object[]{"Venom"}); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } //打印对象的信息 System.out.println(obj); //2获取所有的构造方法的集合 Constructor constructorArr[] = null; constructorArr = class1.getDeclaredConstructors(); constructorArr[1].setAccessible(true); Object obj1 = null; try { obj1 = constructorArr[1].newInstance(new Object[]{"_Venom_"}); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(obj1);
    解释一下:第一个是获得一个指定的方法,我们指定了参数是一个String类型,第二段我们获得了所有的构造方法集合,并选取了其中一个创建了新的对象。
      当我们获得私有的方法的时候,要用setAccessible设置一下可访问的权限。
    以此类推:
      在获取类的成员变量的时候,我们可以使用Field类
        主要的方法非常的类似:
      • public Field getDeclaredField(String name)  获取任意指定名字的成员
      • public Field[] getDeclaredFields()             获取所有的成员变量
      • public Field getField(String name)           获取任意public成员变量
      • public Field[] getFields()                          获取所有的public成员变量

      在获取类的方法的时候,我们可以使用Method类:

         
      • public Method[] getMethods()    获取所有的共有方法的集合
      • public Method getMethod(String name,Class<?>... parameterTypes) 获取指定公有方法 参数1:方法名 参数2:参数类型集合  
      • public Method[] getDeclaredMethods()  获取所有的方法
      • public Method getDeclaredMethod(String name,Class<?>... parameterTypes) 获取任意指定方法

    总结:

      感觉今天学习的Java反射机制还是很有用出的,以此Mark一下我的学习历程。

        

  • 相关阅读:
    SharedPreferences
    Handler
    Gallery 和ImageSwitcher
    poj 1077 Eight (BFS)
    HDU 1208 Pascal's Travels( 记忆化搜索)
    HDU 1619 Unidirectional TSP (dp,dfs)
    HDU 3683 Gomoku (枚举+BFS)
    HDU 3647 Tetris (暴力DFS)
    poj 1020 Anniversary Cake (DFS)
    poj 1375 Intervals(解析几何 过圆外一点求与圆的切线)
  • 原文地址:https://www.cnblogs.com/Venom/p/3280707.html
Copyright © 2011-2022 走看看