Java 静态多态(重载)和泛型之间的继承
Java static polymorphism (overloading) and inheritance between generics
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静态选择不同的方法?
当有多个重载可以调用时,Java选择the most specific applicable method:
The informal intuition is that one method is more specific than another if any invocation handled by the first method could be passed on to the other one without a compile-time error. In cases such as an explicitly typed lambda expression argument (§15.27.1) or a variable arity invocation (§15.12.2.4), some flexibility is allowed to adapt one signature to the other.
toString(Collection<Object>)
不适用于 List<Integer>
,因为 a List<Integer>
isn't a List<Object>
,所以它也不是 Collection<Object>
。因此,只有 toString(Object)
方法适用,所以这是被调用的方法。
toString(Collection<Object>)
适用于 List.of(someInteger)
因为 List.of
是一个多表达式:它可以是 List<Integer>
,也可以是 List<Object>
,也可以是List<Serializable>
.
由于toString(Object)
和toString(Collection<Object>)
都适用,所以只能二选一(或者声明有歧义)。 Collection
重载更具体,因为:
- 您传递给
toString(Collection<Object>)
的任何内容也可以传递给 toString(Object)
- 但有些东西可以传递给
toString(Object)
而不能传递给 toString(Collection<Object>)
(例如 new Object()
)。
这使得 toString(Collection<Object>)
更加具体,因此选择了这个。
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静态选择不同的方法?
当有多个重载可以调用时,Java选择the most specific applicable method:
The informal intuition is that one method is more specific than another if any invocation handled by the first method could be passed on to the other one without a compile-time error. In cases such as an explicitly typed lambda expression argument (§15.27.1) or a variable arity invocation (§15.12.2.4), some flexibility is allowed to adapt one signature to the other.
toString(Collection<Object>)
不适用于 List<Integer>
,因为 a List<Integer>
isn't a List<Object>
,所以它也不是 Collection<Object>
。因此,只有 toString(Object)
方法适用,所以这是被调用的方法。
toString(Collection<Object>)
适用于 List.of(someInteger)
因为 List.of
是一个多表达式:它可以是 List<Integer>
,也可以是 List<Object>
,也可以是List<Serializable>
.
由于toString(Object)
和toString(Collection<Object>)
都适用,所以只能二选一(或者声明有歧义)。 Collection
重载更具体,因为:
- 您传递给
toString(Collection<Object>)
的任何内容也可以传递给toString(Object)
- 但有些东西可以传递给
toString(Object)
而不能传递给toString(Collection<Object>)
(例如new Object()
)。
这使得 toString(Collection<Object>)
更加具体,因此选择了这个。