这就是我所拥有的:
public class Node<T> {
// instance variables
private Node<T> next;
private T data;
// construct with data
private Node(T data){
next = null;
this.data = data;
}
// construct without data
private Node(){
next = null;
this.data = null;
}
// static factory method
public static <T> Node<T> newNodeWithData(T data){
return new Node<T>(data);
}
// static factory method
public static <T> Node<T> newNode(){
return new Node<T>();
}
...
}
我的问题实际上只是泛型的语法加上静态工厂方法的语法。我真的不明白为什么我们把&lt; T>在方法声明中返回类型之前。有点像类型转换吗?任何帮助将不胜感激!
答案 0 :(得分:26)
您要问的是类型推理。
因为它是一个静态方法,它必须从某个地方推断出通用类型;您没有该类的实例。这就是<T>
的含义。
如果你的方法没有参数,它实际上是从赋值的目标推断它。例如,假设您的方法如下所示:
public static <T> List<T> getNewList() {
return new ArrayList<T>();
}
使用此方法时,会从目标推断T
(在本例中为String
):
List<String> myList = MyClass.getNewList();
在你有一个Generic参数的另一个静态方法中,从传入的类型中推断出T
:
public static <T> List<T> getNewListWithElement(T element) {
List<T> list = new ArrayList<T>();
list.add(element);
return list;
}
在这里,如果您尝试过:
List<String> myList = MyClass.getNewListWithElement(new Integer(4));
它会告诉您目标类型错误,并且需要List<Integer>
答案 1 :(得分:8)
你必须用这样的糖装饰静态方法的原因是,作为一个静态方法,它不会从类的声明中继承T
。
您也可以这样做:
// static factory methods
public static <Q> Node<Q> newNode(){
return new Node<Q>();
}
public static Node<String> newStringNode(String s){
return new Node<String>(s);
}
声明的简单叙述可能会有所帮助:
// This static method would have a <T> parameter to the class if it was not static
public static <T>
// It returns an object of type `Node` with generic parameter T
Node<T> newNode(){
// And here it is doing it's business.
return new Node<T>();
}
答案 2 :(得分:5)
这是参数化静态方法的唯一方法,因为Node声明中的原始T
绑定到Node的实例字段和方法。所以你可以写:
public static <T1> Node<T1> newNode(){
return new Node<T1>();
}
原始T
绑定到Node
类的实例,无法在静态上下文中引用。这将导致编译错误:
// ERROR
public static Node<T> newNode(){
return new Node<T>();
}
答案 3 :(得分:4)
<T>
只是信号,此方法使用T
作为类型变量。如果没有它,编译器会认为,T
是class
,interface
或enum
在某处声明并输出错误。它与您的第一行中使用的T
不同。您可以将此方法中的T
替换为任何其他字母,这可能有助于理解。
答案 4 :(得分:0)
T从参数
推断出来public static <T> List<T> getNewListWithElement(T element)
编译器如何区分T作为类和T作为泛型参数?解决方案是使用指定T元素是通用的而不是类/接口。
从使用情况推断
public static <T1> Node<T1> newNode(){
return new Node<T1>();
}
如果没有声明,谁将成为方法体内的T1?