在 Java 6 中我能够使用:
public static <T, UK extends T, US extends T> T getCountrySpecificComponent(UK uk, US us) {
Country country = CountryContext.getCountry();
if (country == Country.US) {
return us;
} else if (country == Country.UK) {
return uk;
} else {
throw new IllegalStateException("Unhandled country returned: "+country);
}
}
使用这些存储库:
public interface Repository{
List<User> findAll();
}
public interface RepositoryUS extends Repository{}
public interface RepositoryUK extends Repository{}
使用这些时:
RepositoryUK uk = ...
RepositoryUS us = ...
此行在 Java6 中编译,但在 Java7 中失败(错误找不到符号 - 因为编译器在类 Object 上查找 findAll())
List<User> users = getCountrySpecificComponent(uk, us).findAll();
这可以在 Java 7 中编译
List<User> users = ((Repository)getCountrySpecificComponent(uk, us)).findAll();
我知道这是一个相当不常见的用例,但这种变化有原因吗?或者告诉编译器变得“更聪明”一点的方法?
我认为
T
应该有界以延伸Repository
。这样编译器就知道 getCountrySpecificComponent
返回一些存储库。
编辑:
写起来应该也可以:
public static <T extends Repository> T getCountrySpecificComponent(T uk, T us)
那么我同意旧编译器接受这一点是一个错误。 我想你想要这样的东西:
public interface UserFindingComponent{
List<User> findAll();
}
public interface Repository extends UserFindingComponent{ }
public interface RepositoryUS extends Repository{}
public interface RepositoryUK extends Repository{}
...
public static <T extends UserFindingComponent, UK extends T, US extends T> T getCountrySpecificComponent(UK uk, US us) {
Country country = CountryContext.getCountry();
if (country == Country.US) {
return us;
} else if (country == Country.UK) {
return uk;
} else {
throw new IllegalStateException("Unhandled country returned: "+country);
}
}
在这种情况下,编译器无法推断类型参数,这在 Java 6 中可能也是如此。但是,您可以使用以下语法告诉编译器泛型类型是什么:
import java.util.List;
class User {
}
interface Repository {
List<User> findAll();
}
interface RepositoryUS extends Repository {
}
interface RepositoryUK extends Repository {
}
class Test {
public static <T, UK extends T, US extends T> T getCountrySpecificComponent(UK uk, US us) {
Country country = CountryContext.getCountry();
if (country == Country.US) {
return us;
} else if (country == Country.UK) {
return uk;
} else {
throw new IllegalStateException("Unhandled country returned: " + country);
}
return us;
}
public static void main(String... args) {
RepositoryUK uk = null;
RepositoryUS us = null;
List<User> users = Test.<Repository, RepositoryUK, RepositoryUS>getCountrySpecificComponent(uk, us).findAll();
}
}