【问题标题】:Java incompatible type for type parameter in presence of wildcards存在通配符时类型参数的 Java 不兼容类型
【发布时间】:2022-11-23 01:44:04
【问题描述】:

我有以下课程。我无法满足通用类型。 请帮助我理解这个问题。

我有以下课程。我无法满足通用类型。 请帮助我理解这个问题。

// Requirement is that each implementation of MappedKey should also be sortable. Hence should implement Comparable<ConcreteType>.
public interface MappedKey<T extends MappedKey<T>> extends Comparable<T> {
  String displayName();
}
public interface DataMapper<K extends MappedKey<K>, V> {
  ImmutableMap<K, ImmutableList<V>> map(List<V> data, Message config);
}
// Call site
Map<MapperType, DataMapper<?, Country>> mappers = getMappers();
ImmutableMap<K, ImmutableList<V>> mapped = mappers.get(MAPPER_TYPE).map(getData());

// Here I want to sort the keys returned by mapper. 
List<MappedKey<?>> keys = new ArrayList<>(mapped.keySet()); // Note that this doesn't throw error because type parameter K in DataMapper definition extends MappedKey<K>.


Collections.sort(keys);

运行时出现以下错误。我的理由是类型是满足的。由于MappedKey&lt;?&gt;实现了Comparable&lt;? super T#1&gt;T#1 = MappedKey&lt;?&gt;满足所有约束。我在这里错过了什么?谢谢

no suitable method found for sort(List<MappedKey<?>>)
    Collections.sort(keys);
               ^
    method Collections.<T#1>sort(List<T#1>) is not applicable
      (inference variable T#1 has incompatible bounds
        equality constraints: MappedKey<?>
        upper bounds: CAP#1,Comparable<? super T#1>)
    method Collections.<T#2>sort(List<T#2>,Comparator<? super T#2>) is not applicable
      (cannot infer type-variable(s) T#2
        (actual and formal argument lists differ in length))
  where T#1,T#2 are type-variables:
    T#1 extends Comparable<? super T#1> declared in method <T#1>sort(List<T#1>)
    T#2 extends Object declared in method <T#2>sort(List<T#2>,Comparator<? super T#2>)
  where CAP#1 is a fresh type-variable:
    CAP#1 extends Comparable<CAP#1> from capture of ?

【问题讨论】:

  • 在呼叫站点的第二行中,您输入 ImmutableMap&lt;K, ImmutableList&lt;V&gt;&gt; mappedKV 声明在哪里?
  • ? 意味着它的意思 - 它不会神奇地更新自己到你正在使用的东西的有效范围?为了。这很不幸,但据我所知,这是一个 Java 限制。您可能只需要在此处接受它,转换为原始类型,然后从那里进行排序 - 并使用 @SuppressWarnings 消除此转换可能导致的警告。

标签: java generics


【解决方案1】:

你的MappedKeys 只能与其他人相提并论同类型. MappedKey&lt;A&gt; 可与MappedKey&lt;A&gt; 相比,但不可与MappedKey&lt;B&gt; 相比。

但是,就 Java 的类型系统而言,List&lt;MappedKey&lt;?&gt;&gt; 可以包含多种不同类型的 MappedKey

List<MappedKey<?>> keys = new ArrayList<>();
keys.add(new KeyA());
keys.add(new KeyB());
keys.add(new KeyC());

而这些没有可比性。

如果您改为将 Comparable 继承子句更改为 extends Comparable&lt;MappedKey&lt;?&gt;&gt;,那么任何kind of key 与 any kind key 相当,然后 sort 将编译。或者如果 keysList&lt;MappedKey&lt;SomeSpecificType&gt;&gt;,那么它也会编译。

我们实际上可以通过编写一个泛型辅助方法,并让SomeSpecificType成为一个泛型类型参数,人为地将keys变为List&lt;MappedKey&lt;SomeSpecificType&gt;&gt;

public static <K extends MappedKey<K>> List<MappedKey<K>> sort(List<MappedKey<K>> list) {
    Collections.sort(list);
    return list;
}

现在你可以这样做:

// not sure what K and V in your code are. The type of mapped should be:
ImmutableMap<? extends MappedKey<?>, ImmutableList<Country>> mapped = mappers.get(MAPPER_TYPE).map(getData());
List<? extends MappedKey<?>> keys = sort(new ArrayList<>(mapped.keySet()));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-07
    • 2013-08-15
    • 1970-01-01
    • 2021-07-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多