Java框架基础——反射(reflect)

一、Class类的使用

1)在面向对象(oop)的世界里,万事万物皆对象。
  在Java中,包括基本的数据类型,都是对象。
  Class c = int.class;//int 的类类型
  那就是说:
  类是对象,类是java.lang.Class类的实例对象。这个对象我们称之为类类型。
  换言之,每一个类都有一个类类型,这个类类型就是java.lang.Class的实例对象
2)如何获取一个类的类类型(三种方法)

  • 类名.class;
  • 类的对象.getClass();
  • Class.forName(“类的全称包含包名”);

  class Foo{}
  Foo foo1=new Foo();
  1. Class c1 = Foo.Class;//任何一个类都有一个隐含的静态成员变量class
  2. Class c2 = foo1.getClass()//已经知道该类的对象通过getClassF方法
  3. Class c3 = null;
  c3 = Class.forName("com.immoc.reflect.Foo");
  //of course, c1 == c2 == c3 is true
3)利用类类型来创造实例对象(需要有无参数的构造方法)(需要有强制类型转化,且有异常抛出)
  Foo foo2 = (Foo)(c1.newInstance());
  Foo foo3 = (Foo)(c2.newInstance());
  Foo foo4 = (Foo)(c3.newInstance());

 1 package com.study.reflect;
 2 
 3 /**
 4  * @description  6  * @date 2016-3-28 下午4:06:29 
 7  */
 8 public class ClassDemo1 {
 9 
10     public static void main(String[] args){
11         //Foo的实例对象如何表示?
12         Foo foo1=new Foo();//foo1就表示Foo的实例对象
13         //Foo这个类也是一个实例对象,它是Class类的对象,那Class类的实例对象,如何表示呢?
14         //任何一个类都是Class的实例对象,但是不能通过new关键字来创建。这个实例对象有三种表示方式:
15         
16         //第一种表示方式---->实际是在告诉我们任何一个类都有一个隐含的静态成员变量class
17         Class c1=Foo.class;//如果Foo已经存在,可以用这种方法来创建Foo的类类型(class type),即Foo类的类类型就是Class类的一个实例对象。
18         
19         //第二种方式-->已知该类的对象,通过getClass方法
20         Class c2=foo1.getClass();//如果Foo类的对象foo1已经存在,可以通过这种方法来创建Foo类的类类型。
21         
22         /**
23          * 上面官网说c1,c2 是表示了Foo类的类类型(class type)---->指的就是Class的对象
24          * 类类型,即万事万物皆对象,
25          * 类也是一个对象,是Class类的实例对象
26          * 这个对象我们把它称为该类的类类型
27          */
28         
29         //不管c1 or c2,他们都代表了Foo类的类类型,一个类只可能是Class类的一个实例对象
30         System.out.println(c1==c2);//true
31         
32         //第三种表示:
33         Class c3=null;
34         try {
35             c3=Class.forName("com.study.reflect.Foo");//通过Foo的全称来创建
36         } catch (ClassNotFoundException e) {
37             e.printStackTrace();
38         }
39         System.out.println(c2==c3);//true
40         
41         //我们完全可以通过类的类类型创建该类的对象实例-->通过c1 or c2 or c3 创建Foo的实例
42         try {
43             //如果c1是A类的类类型,创建的就是A类的实例对象,所以需要做强制类型转换,也会有异常
44             Foo foo = (Foo) c1.newInstance();//这个前提要求是需要有无参数的构造方法
45             foo.print();
46         } catch (InstantiationException e) {
47             e.printStackTrace();
48         } catch (IllegalAccessException e) {
49             e.printStackTrace();
50         }
51     }
52     
53 }
54 class Foo{
55     void print(){
56     }
57 }

二、动态加载类

首先区分什么是动态加载和静态加载。

也就是区分编译和运行。

  • new 创建对象,是静态加载类,在编译时刻就需要加载所有可能使用到的类
  • 通过动态加载类可以解决该问题。通过类类型创建该类的对象

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

比如:

//new 创建对象是静态加载类,在编译时刻就需要加载所有的可能使用到的类。eg:word excel
//通过动态加载类可以解决该问题
//动态加载类,在运行时刻加载
Class c=Class.forName(args[0]);
//通过类类型,创建该类对象
OfficeAble oa=(OfficeAble)c.newInstance();//word 和excel都想加载就用一个标准oa
oa.start();
—————————————————————————————————
//编写一个标准接口
interface OfficeAble
{
public void start();
}
—————————————————————————————————
//让word 和excel继承oa
class Excel implements OfficeAble
{
    public void start(){
}
}

动态加载的好处(设计思想):
扩展性,主程序不需要修改,不需要重新编译,只要新功能实现了相同的接口,启动的时候换个新的参数就可以。

三、获取方法信息

public class ClassDemo2 {
    public static void main(String[] args) {
        /**
         * 基本数据类型、void关键字都存在类类型
         */
        Class c1=int.class;//基本数据类型int的类类型
        Class c2=String.class;//String类的类类型(可以理解为String类的字节码,如:编译生成的xx.class文件即xx的字节码文件)
        Class c3=double.class;//double这个数据类型的类类型
        Class c4=Double.class;//Double这个类的类类型
        Class c5=void.class;//在类里面声明的,比如void,也是有类类型
        
        //获取类的全称getName()
        System.out.println(c1.getName());//输出:int
        System.out.println(c2.getName());//输出:java.lang.String
        //获取不包含包名的类的全称
        System.out.println(c2.getSimpleName());//输出:String
        
    }
}

Class类的基本API操作

获取类的全部信息,包括类的成员函数、成员变量

 1 public class ClassUtil {
 2 
 3     /**
 4      * 
 5      * @description 打印类的信息,包括类的成员函数、成员变量
 6      * @date 2016-3-28 下午5:12:42 
 7      * @param @param obj 该对象所属类的信息
 8      * @return void
 9      */
10     public static void printClassMessage(Object obj){
11         //要获取类的信息,首先要获取类的类类型
12         Class c = obj.getClass();//传递的是哪个子类的对象,c就是该子类的类类型
13         //获取类的名称
14         System.out.println("类的名称是:"+c.getName());
15         //在Java中,方法是Method类的对象
16         /**
17          * Method类,是方法的对象
18          * 一个成员方法就是一个Method的对象
19          * Method类中封装了对方法的操作
20          * getMethods()方法获取的是所有public的函数,包括父类继承而来的
21          * getDeclaredMethods()获取的是所有该类自己声明的方法,不问访问权限
22          */
23         Method[] methods = c.getMethods();
24         Method[] declaredMethods = c.getDeclaredMethods();
25         for(int i=0;i<methods.length;i++){
26             //得到方法的名称
27             System.out.print(methods[i].getName()+"(");
28             //获得参数类型--->得到的参数列表的类型的类类型
29             Class[] parameterTypes = methods[i].getParameterTypes();
30             for(Class class1 : parameterTypes){
31                 System.out.print(class1.getName()+",");
32             }
33             System.out.print(")");
34             //得到方法的返回值类型的类类型
35             Class returnType = methods[i].getReturnType();//如果方法返回得到的是int,那结果就是int.class
36             System.out.println("方法的返回值类型名称:"+returnType.getName());//这个得到的就是名称int
37         }
38     }
39 }

测试类:

 1 public class ClassDemo3 {
 2     public static void main(String[] args) {
 3         String s="Hello";
 4         ClassUtil.printClassMessage(s);
 5         
 6         System.out.println("=================================");
 7         Integer i=1;
 8         ClassUtil.printClassMessage(i);
 9     }
10 }

 运行结果:

  1 类的名称是:java.lang.String
  2 hashCode()方法的返回值类型名称:int
  3 compareTo(java.lang.Object,)方法的返回值类型名称:int
  4 compareTo(java.lang.String,)方法的返回值类型名称:int
  5 indexOf(java.lang.String,int,)方法的返回值类型名称:int
  6 indexOf(java.lang.String,)方法的返回值类型名称:int
  7 indexOf(int,)方法的返回值类型名称:int
  8 indexOf(int,int,)方法的返回值类型名称:int
  9 equals(java.lang.Object,)方法的返回值类型名称:boolean
 10 toString()方法的返回值类型名称:java.lang.String
 11 charAt(int,)方法的返回值类型名称:char
 12 codePointAt(int,)方法的返回值类型名称:int
 13 codePointBefore(int,)方法的返回值类型名称:int
 14 codePointCount(int,int,)方法的返回值类型名称:int
 15 compareToIgnoreCase(java.lang.String,)方法的返回值类型名称:int
 16 concat(java.lang.String,)方法的返回值类型名称:java.lang.String
 17 contains(java.lang.CharSequence,)方法的返回值类型名称:boolean
 18 contentEquals(java.lang.StringBuffer,)方法的返回值类型名称:boolean
 19 contentEquals(java.lang.CharSequence,)方法的返回值类型名称:boolean
 20 copyValueOf([C,int,int,)方法的返回值类型名称:java.lang.String
 21 copyValueOf([C,)方法的返回值类型名称:java.lang.String
 22 endsWith(java.lang.String,)方法的返回值类型名称:boolean
 23 equalsIgnoreCase(java.lang.String,)方法的返回值类型名称:boolean
 24 format(java.lang.String,[Ljava.lang.Object;,)方法的返回值类型名称:java.lang.String
 25 format(java.util.Locale,java.lang.String,[Ljava.lang.Object;,)方法的返回值类型名称:java.lang.String
 26 getBytes(java.nio.charset.Charset,)方法的返回值类型名称:[B
 27 getBytes()方法的返回值类型名称:[B
 28 getBytes(java.lang.String,)方法的返回值类型名称:[B
 29 getBytes(int,int,[B,int,)方法的返回值类型名称:void
 30 getChars(int,int,[C,int,)方法的返回值类型名称:void
 31 intern()方法的返回值类型名称:java.lang.String
 32 isEmpty()方法的返回值类型名称:boolean
 33 lastIndexOf(java.lang.String,)方法的返回值类型名称:int
 34 lastIndexOf(int,)方法的返回值类型名称:int
 35 lastIndexOf(int,int,)方法的返回值类型名称:int
 36 lastIndexOf(java.lang.String,int,)方法的返回值类型名称:int
 37 length()方法的返回值类型名称:int
 38 matches(java.lang.String,)方法的返回值类型名称:boolean
 39 offsetByCodePoints(int,int,)方法的返回值类型名称:int
 40 regionMatches(int,java.lang.String,int,int,)方法的返回值类型名称:boolean
 41 regionMatches(boolean,int,java.lang.String,int,int,)方法的返回值类型名称:boolean
 42 replace(char,char,)方法的返回值类型名称:java.lang.String
 43 replace(java.lang.CharSequence,java.lang.CharSequence,)方法的返回值类型名称:java.lang.String
 44 replaceAll(java.lang.String,java.lang.String,)方法的返回值类型名称:java.lang.String
 45 replaceFirst(java.lang.String,java.lang.String,)方法的返回值类型名称:java.lang.String
 46 split(java.lang.String,int,)方法的返回值类型名称:[Ljava.lang.String;
 47 split(java.lang.String,)方法的返回值类型名称:[Ljava.lang.String;
 48 startsWith(java.lang.String,int,)方法的返回值类型名称:boolean
 49 startsWith(java.lang.String,)方法的返回值类型名称:boolean
 50 subSequence(int,int,)方法的返回值类型名称:java.lang.CharSequence
 51 substring(int,)方法的返回值类型名称:java.lang.String
 52 substring(int,int,)方法的返回值类型名称:java.lang.String
 53 toCharArray()方法的返回值类型名称:[C
 54 toLowerCase()方法的返回值类型名称:java.lang.String
 55 toLowerCase(java.util.Locale,)方法的返回值类型名称:java.lang.String
 56 toUpperCase()方法的返回值类型名称:java.lang.String
 57 toUpperCase(java.util.Locale,)方法的返回值类型名称:java.lang.String
 58 trim()方法的返回值类型名称:java.lang.String
 59 valueOf([C,)方法的返回值类型名称:java.lang.String
 60 valueOf(int,)方法的返回值类型名称:java.lang.String
 61 valueOf(long,)方法的返回值类型名称:java.lang.String
 62 valueOf(float,)方法的返回值类型名称:java.lang.String
 63 valueOf(double,)方法的返回值类型名称:java.lang.String
 64 valueOf(java.lang.Object,)方法的返回值类型名称:java.lang.String
 65 valueOf(char,)方法的返回值类型名称:java.lang.String
 66 valueOf([C,int,int,)方法的返回值类型名称:java.lang.String
 67 valueOf(boolean,)方法的返回值类型名称:java.lang.String
 68 wait()方法的返回值类型名称:void
 69 wait(long,int,)方法的返回值类型名称:void
 70 wait(long,)方法的返回值类型名称:void
 71 getClass()方法的返回值类型名称:java.lang.Class
 72 notify()方法的返回值类型名称:void
 73 notifyAll()方法的返回值类型名称:void
 74 =================================
 75 类的名称是:java.lang.Integer
 76 hashCode()方法的返回值类型名称:int
 77 reverseBytes(int,)方法的返回值类型名称:int
 78 compareTo(java.lang.Object,)方法的返回值类型名称:int
 79 compareTo(java.lang.Integer,)方法的返回值类型名称:int
 80 equals(java.lang.Object,)方法的返回值类型名称:boolean
 81 toString(int,int,)方法的返回值类型名称:java.lang.String
 82 toString(int,)方法的返回值类型名称:java.lang.String
 83 toString()方法的返回值类型名称:java.lang.String
 84 toHexString(int,)方法的返回值类型名称:java.lang.String
 85 decode(java.lang.String,)方法的返回值类型名称:java.lang.Integer
 86 valueOf(java.lang.String,)方法的返回值类型名称:java.lang.Integer
 87 valueOf(java.lang.String,int,)方法的返回值类型名称:java.lang.Integer
 88 valueOf(int,)方法的返回值类型名称:java.lang.Integer
 89 reverse(int,)方法的返回值类型名称:int
 90 byteValue()方法的返回值类型名称:byte
 91 doubleValue()方法的返回值类型名称:double
 92 floatValue()方法的返回值类型名称:float
 93 intValue()方法的返回值类型名称:int
 94 longValue()方法的返回值类型名称:long
 95 shortValue()方法的返回值类型名称:short
 96 parseInt(java.lang.String,)方法的返回值类型名称:int
 97 parseInt(java.lang.String,int,)方法的返回值类型名称:int
 98 bitCount(int,)方法的返回值类型名称:int
 99 getInteger(java.lang.String,)方法的返回值类型名称:java.lang.Integer
100 getInteger(java.lang.String,int,)方法的返回值类型名称:java.lang.Integer
101 getInteger(java.lang.String,java.lang.Integer,)方法的返回值类型名称:java.lang.Integer
102 highestOneBit(int,)方法的返回值类型名称:int
103 lowestOneBit(int,)方法的返回值类型名称:int
104 numberOfLeadingZeros(int,)方法的返回值类型名称:int
105 numberOfTrailingZeros(int,)方法的返回值类型名称:int
106 rotateLeft(int,int,)方法的返回值类型名称:int
107 rotateRight(int,int,)方法的返回值类型名称:int
108 signum(int,)方法的返回值类型名称:int
109 toBinaryString(int,)方法的返回值类型名称:java.lang.String
110 toOctalString(int,)方法的返回值类型名称:java.lang.String
111 wait()方法的返回值类型名称:void
112 wait(long,int,)方法的返回值类型名称:void
113 wait(long,)方法的返回值类型名称:void
114 getClass()方法的返回值类型名称:java.lang.Class
115 notify()方法的返回值类型名称:void
116 notifyAll()方法的返回值类型名称:void
View Code

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

 1 public class ClassUtil {
 2 
 3     /**
 4      * 
 5      * @description 打印类的成员函数的信息
 6      * @date 2016-3-28 下午5:12:42 
 7      * @param @param obj 该对象所属类的信息
 8      * @return void
 9      */
10     public static void printClassMethodMessage(Object obj){
11         //要获取类的信息,首先要获取类的类类型
12         Class c = obj.getClass();//传递的是哪个子类的对象,c就是该子类的类类型
13         //获取类的名称
14         System.out.println("类的名称是:"+c.getName());
15         //在Java中,方法是Method类的对象
16         /**
17          * Method类,是方法的对象
18          * 一个成员方法就是一个Method的对象
19          * Method类中封装了对方法的操作
20          * getMethods()方法获取的是所有public的函数,包括父类继承而来的
21          * getDeclaredMethods()获取的是所有该类自己声明的方法,不问访问权限
22          */
23         Method[] methods = c.getMethods();
24         Method[] declaredMethods = c.getDeclaredMethods();
25         for(int i=0;i<methods.length;i++){
26             //得到方法的名称
27             System.out.print(methods[i].getName()+"(");
28             //获得参数类型--->得到的参数列表的类型的类类型
29             Class[] parameterTypes = methods[i].getParameterTypes();
30             for(Class class1 : parameterTypes){
31                 System.out.print(class1.getName()+",");
32             }
33             System.out.print(")");
34             //得到方法的返回值类型的类类型
35             Class returnType = methods[i].getReturnType();//如果方法返回得到的是int,那结果就是int.class
36             System.out.println("方法的返回值类型名称:"+returnType.getName());//这个得到的就是名称int
37         }
38     }
39 
40     /**
41      * @description 打印类的成员变量的信息
42      * @date 2016-3-29 上午9:32:58 
43      * @param @param obj 该对象所属类的信息
44      * @return void
45      */
46     public static void printClassFieldMessage(Object obj) {
47         //要获取类的信息,首先要获取类的类类型
48         Class c = obj.getClass();//传递的是哪个子类的对象,c就是该子类的类类型
49         /**
50          * 成员变量也是对象
51          * 它是java.lang.reflect.Field的对象
52          * Field类封装了关于成员变量的操作
53          * getFields()方法获取的是所有的public的成员变量的信息
54          * getDeclaredFields()方法获取的是该类自己声明的成员变量信息,不问访问权限
55          */
56         Field[] fields = c.getFields();//public的成员变量用的比较少
57         Field[] declaredFields = c.getDeclaredFields();
58         for(Field field:declaredFields){
59             //得到成员变量的类型的类类型
60             Class fieldType = field.getType();
61             String typeName = field.getName();
62             //得到成员变量的名称
63             String fieldName = field.getName();
64             System.out.println(typeName+" "+fieldName);
65         }
66     }
67     
68     /**
69      * 
70      * @description 打印对象的构造函数信息
71      * @date 2016-3-29 上午9:39:50 
72      * @param @param obj 该对象所属类的信息
73      * @return void
74      */
75     public static void printClassConstructorMessage(Object obj){
76         //要获取类的信息,首先要获取类的类类型
77         Class c = obj.getClass();//传递的是哪个子类的对象,c就是该子类的类类型
78         /**
79          * 构造函数也是对象
80          * 它是java.lang.reflect.Constructor的对象
81          * Constructor类中封装了构造函数的信息
82          * getConstructors()获取所有public的构造函数
83          * getDeclaredConstructors()获取的是该类自己声明的所有的构造函数
84          * 构造方法是没有返回值类型的
85          */
86         Constructor[] constructors = c.getConstructors();
87         Constructor[] declaredConstructors = c.getDeclaredConstructors();
88         for (Constructor constructor : declaredConstructors) {
89             System.out.print(constructor.getName()+"(");
90             //获取构造函数的参数列表--->得到的是参数列表的类类型
91             Class[] parameterTypes = constructor.getParameterTypes();
92             for (Class class1 : parameterTypes) {
93                 System.out.print(class1.getName()+",");
94             }
95             System.out.println(")");
96         }
97     }
98 }

测试类:

 1 /**
 2  * @description 测试ClassUtil类的操作
 3  * @date 2016-3-28 下午5:34:47 
 4  */
 5 public class ClassDemo3 {
 6     public static void main(String[] args) {
 7         System.out.println("=========获取类的成员函数的信息========================");
 8         //测试获取类的成员方法的信息
 9         String s="Hello";
10         ClassUtil.printClassMethodMessage(s);
11         
12         Integer i=1;
13         ClassUtil.printClassMethodMessage(i);
14         
15         System.out.println("=========获取类的成员变量的信息========================");
16         //测试获取类的成员变量的信息
17         Integer i1=1;
18         ClassUtil.printClassFieldMessage(i);
19         
20         System.out.println("=========获取类的构造函数的信息========================");
21         ClassUtil.printClassConstructorMessage("Hello");
22         ClassUtil.printClassConstructorMessage(new Integer(1));
23     }
24 }

注意:要获取类的信息,首先要获取类的类类型。obj.getClass()  

五、方法的反射

1、如何获取某个方法

方法的名称和方法的参数列表才能唯一决定某个方法

2、方法反射的操作

method.invoke(对象,参数列表)

 1 public class MethodDemo1 {
 2     public static void main(String[] args) {
 3         /**思考:如何获得方法对象,然后用方法对象进行反射操作
 4          * 1、要获取一个方法首先要获取类的信息,获取类的信息首先要获取类的类类型
 5          * 2、获取方法必须要有名称和参数列表来决定
 6          */
 7         //1、首先要获取类的信息,获取类的信息首先要获取类的类类型
 8         A a1=new A();
 9         Class c = a1.getClass();
10         
11         /*2、获取方法 名称和参数列表来决定
12          * getMethod获取的是public的方法
13          * getDeclaredMethod()获取自己声明的方法
14          */
15         try {
16             //获取print(int,int)方法.
17             System.out.println("=================获取print(int,int)===============");
18             //这个一定会抛出异常,我们这里简单的处理一下异常,原因:万一这个方法(带两个整型参数的方法)不存在呢
19             Method method = c.getMethod("print", new Class[]{int.class,int.class});//这个方法中“...”代表可变参数,当有几个参数的时候,可以new Class数组
20             //也可以这样写:有几个参数就传几个参数
21             Method method2 = c.getMethod("print", int.class,int.class);
22             a1.print(10, 20);//普通调用(可以理解为a1这个对象操作方法对象print)
23             /*方法的反射操作是用method/method2对象来进行方法调用 和a1.print()调用的效果完全相同
24              *方法如果没有返回值,返回null。有返回值就返回具体的返回值如下面的Object o
25              */
26             Object o = method.invoke(a1, new Object[]{10,20});//方法的反射(可以理解为print这个方法对象,即method/method2来操作a1,即上面普通调用反过来操作,通过invoke来进行操作)
27             //也可以这样:
28             Object o1 = method.invoke(a1, 10,20);
29             
30             
31             
32             System.out.println("=================获取print(String,String)===============");
33             //获取方法print(String,String)
34             Method method3 = c.getMethod("print", String.class,String.class);
35             a1.print("hello", "world");//普通调用
36             //对方法进行反射操作
37             Object o2 = method3.invoke(a1, "hello","world");
38             
39             
40             
41             
42             System.out.println("=================获取print()无参方法===============");
43 //            Method method4 = c.getMethod("print", new Class[]{});
44             Method method5 = c.getMethod("print");//没有参数就不传
45 //            method5.invoke(a1, new Object[]{});
46             method5.invoke(a1);
47         }catch (Exception e) {
48             e.printStackTrace();
49         }
50     }
51 }
52 
53 class A{
54     public void print(){
55         System.out.println("hello world");
56     }
57     public void print(int a,int b){
58         System.out.println(a+b);
59     }
60     public void print(String a,String b){
61         System.out.println(a.toUpperCase()+","+b.toUpperCase());
62     }
63 }

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

通过Class、Method来认识集合泛型的本质

 1 public class MethodDemo2 {
 2     public static void main(String[] args) {
 3         ArrayList list=new ArrayList();
 4         
 5         ArrayList<String> list1 = new ArrayList<String>();
 6         list1.add("hello");
 7 //        list1.add(20);//传个整型,就是错误的
 8         
 9         Class c1 = list.getClass();
10         Class c2 = list1.getClass();
11         System.out.println(c1==c2);//true
12         /**
13          * 分析:
14          * Class,我们可以认为是类类型或字节码,因为文件编译之后就生成*.class文件
15          * 也就是说:反射的操作(Class、Method、field的操作)都是编译之后的操作(就是变成字节码之后的操作)就是在运行时刻执行的
16          * 
17          * c1==c2结果返回true说明编译之后集合的泛型是去泛型化的
18          * Java中集合的泛型,是防止错误输入的,只在编译阶段有效,绕过编译就无效了
19          * 验证:我们可以通过方法的反射来操作,绕过编译
20          */    
21         try {
22             Method method = c2.getMethod("add", Object.class);//参数是Object类型,没有任何的泛型类型
23             method.invoke(list1,20);//绕过了编译就绕过了泛型
24             System.out.println(list1.size());//输出size为2,说明整型20加进去list1集合里面了
25             System.out.println(list1);//输出[hello, 20]
26             //不能再用foreach进行遍历了,这时他认为都是String类型,会报异常:java.lang.ClassCastException,会提示说int类型不能转换成String类型
27             /*for (String string : list1) {
28                 System.out.println(string);
29             }*/
30         } catch (Exception e) {
31             e.printStackTrace();
32         } 
33     }
34 }

 

posted @ 2016-03-29 14:55  萌小Q  阅读(1751)  评论(0编辑  收藏  举报