Java 反射(基础)

一、反射的概述

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

要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.

例如:一个类有:成员变量、方法、构造方法、包等等信息,利用反射技术可以对一个类进行解剖,把个个组成部分映射成一个个对象。

 

1、获取Class对象

获取类对象的三种方式,1已经可以创建实体类了,再用反射,多此一举;2需要配置文件支持;3通过全限定名获取,一般常用

2获取构造器

请注意图中的修饰符和参数

@Test//获取构造器
public void objTest3() {

    System.out.println("**********************************获取所有构造器**********************************");
    Class<?> aClass = null;
    try {
        aClass = Class.forName("com.example.reflex.Student");
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
    Constructor<?>[] constructors = aClass.getConstructors();
    System.out.println("**********************************获取所有公共构造器**********************************");
    for (Constructor<?> constructor : constructors) {

        System.out.println("构造器输出 : " + constructor);
    }
    System.out.println("**********************************获取所有构造器(包括私有,受保护的)**********************************");
    Constructor<?>[] declaredConstructors = aClass.getDeclaredConstructors();
    for (Constructor<?> declaredConstructor : declaredConstructors) {
        System.out.println("构造器输出 : " + declaredConstructor);
    }

    System.out.println("**********************************获取默认的构造器(公有无参)**********************************");
    Constructor<?> constructor = null;
    try {
        constructor = aClass.getConstructor(null);
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    }
    System.out.println("构造器输出:" + constructor);
}

控制台输出结果

getConstructors 获取所有公共的构造器;getDeclaredConstructors 获取所有构造器,包括私有,受保护的

 

获取私有构造器,并调用

@Test//获取私有构造器并调用
public void objTest4() {

    Class<?> aClass = null;
    try {
        aClass = Class.forName("com.example.reflex.Student");
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
    Constructor<?> declaredConstructor = null;
    try {
        //反射获取构造方法对象
       declaredConstructor = aClass.getDeclaredConstructor(int.class);//String.class char.class int.class
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    }
    System.out.println("构造方法:" + aClass);
    declaredConstructor.setAccessible(true);//开启暴力访问,忽略访问修饰符
    try {
        //构造方法中添加属性、返回T类型
        Object newInstance  = declaredConstructor.newInstance(18);
    } catch (InstantiationException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    }
}

控制台输出结果

 

getDeclaredConstructor(int.class) 指定获取构造器,参数int

反射回的对象.setAccessible(true); 开启暴力模式,忽略修饰符

3获取成员变量

@Test//获取成员变量
public void Fields() {

    Class<?> aClass = null;
    try {
        aClass = Class.forName("com.example.reflex.reflexOfEntity");
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
    Field[] fields = aClass.getFields();
    System.out.println("**********************************获取公有成员变量**********************************");
    for (Field field : fields) {
        System.out.println("成员变量:" + field);
    }

    System.out.println("**********************************获取所有成员变量(包括私有、受保护、默认的)**********************************");
    Field[] declaredFields = aClass.getDeclaredFields();
    for (Field declaredField : declaredFields) {
        System.out.println("成员变量:" + declaredField);
    }

}

控制台输出结果

注意修饰符和成员变量名称

类对象.getFields 获取所有公有的成员变量;  类对象.getDeclaredFields 获取所有的成员变量,包括私有的,受保护的,默认的;

 

@Test//获取私有成员变量并调用
public void Fields2() {

    System.out.println("**********************************获取私有属性并调用**********************************");
    Class<?> aClass = null;
    try {
        aClass = Class.forName("com.example.reflex.reflexOfEntity");
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
    Field[] declaredFields = aClass.getDeclaredFields();
    for (Field declaredField : declaredFields) {
        System.out.println("遍历所有成员变量:" + declaredField);
    } //private java.lang.String com.example.reflex.reflexOfEntity.phoneNum 获取到的私有成员变量
    Field phoneNum = null;
    try {
        phoneNum = aClass.getDeclaredField("phoneNum");
    } catch (NoSuchFieldException e) {
        e.printStackTrace();
    }
    System.out.println("输出私有成员变量:" + phoneNum);
    //反射类对象
    Object newInstance = null;
    try {
        newInstance = aClass.getConstructor().newInstance();
    } catch (InstantiationException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    }
    phoneNum.setAccessible(true);//开启暴力模式,忽略修饰符
    try {
        phoneNum.set(newInstance,"222");
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    }
    reflexOfEntity reflexOfEntity = (reflexOfEntity) newInstance;//获取类实例化对象
    System.out.println("输出对象,查看phoneNum属性:" + reflexOfEntity);
}

 

控制台输出

私有的成员变量 phoneNum 被赋值

类对象.getConstructor().newInstance(); 获取类实例化对象

成员变量对象.set(类实例化对象,"222");

aClass.getDeclaredField("phoneNum"); aClass(类对象)phoneNum (成员变量名称)

 

4获取方法

 

@Test//获取方法
public void testMethod() {

    //获取类对象
    Class<?> aClass = null;
    try {
        aClass = Class.forName("com.example.reflex.reflexOfMethod");
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }

    System.out.println("**********************************获取所有共有方法**********************************");
    //获取所有的共有方法
    Method[] methods = aClass.getMethods();
    for (Method method : methods) {

        System.out.println("共有方法:" + method);
    }

    System.out.println("**********************************获取所有(自定义)方法(包括私有,默认,受保护的)**********************************");
    //获取所有方法
    Method[] declaredMethods = aClass.getDeclaredMethods();
    for (Method declaredMethod : declaredMethods) {

        System.out.println("所有方法:" + declaredMethod);
    }
}

控制台输出

注意方法名,修饰符,包名

getMethods();获取所有共有方法,包括Java内设方法 ; getDeclaredMethods()获取所有自定义方法,包括私有的,受保护的,默认的;

 

@Test//获取指定方法,并调用
public void testMethod2() {

    //获取类对象
    Class<?> aClass = null;
    try {
        aClass = Class.forName("com.example.reflex.reflexOfMethod");
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
    System.out.println("获取类对象:" + aClass);
    System.out.println("**********************************获取所有(自定义)方法(包括私有,默认,受保护的)**********************************");
    //获取自定义所有方法
    Method[] declaredMethods = aClass.getDeclaredMethods();
    for (Method declaredMethod : declaredMethods) {

        System.out.println("查看方法:" + declaredMethod);
    }
    //public void com.example.reflex.reflexOfMethod.show1(java.lang.String)公有方法show1
    //private java.lang.String com.example.reflex.reflexOfMethod.show4(int)私有方法show4

    //调用指定方法
    Method show1 = null;
    try {
        show1 = aClass.getMethod("show1", String.class);
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    }
    System.out.println("获得方法:" + show1);
    //获取类实例化对象
    Object newInstance = null;
    try {
        newInstance = aClass.getConstructor().newInstance();
    } catch (InstantiationException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    }
    Object chenyb = null;
    try {
        chenyb = show1.invoke(newInstance, "Chenyb");
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    }

    System.out.println("调用方法show1,输出返回值:" + chenyb);
    Method show4 = null;
    try {
        show4 = aClass.getDeclaredMethod("show4", int.class);
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    }
    System.out.println("获得私有方法:" + show4);
    //调用类对象
    show4.setAccessible(true);//暴力调用,忽略修饰符
    Object invoke = null;
    try {
        invoke = show4.invoke(newInstance, 18);
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    }
    System.out.println("调用方法show4,输出返回值:" + invoke);
}

 

控制台输出

-

以上环节,注意开启暴力权限的步奏,和参数类型  类型 类型 

2018-09-05

Chenyb 随笔记录,方便自己学习(学习到了Java 线程&反射,才感觉自己java 才刚刚入门) 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值