java 泛型编程_Java 5.0泛型编程之泛型类型(2) | 学步园

理解泛型类型

本段将对泛型类型的使用细节做进一步的探讨,以尝试说明下列问题:

不带类型参数的使用泛型的后果

参数化类型的体系

一个关于编译期泛型类型的类型安全的漏洞和一个用于确保运行期类型安全的补丁

为什么参数化类型的数组不是类型安全的

未经处理的类型和不被检查的警告

即使被重写的Java集合类带来了泛型的好处,在使用他们的时候您也不被要求说明类型变量。一个不带类型变量的泛型类型被认为是一个未经处理的类型(raw type)。这样,5.0版本以前的java代码仍然能够运行:您显式的编写所有类型转换就像您已经这样写的一样,您可能会被一些来自编译器的麻烦所困扰。查看下列存储不同类型的对象到一个未经处理的List:

List l = new ArrayList();

l.add("hello");

l.add(new Integer(123));

Object o = l.get(0);

这段代码在java1.4下运行得很好。如果您用java5.0来编译它,javac编译了,但是会打印出这样的“抱怨”:

Note: Test.java uses unchecked or unsafe operations.

Note: Recompile with -Xlint:unchecked for details.

如果我们加入-Xlint参数后重新编译,我们会看到这些警告:

Test.java:6: warning: [unchecked]

unchecked call to add(E) as a member of the raw type java.util.List

l.add("hello");

^

Test.java:7: warning: [unchecked]

unchecked call to add(E) as a member of the raw type java.util.List

l.add(new Integer(123));

^

编译在add()方法的调用上给出了警告,因为它不能够确信加入到list中的值具有正确的类型。它告诉我们说我们使用了一个未经处理的类型,它不能验证我们的代码是类型安全的。注意,get()方法的调用是没有问题的,因为能够被获得的元素已经安全的存在于list中了。

如果您不想使用任何的java5.0的新特性,您可以简单的通过带-source1.4标记来编译他们,这样编译器就不会再“抱怨”了。如果您不能这样做,您可以忽略这些警告,通过使用一个“@SuppressWarnings("unchecked")”注解(查看本章的4.3节)隐瞒这些警告信息或者升级您的代码,加入类型变量描述。[2]下列示例代码,编译的时候不再会有警告但仍然允许您往list中放入不同的类型的对象。

List l = new ArrayList();

l.add("hello");

l.add(123);              // autoboxing

Object o = l.get(0);

参数化类型的体系

参数化类型有类型体系,就像一般的类型一样。这个体系基于对象的类型,而不是变量的类型。这里有些例子您可以尝试:

ArrayList l = new ArrayList();

List m = l;                            // okay

Collection n = l;                      // okay

ArrayList o = l;                        // error

Collection p = (Collection)l;   // error, even with cast

一个List是一个Collection,但不是一个List。这句话不容易理解,如果您想理解为什么泛型这样做,这段值得看一下。考察这段代码:

List li = new ArrayList();

li.add(123);

// The line below will not compile.  But for the purposes of this

// thought-experiment, assume that it does compile and see how much

// trouble we get ourselves into.

List lo = li;

// Now we can retrieve elements of the list as Object instead of Integer

Object number = lo.get(0);

// But what about this?

lo.add("hello world");

// If the line above is allowed then the line below throws ClassCastException

Integer i = li.get(1);  // Can't cast a String to Integer!

这就是为什么List不是一个List的原因,虽然List中所有的元素事实上是一个Object的实例。如果允许转换成List,那么转换后,理论上非整型的对象也将被允许添加到list中

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值