java 反射

java 反射

http://www.imooc.com/learn/199

Class类的使用

  1. 类也是对象,是Class类的实例对象。
  2. 通过 类.class,可以获得该类的类类型 //相当于每一个类都有一个静态变量class
  3. 通过 类对象.getClass() 可以获得该类的类类型。
  4. 通过 Class.forname(“类”) 可以获得该类的类类型

动态加载类

  1. 静态加载类,是编译时刻加载;动态加载类,是运行时刻加载
  2. new创建对象:是静态加载类,在编译时刻就需要加载所有的【可能使用到的类】。有一个类有问题(如不存在),都不能通过编译,会报错。
  3. Class.forName()通过动态加载类,可以用到一个类时,才进行加载。
    【功能性的类尽量使用动态加载,并对新添的类实现功能性接口(标准),这样就不用重新编译】

获取方法信息

基本数据类型,void关键字都存在类类型

class.getMethods()方法获取是该类的所有public方法,包括从父类继承的方法;
class.getDeclareMethods()方法获取该类自行声明的所有方法,不论访问权限;
method.getName()获取方法名
method.getReturnType()获取方法的返回值
method.getParameterTypes(),获取方法的参数类型的类类型数组class[]

基本的数据类型,void关键字等都存在类类型

Class c = 基类.class (int,String,double,void等)

Class类的基本API操作的

  1. c.getName()可以获取类的名称
  2. c.getSimpleName();//不包含包名的类的名称
  3. c.getMethods()获取类的【public方法】集合,【包括继承来的】注意【所有方法都是Method类的对象】
  4. c.getDeclaredMethods()获取的是所有该类【自己声明】的方法,【不问访问权限】

Method类提供了一些操作方法的方法

  1. .getReturnType()得到该方法的返回值类型的类类型(class),如int.class String.class
  2. .getName()得到方法的名称
  3. .getParameterTypes()获得参数列表类型的类类型,如参数为(int,int)则得到(int.class ,int class)

如:

Class c1 = int.class; int的类类型
Class c2 = String.class; String类的类类型 String类字节码
Class c3 = double.class; double这个数据类类型的字节码表示方式
Class c4 = Double.class; Double这个类的类类型字节码表示方式
Class c5 = void.class; 表达了void这个类的类类型

getName为这个类的类类型的具体名称

c1.getName —> int
c2.getName —> java.lang.String 类的全称
c2.getSimpleName —> String 不包含包名的类的名称

获取成员变量构造函数信息

构造函数也是对象
java.lang. Constructor中封装了构造函数的信息
getConstructors获取所有的public的构造函数
getDeclaredConstructors得到所有自己声明的构造函数

方法反射的基本操作

获取A类中的print(int,int)方法:

  1. 要获取一个方法就是获取类的信息,获取类的信息首先要获取类的类类型

A a1=new A(); Class c= a1.getClass();

  1. 获取方法 由名称和参数列表来决定,getMethod获取的是public方法,getDelcaredMethod获取自己声明的方法

Method m =c.getMethod(methodName,paramtypes);//paramtypes可以用数组的形式表示new Class[]{int.class,int.class},也可以直接列举类类型

方法的反射操作

用m对象来进行方法调用,和a1.print(10,20)调用的方法相同m.invoke(a1,new Object[]{10,20})

Object o=m.invoke(对象名,参数);//方法如果没有返回值返回null,如果有返回值返回具体值,参数可用数组的方式表示,也可以直接列举,没有参数就不写

获取方法和调用反射操作必须一致

通过反射了解集合泛型的本质:

  • 反射的操作都是编译之后的操作;就是运行阶段
  • java中集合的泛型是防止错误输入的;只在编译阶段有效,只要绕过编译就无效啦,在运行期间字节码是去泛型化的。
    我们可以通过方法的反射来操作,绕过编译
    eg:
ArrayList list1=new ArrayList();
ArrayList<String> list2=new ArrayList<String>();
Class c1=list1.getClass();
Class c2=list2.getClass();
System.out.print(c1==c2);//true
Method m=c2.getMethod("add",Object.class);
m.invoke(list2,20);//向list2集合中添加一个int 型的值;绕过编译

当然是不能直接foreach list2集合的,会报类型转换错误

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值