反射笔记

一、Class类

(1)类是对象,类是java.lang.Class的实例对象
(2)数据类型不是对象,静态的东西也不是对象
(3)Class类的对象表示:如 Class A{}

//A类的实例对象如何表示
    A a = new A(); //a就表示A类的实例对象
//任何一个类都是Class类的实例对象,有三种表示形式
//第一种→实际在告诉我们任何一个类都有一个隐含的静态成员变量class
    Class a_one = A.class;
//第二种→已经知道该类的对象,通过getClass方法
    Class a_two = a.getClass();
//a_onea_two 都表示了A类的类类型
//第三种
    Class a_tri = null;
    a_tri = Class.forName("com.demo.A");//会抛出ClassNotFound异常
//可以通过类的类类型创建该类的对象实例
    A a = (A)a_one.newInstance();//需要有无参构造方法(会抛出ClassNotFound异常)

二、动态加载类

Class.forName(“包名+类的名称”);
(1)不仅表示了类的类类型,还代表了动态加载类
(2)编译时刻加载类是静态加载类,运行时刻加载类是动态加载类
//new 创建的对象是静态加载类,在编译时刻就需要加载所有可能用到的类
//Class.forName()是动态加载类,在运行时刻加载,并可通过类类型的newInstance方法创建该类的对象

三、获取方法信息

(1)数据类型也有类类型

    Class i_c = int.class;//int的类类型
    Class s_c = String.class;//String的类类型

    System.out.pringln(i_c.getName());//输出结果→int
    System.out.pringln(s_c.getName());//输出结果→java.lang.String
    System.out.pringln(s_c.getSimpleName())//输出结果→String(不包含包名的类名称)

(2)获取类的信息

public static void getClassMsg(Object obj){
    //先获取类的类类型
    Class c = obj.getClass();//传递的是哪个子类,c就是哪个子类的类类型
    //获取类的名称
    c.getName();
    /**
    *Method类,方法对象
    *一个成员方法就是一个Method对象
    *getMethods()获取的是所有public的函数,包括父类
    *getDeclaredMethods()获取的是所有该类自己声明的方法,不需要访问权限
    */
    Method[] ms = c.getMethods();
    for(Method m : ms){
        //得到方法的返回值类型
        Class returnType = m.getReturnType();
        //得到方法名
        m.getName();
        //参数类型
        Class[] params = m.getParamterTypes();
    }
}

四、获取成员变量的构造函数

/*
*成员变量也是对象
*java.lang.reflect.Field
*Field类封装了关于成员变量的操作
*getFields()获取所有的public的成员变量信息
*getDeclaredFields()获取该类自己声明的成员变量信息
*/
Field[] fs = c.getDeclaredFields();
for(Field f : fs){
    //得到成员变量的类型的类类型
    Class fieldType = f.getType();
    //类型名称
    fieldType.getName();
    //变量名称
    f.getName();
}

//构造函数也是对象,java.lang.Constructor中封装了构造函数的信息
Constructor[] cs = c.getDeclaredConstructor();
for(Constructor c : cs){
    //得到参数列表类类型
    c.getParameterType();
}

五、方法的反射操作

(1)定义一个A类,并声明方法print()

Class A{
    public void print(int a,int b){}
    public void print(){}
}

(2)反射操作代码举例

//先获取类的类类型
A a = new A();
Class c = a.getClass();
//获取print(int,int)方法
//Method m = c.getMethod("print",new Class[]{int.class,int.class});
Method m = c.getMethod("print",int.class,int.class);
//方法反射操作,有返回值就返回具体值,没有就返回null
//Object o = m.invoke(a,new Object[]{10,20});
Object o = m.invoke(a,10,20);
//获取print()方法
//Method m2 = c.getMethod("print",new Class[]{});
Method m2 = c.getMethod("print");
//m2.invoke(a,new Object[]{});
m2.invoke(a);

六、拓展

Java中的泛型,是防止错误输入的,只有编译阶段有效,绕过编译就无效了

//可以通过方法的反射来操作,绕过编译
ArrayList<String> list = new ArrayList<String>();
Class c = list.getClass();
Method m = c.getMethod("add",Object.class);
m.invoke(list,100);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值