泛型,需要外行解释?

时间:2014-10-02 15:44:46

标签: java generics

我遇到了以下使用泛型的代码片段。

public class Generics<T> {

   public static <T> T replaceIfNull(T objectToCheck, T defaultValue) {
      return objectToCheck == null ? defaultValue : objectToCheck;
   }

   public static <T> boolean CheckIfNull(T objectToCheck) {
      return objectToCheck == null ? true : false;
   }
}

我很难真正理解泛型如何工作,形成和使用。我有一个高层次的理解,这意味着我知道泛型的定义。根据定义,我对此代码片段的解释是replaceIfNull方法检查任何对象的空值,然后返回默认值(无论是什么)。并且CheckIfNull方法类似,因为它检查任何对象的空值。

但这是如何运作的?为什么该方法由<T>形成,它似乎是一种类型,然后有T。我不明白这种语法,<T> T是什么意思? T如何成为参数中的类型?例如,为什么这种方法不能写成

public static Object replaceIfNull(Object objectToCheck, Object defaultValue) {
   return objectToCheck == null ? defaultValue : objectToCheck;
}

提前感谢您的澄清。

2 个答案:

答案 0 :(得分:2)

泛型的主题非常广泛,您可以在Oracle的网站或Stack Overflow上广泛阅读。

  

为什么该方法由<T>构成,它似乎是一种类型,然后有T

这是一种通用方法。 <T>声明一个没有边界的新类型变量。

//                v return type   
public static <T> T replaceIfNull(T objectToCheck, T defaultValue) {
//             ^ new type variable                 ^ type variable used as a type

在方法体内,由于类型变量没有边界,T最多可以解释为Object。您只能访问Object类型T表达式T中声明的方法。

在方法之外,即。在调用上下文中,类型变量replaceIfNull(someStringVar, otherStringVar); 将接收具体的类型值。也就是说,它将从其调用上下文推断它,或者它将被明确提供。

例如,在

T

类型变量String将绑定到T,因此String的所有用法都将被解释为String notNull = replaceIfNull(someStringVar, " not null "); 。你可以这样做

Generics.<String>replaceIfNull(nullVar, " not null ");

您还可以明确提供类型参数

String

现在再次将类型变量绑定到T

请注意,在类型级别

声明的类型变量public class Generics<T>
T

与方法中声明的类型变量{{1}}完全不同。

答案 1 :(得分:2)

让我们开始回答你的上一个问题。使用Object而不是泛型重写的方法有两个缺点。首先,它不适用于原语(在这种情况下可能不是真正的缺点,因为你正在检查null,而原语不能取空值,但仍然......)。其次,它需要铸造。例如,如果你在两个字符串上使用这个方法,比如replaceIfNull(myString, "Default Value"),那么你希望得到一个String作为输出,对吧?但是声明返回Object的方法;因此,编译器无法知道它将返回一个String,并且每次使用它时都必须进行转换:`String result =(String)replaceIfNull(myString,&#34;默认值&#34;) ;&#39;特别介绍了泛型来解决这种情况。

您可以将泛型视为模板;无论何时使用类型参数,您在角度括号中放置的任何类型都将在代码中稍后使用。所以,<T>意味着:&#34;这将是某种类型;在代码中随处替换T&#34;。

最后一个问题是方法签名。我想在这里你混淆了两种使用泛型的方法 - 在类级别和方法级别。由于您已经在类级别引入了类型参数,因此无需在方法级别上再次执行此操作,因此我认为您可以安全地从方法声明中删除<T>

我建议您在此处阅读有关泛型的更详细说明:http://docs.oracle.com/javase/tutorial/java/generics/