泛型类型推断失败? [英] Generics type inference fails?

查看:91
本文介绍了泛型类型推断失败?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

示例A



请阅读以下代码片段:

  public class ExampleA {
static class Pair< F,S> {}

static< F,S>对< F,S> anyPair(){return null; }

static< F,S> (Pair p1,Pair p2){return; }

public static void main(String [] args){
Pair< String,Integer> p = anyPair();

process(p,anyPair()); //不会编译
}
}

有人可以解释为什么type推理适用于赋值给局部变量 p ,但不适用于第二个实际参数< process ?






示例B



这可能更容易理解:

  public class ExampleB {
public static< E>无效过程(Set< E> s1,Set< E> s2){return; }
$ b public static void main(String [] args){
process(new HashSet< String>(),Collections.emptySet()); // does not compile
}
}

同样的问题: 't it compile?



我希望 Collections.emptySet()只适用于 ANY 参数化 Set 类型。

解决方案

anyPair()没有任何方法来确定它的类型,所以它默认为< Object,Object>

编译器将 process(p,anyPair()); 分解为几部分并分别进行处理。当它这样做时,它需要首先处理参数以确定它们的类型,然后可以在处理 process 时使用它。



当它处理 anyPair()时,没有可用的类型信息,因为它不知道它是 process 。它默认为< Object,Object> ,然后在查看 process 时导致类型不匹配。



第二个例子会发生同样的情况。 Collections.emptySet()需要自行处理,但无法确定所需的类型。

有两种方法可以解决这个问题:

第一种方法是给编译器提供类型推断所需的信息,就像您对第一次调用<$ c

第二个(感谢@BalusC)是$ b> anyPair(),它存储在一个临时变量中。使用 ExampleA。< String,Integer> anyPair()。该语法显式设置所需的类型,而不必超出调用范围。


Example A

Study the following snippet:

public class ExampleA {
   static class Pair<F,S> { }

   static <F,S> Pair<F,S> anyPair() { return null; }

   static <F,S> void process(Pair<F,S> p1, Pair<F,S> p2) { return; }

   public static void main(String[] args) {
      Pair<String,Integer> p = anyPair();

      process(p, anyPair()); // doesn't compile
   }
}

Can someone explain why type inference works for the assignment to local variable p but not for the second actual parameter to process?


Example B

This is perhaps simpler to understand:

public class ExampleB {     
   public static <E> void process(Set<E> s1, Set<E> s2) { return; }

   public static void main(String[] args) {
      process(new HashSet<String>(), Collections.emptySet()); // doesn't compile
   }
}

Same question: why doesn't it compile?

I'd hope that Collections.emptySet() would just work for ANY parameterized Set type.

解决方案

Your second call to anyPair() does not have any way to determine it's types and so it defaults to <Object, Object>.

The compiler is breaking process(p, anyPair()); into it's pieces and processing each individually. When it does this, it needs to process the arguments first to determine their types, which can then be used when processing process.

When it goes to process anyPair() there is no type information available for that piece, because it does not know that it is part of process at that point. It defaults to <Object, Object>, which then causes a type mismatch when looking at process.

The same thing happens with your second example. Collections.emptySet() needs to be processed by itself, but has no way of determining the Types needed.

There are 2 ways to solve this:

The first is to give the compiler the information it needs for type inference the same way you did with the first call to anyPair(), by storing it in a temporary variable with the correct type.

The second (thanks to @BalusC) is to use ExampleA.<String, Integer>anyPair(). This syntax explicitly sets the types needed without having to look beyond the invocation.

这篇关于泛型类型推断失败?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆