解释泛型如何在此方法中工作

时间:2010-02-23 15:16:19

标签: java generics

我一直致力于Google AdWords,并且遇到了这段代码

adwords-api-6.4.0,com.google.api.adwords.lib.AdWordsUser

public <T extends java.rmi.Remote> T getService(AdWordsService service) throws ServiceException {
    try {
      return (T) AdWordsServiceFactory.generateSerivceStub(service, this,
          service.getEndpointServer(this.isUsingSandbox()), false);
    } catch (ClassCastException e) {
      throw new ServiceException("Cannot cast serivce. Check the type of return-capture variable.", e);
    }
}

这样调用:

AdWordsUser user = new AdWordsUser();
AdGroupServiceInterface adGroupService = user.getService(AdWordsService.V200909.ADGROUP_SERVICE);

您能解释一下generics在 getService 方法中的工作原理吗?如何确定退货类型?
这种用法的目的是什么?它似乎不提供类型安全 此用法是否具有特定名称(因此我可以在其上找到更多信息并更改问题标题)?

2 个答案:

答案 0 :(得分:2)

我对C#的了解比Java更多,但我猜测getService方法采用AdWordsService类型的参数,并返回类型T,它必须来自{ {1}}。

大概java.rmi.Remote方法返回类型的类型为AdWordsServiceFactory.generateSerivceStub或类似,因此将其转换为java.rmi.Remote类型是合法的。

在C#中,仿制药以这种方式用于避免铸造,但铸件仍然在这里发生。我想通过这种特殊的方法,它可以让你不必投射到你想要的类型,让你告诉泛型方法你想要的类型。

我还想象您需要在调用T时指定T的类型。也许是这样的?

getService

答案 1 :(得分:2)

编译器通常可以从调用上下文推断返回类型。在提供的示例中,编译器推断泛型类型为AdGroupServiceInterface,因为结果已分配给该类型。如果没有可用的推断返回类型的上下文,则必须明确指定:

user.<AdGroupServiceInterface>getService(svc);

但是,getService方法类型安全。即使它包含一个强制转换,这只能确保结果实现java.rmi.Remote接口。由于Java泛型中的类型擦除,确切类型T未知,并且强制转换无法检查以确保结果为AdGroupServiceInterface

这就是为什么编译器会警告不安全的cast-a ClassCastException,当结果被分配给AdGroupServiceInterface变量时,而不是在方法及其catch块内。