英文:
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 <T, U extends Comparable<? super U>> Comparator<T> comparing(
Function<? super T, ? extends U> 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 -> { ... });
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 -> { ... }));
// or
Comparator<SomeType> c = Comparator.comparing(x -> { ... });
In both of these situations, there are more information to determine what T
is. Notice that the return type of comparing
is Comparator<T>
, so if someMethod
above accepts a Comparator<SomeType>
, 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) -> { ... })
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论