Java7中的编译器更改

Java7中的编译器更改,java,compiler-construction,javac,java-7,Java,Compiler Construction,Javac,Java 7,在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

在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);
    }
}
这一行在Java6中编译,但在Java7中失败(错误找不到符号-因为编译器在类对象上查找findAll())

List users=getCountrySpecificComponent(英国、美国).findAll();
这是用Java7编译的

List<User> users = ((Repository)getCountrySpecificComponent(uk, us)).findAll();
List users=((存储库)getCountrySpecificComponent(英国、美国)).findAll();

我知道这是一个相当不常见的用例,但是这种改变有什么原因吗?或者告诉编译器更“聪明”一点的方法?

我认为
T
应该限定为扩展
存储库。这样编译器就知道
getCountrySpecificComponent
返回一些存储库

编辑:


也可以这样写:
公共静态T getCountrySpecificComponent(tuk,tus)

那么我同意旧编译器接受这一点是错误的。我想你想要这样的东西:

public interface UserFindingComponent{
   List<User> findAll(); 
}

public interface Repository extends UserFindingComponent{ }

public interface RepositoryUS extends Repository{}

public interface RepositoryUK extends Repository{}
公共接口用户查找组件{
列出findAll();
}
公共接口存储库扩展了UserFindingComponent{}
公共接口RepositoryUS扩展存储库{}
公共接口RepositoryUK扩展存储库{}

public static T getCountrySpecific组件(英国、美国){
Country=CountryContext.getCountry();
if(country==country.US){
归还我们;
}else if(country==country.UK){
返回英国;
}否则{
抛出新的IllegalStateException(“未处理的国家返回:+国家”);
}
}

在本例中,编译器无法推断类型参数,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(); 
  }
}
import java.util.List;
类用户{
}
接口存储库{
列出findAll();
}
接口RepositoryUS扩展存储库{
}
接口RepositoryUK扩展了存储库{
}
课堂测试{
公共静态T GetCountrySpecific组件(英国、美国){
Country=CountryContext.getCountry();
if(country==country.US){
归还我们;
}else if(country==country.UK){
返回英国;
}否则{
抛出新的IllegalStateException(“未处理的国家返回:+国家”);
}
归还我们;
}
公共静态void main(字符串…参数){
RepositoryUK=null;
RepositoryUS=null;
List users=Test.getCountrySpecificComponent(英国、美国).findAll();
}
}

T
类型的用途是什么?您是否可以删除该通用参数并让
UK
US
扩展
存储库
?我认为这是问题的根源——除非您告诉编译器,否则编译器无法知道您传递给
getCountrySpecificComponent()
的所有内容都是
存储库。问得好!我想将它用于所有类型的存储库、服务和其他特定于国家的东西。我只是想让它更通用/更有用。我不认为即使在Java6中也可以编译它,除非做出一些危险的假设。。。为什么
T
应该是
Repository
,而在给定的情况下它也可以是
Object
?我不知道,我想这是一个危险的假设,但对我们来说是可行的。事实上,我们从来没有遇到过问题,所以我很高兴代码更少。我同意这是一个危险的假设。由于您希望此方法不仅仅适用于
存储库
对象,因此可能需要另一个基本接口。见下面我的答案。
List<User> users = ((Repository)getCountrySpecificComponent(uk, us)).findAll();
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);
    }
}
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(); 
  }
}