簡體   English   中英

Java泛型語法

[英]Java generics syntax

我想了解以下是什么意思?

public class Bar<T extends Bar<T>> extends Foo<T> {
    //Some code
}

做這樣的事情有什么好處(例如用例?)。

這是一個相當理論的例子,但在這種情況下你可能需要它:

public class Bar<T extends Bar<T>> extends Foo<T> {

    private final T value;

    public T getValue() { return value; }

    public void method(T param) {
        if (param.getValue().equals(someValue)) {
            doSomething();
        } else {
            doSomethingElse();
        }
    }
}

如果T不是Bar ,你將無法調用param.getValue() ,因為T extends Bar<T>

這與java.lang.Enum類的定義方式非常相似:

public abstract class Enum<E extends Enum<E>> implements Comparable<E> {
  private final String name;
  private final int ordinal;
  protected Enum(String name, int ordinal) {
    this.name = name; this.ordinal = ordinal;
  }
  public final String name() { return name; }
  public final int ordinal() { return ordinal; }
  public String toString() { return name; }
  public final int compareTo(E o) {
    return ordinal - o.ordinal;
  }
}

由於像這樣定義的類必須是抽象的並且無法直接實例化,因此該模式在與擴展普通枚舉的方式類似的構造中很有用:

// corresponds to
// enum Season { WINTER, SPRING, SUMMER, FALL }
final class Season extends Enum<Season> {
  private Season(String name, int ordinal) { super(name,ordinal); }
  public static final Season WINTER = new Season("WINTER",0);
  public static final Season SPRING = new Season("SPRING",1);
  public static final Season SUMMER = new Season("SUMMER",2);
  public static final Season FALL   = new Season("FALL",3);
  private static final Season[] VALUES = { WINTER, SPRING, SUMMER, FALL };
  public static Season[] values() { return VALUES.clone(); }
  public static Season valueOf(String name) {
    for (Season e : VALUES) if (e.name().equals(name)) return e;
    throw new IllegalArgumentException();
  }

}

書籍“Java Generics and Collection”中的示例。

您基本上將Bar將“處理”的類型限制為擴展Bar<T>任何類型。 在這種情況下,您希望確保Bar僅處理其自身的擴展 - 可能會調用一個專用於Bar 一個簡單的例子是你可以使用這個類來實現一種鏈表,並在做一些只有Bar可以/應該做的事情時迭代它。 假設您有以下代碼:

public class Bar<T extends Bar<T>> extends Foo<T> {
    private T next;

    //Initialize next in constructor or somewhere else

    private void doSomethingOnlyBarCanDo(){
        //Do it...
    }

    public void iterate(){
        T t = next;
        while(t != null){
            t.doSomethingOnlyBarCanDo();
            t = t.next;
        }
    }
}

使用這種構造,迭代Bar實例的“鏈”非常容易,因為每個實例都會引用下一個 - 調用T擴展Bar<T> ,所以你可以引用它因此。

一個典型的用例是Wrapper / Decorator模式。 Bar可能包含了擴展Bar本身的T Foo只是一個處理T的參數化類。

public abstract class Foo<T> {
    public abstract void foo(T t);
}

public class Bar<T extends Bar<T>> extends Foo<T> {
    private T wrapped;
    public Bar(T w) {
         this.wrapped = w;
    }

    public abstract void foo(T t) {
        // do something 
    }
}

我唯一可以告訴你的是<T extends Bar<T>>使用這個你告訴我T現在是Type Bar<T>這意味着TBar所以你可以訪問Bar可用的所有方法,其他方面如果你只做Bar<T>你將無法訪問它,因為T本來就是通用的。

什么是使用呢?

你可以用它來作曲。 例如

public class CustomList<T extends List<T>> {
    T t;

    T get(int index) {
        //Some custom code here
        return t.get(index);
    }
}

你的例子有點不對,因為Telling沒有真正的優勢,因為你總是可以訪問Bar類中的Bar類方法。

暫無
暫無

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

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