反射笔记

来源:互联网 发布:算法的乐趣 pdf 编辑:程序博客网 时间:2024/06/06 05:54

一、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
原创粉丝点击