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

时间:2012-06-08 08:44:03

标签: java generics type-inference scjp

我已经阅读了整本SCJP6书籍Sierra和Bates的书,考试成绩为88%。

但是,我仍然没有听说过这种代码是如何工作的,因为它在泛型章节中没有解释:

Collections.<TimeUnit>reverseOrder()

这种仿制药的用法是什么? 我在一些代码中发现它但从未读过任何关于它的内容。 在我看来它允许给类型推断一些帮助。 我试图搜索一下,但这并不容易找到(而且它甚至不在SCJP书/考试中!)

那么有人可以给我一个正确的解释它是如何工作的,这些都是用例等吗?

由于


修改 谢谢你的答案,但我期待更多的细节:)所以,如果有人想添加一些额外的信息:

比较复杂的案例如

  • 使用类中声明的类型,我可以执行类似Collections.<T>reverseOrder()的示例吗?
  • 使用extendssuper
  • 使用?
  • 仅为编译器提供部分帮助(即O.manyTypesMethod<?,MyHelpTypeNotInfered,?,?,?,?,?>()

5 个答案:

答案 0 :(得分:18)

它是泛型方法的显式类型规范。你总是可以这样做,但在大多数情况下,它是不需要的。但是,在某些情况下,如果编译器无法自己推断泛型类型,则需要它。

查看the tutorial page末尾的示例。

更新:只有您的第一个示例有效。显式类型参数必须是明确的,因此不允许使用通配符extendssuper。此外,要么明确指定每个类型参数,要么不指定任何类型参数;即显式类型参数的数量必须与被调用方法的类型参数的数量相匹配。如果在当前范围内定义良好,则允许使用T等类型参数,例如作为封闭类的类型参数。

答案 1 :(得分:3)

你100%正确,它是为了帮助进行类型推断。大多数时候你不需要在Java中这样做,因为它可以推断出类型(甚至从作业的左侧来看,这很酷)。 Java网站上的generics tutorial 中介绍了此语法。

答案 2 :(得分:1)

只是对其他回复的一小部分。

获取相应的编译器错误时:

虽然是“传统”的铸造方式

(Comparator<TimeUnit>) Collections.reverseOrder()

看起来类似于泛型方法

Collections.<TimeUnit>reverseOrder()

转换方法当然不是类型安全的(可能的运行时异常),而泛型方法会在出现问题时产生编译错误。因此,当然,首选方法是优选的。

答案 3 :(得分:1)

正如其他答案已经阐明的那样,它可以帮助编译器找出你想要的泛型类型。当使用返回泛型类型并且不接收参数的Collections实用程序方法时,通常需要它。

例如,考虑返回空集合的Collections.empty*方法。如果您的方法需要Map<String, String>

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

无法直接将Collections.emptyMap()传递给它。 The compiler will complain即使知道它期望Map<String, String>

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

你必须明确declare the type you want in the call,我认为这看起来很丑陋:

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

或者你可以在方法调用中省略该类型声明,如果你assign the emptyMap return value to a variable之前将它传递给函数,我觉得这很荒谬,因为它似乎没必要,它表明编译器真的不一致:它有时会对没有参数的泛型方法进行类型推断,但有时它不会:

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

它可能看起来不是一件非常重要的事情,但是当泛型类型开始变得越来越复杂时(例如Map<String, List<SomeOtherGenericType<Blah>>>),一种开始希望Java会有更智能的类型推断(但是,因为它没有' t,人们可能会开始编写不需要的新类,只是为了避免所有那些丑陋的<> = D)。

答案 4 :(得分:0)

在这种情况下,它是一种告诉reverseOrder方法的方法,根据您指定的类型,应该对对象强加什么样的排序。比较器需要获得有关如何订购的具体信息。