我一直致力于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 方法中的工作原理吗?如何确定退货类型?
这种用法的目的是什么?它似乎不提供类型安全
此用法是否具有特定名称(因此我可以在其上找到更多信息并更改问题标题)?
答案 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块内。