诊断Java代码: 轻松掌握Java泛型

J2SE 1.5 - 代号为 Tiger - 计划在 2003 年年底发布。我一直都热衷于尽可能多地收集有关即将推出的新技术的预告信息,因此我将撰写一系列的文章,讨论可从 V1.5 中获得的新的和经过重组的特性,本文是第一篇。我特别想谈谈泛型类型并重点讲述在 Tiger 中为了支持它们而进行的更改和调整。

在许多方面,Tiger 肯定是迄今为止在 Java 编程方面(包括对源语言语法的重大扩展)所取得的最大进步。Tiger 中计划进行的最显著的变化是添加泛型类型,正如在 JSR-14 原型编译器中所预先展示的那样(您可以立即免费下载该编译器;请参阅 参考资料)。

让我们从介绍泛型类型是什么以及添加了什么特性来支持它们开始吧。

数据类型转换和错误

为理解泛型类型为何如此有用,我们要将注意力转向 Java 语言中最容易引发错误的因素之一 - 需要不断地将表达式向下类型转换(downcast)为比其静态类型更为具体的数据类型(请参阅 参考资料中的“The Double Descent bug pattern”,以了解进行数据类型转换时,可能会碰到的麻烦的某些方面)。

程序中的每个向下类型转换对于 ClassCastException 而言都是潜在的危险,应当尽量避免它们。但是在 Java 语言中它们通常是无法避免的,即便在设计优良的程序中也是如此。

在 Java 语言中进行向下类型转换最常见的原因在于,经常以专用的方式来使用类,这限制了方法调用所返回的参数可能的运行时类型。例如,假定往 Hashtable 中添加元素并从中检索元素。那么在给定的程序中,被用作键的元素类型和存储在散列表中的值类型,将不能是任意对象。通常,所有的键都是某一特定类型的实例。同样地,存储的值将共同具有比 Object 更具体的公共类型。

但是在目前现有的 Java 语言版本中,不可能将散列表的特定键和元素声明为比 Object 更具体的类型。在散列表上执行插入和检索操作的类型特征符告诉我们只能插入和删除任意对象。例如, put 和 get 操作的说明如下所示:

清单 1. 插入/检索类型说明表明只能是任意对象

class Hashtable {
  Object put(Object key, Object value) {...}
  Object get(Object key) {...}
  ...
}

因此,当我们从类 Hashtable 的实例检索元素时,比如,即使我们知道在 Hashtable 中只放了 String ,而类型系统也只知道所检索的值是 Object 类型。在对检索到的值进行任何特定于 String 的操作之前,必须将它强制转换为 String ,即使是将检索到的元素添加到同一代码块中,也是如此!

清单 2. 将检索到的值强制转换成 String

import java.util.Hashtable;
class Test {
  public static void main(String[] args) {
   Hashtable h = new Hashtable();
   h.put(new Integer(0), "value");
   String s = (String)h.get(new Integer(0));
   System.out.println(s);
  }
}

请注意 main 方法主体部分的第三行中需要进行的数据类型转换。因为 Java 类型系统相当薄弱,因此代码会因象上面那样的数据类型转换而漏洞百出。这些数据类型转换不仅使 Java 代码变得更加拖沓冗长,而且它们还降低了静态类型检查的价值(因为每个数据类型转换都是一个选择忽略静态类型检查的伪指令)。我们该如何扩展该类型系统,从而不必回避它呢?

时间: 2024-08-11 15:08:29

诊断Java代码: 轻松掌握Java泛型的相关文章

诊断Java代码: 轻松掌握 Java 泛型,第4部分

至此,在这个讨论 JSR-14 和 Tiger 中泛型类型的微型系列中,我们已经探讨了: 泛型类型及被设计成支持它们的即将发布的功能 基本类型.受约束的泛型以及多态方法上的限制 几个强加给这些 Java 扩展的限制 这些扩展语言的编译器所用的实现策略如何使这些限制成为必需 在泛型类型中添加对"裸"类型参数的 new 操作的支持所带来的影响 本月,我们将探讨在可以处理 mixin(可能被期望是泛型类型中最强大的功能)之前需要先解决的问题,以此来结束对 Java 语言中泛型类型的讨论. m

诊断Java代码: 轻松掌握Java泛型,第3部分

这一系列主要讨论在 Java 编程中添加泛型类型,本文是其中的一篇,将研究还未讨论过的有关使用泛型的两个限制之一,即添加对裸类型参数的 new 操作的支持(如类 C<T> 中的 new T() ). 正如我 上个月所提到的那样,Tiger 和 JSR-14 通过使用"类型消除(type erasure)"对 Java 语言实现泛型类型.使用类型消除(type erasure),泛型类型仅用于类型检查:然后,用它们的上界替换它们.由此定义可知:消除将与如 new T() 之类

诊断Java代码: 轻松掌握Java泛型类型,第2部分

J2SE 1.5 ― 代号为"Tiger" ― 计划在 2003 年年底发布,它将包括泛型类型(如在 JSR-14 原型编译器中预先展示的那样,现在可下载获得).在 第 1 部分中,我们讨论了泛型类型的基础知识,以及为什么它们是对 Java 语言的一个重要且迫切需要的补充.我们还说明了为 Tiger 制定的泛型类型的实现怎么会包含数个"缺陷",这些缺陷限制了可以使用泛型类型的上下文. 为了帮助新程序员有效地使用泛型类型,我将详细说明到底泛型类型的哪些用法在 Tige

java代码-我用Java 写的一个简单截图小工具 但是出现一些在重截时出现bug 跪求大神

问题描述 我用Java 写的一个简单截图小工具 但是出现一些在重截时出现bug 跪求大神 /**在这里贴上我注释满满的代码 求一语道破 求建议 求批评 没有贴main 方法 随便写个main方法便可运行 */ ` package com.subimaga; import java.awt.AWTException; import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Cursor; import java.

java代码-急求java高手,帮忙看下面的游戏代码,为何只能运行界面类然后其他都看不见也不能玩

问题描述 急求java高手,帮忙看下面的游戏代码,为何只能运行界面类然后其他都看不见也不能玩 //子弹Bullet类 package hy; import java.awt.Graphics; import java.awt.Image; import java.awt.Toolkit; public class Bullet { //坐标 public int x,y; //子弹大小 public int width,height; //子弹杀伤力 public int kill; //速度

java代码 文本处理-java中文文本处理代码

问题描述 java中文文本处理代码 Java对文章进行处理,能输出作者,关键词之类的,求代码和解析. 解决方案 我谈谈我的看法,论文中的作者和其它一些前后没有什么特定符号的字符,估计正则表达式很难获取剩下的就是http://poi.apache.org/download.html,获取字体大小,来进行判断. 解决方案二: 那你的待处理文本的内容是否有一定的规律呢,时本身是否是HTML文件格式,单纯对内容解析的话,可以直接用字符串截取处理,但是如果是HTML文件可以用htmlparser工具类进行

java代码java-关于Java五子棋游戏端口被占用,玩家无法添加

问题描述 关于Java五子棋游戏端口被占用,玩家无法添加 如何在其中添加玩家,求大神帮助,具体步骤 解决方案 写个函数判断哪些端口被用到,用那些还没被用到的端口就好了. 解决方案二: 检查下防火墙,换一个端口,使用随机端口

java代码-怎么用JAVA编写图书管理系统

问题描述 怎么用JAVA编写图书管理系统 我需要一套完整的图书管理系统,自己弄的老出错....有没有大神帮忙啊

java代码-我用java写了一个简易计算器的程序,但是有时候结果不正确

问题描述 我用java写了一个简易计算器的程序,但是有时候结果不正确 就是有时候计算结果后面会显示很多9或者0 ,比如计算8.3-2.1时,请问大神怎么解决啊? 我是菜菜鸟,程序如下: //Calculator.java import java.awt.*; import java.awt.event.*; import javax.swing.*; public class Calculator extends JFrame { private JPanel p1=new JPanel();