还谈java2的泛型以及泛型与静态方法( 转)

还谈java2的泛型以及泛型与静态方法
2007/10/07 12:08 P.M.

英文原文 http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf
译文:http://www.360doc.com/showWeb/0/0/361230.aspx

 

静态成员中的封闭类型参数

编译器完全禁止在静态方法和静态内部类中引用封闭类型参数。所以,举例来说,以下代码在 Tiger 中就是非法的:

清单 1. 在静态上下文中非法引用封闭类型参数
class C<T> {
   static void m() {
     T t;
   }

   static class D {
     C<T> t;
   }
}

当编译这一代码时,会生成两个错误:

静态方法 m 中非法引用 T 的错误
静态类 D 中非法引用 T 的错误

当定义静态字段时,情况变得更加复杂。在 JSR-14 和 Tiger 中,在泛型类的所有实例中共享该类中的静态字段。现在,在 JSR-14 编译器 1.0 和 1.2 中,如果您在静态字段声明中引用类型参数,编译器不会报错,但它本应该这么做。字段被共享这一事实很容易在运行时导致奇怪的错误,如在不包含数据类型转换的代码中出现 ClassCastException 。

例如,以下程序将在这两个版本的 JSR-14 下通过编译而没有任何警告:

清单 2. 在静态字段中对封闭类型参数的有问题的引用
class C<T> {
   static T member;

   C(T t) { member = t; }

   T getMember() { return member; }

   public static void main(String[] args) {
     C<String> c = new C<String>("test");
     System.out.println(c.getMember().toString());
     new C<Integer>(new Integer(1));
     System.out.println(c.getMember().toString());
   }
}

请注意,每次分配类 C 的实例时,都要重新设置静态字段 member 。而且,它被设置成的对象类型取决于 C 的实例的类型!在所提供的 main 方法中,第一个实例 c 是 C<String> 类型。而第二个是 C<Integer> 类型。每当从 c 访问 member 这一共享静态字段时,总是假定 member 的类型是 String 。但是,在分配了类型为 C<Integer> 的第二个实例之后, member 的类型是 Integer 。

运行 C 的 main 方法的结果可能会让您吃惊 ― 它将发出一个 ClassCastException !源代码根本没有包含任何数据类型转换,怎么会这样呢?事实证明编译器确实在编译阶段将数据类型转换插入到代码中,这样做是为了解决类型擦除会降低某些表 达式的类型的精度这一事实。这些数据类型转换 被期望能够成功,但在本例中却没有成功。

应该认为 JSR-14 1.0 和 1.2 的这一特殊“功能”是个错误。它破坏了类型系统的健全性,或者可以说,它破坏了类型系统应该和程序员达成的“基本契约”。象对静态方法和类所做的那样,只要防止程序员在静态字段中引用泛型类型,情况就会好很多。

请注意允许这种有潜在“爆炸性”的代码存在所带来的问题并不是程序员 有意在自己的代码中覆盖类型系统。问题是程序员可能会无意中编写这样的代码(比如,由于“复制和粘贴”操作,错误地在字段声明中包括静态修饰符)。

类型检查器应该能帮助程序员从这些类型的错误中恢复,但对于静态字 段而言,类型系统实际上会使程序员更迷惑。当未使用数据类型转换的代码中显示的唯一错误就是 ClassCastException 时,我们应如何诊断这样的错误?对于不清楚 Tiger 中泛型类型所用的实现方案而又恰好假定类型系统合理运行的程序员而言,情况更糟。因为在这样的情况下,类型系统不是合理地运行。

幸运的是,JSR-14 的最新版本(1.3)宣布在静态字段中使用类型参数是不合法的。因此,我们有理由期待在 Tiger 的静态字段中使用类型参数也是不合法的。

posted @   wtx  阅读(3754)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述
点击右上角即可分享
微信分享提示