反射学习总结

1、Class类

 Class的三种表现形式

 1 public class ClassDemo{
 2 
 3     Fu f = new Fu();
 4     Class c1 = f.class;
 5     Class c2 = f.getClass();
 6     
 7     Class c3 = Class.forName("Fu");
 8 }
 9 
10 class Fu(){
11 
12 }
ClassDemo

2、动态加载类

  编译器加载类成为静态加载类,运行时加载类称为动态加载类。

 静态加载类的实例:

class Office{
    public static void main(String[] args)
    {
        //new 对象是静态加载类,编译时就需要加载所有的类
        if("Word".equals(args[0]))
        {
            Word word = new Word();
            word.start();
        }
        if("Excel".equals(args[0]))
        {
            Excel excel = new Excel();
            excel.start();
        }
    }
}
Static Class

动态加载类的实例:

interface OfficeAble
{
    public void start();
}
OfficeAble
class Word implements OfficeAble
{
    public void start(){
        System.out.println("word start");
    }
}
Word
class Excel implements OfficeAble
{
    public void start(){
        System.out.println("excel start");
    }
}
Excel
class Officebetter{
    public static void main(String[] args){
        try{
            //动态加载类,在运行时刻
            Class c = Class.forName(args[0]);
            //通过类类型创建该类对象
            OfficeAble oa  = (OfficeAble)c.newInstance();
            oa.start();
        }catch(Exception e){
            e.printStackTrace();
        }    
    }
}
Officebetter

 3、获取类的信息

 1 package com.imooc.reflect;
 2 
 3 import java.lang.reflect.Constructor;
 4 import java.lang.reflect.Field;
 5 import java.lang.reflect.Method;
 6 import java.util.Iterator;
 7 
 8 
 9 
10 /**
11  * @author Administrator
12  *
13  */
14 /**
15  * @author Administrator
16  *
17  */
18 public class ClassUtil {
19     /**
20      * 获取类的成员函数信息
21      * @param obj 该对象所属了的信息
22      * */
23     public static void printClassInfo(Object obj){
24         //要获取类的信息,首先要获取类的类类型
25         Class c = obj.getClass();//传递的是哪个子类的对象,c就是该子类的类类型
26         //获取类的名称
27         System.out.println("类的名称是: "+c.getName());
28         /*
29          *     Method类,方法对象
30          *  一个成员方法就是一个Method对象
31          *  getMethods()方法获得的是所有的public的函数,包括继承父类的
32          *  getDeclaredMethods获取的是所有该类自己声明的方法
33          * */
34         Method[] ms = c.getMethods(); //c.getDeclaredMethods();
35         for(int i=0;i<ms.length;i++){
36             
37             //得到返回值类型的类类型
38             Class returnType = ms[i].getReturnType();
39             System.out.print(returnType.getName()+" ");
40             //得到方法的名称
41             System.out.print(ms[i].getName()+"(");
42             //获取参数类型-->得到的是参数列表的类型的类类型
43             Class[] paramTypes = ms[i].getParameterTypes();
44             for(Class cl : paramTypes){
45                 System.out.print(cl.getName()+",");
46             }
47             System.out.println(")");
48         }
49     }
50     /**
51      * 获取类的成员变量的信息
52      * */
53     public static void printFieldInfo(Object obj) {
54         Class c = obj.getClass();
55         /**
56          * 成员变量也是对象
57          * java.lang.reflect.Field
58          * Field封装了关于成员变量的操作
59          * getFields获取的是所有的public成员变量信息
60          * getDeclaredFields获取所有自己声明的成员变量信息
61          * */
62         //Field[] fs = c.getFields();
63         Field[] fs = c.getDeclaredFields();
64         for(Field f : fs)
65         {
66             //得到成员变量的类类型 -->名字
67             Class fieldType = f.getType();
68             String typeName = fieldType.getName();
69             //获得成员变量的名字
70             String fieldName = f.getName();
71             System.out.println(typeName+" : "+fieldName);
72         }
73     }
74     
75     /**
76      * 打印对象的构造函数信息
77      * @param obj
78      */
79     public static void printConstructerInfo(Object obj){
80         Class c = obj.getClass();
81         /*
82          * 构造函数也是对象
83          * java.lang.Construction中封装了构造函数的信息
84          * getConstructors获得所有的public的构造函数
85          * getDeclaredConstructors得到所有的构造函数
86          * */
87 //        Constructor[] cs = c.getConstructors();
88         Constructor[] cs = c.getDeclaredConstructors();
89         for (Constructor constructor : cs) {
90             System.out.print(constructor.getName()+"(");
91             //获取构造函数的参数列表-->参数列表的类类型
92             Class[] paramType = constructor.getParameterTypes();
93             for (Class class1 : paramType) {
94                 System.out.print(class1.getName()+",");
95             }
96             System.out.println(")");
97         }
98     }
99 }
ClassUtil

 4、方法的反射操作

 1 package com.imooc.reflect;
 2 
 3 import java.lang.reflect.InvocationTargetException;
 4 import java.lang.reflect.Method;
 5 
 6 public class MethodDemo1 {
 7     public static void main(String[] args){
 8         //要获取print(int,int)方法
 9         
10          // 1、获取类的类类型
11 
12         A a = new A();
13         Class c = a.getClass();
14         
15         try {
16             /*
17              * 2、获取方法
18              * getMethod(name,parameterType)获取public方法
19              * getDeclaredMethod 自己声明的方法
20              * */
21             //Method m = c.getDeclaredMethod("print", new Class[]{int.class,int.class});
22             Method m = c.getMethod("print", int.class,int.class);
23             Method m1 = c.getMethod("print", String.class,String.class);
24             //a.print(10,20); 反射操作为m对象来进行方法调用
25             //有返回值会返回具体的值
26             Object o = m.invoke(a,new Object[]{10,20});
27         } catch (Exception e) {
28             e.printStackTrace();
29         }
30     }
31 }
32 
33 class A{
34     public void print(int a,int b){
35         System.out.println(a+b);
36     }
37     public void print(String a, String b){
38         System.out.println(a.toUpperCase()+b.toLowerCase());
39     }
40 }
MethodDemo

 5、泛型的本质

 

 1 package com.imooc.reflect;
 2 
 3 import java.lang.reflect.Method;
 4 import java.util.ArrayList;
 5 
 6 public class MethodDemo2 {
 7     public static void main(String[] args) {
 8         ArrayList list = new ArrayList();
 9         
10         ArrayList<String> list1 = new ArrayList<String>();
11         list1.add("hello");
12         //list1.add(20);错误的
13         Class c1 = list.getClass();
14         Class c2 = list1.getClass();
15         System.out.println(c1 == c2);
16         //反射的操作都是编译之后的操作
17         
18         /*
19          * c1==c2结果返回true说明编译之后集合的泛型是去泛型化的
20          * Java中集合的泛型,是防止错误输入的,只在编译阶段有效,
21          * 绕过编译就无效了
22          * 验证:我们可以通过方法的反射来操作,绕过编译
23          */
24         try {
25             Method m = c2.getMethod("add", Object.class);
26             m.invoke(list1, 20);//绕过编译操作就绕过了泛型
27             System.out.println(list1.size());
28             System.out.println(list1);
29             /*for (String string : list1) {
30                 System.out.println(string);
31             }*///现在不能这样遍历
32         } catch (Exception e) {
33           e.printStackTrace();
34         }
35     }
36 
37 }
MethodDemo

 

posted @ 2016-04-12 16:11  不字书  阅读(195)  评论(0编辑  收藏  举报