简体   繁体   English

Java中的这种泛型用法是什么? X. <Y>()的方法

[英]What's this generics usage in Java? X.<Y>method()

I've read the whole SCJP6 book Sierra and Bates book, scored 88% the exam. 我已经阅读了整本SCJP6书籍Sierra和Bates的书,考试成绩为88%。

But still, i never heard of how this kind of code works as it's not explained in the generics chapter: 但是,我仍然没有听说过这种代码是如何工作的,因为它在泛型章节中没有解释:

Collections.<TimeUnit>reverseOrder()

What is this kind of generics usage? 这种仿制药的用法是什么? I discovered it in some code but never read anything about it. 我在一些代码中发现它但从未读过任何关于它的内容。 It seems to me it permits to give some help to type inference. 在我看来它允许给类型推断一些帮助。 I've tried to search about that but it's not so easy to find (and it's not even in the SCJP book/exam!) 我试图搜索一下,但这并不容易找到(而且它甚至不在SCJP书/考试中!)

So can someone give me a proper explaination of how it works, which are all the usecases etc? 那么有人可以给我一个正确的解释它是如何工作的,这些都是用例等吗?

Thanks 谢谢


Edit Thanks for the answers but i expected more details :) so if someone want to add some extra informations: 编辑感谢您的答案,但我期待更多细节:)所以如果有人想添加一些额外的信息:

What about more complex cases like 更复杂的情况如何呢?

  • Using a type declared in class , can i do something like Collections.<T>reverseOrder() for exemple? 使用类中声明的类型,我可以执行类似Collections.<T>reverseOrder()例如?
  • Using extends , super ? 使用extendssuper
  • Using ? ?
  • Giving the compiler only partial help (ie O.manyTypesMethod<?,MyHelpTypeNotInfered,?,?,?,?,?>() ) 只为编译器提供部分帮助(即O.manyTypesMethod<?,MyHelpTypeNotInfered,?,?,?,?,?>()

It is explicit type specification of a generic method. 它是泛型方法的显式类型规范。 You can always do it, but in most cases it's not needed. 你总是可以这样做,但在大多数情况下,它是不需要的。 However, it is required in some cases if the compiler is unable to infer generic type on its own. 但是,在某些情况下,如果编译器无法自己推断泛型类型,则需要它。

See an example towards the end of the tutorial page . 请参阅教程页面末尾的示例

Update: only the first of your examples is valid. 更新:只有您的第一个示例有效。 The explicit type argument must be, well, explicit, so no wildcards, extends or super is allowed there. 显式类型参数必须是明确的,因此不允许使用通配符, extendssuper Moreover, either you specify each type argument explicitly or none of them; 此外,要么明确指定每个类型参数,要么不指定任何类型参数; ie the number of explicit type arguments must match the number of type parameters of the called method. 即显式类型参数的数量必须与被调用方法的类型参数的数量相匹配。 A type parameter such as T is allowed if it is well defined in the current scope, eg as a type parameter of the enclosing class. 如果在当前范围中明确定义了类型参数(例如T则允许使用类型参数,例如作为封闭类的类型参数。

You are 100% correct, it is to help with type inference. 你100%正确,它是帮助类型推断。 Most of the time you don't need to do this in Java, as it can infer the type (even from the left hand side of an assignment, which is quite cool). 大多数时候你不需要在Java中这样做,因为它可以推断出类型(甚至从作业的左侧来看,这很酷)。 This syntax is covered in the generics tutorial on the Java website. Java网站上的泛型教程中介绍了此语法。

Just a small addition to the other responses. 只是对其他回复的一小部分补充。

When getting the according compiler error: 获取相应的编译器错误时:

While the "traditional" casting approach 而“传统”的铸造方式

(Comparator<TimeUnit>) Collections.reverseOrder()

looks similar to the generics approach 看起来类似于泛型方法

Collections.<TimeUnit>reverseOrder()

the casting approach is of course not type-safe (possible runtime exception), while the generics approach would create a compilation error, if there is an issue. 转换方法当然不是类型安全的(可能的运行时异常),而泛型方法会在出现问题时产生编译错误。 Thus the generics approach is preferred, of course. 因此,当然,优选通用方法。

As the other answers have clarified, it's to help the compiler figure out what generic type you want. 正如其他答案所阐明的那样,它可以帮助编译器找出您想要的泛型类型。 It's usually needed when using the Collections utility methods that return something of a generic type and do not receive parameters. 当使用Collections实用程序方法返回泛型类型并且不接收参数时,通常需要它。

For example, consider the Collections.empty* methods, which return an empty collection. 例如,考虑Collections.empty*方法,它返回一个空集合。 If you have a method that expects a Map<String, String> : 如果您有一个需要Map<String, String>

public static void foo(Map<String, String> map) { }

You cannot directly pass Collections.emptyMap() to it. 不能直接将Collections.emptyMap()传递给它。 The compiler will complain even if it knows that it expects a Map<String, String> : 即使编译器 知道它需要Map<String, String> ,它也会抱怨

// This won't compile.
foo(Collections.emptyMap());

You have to explicitly declare the type you want in the call , which i think looks quite ugly: 你必须在调用中明确声明你想要的类型 ,我觉得这看起来很难看:

foo(Collections.<String, String>emptyMap());

Or you can omit that type declaration in the method call if you assign the emptyMap return value to a variable before passing it to the function, which i think is quite ridiculous, because it seems unnecessary and it shows that the compiler is really inconsistent: it sometimes does type inference on generic methods with no parameters, but sometimes it doesn't: 或者你可以在方法调用中省略该类型声明,如果你emptyMap返回值分配给变量,然后再将它传递给函数,我认为这是非常荒谬的,因为它似乎没必要,它表明编译器确实是不一致的:它有时会对没有参数的泛型方法进行类型推断,但有时它不会:

Map<String, String> map = Collections.emptyMap();
foo(map);

It may not seem like a very important thing, but when the generic types start getting more complex (eg Map<String, List<SomeOtherGenericType<Blah>>> ) one kind of starts wishing that Java would have more intelligent type inference (but, as it doesn't, one will probably start writing new classes where it's not needed, just to avoid all those ugly <> =D). 它可能看起来不是一件非常重要的事情,但是当泛型类型开始变得越来越复杂时(例如Map<String, List<SomeOtherGenericType<Blah>>> ),一种开始希望Java会有更智能的类型推断(但是,因为它没有,人们可能会开始编写不需要的新类,只是为了避免所有那些丑陋的<> = D)。

In this case it is a way of telling the reverseOrder method what kind of ordering should be imposed on the object, based on what type you specify. 在这种情况下,它是一种告诉reverseOrder方法的方法,根据您指定的类型,应该对对象强加什么样的排序。 The comparator needs to get specific information about how to order things. 比较器需要获得有关如何订购的具体信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM