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

本文通过一个具体的Java示例,展示了如何利用泛型和反射机制实现向指定类型的ArrayList中添加不同类型的元素。通过对编译前后代码的对比,揭示了泛型的实际作用,并通过反射获取并调用对象的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

编写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.java

package 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);
    }
}

输出:

[添加的字符串是我, 再添加一个字符串呀]
在 `ArrayList<Integer> numbers = new ArrayList<>();` 这段代码中,`Integer` 是 Java 中的一个包装类(Wrapper Class),用于将基本数据类型 `int` 封装成对象。 --- ### **1. 什么是 Integer?** `Integer` 是 Java 提供的基本数据类型 `int` 的包装类。它属于引用类型(Reference Type),位于 `java.lang` 包下,默认导入无需额外声明。 通过 `Integer` 类型,可以对 `int` 数字应用面向对象的操作,例如将其储到泛型集合(如 `ArrayList`)中或调用其内置方法。 #### **关键点**: - `Integer` 是不可变的(Immutable),一旦创建就不能更改其值。 - 它还提供了许多实用方法,比如字符串转换、最大最小值操作等。 --- ### **2. 泛型中的 `<Integer>` 意义** 在这段代码中,`<Integer>` 表明这个 `ArrayList` 集合只能放 `Integer` 类型的对象。由于 Java 泛型的在,在编译期就能保证类型的正确性,避免了不同类型之间的错误操作。 --- ### **3. 自动装箱与拆箱** 从 JDK 5 开始,Java 引入了自动装箱(Autoboxing)和拆箱(Unboxing)机制,使得开发者可以在基本数据类型和对应的包装类之间无缝切换: - **装箱(Boxing)**: 把基本数据类型转换为包装类。 示例:`Integer num = 10;` (这里的 `10` 实际上被自动封装成了 `new Integer(10)`) - **拆箱(Unboxing)**: 把包装类转换回基本数据类型。 示例:`int value = num;` (这里的 `num` 被自动解包为原始的 `int`) 这种机制让编码更加简洁高效,同时也隐藏了许多底层细节。 --- ### **4. 使用场景举例** 以下是关于 `ArrayList<Integer>` 的简单示例: ```java // 创建一个放 Integer 对象的列表 ArrayList<Integer> numbers = new ArrayList<>(); // 添加元素(自动装箱发生在这里) numbers.add(1); // 等价于 numbers.add(new Integer(1)); numbers.add(2); numbers.add(3); // 获取元素(自动拆箱发生在这里) int firstNumber = numbers.get(0); // 等价于 int firstNumber = ((Integer)numbers.get(0)).intValue(); // 遍历并打印所有数字 for(int number : numbers){ System.out.println(number); } ``` 在这个过程中可以看到,虽然我们直接传入或取出的是 `int` 类型变量,但实际上它们都被当作 `Integer` 对象处理。 --- ### 总结 `Integer` 是一种非常重要的包装类,能够帮助我们将基础数据类型融入复杂的面向对象系统之中,同时借助自动装箱和拆箱的功能极大简化程序编写过程。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值