JAVA类反射--基本认识

类反射:

  1. JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制。
  2. 反射(Reflection)是Java程序开发语言的特征之一,它允许运行中的Java程序对自身进行检查, 也称自审,并能直接操作程序的内部属性。例如,使用它能获得Java类中各成员的名称并显示出来。
  3. Java的这一能力在实际应用中应用得很多,在其它的程序语言中根本就不存在这一特性。例如,Pascal、C或者C++中就没有办法在程序中获得函数定义相关的信息。
  4. JavaBean是类反射的实际应用之一,它能让一些工具可视化的操作软件组件。这些工具通过类反射动态的载入并取得Java组件(类)的属性。后面学习的各种框架,基本上都会有反射的使用。

接下来我将用代码的形式逐一演示类反射,带你玩转类反射! 
反射使用的三个步骤 
第一步:获得你想操作的类的java.lang.Class对象。在运行中的Java程序中,用java.lang.Class类来描述类和接口等。 
第二步:调用诸如getDeclaredMethods的方法,取得该类中定义的所有方法的列表。 
第三步:使用反射的API来操作这些信息。

获取Class对象的三种方式 
★ 方式一 
通过对象的getClass方法进行获取。这种方式需要具体的类和该类的对象,以及调用getClass方法。 
★ 方式二 
任何数据类型(包括基本数据类型)都具备着一个静态的属性class,通过它可直接获取到该类型对应的Class对象。这种方式要使用具体的类,然后调用类中的静态属性class完成,无需调用方法,性能更好。 
★ 方式三(这种方式仅仅依赖于javaAPI中的String类,在开发中常用!) 
通过Class.forName()方法获取。这种方式仅需使用类名,就可以获取该类的Class对象,更有利于扩展。

代码演示(代码演示中我们采用JUnit 测试工具来进行测试)

package cn.hncu.reflect;

import org.junit.Test;

//获取Class对象的三种方式
public class ReflectGetClass {

    @Test//法1:通过 对象.getClass()
    public void getClass1() {
        Person p = new Person("Jack",22);
        Class c = p.getClass();
        System.out.println(c);
    }

    @Test//法2:通过类型---任何数据类型(包含基本数据类型)都拥有一个静态变量class
    public void getClass2() {
        Class c = Person.class;
        System.out.println(c);

        Class c2 = int.class;
        System.out.println(c2);
    }

    @Test//法3:通过Class.forName直接获取---不依赖具体的类或对象(仅仅依赖String类,而我们做项目时通常把使用API中的类看成不是依赖的!)
    public void getClass3() {
        try {
            Class c = Class.forName("cn.hncu.reflect.Person");//“类全名”的字符串形式
            System.out.println(c);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }


    //※法3是不依赖于被反射类或对象的,能够完全达到解藕的效果,是我们以后开发当中的首选策略

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

类的解剖(获取类的定义信息) 
★ 获取类的方法 
找出一个类中定义了些什么方法,这是一个非常有价值也非常基础的反射用法。 
★ 获取类的构造器 
找出一个类中定义的构造方法,构造器没有返回类型。 
★ 获取类的属性字段 
找出一个类中定义了哪些属性字段。

代码演示

package cn.hncu.reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

import org.junit.Test;

//类的解剖:把一个类中的所有方法、属性、构造方法全部获取出来
public class ReflectDecompose {
    private static final String className="cn.hncu.reflect.Student"; 
    //private static final String className="cn.hncu.reflect.Person"; 

    //1 c.getMethods()----获取的是当前类及其父类的公开方法---无法获取到私有方法
    //2 c.getDeclaredMethods()----获取的是当前类自己定义的那些方法---包括私有的 但不包括父类中的方法
    @Test//获取方法
    public void fetchMethods() throws Exception{
       Class c = Class.forName(className);
       //Method ms[] = c.getMethods();//所能访问的方法和一个“Person p=new Person()”中的p对象一样
       Method ms[] = c.getDeclaredMethods();

       for(int i=0;i<ms.length;i++){
           Method m = ms[i];
           System.out.println("name: "+m.getName());
           System.out.println("declaringClass: "+ m.getDeclaringClass());
           Class paramTypes[] = m.getParameterTypes();
           for(int j=0;j<paramTypes.length;j++){
               System.out.println("param#"+j+": "+ paramTypes[j]);
           }

           Class returnType = m.getReturnType();
           System.out.println("returnType: "+returnType);

           Class excepts[] = m.getExceptionTypes();
           for(int j=0;j<excepts.length;j++){
               System.out.println("excepts#"+j+": "+ excepts[j]);
           }

           int modifiers = m.getModifiers();
           System.out.println("modifiers: "+modifiers);
           System.out.println("--------------");
       }

    }

    //注意,构造方法都不包含父类的
    //1 c.getConstructors()----获取的是当前类(注意不包含父类的)的公开构造方法---无法获取到私有方法
    //2 c.getDeclaredConstructors()----获取的是当前类自己定义的构造方法---包括私有的
    @Test//获取方法
    public void fetchConstructors() throws Exception{
        Class c = Class.forName(className);
        //Constructor cons[] = c.getConstructors();//所能访问的方法和一个“Person p=new Person()”中的p对象一样
        Constructor cons[] = c.getDeclaredConstructors();
        for(int i=0;i<cons.length;i++){
            Constructor con = cons[i];
            System.out.println("name: "+con.getName());
            System.out.println("declaringClass: "+ con.getDeclaringClass());
            Class paramTypes[] = con.getParameterTypes();
            for(int j=0;j<paramTypes.length;j++){
                System.out.println("param#"+j+": "+ paramTypes[j]);
            }

            Class excepts[] = con.getExceptionTypes();
            for(int j=0;j<excepts.length;j++){
                System.out.println("excepts#"+j+": "+ excepts[j]);
            }

            int modifiers = con.getModifiers();
            System.out.println("modifiers: "+modifiers);
            System.out.println("--------------");
        }
    }


    //1 c.getFields()----获取的是当前类和父类的公开属性---无法获取到私有属性
    //2 c.getDeclaredFields()----获取的是当前类自己定义的属性---包括私有的
    @Test//获取方法
    public void fetchFields() throws Exception{
        Class c = Class.forName(className);
        //Field flds[] = c.getFields();
        Field flds[] = c.getDeclaredFields();
        for(int i=0;i<flds.length;i++){
            Field fld = flds[i];
            System.out.println("name: "+fld.getName());
            System.out.println("declaringClass: "+ fld.getDeclaringClass());

            Class type = fld.getType();
            System.out.println("type: "+ type);
            int modifiers = fld.getModifiers();
            System.out.println("modifiers: "+Modifier.toString(modifiers) );
            System.out.println("--------------");
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95

Class类中包含的主要三个需要解剖的东西: 
Field[]—{Name,DeclaringClass,Type,Modifiers,(…annotation,genericType…)}

Constructor[]—{Name,DeclaringClass,Modifiers,ParameterTypes,ExceptionTypes(…annotation,genericType…)}

Method[]–{Name,DeclaringClass,ReturnType,Modifiers,ParameterTypes,ExceptionTypes(…annotation,genericType…)}

附上一张修饰符对应的二进制整数的图(来自JAVA–API) 
这里写图片描述

猜你喜欢

转载自blog.csdn.net/m0_37988084/article/details/80340379