因此,好的' Dietel 表示,“所有通用方法声明都有类型参数部分由尖括号(<和>)在方法返回类型,“(Deitel,2012,italicized emphasis mine)之前。给出的例子如下:
public static < T > void printArray (T[] inputArray)
{
for (T element : inputArray)
(
System.out.printlf("%s", element);
}
这对我有意义。我明白了。但是,这是我的问题,书中没有明确说明。
我有一个非常简单的课程来演示:
public class Pair<F, S>
{
private F first;
private S second;
}
现在,根据Deitel的说法,“ ALL ”泛型方法声明必须包含一个类型参数部分。所以,当然,我想在我的类示例中添加get()
和set()
方法。所以,我这样做:
public class Pair<F, S>
{
private F first;
private S second;
// Here, I'll do one instead of both for the sake of shortening the code
public < F > F getF()
{
return F;
}
// And the Accessor:
public < F > void setF(F first)
{
this.first = first;
}
}
所以,这是交易。在我尝试编译(Intellisense的Java版本)之前,Eclipse IDE给出了一个警告:“类型参数F隐藏类型F”。现在,我并不特别信任 Dietel for Java - 并且我越来越了解他们并不是特别可靠(因为他们经常遗漏重要的区别)。所以,我去了Oracle Documentation我正在做的事情 - GUESS WHAT - 他们没有提到任何类型,除非你在谈论'upperbounded'类型参数。
这是问题(它有三个):
答案 0 :(得分:4)
JLS专门指定一个声明类型参数的泛型方法。 (JLS)所以这里的混淆是Deital已经说过&#34;所有泛型方法都有一个类型参数部分&#34; 但可能没有特别指出这是他们的定义。更明显的是,&#34;泛型方法是具有类型参数部分&#34; 的方法。
如注释中所述,当您具有类声明的类型参数时,您无需在该方法中重新声明它们。如Eclipse所述,这样做实际上声明了新类型参数,这些参数隐藏了类声明的参数。
当在课堂上宣布它们时,你可以直接使用它们:
class Pair<F, S> {
F getF() { ... }
S getS() { ... }
void setF(F f) { ... }
void setS(S s) { ... }
}
通用方法的目的是参数化地使用它。给出的示例不是特别适合理解,因为泛型类型实际上未使用:调用Object的printf
重载。它可以在没有泛型的情况下重写,而不会改变其功能:
public static void printArray(Object[] arr) {
for(Object o : arr) {
System.out.printf("%s", o);
}
}
理解泛型方法使用的最简单的例子是Objects#requireNonNull
的实现,如下所示:
public static <T> T requireNonNull(T obj) {
if(obj == null)
throw new NullPointerException();
return obj;
}
它接受任何对象并方便地将其作为T
:
// T is inferred
String hello = Objects.requireNonNull("hello world");
// T is provided as a witness (rarely necessary)
Integer five = Objects.<Integer>requireNonNull(5);
这是最简单的通用方法。