如何给ArrayList<Integer>对象里面添加字符串?

来源:互联网 发布:淘宝快递模板下载 编辑:程序博客网 时间:2024/06/05 19:12

编写java文件如下:

package org.danni.reflect_1;import java.util.ArrayList;public class ArrayListDemo {    public static void main(String[] args) {        //创建集合对象        ArrayList<Integer> array = new ArrayList<Integer>();        array.add(10);        System.out.println(array);    }}

使用xJad反编译文件打开编译后的class文件,我们可以发现内容变成下面这样的了
对应的class字节码文件如下:

// Decompiled by Jad v1.5.8e2. Copyright 2001 Pavel Kouznetsov.// Jad home page: http://kpdus.tripod.com/jad.html// Decompiler options: packimports(3) fieldsfirst ansi space // Source File Name:   ArrayListDemo.javapackage org.danni.reflect_1;import java.util.ArrayList;public class ArrayListDemo{    public ArrayListDemo()    {    }    public static void main(String args[])    {        ArrayList array = new ArrayList();        array.add(Integer.valueOf(10));        System.out.println(array);    }}

我们可以发现在Class文件中,在add方法内进行了强制类型转换。而ArrayList中的泛型却不见了。可见这个泛型只是给编译器看的。
现在我们再看一下add()方法的源码:add方法中传递的必须是E类型,也就是此处的Integer类型

 public boolean add(E e) {    ensureCapacity(size + 1);  // Increments modCount!!    elementData[size++] = e;    return true;}

因此我们可以想到要想在一个ArrayList对象中插入字符串,只要获得他的class字节码文件就可以了,因为在字节码文件中是在add方法内进行了强制类型转换,所以我们传递任何类型的参数都是可以的。
要获得class字节码文件,我们自然而然也就想到了要使用反射,以为这个题目的解决答案就如下所示:

public class ArrayListDemo {    public static void main(String[] args) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {        //创建集合对象        ArrayList<Integer> array = new ArrayList<Integer>();        //获得array对象的字节码对象,返回的结果是个Class对象        Class c = array.getClass();        //参数解释:(方法名,参数类型的class)        //add(E e) :因此参数是个泛型E,也就是Object类型        Method m = c.getMethod("add", Object.class);        m.invoke(array, "添加的字符串是我");        //调用array的add方法,并传入值        m.invoke(array, "再添加一个字符串呀");        System.out.println(array);    }}

输出:

[添加的字符串是我, 再添加一个字符串呀]