2012-04-11 18 views
2

我的问题涉及将泛型引入遗留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... 
     } 
    } 

} 
+0

Loop 4如何在遗留代码中工作?没有泛型是不可能的。 – 2012-04-11 12:47:38

+0

getProxies的先前的签名()是: '公开名单 getProxies(){ ... }' ,返回的清单参数,但代理本身并不是 – 2012-04-11 13:13:35

+0

这将是很好的编辑问题是为了说明这一点。我认为这是考虑解决方案时非常重要的一点。 – 2012-04-11 13:18:33

回答

1

在处理泛型代码,尽量避免使用原始类型的。当你使用这些类型时,你会经常失去比你期望的更多的类型信息,就像在这种情况下发生的那样。

在最后一个循环返回该呼叫实际上proxyContainer.getProxies()List一个(因为proxyContainer是原始类型的,关于其类型的所有泛型被除去,包括在方法签名泛型)。如果你迭代原始的List,你只会得到Object,所以会出现编译错误。你可以通过在for循环中写入(List<ClientObjectProxy>)proxyContainer.getProxies()来解决这个问题(当然会得到一个警告)。

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

当使用的proxyContainer类型的通配符的getProxies()结果类型将是List<ClientProxyObject<?>>,而不是仅仅List,这样你就可以采取ClientProxyObject出去了吧(但在这里,也喜欢用ClientProxyObject<?>!)。

0

如果您引入泛型,我更喜欢循环1方法。然后您不必担心类型检查。