Java 泛型和静态工厂方法 -- 语法

2022-09-01 15:22:21

以下是我得到的:

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>();
    }
...
}

我的问题实际上只是关于泛型的语法与静态工厂方法的语法。我真的不明白为什么我们在方法声明中的返回类型之前放置< T >。这有点像类型转换吗?任何帮助将不胜感激!


答案 1

你问的是类型推断

由于它是一个静态方法,因此它必须从某个地方推断出泛型类型;您没有该类的实例。这就是意思。<T>

对于不带任何参数的方法,它实际上是从赋值的目标推断出来的。例如,假设您的方法如下所示:

public static <T> List<T> getNewList() {
    return new ArrayList<T>();
}

使用此方法时,是从目标推断出来的(在本例中):TString

List<String> myList = MyClass.getNewList();

在具有泛型参数的其他静态方法中,是从传入的类型推断出来的: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>

具体而言,JLS 的第 15.12.2.715.12.2.8 节对此进行了介绍。


答案 2

必须用这样的糖修饰静态方法的原因是,作为静态方法,它不会从类的声明继承 。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>();
}