黑马程序员技术交流社区

标题: 学习泛类的时候遇到的问题 [打印本页]

作者: 凡延海    时间: 2012-5-29 23:36
标题: 学习泛类的时候遇到的问题

  1. <P>public class GenericTest {
  2. public static <T extends Number/*Object*/ > void printGeneric(T...args)
  3. {
  4.   for(T arg:args)
  5.   {
  6.    System.out.println(arg);
  7.    
  8.   }
  9. }
  10. public static void main(String [] args)
  11. {
  12.   Integer [] integer=new Integer[]{1,2,3};
  13.   printGeneric(new int[]{1,2,3});
  14. }
  15. } </P>
复制代码
我用<T extends Number>做测试则的时候 printGeneric(new int[]{1,2,3})会出问题,我用<T extends Object>的时候呢就不会出问题。int[]数组中的数据不是要自动封装成Integer对象的么,怎么在用<T extends Number>时候就出错了呢,而在用<T extends Object>的时候没有出错呢。



作者: 秦冲    时间: 2012-5-30 00:49
你现在能思考出这个问题有很厉害啊,在java高新技术里面反射那一章你将深入的了解,当你理解了反射后再来理解就会很简单了,我简单说下:数组这种类型很特别,它不像int是原始数据类型,也不是引用数据类型,它就是数组这种类型的。
int [] a1 = new int[]{1,2,3};
a1.getClass().getSuperclass().getName())----->java.lang.Object

可变参数内部其实也是用的数组,这又涉及到jdk5.0兼容性的问题,当你传递了一个数组时,那边把它看成一个对象了,就是数组对象你传过去,相当于Object数组第一个元素接受的是一个数组也就是
Object args[0] =a1;
所以你打印的是 [I@152b6651 数组类型的
当你把参数改为Number类型的,这就是引用类型的了对应的int应该为Integer才能接受,至于你说的自动封装为Integer是指的数组里面的元素单个取出来的时候视具体情况可能会,但是作为int[] 是无法作为Number的,也就是说:
Number args[0] =a1;//cannot convert from int[] to Number
你理解了吗?确实有点绕。

作者: 胡团乐    时间: 2012-5-30 04:20
楼主想说的可能是自动装箱的功能吧
Integer是继承Number,所以不会出错,而int属于基本类型,如果 int i=5; Integer ig= i;会自动装箱;
而new int[]{1,2,3}这个数组本身就是一个对象,不会出现把int数组转换为Integer数组的情况;
作者: 张晨    时间: 2012-5-30 09:06
数组不会自动拆箱装箱
作者: 黑马张健    时间: 2012-5-30 10:51
int是基本类型。它并不一个类,所以它也就不会存在 extends Number 类的关系。
Number类的子类有:AtomicInteger, AtomicLong, BigDecimal, BigInteger, Byte, Double, Float, Integer, Long, Short
所以必须要写成与它相关的子类才可以。这里面的<T extends Number>  传人的参数可以是上面的任意子类的类型。编译器不会报错。
你给它传人int类型的数组,当然会编译不通过,因为int类型不符合<T extends Number>这种关系。

当<T extends Object> 时,编译器会把数组当作是一个对象,满足了这种继承关系,所以编译通过。就不会报错了。


作者: 凡延海    时间: 2012-5-30 11:41
嗯,数组本身就是一个引用对象不属于Number类型。




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