【问题标题】:Javac cannot infer the type without auxiliary variableJavac 无法推断没有辅助变量的类型
【发布时间】:2015-03-06 15:43:35
【问题描述】:

我遇到了无法解释的 java 编译器 (jdk1.6.0_45) 行为。 这里有两个代码 sn-ps——第一个编译,而第二个不编译。 编译:

Map<String, Collection<MyClass>> result = Maps.newHashMap();

Comparator<? super MyClass> comparator = comparatorProvider.getComparator(*some parameter*);
TreeMultiset<MyClass> multiSet = TreeMultiset.create(comparator);
result.put("blahBlah", multiSet);

不编译:

Map<String, Collection<MyClass>> result = Maps.newHashMap();

Comparator<? super MyClass> comparator = comparatorProvider.getComparator(*some parameter*);
result.put("blahBlah", TreeMultiset.create(comparator));

Maps 和 TreeMultiset 类是 Google-Guava 库的一部分。

第二个 sn-p 无法编译,报错:

put(java.lang.String,java.util.Collection<MyClass>) in java.util.Map<java.lang.String,java.util.Collection<MyClass>> cannot be applied to (java.lang.String,com.google.common.collect.TreeMultiset<java.lang.Object>)

注意 java.lang.Object 部分的错误。因此,如果没有明确的“multiset”变量,javac 似乎无法推断 TreeMultiset 的类型。

工厂方法的代码如下:

@SuppressWarnings("unchecked")
public static <E> TreeMultiset<E> create(
  @Nullable Comparator<? super E> comparator) {
return (comparator == null)
       ? new TreeMultiset<E>((Comparator) Ordering.natural())
       : new TreeMultiset<E>(comparator);
}

非常感谢您对此行为的任何澄清。

即使是 IDE (Intellij IDEA) 也不会出错。

【问题讨论】:

  • 提高你的警告。你有很多未经检查的操作,可能会导致一些意想不到的结果。
  • 没有一个未经检查的操作——“getComparator()”方法在输入参数上参数化并且类型安全。而且为 TreeMultiset 提供的工厂方法是 Google-Guava 库的一部分,我无能为力。
  • 用番石榴标记了这个。对番石榴更熟悉的人可能会提供更好的帮助。

标签: java guava type-inference java-6


【解决方案1】:

Java 类型推断没有我们想要的那么强大(与 Scala 相比)。您可以在没有辅助变量的情况下给出相同的类型参数:

result.put("blahBlah", TreeMultiset.<MyClass>create(comparator));

【讨论】:

  • 是的,我知道我可以,但我仍然不知道在这种特殊情况下有什么问题。工厂方法清楚地指出——“获取传递的比较器的有界类型并返回该类型的 TreeMultiset(实现 Collection 接口)”。在这种情况下,它应该总是返回 TreeMultiset。为什么我必须显式声明类型?
  • 在第一个示例中,调用“create”的结果被分配给变量 TreeMultiset。因此,编译器推断唯一可能的类型参数是 MyClass ——这是一个很容易做出的推断。在第二个示例中,调用“create”的结果作为参数传递给“put”,它本身就是一个通用方法。你和我可以看到 put 的类型参数将是 Collection,所以它唯一的工作方式是如果 create 的类型参数是 MyClass,但这是一个额外的逻辑步骤,Java 编译器没有实现.
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-08-05
  • 1970-01-01
  • 2019-03-10
  • 2020-02-18
  • 2019-03-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多