Fat*_*ler 20 java generics syntax static factory
这是我得到的:
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>();
}
...
}
Run Code Online (Sandbox Code Playgroud)
我的问题实际上只是泛型的语法加上静态工厂方法的语法.我真的不明白为什么我们在方法声明中将<T>放在返回类型之前.有点像类型转换吗?任何帮助将非常感激!
Bri*_*ach 27
你要问的是类型推理.
因为它是一个静态方法,它必须从某个地方推断出通用类型; 您没有该类的实例.这就是<T>
意味着什么.
如果你的方法不带参数,它实际上是从赋值的目标推断它.例如,假设您的方法如下所示:
public static <T> List<T> getNewList() {
return new ArrayList<T>();
}
Run Code Online (Sandbox Code Playgroud)
使用此方法时,T
从目标推断(在本例中String
):
List<String> myList = MyClass.getNewList();
Run Code Online (Sandbox Code Playgroud)
在你的另一个静态方法中,你有一个Generic参数,T
是从传入的类型推断出来的:
public static <T> List<T> getNewListWithElement(T element) {
List<T> list = new ArrayList<T>();
list.add(element);
return list;
}
Run Code Online (Sandbox Code Playgroud)
在这里,如果您尝试过:
List<String> myList = MyClass.getNewListWithElement(new Integer(4));
Run Code Online (Sandbox Code Playgroud)
它会告诉你你的目标类型是错误的,你需要一个 List<Integer>
具体而言,这将在JLS的第15.12.2.7和15.12.2.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);
}
Run Code Online (Sandbox Code Playgroud)
声明的简单叙述可能有助于:
// 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>();
}
Run Code Online (Sandbox Code Playgroud)
这是参数化静态方法的唯一方法,因为T
Node声明中的原始绑定到Node的实例字段和方法.所以你可以写:
public static <T1> Node<T1> newNode(){
return new Node<T1>();
}
Run Code Online (Sandbox Code Playgroud)
原始T
绑定到Node
类的实例,不能在静态上下文中引用.这会导致编译错误:
// ERROR
public static Node<T> newNode(){
return new Node<T>();
}
Run Code Online (Sandbox Code Playgroud)