通用方法,没有关于参数的额外信息。

huangapple go评论82阅读模式
英文:

Generic methods with no extra information on Parameter

问题

据我所知,这是一个通用方法(与通用类的方法相对):

public static <T, U extends Comparable<? super U>> Comparator<T> comparing(
        Function<? super T, ? extends U> keyExtractor)

我很好奇在我传入任何keyExtractor lambda时,Java如何决定参数类型,考虑到T是参数化的。

如果有一些额外的信息,比如如果T被限制为T super Z,其中Z是某个具体的类型,那么只能传入Z的子类是有意义的,因此在keyExtractor lambda内部,我可以进行类型检查,就好像传入了一个Z类对象一样。

但考虑到关于T没有可用信息,这是如何工作的呢?
它是根据调用comparing返回的lambda的上下文来决定的吗?
我感到非常困惑,可能我对泛型和lambda的理解不够透彻。

如果有任何解释,我将不胜感激,谢谢!

英文:

As far as I can tell, this is a generic method (as opposed to a method of a generic class):

public static &lt;T, U extends Comparable&lt;? super U&gt;&gt; Comparator&lt;T&gt; comparing(
        Function&lt;? super T, ? extends U&gt; keyExtractor)

I'm curious how Java decides the parameter types for any keyExtractor lambda that I pass in, given that T is parameterized.

If there was some extra information, like if T was restricted to being T super Z for some concrete Z, then it would make sense that you can only pass in subclasses of Z, and thus inside the keyExtractor lambda I can typecheck as if a class Z object has been passed in.

But given that there's no information available on T, how does this even work?
Does it decide based on the context of how the lambda being returned by comparing is being used?
I'm very confused, but maybe I don't fully understand generics and lambdas.

Any clarification would be appreciated, thanks!

答案1

得分: 0

> 但是考虑到关于 T 没有可用信息,这是如何工作的呢?

如果确实没有关于 T 的可用信息,那么它会默认为 Object,就像当你将 comparing 作为独立语句调用时一样:

Comparator.comparing(x -> { ... });

x 的编译时类型将是 Object

但是你很少会这样调用 comparing,对吧?通常你会将它的返回值传递给方法,或者至少先将它赋值给一个已知类型的变量:

someMethod(Comparator.comparing(x -> { ... }));
// 或者
Comparator<SomeType> c = Comparator.comparing(x -> { ... });

在这两种情况下,都有更多的信息来确定 T 是什么。请注意,comparing 的返回类型是 Comparator<T>,因此如果上述的 someMethod 接受一个 Comparator<SomeType>,类型推断引擎可以推断出在这两种情况下 T 必须是 SomeType

还要注意,你可以在 lambda 表达式中指定参数的类型,这也有助于推断 T

Comparator.comparing((SomeType x) -> { ... })
英文:

> But given that there's no information available on T, how does this even work?

If there really is no information available on T, then it defaults to Object, such as when you call comparing as a standalone statement:

Comparator.comparing(x -&gt; { ... });

The compile time type of x will be Object.

But you rarely call comparing like that, right? You usually pass its return value into method, or at least assign it to a variable of a known type first:

someMethod(Comparator.comparing(x -&gt; { ... }));
// or
Comparator&lt;SomeType&gt; c = Comparator.comparing(x -&gt; { ... });

In both of these situations, there are more information to determine what T is. Notice that the return type of comparing is Comparator&lt;T&gt;, so if someMethod above accepts a Comparator&lt;SomeType&gt;, the type inference engine can work out that T must be SomeType in both cases.

Also note that you can specify the parameter's type in a lambda, this helps infer T as well:

Comparator.comparing((SomeType x) -&gt; { ... })

huangapple
  • 本文由 发表于 2020年8月27日 08:17:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/63607419.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定