正如其他帖子所指出的,您正在询问一个称为泛型的 Java 功能。在 C++ 中,这称为模板。 Java 中的此功能通常比 C++ 中的功能更容易使用。
让我从功能上回答你的问题(如果这对于 OO 讨论来说不是一个淘气的话)。
在泛型之前,存在像 Vector 这样的具体类。
Vector V = new Vector();
向量保存你给它们的任何对象。
V.add("This is an element");
V.add(new Integer(2));
v.add(new Hashtable());
他们通过将赋予它的所有值转换为一个对象(所有 Java 类的根)来实现这一点。当您尝试检索存储在 Vector 中的值时,您需要将该值转换回original类(如果你想用它做任何有意义的事情)。
String s = (String) v.get(0);
Integer i = (Integer) v.get(1);
Hashtable h = (Hashtable) v.get(2);
铸造很快就会过时。不仅如此,编译器还会向您抱怨未经检查的强制转换。像这样的转换最紧迫的问题是 Vector 的使用者必须知道其值的类别编译时间以便正确施放。在 Vector 的生产者和消费者彼此完全隔离的情况下(想想 RPC 消息),这可能是一个致命的问题。
输入仿制药。泛型尝试创建强类型类来执行泛型操作。
ArrayList<String> aList = new ArrayList<String>();
aList.add("One");
String element = aList.get(0); // no cast needed
System.out.println("Got one: " + element);
The 设计模式本书鼓励读者根据契约而非具体类型进行思考。将变量与其实现类分开是明智的(和代码重用)。
考虑到这一点,您可能会认为所有实现 List 对象都应该执行相同的操作:add()
, get()
, size()
等等。稍加思考,您可以想象以各种方式遵守 List 契约的 List 操作的许多实现(例如ArrayList
)。然而,这些对象处理的数据类型与对其执行的操作正交。
把它们放在一起,你会经常看到以下类型的代码:
List<String> L = new ArrayList<String>();
您应该将其理解为“L 是一种处理 String 对象的 List”。当您开始处理工厂类时,处理契约而不是特定的实现至关重要。工厂在运行时生成各种类型的对象。
使用泛型非常简单(大多数时候)。
有一天,您可能决定要实现自己的通用类。也许您想编写一个新的数据库抽象接口来消除各种数据存储之间的差异。当您定义该泛型类时,您将使用<t>
作为将由方法操作的对象类型的占位符。
如果您仍然感到困惑,请使用 List 的泛型类,直到您感到舒服为止。稍后,您可以更有信心地深入实施。或者您可以查看 JRE 附带的各种 List 类的源代码。开源在这方面就很棒。
看看 Oracle/Sun关于泛型的文档 http://www.oracle.com/technetwork/articles/javase/generics-136597.html。
干杯。