Java 通用拼图
Java Generic puzzle
我有 Java classes:
abstract class Parent {
abstract void test(Object pObject, Map<String, Object> pData);
}
public class Test extends Parent {
@Override
void test(Object pObject, Map<String, Object> pData) {
}
}
并想将代码重构为:
abstract class Parent<T> {
abstract void test(T pObject, Map<String, Object> pData);
}
public class Test extends Parent {
@Override
void test(Object pObject, Map<String, Object> pData) {
}
}
Eclipse(4.4.2 如果重要的话)告诉我测试 class 中的代码无效(编译时错误)并且正确的 test()
方法签名必须是:
@Override
void test(Object pObject, Map pData) {
}
我的问题是为什么!?
实际上,真实的故事要长一些。我有很多 children class(如测试),不想更改它们,更喜欢使用通用的(即 <T>
class)新 [= Parent class 的 31=]。在这两种情况下,test()
方法的第二个参数必须是 Map<String, Object>
。
有什么想法吗?
My question is WHY!?
当您扩展 Parent
的 raw 版本时,class 中的所有通用信息都会被忽略。因此,您正在扩展一个 Parent
,它看起来像:
abstract class Parent {
abstract void test(Object pObject, Map pData);
}
为了保留 Map
参数的类型参数,您可以指定扩展 Parent<Object>
。现在这段代码应该可以正常编译了:
public class Test extends Parent<Object> {
@Override
void test(Object pObject, Map<String, Object> pData) {
}
}
在第一个例子中,Parent
是一个普通的 class 并且您已经按照预期的方式对其进行了子类化,一切都很好。
在第二个示例中,您没有扩展 Parent<T>
,而是扩展了已删除的泛型 Parent
,它从 class 中删除了所有泛型,即使它们不涉及 [=14] =].
尝试
public class Test extends Parent<Object> {
@Override
void test(Object pObject, Map<String, Object> pData) {
}
}
我看到到达您想要的位置的唯一方法是保持 Parent
class 不变,并引入另一个 class 为您提供模板功能,如下所示:
abstract class TemplatedParent<T> {
abstract void test(T pObject, Map<String, Object> pData);
}
abstract class Parent extends TemplatedParent<Object> {}
这样您可以保留旧代码,而需要模板功能的新代码必须直接扩展 TemplatedParent
。
我有 Java classes:
abstract class Parent {
abstract void test(Object pObject, Map<String, Object> pData);
}
public class Test extends Parent {
@Override
void test(Object pObject, Map<String, Object> pData) {
}
}
并想将代码重构为:
abstract class Parent<T> {
abstract void test(T pObject, Map<String, Object> pData);
}
public class Test extends Parent {
@Override
void test(Object pObject, Map<String, Object> pData) {
}
}
Eclipse(4.4.2 如果重要的话)告诉我测试 class 中的代码无效(编译时错误)并且正确的 test()
方法签名必须是:
@Override
void test(Object pObject, Map pData) {
}
我的问题是为什么!?
实际上,真实的故事要长一些。我有很多 children class(如测试),不想更改它们,更喜欢使用通用的(即 <T>
class)新 [= Parent class 的 31=]。在这两种情况下,test()
方法的第二个参数必须是 Map<String, Object>
。
有什么想法吗?
My question is WHY!?
当您扩展 Parent
的 raw 版本时,class 中的所有通用信息都会被忽略。因此,您正在扩展一个 Parent
,它看起来像:
abstract class Parent {
abstract void test(Object pObject, Map pData);
}
为了保留 Map
参数的类型参数,您可以指定扩展 Parent<Object>
。现在这段代码应该可以正常编译了:
public class Test extends Parent<Object> {
@Override
void test(Object pObject, Map<String, Object> pData) {
}
}
在第一个例子中,Parent
是一个普通的 class 并且您已经按照预期的方式对其进行了子类化,一切都很好。
在第二个示例中,您没有扩展 Parent<T>
,而是扩展了已删除的泛型 Parent
,它从 class 中删除了所有泛型,即使它们不涉及 [=14] =].
尝试
public class Test extends Parent<Object> {
@Override
void test(Object pObject, Map<String, Object> pData) {
}
}
我看到到达您想要的位置的唯一方法是保持 Parent
class 不变,并引入另一个 class 为您提供模板功能,如下所示:
abstract class TemplatedParent<T> {
abstract void test(T pObject, Map<String, Object> pData);
}
abstract class Parent extends TemplatedParent<Object> {}
这样您可以保留旧代码,而需要模板功能的新代码必须直接扩展 TemplatedParent
。