簡體   English   中英

Java泛型和靜態工廠方法 - 語法

[英]Java Generics and Static Factory Methods — Syntax

這是我得到的:

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>放在返回類型之前。 有點像類型轉換嗎? 任何幫助將非常感激!

你要問的是類型推理

因為它是一個靜態方法,它必須從某個地方推斷出通用類型; 您沒有該類的實例。 這就是<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>

具體而言,這將在JLS的第15.12.2.715.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);
}

聲明的簡單敘述可能有助於:

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

這是參數化靜態方法的唯一方法,因為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>();
}

<T>只是信號,該方法使用T作為類型變量。 沒有它,編譯器會認為, T是在某處聲明的classinterfaceenum並輸出錯誤。 它與您的第一行中使用的T不同。 您可以將此方法中的T替換為任何其他字母,這可能有助於理解。

從參數推斷出T.

public static <T> List<T> getNewListWithElement(T element)

編譯器如何區分T作為類和T作為泛型參數? 解決方案是使用指定T元素是通用而不是類/接口。

從使用中推斷出來

public static <T1> Node<T1> newNode(){
    return new Node<T1>();
}

如果沒有聲明,誰將成為方法體內的T1?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM