gpt4 book ai didi

java - 在返回与其对象相同类型的值的 final方法中使用泛型

转载 作者:塔克拉玛干 更新时间:2023-11-02 07:44:50 26 4
gpt4 key购买 nike

考虑以下不可变类:

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.

}

我想修改源代码以将那些运行时错误转换为编译时错误或警告,而不必重载或覆盖进程 方法。

但是,客户端/测试 代码不得更改(不得强制转换或通用参数)。

编辑: 这个问题没有真正的解决方案。所以我接受了关于覆盖 process 方法的明显答案。这是最适合客户端代码的方法,即使它是维护的噩梦。也许有一天可以修改 Java 类型系统,以便可以编写“this 的类型”。然后我们可以写类似public final this process(A a)的东西。请参阅 this page 中的建议(在评论部分)如果您有兴趣。

最佳答案

使用自引用类型:

public class A<T extends A<T>>{

public final T process(A a) {
Class clazz = getClass();
T result = createObjectOfType(clazz);
return result;
}
}

public class B<T extends B<T>> extends A<T>{ }

public class C extends B<C> { }

要避免在客户端代码中完全使用泛型参数,您必须创建第二组泛型类,其固定类型实现为 A、B、C 等,如下所示:

public class BaseA<T extends BaseA<T>>{
public final T process(BaseA a) {
Class clazz = getClass();
T result = createObjectOfType(clazz);
return result;
}
}
public class A extends BaseA<A> {}

public class BaseB<T extends BaseB<T> extends BaseA<BaseB<T>> {}

public class B extends BaseB<B> {}

public class C extends BaseB<C> {}

这里的问题是 b instance A 不会为真,但它可能感觉足够接近以至于客户端代码不会关心。

关于java - 在返回与其对象相同类型的值的 final方法中使用泛型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29188497/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com