【发布时间】:2008-12-11 05:43:40
【问题描述】:
我正在学习 Java 进行测试(明天),我想知道一个可能永远不会出现但让我很好奇的问题。
是否可以创建一个新的集合类,例如列表或只能包含特定类型而不包含其子类型的东西?我会使用泛型来实现这个目标吗?
【问题讨论】:
我正在学习 Java 进行测试(明天),我想知道一个可能永远不会出现但让我很好奇的问题。
是否可以创建一个新的集合类,例如列表或只能包含特定类型而不包含其子类型的东西?我会使用泛型来实现这个目标吗?
【问题讨论】:
不是真的,或者至少实际上不是。
子类型应该像数学集合论中的集合一样运行。如果 B 是 A 的子集,则 B 中的任何项目也是 A 中的项目。
同理,如果 B 是 A 的子类型,则 B 中的任何项也是 A 的项。因此,A 的任何集合都必须能够维护 B 的项。
话虽如此,B 可能会以令人费解的方式覆盖某些操作,以显式破坏在集合中使用它或实例化它的能力。
我认为泛型不会解决这个问题。
【讨论】:
如果您创建自定义集合类,您可以在插入时使用反射检查对象的类,如果它不是特定的确切类型,则拒绝它。或者,如果您可以控制集合中包含的类的类定义,则将其设为 final 将阻止创建子类。 (如果您需要子类用于其他用途,显然这是一个问题)
【讨论】:
问题是:您为什么要这样做。如果您有一个包含动物的列表,为什么要仅使用“基本动物”填充该列表,但要防止将狗或猫添加到列表中。 OO 的基本概念之一是在需要基类实例的任何地方都使用子类的实例 (Wikipedia: Liskov substitution principle)。如果这不适用于您的情况,则您的类层次结构可能有问题。
【讨论】:
您可以在包含的类的类定义中使用“final”来禁止对其进行子类型化。我没有立即看到如何对此进行测试或将泛型限制为需要最终类。您可以使用反射来测试该类是否具有 final 修饰符集,例如在构造集合时,如果没有,则抛出。
如果类本身不是最终类,您可以检查添加到集合中的每个对象,以确保其运行时类正是该集合想要的类,而不是它的子类。
请参阅http://java.sun.com/docs/books/tutorial/reflect/ 了解有关 Java 的反思信息。
【讨论】: