我的方法签名中的这些东西叫做什么?泛型?

时间:2014-10-09 03:31:01

标签: java generics

我有一个方法签名,可以按值对给定的地图进行排序。

public static <K extends Comparable<K>, V extends Comparable<V>> Map<K,V> sortByValues(Map<K,V> map){

我正在尝试理解此方法签名中的事物的术语。我得到publicstaticMap<K,V>,函数名称和参数部分。

我的困惑在于<K extends Comparable<K>, V extends Comparable<V>>部分。它的目的是在方法的上下文中定义KV是什么,对吗?描述这个的适当术语是什么?

关于泛型的任何推荐读物或文章?

3 个答案:

答案 0 :(得分:0)

是的,KV这里是通用type parameters。更具体地说,正如@aruisdante在注释中指出的那样,它们是有界类型参数,因为它们指定了参数化类型必须满足的边界 - 即它们都必须实现Comparable。

看起来您的问题一般是关于参数,而不是特别关于有界参数。你应该自己做一些阅读,因为你正在询问a big (and important) topic,但我会尝试介绍它:

您可能熟悉在不同的上下文中查看类型参数 - Map<String, Integer><String, Integer>这里也是类型参数,并且它们指定此映射中的键为String s其中的值为Integer s。在方法声明的上下文中,类型参数指定返回类型的内容。这意味着您可以编写generic methods,每次调用时都会返回不同的类型,具体取决于您传入的内容:

请注意,KV是方法本身和传入参数的类型参数:这告诉Java确定KV查看传入的映射的键和值类型,返回具有相同类型的映射。如果您致电sortByValue(fooMap)fooMapMap<String, FooType>,则会返回地图<String, FooType>,如果fooMapMap<Integer, BarType>你将得到一个Map<Integer, BarType>

有关更清晰的示例,请考虑:

public <T> foobar(T t) {  }

这里类型参数是无界的 - 意味着T可以是任何类,因此您可以将任何类的对象作为参数传递,并获得返回的相同类型的对象。或者

public<T> convertTo(Object o, Class<T> clazz) { } 

在这里,您可以传入任何类的对象作为第一个参数,并将Class对象作为第二个参数传递,以确定T将是什么。所以你可以这样做:

Fooclass s = convertTo(someObject, Fooclass.class) 

,正如您可能想象的那样,这可能是一个非常有用的模式。

答案 1 :(得分:0)

它们是参数化类型的示例,根据JLS Chapter 4. Types, Values, and Variables部分说明

  

具有一个或多个类型参数A1,...,An的泛型类或接口声明C(§8.1.2§9.1.2)具有相应的边界B1,...,Bn定义了一个集合参数化类型,每个可能调用类型参数部分。

     

集合中的每个参数化类型都是C形式,其中每个类型参数Ti的范围超过所有类型,这些类型是相应边界中列出的所有类型的子类型。也就是说,对于Bi中的每个束缚型Si,Ti是Si的子类型[F1:= T1,...,Fn:= Tn]。

     

...

     

给定一个类型声明说明符后面紧跟一个类型参数列表,让C成为说明符中的最终标识符。

答案 2 :(得分:0)

我看到泛型的方式与我看到类的方式相同,仅用于类型和方法。他们将方法和数据结构概括为原生支持所有有界类型。

不是用相同的方法一遍又一遍地编码同一个对象,而是说#34;好的家伙,无论你在< >告诉我什么课,我都会理解&# 34。

假设您要在未知对象的数组中编写二进制搜索...您可以编写以下签名:

public boolean binarySearch(Object[] array)...

但是,如果您希望仅通过某些类型的数据(彼此可比较的类型)访问该方法,该怎么办?这就是你将如何做到这一点:

public <T extends Comparable<T>> boolean binarySearch(T[] array)...

其内容如下:&#34;这是一个公共方法,只接收包含对象的数组(我们称之为T),这些对象实现了相同类(T)的Comparable接口。

不仅可以在泛型中扩展类,还可以扩展接口(就像上面的例子一样)。

对于像

这样的数据结构
Vector<Integer> v;

这意味着Vector v只能保存Integer对象而不包含其他类型。

通配符在绑定对象时具有相同的原则,例如:

Vector<? extends Person> v;

该向量v仅包含超类为Person的类。

Vector<?> v;

大致相当于此

Vector<Object> v;