反射的基本概念

什么是反射
反射是一种机制,利用该机制可以在程序运行过程中对类进行解剖并操作类中的方法,属性,构造方法等成员。
使用反射机制解剖类的前提
必须先要获取到该类的字节码文件对象,即Class类型对象。
获取Class对象的三种方式
创建测试类:Student

public class Student {
            static {
                System.out.println("静态代码块");
            }

            {
                System.out.println("构造代码块");
            }
        }

方式1:通过类名.class获取

public class Demo01 {
            public static void main(String[] args) {
            	// 获得Student的Class的对象
                Class c = Student.class;
                // 打印输出:class com.dfbz.reflect.Student
                System.out.println(c);
            }
        }

方式2:通过Object类的成员方法getClass()方法获取

 public class Demo01 {
            public static void main(String[] args) {
            	// 创建学生对象 
                Student stu = new Student();
                // 获得学生类的Class对象 
                Class c = stu.getClass();
                // 打印输出:class com.dfbz.reflect.Student 
                System.out.println(c);
            }
        }

方式3:通过Class.forName(“全限定类名”)方法获取

public class Demo01 {
            public static void main(String[] args) throws Exception {
                // 获得字符串的Class对象 
                Class c = Class.forName("java.lang.String");
                // 打印输出:class java.lang.String 
                System.out.println(c);
            }
        }

知道怎么获取Class对象之后,接下来就介绍几个Class类中常用的方法了。
Class对象相关方法

  1. String getSimpleName() : 获得简单类名,只是类名,没有包
    . String getName() : 获取完整类名,包含包名+类名
  2. T newInstance() :创建此 Class 对象所表示的类的一个新实例。要求:类必须有public的无参数构造方法

获取简单类名

public class Demo02 {
            public static void main(String[] args) throws Exception {
                // 获得字符串的Class对象 
                Class c = Class.forName("java.lang.String");
                // 获得简单类名 
                String name = c.getSimpleName();
                // 打印输入:name = String 
                System.out.println("name = " + name);
            }
        }

获取完整类名

public class Demo02 {
            public static void main(String[] args) throws Exception {
                // 获得字符串的Class对象 
                Class c = Class.forName("java.lang.String");
                // 获得完整类名(包含包名和类名) 
                String name = c.getName();
                // 打印输入:name = java.lang.String 
                System.out.println("name = " + name);
            }
        }

创建对象

public class Demo02 {
            public static void main(String[] args) throws Exception {
                // 获得字符串的Class对象 
                Class c = Class.forName("java.lang.String");
                // 创建字符串对象 
                String str = (String) c.newInstance();
                // 输出str:空字符串 "" 
                System.out.println(str);
            }
        }

获取Class对象的Constructor信息
一开始在阐述反射概念的时候,我们说到利用反射可以在程序运行过程中对类进行解剖并操作里面的成员。而一般
常操作的成员有构造方法,成员方法,成员变量等等,那么接下来就来看看怎么利用反射来操作这些成员以及操作
这些成员能干什么,先来看看怎么操作构造方法。而要通过反射操作类的构造方法,我们需要先知道一个
Constructor类。
Constructor类概述
Constructor是构造方法类,类中的每一个构造方法都是Constructor的对象,通过Constructor对象可以实例化对
象。
在这里插入图片描述
Class类中与Constructor相关方法

  1. Constructor getConstructor(Class… parameterTypes) 根据参数类型获取构造方法对象,只能获得public修饰的构造方法。 如果不存在对应的构造方法,则会抛出 java.lang.NoSuchMethodException 异常。
  2. Constructor getDeclaredConstructor(Class… parameterTypes) 根据参数类型获取构造方法对象,能获取所有的构造方法,包括private修饰的构造方法。 如果不存在对应的构造方法,则会抛出 java.lang.NoSuchMethodException 异常。
  3. Constructor[ ] getConstructors() 获取所有的public修饰的构造方法
  4. Constructor[ ] getDeclaredConstructors() 获取所有构造方法,包括public、privat、默认、protected修饰的
    Constructor类中常用方法
    1.T newInstance(Object… initargs)
    根据指定参数创建对象。
    2.void setAccessible(true)
    暴力反射,除public修饰的构造方法外,其他构造方法反射都需要暴力反射
    获取Class对象的Method信息
    操作完构造方法之后,就来看看反射怎么操作成员方法了。同样的在操作成员方法之前我们需要学习一个类:
    Method类。
    Method类概述
    Method是方法类,类中的每一个方法都是Method的对象,通过Method对象可以调用方法。
    在这里插入图片描述
    Class类中与Method相关方法
    1、 Method getMethod(“方法名”, 方法的参数类型… 类型) 根据方法名和参数类型获得一个方法对象,只能是获取public修饰的
    2、 Method getDeclaredMethod(“方法名”, 方法的参数类型… 类型) 根据方法名和参数类型获得一个方法对象,包括private修饰的
    3、 Method[ ] getMethods() 获取所有的public修饰的成员方法,包括父类中。
    4、 Method[ ] getDeclaredMethods() 获取当前类中所有的方法,包含私有的,不包括父类中。
    Method类中常用方法
    1.Object invoke(Object obj, Object… args)
    根据参数args调用对象obj的该成员方法
    如果obj=null,则表示该方法是静态方法
    2.void setAccessible(boolean flag) 暴力反射,设置为可以直接调用私有修饰的成员方法
    获取Class对象的Field信息
    Field类概述
    Field是属性类,类中的每一个属性(成员变量)都是Field的对象,通过Field对象可以给对应的成员变量赋值和取
    值。
    在这里插入图片描述
    Class类中与Field相关方法
    1、Field getDeclaredField(String name)
    根据属性名获得属性对象,包括private修饰的
    2、 Field getField(String name)
    根据属性名获得属性对象,只能获取public修饰的
    3、 Field[ ] getFields()
    获取所有的public修饰的属性对象,返回数组。
    4、Field[ ] getDeclaredFields()
    获取所有的属性对象,包括private修饰的,返回数组。
	void set(Object obj, Object value)
    void setInt(Object obj, int i)
    void setLong(Object obj, long l)
    void setBoolean(Object obj, boolean z)
    void setDouble(Object obj, double d)
    
    Object get(Object obj)
    int getInt(Object obj)
    long getLong(Object obj)
    boolean getBoolean(Object ob)
    double getDouble(Object obj)

	void setAccessible(true);暴力反射,设置为可以直接访问私有类型的属性。
	Class getType(); 获取属性的类型,返回Class对象。

setXxx方法都是给对象obj的属性设置使用,针对不同的类型选取不同的方法。
getXxx方法是获取对象obj对应的属性值的,针对不同的类型选取不同的方法。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值