反射

作者: 风吹稻子 | 来源:发表于2017-04-13 08:44 被阅读27次

1.什么是反射?

“听其声,问其人”,就是根据声音,我们可以知道这个人。而反射就是“根据当前类,获取这个类的属性和方法以及构造器”。

比如我们知道一个类名Person,但不知道Person类的方法,属性以及构造器。如果我们想知道Person类到底有什么方法、属性、构造器?怎么办呢?那就使用反射。

2.为什么要用反射?

1. 判断运行时对象所属的类
2. 判断运行时对象所具有的成员变量和方法
3. 甚至可以调用到private的方法
4. 生成动态代理

3.什么是动态代理?

4.使用反射的步骤

  1. 首先获取一个类的Class对象
  2. 用这个对象来调用相应的方法获取属性、构造器和方法。

注意:三个重要的反射类,Filed、Constructor、Method

5.获取Class对象的方式

  1. “.class”方法:在知道类型的情况下使用,比如boolean.class
  2. "Object.getClass()":在知道对象的情况下使用,比如:new Date().getClass
  3. "Class.forName()":在知道类的全名下使用,比如“java.lang.String”.但是这种方法不能用在基本类型上,但可以用在基本类型的数组上。而且此类在使用的基础上,会抛出异常。

代码示例:
package reflection;

import java.util.Date;

public class TestReflection {

    public static void main(String[] args) throws ClassNotFoundException {
        System.out.println("第一种方法:Object.getClass()");
        Class c1 = new Date().getClass();
        System.out.println(c1.getName());// 输出对象名称
        System.out.println("第二种方法:.class语法");
        Class c2 = boolean.class;
        System.out.println(c2.getName());
        System.out.println("第三种方法:Class.forName()");
        Class c3 = Class.forName("java.lang.String");
        System.out.println(c3.getName());
        System.out.println("第四种方法:包装类的Type域");
        Class c4 = Double.TYPE;
        System.out.println(c4.getName());
        
    }

}

结果:

第一种方法:Object.getClass()
java.util.Date
第二种方法:.class语法
boolean
第三种方法:Class.forName()
java.lang.String
第四种方法:包装类的Type域
double

说明:
TYPE:每个基本数据类型和void都有包装类,利用TYPE就可以获取Class对象
getName():查看各种类型对象的名称,可以根据这些名称判断原来对象的类型

6.奇怪的数组类型

// 奇怪的数组类型
    String array = new int[4].getClass().getName();
    String array2 = new int[4][4].getClass().getName();

    System.out.println("一维基本类型数组" + array);
    System.out.println("二维基本类型数组" + array2);

    System.out.println("使用getCanonicalName()方法可以直接获取数组");
    String arrayCopy = new int[4].getClass().getCanonicalName();
    String arrayCopy2 = new int[4][4].getClass().getCanonicalName();

    System.out.println("一维基本类型数组" + arrayCopy);
    System.out.println("二维基本类型数组" + arrayCopy2);

测试结果:

一维基本类型数组[I
二维基本类型数组[[I
使用getCanonicalName()方法可以直接获取数组:
一维基本类型数组int[]
二维基本类型数组int[][]

说明:
1.一维数组和二维数组对象类型是“[”组成
2.可以直接使用getCanonicalName()方法获取直观的数组类型

获取类的一些基本信息

 package reflection;

import java.lang.reflect.Modifier;

public class TestReflection {
    private String name;
    private boolean b;
    private int[] age;

    //方法
    public int info(int a) {
        return a;
    }

    public static void main(String[] args) throws ClassNotFoundException {
        // 获取类名
        Class c1 = TestReflection.class;
        Class c2 = Class.forName("reflection.TestReflection");
        System.out.println("类名" + c1);

        // 获取指定的包名
        String package1 = c1.getPackage().getName();
        System.out.println("包名:" + package1);

        // 获取类的修饰符,注意修饰符返回的是数字0,1,2
        int mod = c1.getModifiers();
        String modifier = Modifier.toString(mod);
        System.out.println("修饰符:" + modifier);

        // 获取父类 
        Class superClazz = c1.getSuperclass();
        String superClazzName = superClazz.getName();
        System.out.println("父类:" + superClazzName);

        // 获取实现的接口
        Class[] interfaces = c1.getInterfaces();
        for (Class i : interfaces) {
            System.out.println("接口名" + i.getName());
        }
    }

}

测试结果:

类名class reflection.TestReflection
包名:reflection
修饰符:public
父类:java.lang.Object

获取成员变量

        // 获取指定类的成员变量
        Field[] fields = c1.getDeclaredFields();
        for(Field f : fields){

        //获取每一个变量的修饰符
        int modf = f.getModifiers();
        String  modifiers = Modifier.toString(modf);
        
        //获取类型
        Class type = f.getType();
        String typeName = type.getName();

        //获取变量名
        String name = f.getName();
        System.out.println("变量名:"+name+" 类型:"+typeName+" 修饰符:"+modifiers);

测试结果:

变量名:name 类型:java.lang.String 修饰符:private
变量名:b 类型:boolean 修饰符:private
变量名:age 类型:[I 修饰符:private

获取构造方法

    //获取构造方法
    Constructor[] constructor = c1.getDeclaredConstructors();
    for(Constructor construct : constructor){
        //这里只获取了名字,修饰符,参数与上大致相同
        String conName = construct.getName();
        System.out.println("构造方法的名字:"+conName);
    }

测试结果:

构造方法的名字:reflection.TestReflection

获取成员方法

// 获取成员方法
    Method[] methods = c1.getDeclaredMethods();
    for (Method m : methods) {
        // 获取方法的修饰符
        int modm = m.getModifiers();
        String modName = Modifier.toString(modm);
        // 获取返回值类型
        Class returnType = m.getReturnType();
        String returName = returnType.getName();
        if (returnType.isArray()) {
            //returName = returnType.getClass().getCanonicalName();
            returName = returnType.getComponentType().getName();
        }
        // 获取方法名
        String methodName = m.getName();
        System.out.println("方法名:" + methodName + " 方法修饰符:" + modName + " 方法的返回类型" + returName);
        // 获取参数相关信息
        Class[] parameter = m.getParameterTypes();
        for (Class p : parameter) {
            // 获取参数的类型
            String paramType = p.getTypeName();

            // 获取参数名
            String paramName = p.getName();
            System.out.println(methodName + "方法的参数名:" + paramName + " 参数的类型:" + paramType);
        }

        System.out.println("-------------------------");
    }

测试结果:

方法名:main 方法修饰符:public static 方法的返回类型void
main方法的参数名:[Ljava.lang.String; 参数的类型:java.lang.String[]
-------------------------
方法名:info 方法修饰符:public 方法的返回类型int
info方法的参数名:int 参数的类型:int
info方法的参数名:boolean 参数的类型:boolean
-------------------------

反射应用的链接

http://www.jianshu.com/p/2de67f864d04

相关文章

  • Java基础之反射

    Java基础之反射 反射基本介绍 反射的使用通过反射调用属性和方法通过反射获取配置文件 反射基本介绍 Java反射...

  • 镜面反射矩阵的推导

    镜面反射是以镜面作为反射平面,实物与反射物到反射平面的距离相等,实物与反射物方向相反,所以,反射矩阵由反射平面确定...

  • reflect.go包学习_之二 指针操作提高反射性能 反射应用

    reflect.go包学习_之二 指针操作提高反射性能 反射应用 反射创建实例 反射信息、反射调用方法、反射修改值...

  • Java互联网公司-经典面试题附答案

    基础:Java 反射?反射有什么缺点?你是怎么理解反射的(为什么框架需要反射)?优点:反射具有解耦性,缺点:反射属...

  • Java反射与joor反射库的使用

    java原生反射的使用 反射构造对象 反射方法 反射字段 joor反射库的使用 github:https://gi...

  • Java反射

    什么是反射? 反射的作用? 反射性能优化?

  • 反射三定律

    反射第一定律:反射可以将interface类型变量转换成反射对象 反射第二定律:反射可以将反射对象还原成inter...

  • 反射

    1.反射是什么?反射的定义,概念 2.为什么要学反射? 3.怎么使用反射?反射的使用

  • 一周岁前做好两件事,孩子就不会语言迟缓,保证口齿伶俐

    与语言发展相关的原始反射有四个:张口反射、足跖反射、抓握反射和手拉反射,每个反射的发生、发展和整合都是次第进行的,...

  • 面试官问go反射第一弹

    目录 反射概念 reflect包 反射类型(Type)和种类(Kind) 反射类型(Type)使用 反射类型对象(...

网友评论

    本文标题:反射

    本文链接:https://www.haomeiwen.com/subject/rqovattx.html