黑马程序员技术交流社区

标题: 关于泛型的问题 [打印本页]

作者: 朱秀梅    时间: 2012-6-11 09:25
标题: 关于泛型的问题
import java.util.*;
public class Text
{
public static void append(List list)
{
list.add("0042");
}
public static void main(String[] agrs)
{
  List<Integer> intList = new ArrayList<Integer>();
  append(intList);
  System.out.println(intList.get(0));
}
}
为什么输出的是0042?
“0042”应该是String的
但是List<Integer> intList 这里要求的是Integer的,请各位高手指点
作者: 江南    时间: 2012-6-11 09:27
这个问题,其实也是由于“泛型绕过了编译器”而引起的。
仔细看看ArrayList<E>的源代码,虽然这个类使用了泛型,但是保存数据的数组,确是Object类型的。[code=java]private transient Object[] elementData;[/code]最初,您的代码为:[code=java]List<Integer> intList = new ArrayList<Integer>(); [/code]定义一个List<Integer>的变量intList 。 此时intList 的add()方法中仅可以添加Integer类型的对象,否则编译报错。
然后,您的代码为:[code=java]append(intList); [/code]其实就相当于:List list = new ArrayList<Integer>();
换种写法就是:List<?> list = new ArrayList<Integer>();  。此时,其实就擦除了list的泛型。
也就是说,编译器不会再阻止咱们向list中插入String对象了。事实上,现在咱们可以为所欲为,向其内插入任意Object对象。
因此,在您写的append()方法中,咱们成功的将String类型的数据插入到那个名为elementData的Object[]数组之中了。
相应的调用intList.get()方法,就是从Object[]数组中取出数据。
但是,还是有个问题,下面是ArrayList类中get()方法的源代码:[code=java]public E get(int index) {
        RangeCheck(index);
        return (E) elementData[index];
    }[/code]返回值的类型为E类型,在List<Integer> intList中,E为Integer。
但是咱们调用intList.get()方法,却成功返回了一个String类型的对象。好神奇。到了后面学了反射应该就会更明白了!
作者: 潘东升    时间: 2012-6-11 10:19
楼上非正解
lz这里根本没有用到反射。
这里的问题是,实际参数和形式参数的传递问题,实参传递的是对象的引用,并非实际对象。
若你在形参声明的时候也加上泛型限定Integer,编译list.add("0042");这句时就会出错,
若你在形参声明为List<String>,则是在传递参数时就编译出错,即在append(intList);。
你再看看我下面这个例子就知道,形参接收的只是实参的引用

import java.io.*;
public class test2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
    String string = "Hello";
    testString(string);
    System.out.println(string);
}
    public static void testString(String str)
    {
     str = "World";
    }
}

先思考结果,再运行验证
作者: 张洁    时间: 2012-6-11 11:37
楼主有eclipse没~我把你的代码放进去啦,没有错误,但是有提示,eclipse会告诉你哪里有问题的
你自定义的append方法的参数有点问题,之前List都定义了泛型List<Integer>,但是方法参数没写,
应该修改为append(List<Integer> list)
然后你就会发现运行错误啦~
因为你append方法里add的是一个String型,只有改为Integer型才可以

最终修改代码如下:
import java.util.*;

public class Questiion3 {
        public static void append(List<Integer> list) {
                list.add(0042);
        }

        public static void main(String[] agrs) {
                List<Integer> intList = new ArrayList<Integer>();
                append(intList);
                System.out.println(intList.get(0));
        }
}





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2