2011-01-17 6 views
1

Javaインターフェイスでカスタム 'T'を説明してください。ここではジェネリックスを使用しています。次に、タイプ 'T'はどこに定義されていますか?カスタムGenericsの説明

public interface TemplateBuilder<T extends TemplateBuilder> 

答えて

7

Tは実際のクラスではありません。これは、クラスTemplateBuilderの使用状況に応じてコンパイル時に決定されます。あなたの状況に応じてその中の一つが「選択」されている、さまざまなタイプのプレースホルダーとして考えることができます。単純例えば

、以下の(Javaのチュートリアルから適応)を見て:

あなたは(ボックス内に保持するためのオブジェクトの)特定の型を取ることができ、クラスのボックスを、宣言したい想像し、さまざまな状況でこれを再利用して、さまざまなタイプを保持したいとします。

ので、代わりの箱を取ることができます実際の型を固定次のように、あなたはそれを宣言します。

public class Box<T> { 

    private T t; // T stands for "Type"   

    public void set(T t) { 
     this.t = t; 
    } 

    public T get() { 
     return t; 
    } 
} 

あなたがそれを使用する場合、あなたはそれからような何かを:

Box<Integer> integerBox = new Box<Integer>(); 

いただきまし全体あなたが聞くかもしれない点? Boxをオブジェクトにするのはなぜですか?

実際、Java 1.5以前ではこれは不可能でした。これは、これらの状況でさらにタイプセーフティを導入するために導入され、Collectionsフレームワークで採用されました。

このメカニズムがないと、Objectを使用した場合、ボックスの特定のインスタンスにIntegersのみを保持させることはできません。一方、特にIntegersを使用するようにした場合、Stringやその他のオブジェクト用にBoxを再利用することはできず、別のタイプのBoxクラスを作成する必要があります。

Java 1.5より前では、ArrayListのようなオブジェクトは単純なObjectを取りましたが、実行時に型の安全性が損なわれたケースが多かったです。これはIntegerオブジェクトのリストを想定していて、ジェネリックス(このマジックTを通して)は、彼らが何であるかを制限することなく、力のタイプになります。

T extends TemplateBuilderはさらに進んでTが何であれ、それはTemplateBuilderを拡張するクラスでなければならないと述べています。それがなければ、Object(Javaの汎用基底クラス)を拡張するすべてのクラスになります。

+0

は 'IntegerBox'種類やタイプミスですか? – HyperNeutrino

+0

うん...固定...歓声。 – jbx

1

Tは、Tは、任意のオブジェクトを意味TemplateBuilder

から延びる任意Objectあります。例えば、ここで

List<T> list = new ArrayList<T>(); 

TはIntegerString ...

<T extends A>することができる任意Object Tインターフェイスを実装するとき、このタイプが定義されてA

1

から延びている意味、すなわち

class StringBuilder implements TemplateBuilder<StringBuilder> {} 

BTW、クラスEnum(すべてのenumの基本クラス)を参照してください。

0

マイカスタムジェネリック説明

Backgorund:

  1. カスタムジェネリック医薬品は、例えば、データ構造に常に使用されています「もの」
  2. のリストは、(保存/検索)を管理するときは、は、カスタムのジェネリック医薬品が多型の原則を取り入れてコンパイルするコードのためにをチェックし、独自のタイプをする必要はありません
  3. しかし、多型の「伝統的な」OOの原則とは対照的に、このクラスは、物事のリストを格納することができなし「のもの(複数可)、」それが保存される(OOの基本原理を持つ任意の関係を持ちますここでAはBクラスのスーパークラスではありません)
  4. あなたは、保存したい "物"のあらゆる種類の可能な種類のサブクラスを作成しません。

例1

例として無関係である下に次の2つのクラスを考えます。これは非常に原始的な例であるが、それにもかかわらず、カスタムジェネリック医薬品の原則の概要を示します:

/** 
* 
* Simple class which overrides the toString() 
* method from Object's class toString() method 
* 
*/ 
class B 
{ 

    @Override 
    public String toString() 
    { 
    return "B Object"; 
    } 

    public static void main(String[] args) 
    { 
    A<B> a = new A<>(new B()); 

    System.out.println(a.getT());   
    } 
} 

以下
/** 
* 
* Class A is a Custom Generic class that can be 'typed' 
* to any kind of class using diamond 'T' syntax. 
* 
*/ 

class A<T> 
{ 
    // The instance variable of the object type 'T' known at run time 
    T theI; 

    // The constructor passing the object type 'T' 
    A(T anI) 
    { 
    this.theI = anI; 
    } 

    // Method to return the object 'T' 
    T getT() 
    { 
    return theI; 
    } 
} 

は、Bすなわち、クラスAとは無関係なクラスBは拡張しないで上記のクラスBのメインメソッドでは:

a.getT()は、この例では 'B'型のオブジェクト 'T'を返します(これは多態性の例です)。

a.getT()は、オブジェクトのtoString()メソッドをオーバーライドし、 "B Object"を出力するので、オブジェクトインスタンスCのメソッドtoString()がIMPLICITLYを呼び出すようにします。

カスタムジェネリック医薬品および多型について注意すべき興味深い点があることである:カスタムジェネリック医薬品の文脈では

は、クラス間の関係ためは制約が多型

例えばを実行するためにはありませんクラスBは、上記すなわちクラスB 無関係ある「従来」オブジェクト配向多型原理で A.

を拡張しない、何らかの形で関連するクラスの要件の制約が常に存在します。ただし、これはカスタムジェネリックスでは必要ありません。

例2

public interface TemplateBuilder<T extends TemplateBuilder> 

上記 TemplateBuilderを拡張する任意のクラスにを入力TemplateBuilderインターフェースはとすることができることを意味します。

はのは、工assがTemplateBuilderを拡張すると仮定しましょう、次は大丈夫です:

TemplateBuilder<SomeClass> tbRef = ... 
/* Using an Anonymous Inner Class reference to interface TemplateBuilder<SomeClass> */ 

または

TemplateBuilder<SomeClass> tbRef = .... /* Referencing a concrete class 
that implements TemplateBuilder */