标签:class-hierarchy java generics hierarchy
考虑以下不可变类:
A
B extends A
C extends B
D extends C
...
类A有一个名为process的方法,它获取一个类型为A的参数,然后返回一个调用对象类型的值:
public class A {
public final <T extends A> T process(A a) {
Class clazz = getClass();
T result = createObjectOfType(clazz);
return result;
}
}
public class B extends A { }
public class C extends B { }
这是(非常简单的)测试代码:
public void test()
{
A a = new A();
B b = new B();
C c = new C();
// Returns type A:
A resultAAA = a.process(a); // Works.
A resultAAB = a.process(b); // Works.
A resultAAC = a.process(c); // Works.
B resultAAA = a.process(a); // Runtime error.
B resultAAB = a.process(b); // Runtime error.
B resultAAC = a.process(c); // Runtime error.
C resultAAA = a.process(a); // Runtime error.
C resultAAB = a.process(b); // Runtime error.
C resultAAC = a.process(c); // Runtime error.
// Returns type B:
A resultBBA = b.process(a); // Works.
A resultBBB = b.process(b); // Works.
A resultBBC = b.process(c); // Works.
B resultBBA = b.process(a); // Works.
B resultBBB = b.process(b); // Works.
B resultBBC = b.process(c); // Works.
C resultBBA = b.process(a); // Runtime error.
C resultBBB = b.process(b); // Runtime error.
C resultBBC = b.process(c); // Runtime error.
// Returns type C:
A resultCCA = c.process(a); // Works.
A resultCCB = c.process(b); // Works.
A resultCCC = c.process(c); // Works.
B resultCCA = c.process(a); // Works.
B resultCCB = c.process(b); // Works.
B resultCCC = c.process(c); // Works.
C resultCCA = c.process(a); // Works.
C resultCCB = c.process(b); // Works.
C resultCCC = c.process(c); // Works.
}
我想修改源代码以将这些运行时错误转换为编译时错误或警告,而不必重载或覆盖进程方法.
但是,客户端/测试代码不得更改(没有强制转换或通用参数).
编辑:这个问题没有真正的解决方案.所以我接受了关于覆盖过程方法的明显答案.这对客户端代码最有效,即使这是一个维护噩梦.也许有一天可以修改Java类型系统,以便可以编写“这种类型”.然后我们可以写一些像公共最终这个过程(A a).如果您有兴趣,请参阅this page中的建议(在评论部分).
解决方法:
从Java 5开始,允许您的代码为在子类中重写的方法提供共变量返回类型.这是什么意思?
这意味着重写方法的返回类型必须是原始方法的子类.这使子类能够返回适当类型而不是父类型的类型.
假设您在A中有一个要在子类B中使用的方法,但是您希望它返回一个B实例.使用此模式:
class A {
public A myMethod() { ... }
}
class B extends A {
@Override public B myMethod() { ... }
}
B类重写A类中的方法(如果需要,它可以通过调用super.myMethod()来调用它并返回B实例).这是允许的,因为B是A的子类型(在类设计语言中,B是-A-A).
标签:class-hierarchy,java,generics,hierarchy 来源: https://codeday.me/bug/20190830/1765055.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。