JAVA reflect

JAVA reflect


看了视频,老师讲的很细,写点note, 自己的理解,可能有误.仅供自己参考.

Class类的使用:

  1. 在面向对象的世界里,万物都是对象.
    在java语言中,静态成员和普通的数据类型不是面向对象.但普通数据对象有封装,例如integer
    任何类是java.lang.class类的事例对象.这个实例对象有三种表示方法.
    Foo foo1 = new Foo();
    /*foo1 是 Foo的实例化对象表示,而Foo又是Java.Lang.Class的实例化对象,我们称之为类类型,也就是说任何类都是lang.Class的实例化对象,而Class是不允许new Class()的, 这个实例化对象有三种表示方法*/
    Class c1 = Foo.class //知道类名
    Class c2 = foo1.getClass()//知道类的实例化对象
    Class c3 = Class.forName("类的全称");// 知道类的全称

    //c1 == c2 == c3,类类型
    //我们可以通过类的类类型创建该类的对象实例
    Foo foo = c1.newInstance(); //就能得到这个类对象, 需要无参的构造方法

2. Class.forName("类的全称"),不仅代表了类的类类型,类(java.lang.class)的类类型(c1),还代表了动态加载类。
2.1 编译是静态加载类,运行时刻是动态加载类。
2.2 new 对象是静态加载类,在编译时刻就需要加载所有可能使用到的类

3. 

方法的反射

Method[] methods = c1.getMethods(); //public 和从父类获得的方法
Method[] methods = c2.getDeclaredMethods();//该类所声明的所有方法

然后根据方法获得方法的方法名,返回值类型,参数类型信息等
得到方法名: String methodName = methods[i].getName();
得到返回值类类型: Class returnType = methods[i].getReturnType();
返回值类型: returnType.getName();
得到参数的类类型: Class[] params = methods[i].getParameterTypes();
参数类型: params[i].getName();


成员变量的操作

Field[] fields = c.getFields(); //public
Field[] fields = c.getDeclaredFields() //该类所有的成员变量
然后获得该成员变量的类类型,类名字,成员变量的名字,
类类型:Class fieldType = fields[i].getType();
类名字:String typeName = fieldType.getName();
变量名字:String fieldName = fields[i].getName

构造函数

Class c = Class.forName(“完整的类名”);
Constructor[] cs = c.getConstructors();
Constructor[] cs = c.getDeclaredConstructors();//获取该类的构造函数
构造函数参数类类型:Class[] paramTypes = cs[i].getParameterTypes();
构造函数参数类型: paramTypes[i].getName()

方法的反射操作

先获得method,需要拿到类类型,方法名,方法参数
Class c1 = a.getClass();
Method method = c1.getMethod(“方法名”, 方法参数类型);
最后方法的反射操作
method.invoke(a, 2, 5);
如果没有返回值,返回null, 有返回值,则返回得到的值

泛型的本质

ArrayList<String> list1 = new ArrayList<String>();
ArrayList<Integer> list2 = new ArrayList<Integer>();
list1.add("zhangsan");
List2.add(10);
Class c1 = list1.getClass();
Class c2 = list2.getClass();

c1==c2 //true 由结果可以知道反射的操作都是编译之后的操作。
        // 编译之后的集合泛型是去泛型的(不存在泛型的这样一说法)。
        //编译之前只是为了防止错误输入。

java 中的集合泛型只是为了防止错误输入,只在编译阶段有效。
反射的操作都是编译之后的操作。
如果要进行验证,可以绕过编译操作,也就可以绕过了泛型
也就是用泛型的method.invoke()方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值