【问题标题】:Java static polymorphism (overloading) and inheritance between genericsJava静态多态(重载)和泛型之间的继承
【发布时间】:2020-02-04 14:02:30
【问题描述】:

Java 11(可能不相关):

public static String toString(Object obj) {
    return ReflectionToStringBuilder.toString(obj, ToStringStyle.SHORT_PREFIX_STYLE);
}

public static String toString(Collection<Object> collection) {
    return collection.stream()
            .map(SaLogUtils::toString)
            .collect(Collectors.joining(", ", "[", "]"));
}

public static void main(String[] args) {
    List<Integer> list = List.of(Integer.valueOf(1));
    System.out.println(SaLogUtils.toString(list));
    System.out.println(SaLogUtils.toString(List.of(Integer.valueOf(1))));
}

令人惊讶的输出:

// from toString(Object)
ImmutableCollections.List12[e0=1,e1=<null>]
// from toString(Collection<Object>)
[Integer[value=1]]

为什么Java静态选择不同的方法?

【问题讨论】:

  • 顺便说一句,没有理由使用Integer.valueOf(1)。你可以简单地写List.of(1)

标签: java generics java-11 overload-resolution static-polymorphism


【解决方案1】:

当有多个可以调用的重载时,Java 选择the most specific applicable method

非正式的直觉是,如果第一个方法处理的任何调用都可以传递给另一个方法而不会出现编译时错误,那么一个方法比另一个方法更具体。在诸如显式类型化的 lambda 表达式参数 (§15.27.1) 或变量 arity 调用 (§15.12.2.4) 等情况下,可以灵活地调整一个签名以适应另一个签名。


toString(Collection&lt;Object&gt;) 不适用于List&lt;Integer&gt;,因为a List&lt;Integer&gt; isn't a List&lt;Object&gt;,所以它也不是Collection&lt;Object&gt;。因此,只有toString(Object) 方法适用,所以它是被调用的。


toString(Collection&lt;Object&gt;) 适用于List.of(someInteger),因为List.of 是一个多表达式:可以是List&lt;Integer&gt;,可以是List&lt;Object&gt;,也可以是List&lt;Serializable&gt;

由于toString(Object)toString(Collection&lt;Object&gt;) 都适用,它必须选择一个或另一个(或声明它是模棱两可的)。 Collection 重载更具体,因为:

  • 你传递给toString(Collection&lt;Object&gt;)的任何东西也可以传递给toString(Object)
  • 但是有些东西可以传递给toString(Object),但不能传递给toString(Collection&lt;Object&gt;)(例如new Object())。

这使得toString(Collection&lt;Object&gt;) 更加具体,所以这是被选中的那个。

【讨论】:

  • 作为附录,解决该问题的可能预期是将签名更改为toString(Collection&lt;?&gt; collection)...
猜你喜欢
  • 2020-01-06
  • 2014-06-01
  • 1970-01-01
  • 2014-05-24
  • 1970-01-01
  • 2018-01-19
  • 2013-06-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多