4

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();

これはJava7でコンパイルされます

List<User> users = ((Repository)getCountrySpecificComponent(uk, us)).findAll();

これはかなり珍しいユースケースであることを私は知っていますが、この変更の理由はありますか?または、コンパイラに少し「賢い」ことを伝える方法はありますか?

4

3 に答える 3

3

Tを拡張するために制限されるべきだと思いますRepository。このようにして、コンパイラはそれgetCountrySpecificComponentがリポジトリを返すことを認識します。

編集:

次のように書いても大丈夫です。public static <T extends Repository> T getCountrySpecificComponent(T uk, T us)

于 2012-05-22T13:12:44.040 に答える
0

それから私は、古いコンパイラがそれを受け入れるのは間違いだったことに同意します。私はあなたがこのようなものが欲しいと思います:

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);
    }
}
于 2012-05-22T13:19:33.263 に答える
0

この場合、コンパイラは型パラメータを推測できませんでした。これはおそらくJava6でも当てはまるはずです。ただし、以下の構文を使用して、ジェネリック型が何であるかをコンパイラーに伝えることができます。

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(); 
  }
}
于 2012-05-22T15:23:24.060 に答える