小编典典
正如其他文章所指出的那样,你正在询问有关称为泛型的Java功能。在C 中,这称为模板。Java中的此功能通常比C中的功能更易于使用。
让我从功能上回答你的问题(如果这不是面向对象的讨论的顽皮话)。
在泛型之前,有像Vector这样的具体类。
Vector V = new Vector();
向量可容纳你提供的任何对象。
V.add("This is an element");
V.add(new Integer(2));
v.add(new Hashtable());
他们通过将赋予它的所有值转换为对象(所有Java类的根)来实现此目的。当你尝试检索存储在Vector中的值时,需要将值强制转换回原始类(如果你想对其进行有意义的操作)。
String s = (String) v.get(0);
Integer i = (Integer) v.get(1);
Hashtable h = (Hashtable) v.get(2);
投放会很快变老。不仅如此,编译器还向你抱怨未经检查的强制转换。像这样进行转换的最紧迫的问题是,Vector的使用者必须在编译时知道其值的类别,才能正确进行转换。如果Vector的生产者和使用者的消费者完全相互隔离(请考虑RPC消息),这可能是一个致命的问题。
输入泛型。泛型试图创建强类型的类来进行泛型操作。
ArrayList aList = new ArrayList();
aList.add("One");
String element = aList.get(0); // no cast needed
System.out.println("Got one: " + element);
《设计模式》一书鼓励读者从合同而非具体类型的角度进行思考。将变量与实现类分开是明智的(和代码重用)。
考虑到这一点,你可能会认为,所有实现List对象应该做同样的一套东西:add(),get(),size()等有了一点点反思,你可以想像列表操作的许多实现服从以各种方式列表合同(例如ArrayList) 。但是,这些对象处理的数据类型与对其执行的操作正交。
放在一起,你将经常看到以下类型的代码:
List L = new ArrayList();
你应该读为“ L是一种处理String对象的列表”。当你开始处理Factory类时,处理合同而不是特定的实现至关重要。工厂在运行时会产生各种类型的对象。
使用泛型非常容易(大多数时候)。
有一天,你可能决定要实现自己的通用类。也许你想编写一个新的数据库抽象接口,以消除各种数据存储之间的差异。当定义该通用类时,将用作将由方法操作的对象的占位符。
如果仍然感到困惑,请对List使用通用类,直到你感到舒适为止。稍后,你可以更有信心地深入实施。或者,你可以查看JRE附带的各种List类的源代码。开源很棒。
2020-03-05