gpt4 book ai didi

java - 将泛型引入遗留代码并迭代参数化实例

转载 作者:行者123 更新时间:2023-11-30 11:45:54 27 4
gpt4 key购买 nike

我的问题涉及将泛型引入遗留 Java 类。我想泛化的下面代码中的遗留类是 ClientObjectProxy 和 ClientObjectContainer。 ClientObject 保持不变。为简单起见,我将所有类都放在一个外部类中。

现在在遗留代码中有许多未参数化的 ClientObjectProxyContainer 实例上的 ClientObjectProxyContainer.getProxies() 方法调用。

通过引入泛型,现有代码(如循环 4 中)将不再编译,需要将调用提取到循环 1 中的局部变量,或者需要使用类似于循环 2 的带问号的声明。新代码应该像循环 3 中那样使用参数化变量。

我的问题是,这是否适合我,将现有代码更改为循环 1 或循环 2,还是有不修改遗留代码的方法?

谢谢

一月

import java.util.ArrayList;
import java.util.List;

public class GenericForumsExample {
/**
* This class is unchanged
*/
private class ClientObject {
}

/**
* @param <T> Type of the ClientObject behind this proxy
*/
private class ClientObjectProxy<T extends ClientObject> {
}

/**
* @param <T> Type of the ClientObject contained in this collection
*/
private class ClientObjectProxyContainer<T extends ClientObject> {
//Previous signature was:
// public List<ClientObjectProxy> getProxies(){
// New signature is the following
public List<ClientObjectProxy<T>> getProxies(){
return new ArrayList<ClientObjectProxy<T>>();
}
}

public void testScenario() {
ClientObjectProxyContainer proxyContainer = new ClientObjectProxyContainer();
List<ClientObjectProxy> proxies = proxyContainer.getProxies(); // Just a compiler warning

// Loop 1
for (ClientObjectProxy proxy : proxies) { // Compiler OK
//Do something...
}

// Loop 2
ClientObjectProxyContainer<?> clientObjectProxyContainer = new ClientObjectProxyContainer();
for (ClientObjectProxy<?> proxy : clientObjectProxyContainer.getProxies()) {
//Do something...
}

// Loop 3
for (ClientObjectProxy<ClientObject> proxy : new ClientObjectProxyContainer<ClientObject>().getProxies()) {
//Do something...
}

// Loop 4
// Compiler fails on next code line
// incompatible types
// found : java.lang.Object
// required: GenericForumsExample.ClientObjectProxy
for (ClientObjectProxy proxy : proxyContainer.getProxies()) {
//Do something...
}
}

}

最佳答案

在处理泛型的代码中,尽量避免使用原始类型。当您使用这些类型时,您通常会丢失比预期更多的类型信息,正如本例中所发生的那样。

来电proxyContainer.getProxies()在最后一个循环中实际上返回一个 List (因为 proxyContainer 是原始类型,所有与其类型相关的泛型都被删除,包括方法签名中的泛型)。如果你遍历一个原始的 List , 你只会得到 Object s出来了,所以出现了编译错误。您可以通过编写 (List<ClientObjectProxy>)proxyContainer.getProxies() 来解决此问题在 for 循环中(您当然会收到警告)。

因此,使用通配符而不是原始类型通常更清晰。在已经“通用化”的代码中,永远不要使用原始类型 ClientObjectProxyContainer , 但总是 ClientObjectProxyContainer<?> ,如果您没有具体类型。该类型的含义基本相同,但不会导致在使用时忽略所有泛型类型。

当对 proxyContainer 的类型使用通配符时, getProxies() 的结果类型将是 List<ClientProxyObject<?>>而不仅仅是 List , 所以你可以取 ClientProxyObject不用了(但这里也更喜欢使用 ClientProxyObject<?> !)。

关于java - 将泛型引入遗留代码并迭代参数化实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10105848/

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