ホームページ > Java > &#&チュートリアル > Java で型変数を使用して現在の型を参照するにはどうすればよいですか?

Java で型変数を使用して現在の型を参照するにはどうすればよいですか?

DDD
リリース: 2024-12-24 21:53:14
オリジナル
420 人が閲覧しました

How Can I Refer to the Current Type Using a Type Variable in Java?

型変数を使用して現在の型を参照する方法

型変数を使用して現在の型を参照できますか?

次のように仮定します。現在の型のインスタンスを返す関数を作成します。型変数 T が正確なサブタイプを参照するようにする方法はありますか (つまり、T はクラス B の B を参照する必要があります)?

class A {
    <T extends A> void foo();
}

class B extends A {
    @Override
    T foo();
}
ログイン後にコピー

解決策

StriplingWarrior の応答に基づいて構築するには、次の設計が必要です (階層型の Fluent ビルダー API の式):

まず、抽象基本クラス (またはインターフェース) は、クラスを拡張するインスタンスのランタイム型を取得するためのコントラクトを確立します:

/**
 * @param <SELF> The runtime type of the implementer.
 */
abstract class SelfTyped<SELF extends SelfTyped<SELF>> {

   /**
    * @return This instance.
    */
   abstract SELF self();
}
ログイン後にコピー

中間拡張クラスは抽象クラスであり、再帰型パラメーター SELF を維持する必要があります:

public abstract class MyBaseClass<SELF extends MyBaseClass<SELF>>
extends SelfTyped<SELF> {

    MyBaseClass() { }

    public SELF baseMethod() {

        //logic

        return self();
    }
}
ログイン後にコピー

さらに派生したクラスも同じパターンに従うことができます。ただし、これらのクラスはいずれも、生の型またはワイルドカード (パターンの目的を損なう) を使用せずに変数の型として直接利用することはできません。例: (MyClass が抽象でない場合):

//wrong: raw type warning
MyBaseClass mbc = new MyBaseClass().baseMethod();

//wrong: type argument is not within the bounds of SELF
MyBaseClass<MyBaseClass> mbc2 = new MyBaseClass<MyBaseClass>().baseMethod();

//wrong: no way to correctly declare the type, as its parameter is recursive!
MyBaseClass<MyBaseClass<MyBaseClass>> mbc3 =
        new MyBaseClass<MyBaseClass<MyBaseClass>>().baseMethod();
ログイン後にコピー

これが、これらのクラスが「中間」と呼ばれる理由であり、すべて抽象と宣言される必要がある理由です。 「リーフ」クラスは、ループを完了し、継承された型パラメータ SELF をその型で解決し、self() を実装するパターンを利用するために必要です。コントラクトの違反を防ぐために、それらも最終としてマークする必要があります:

public final class MyLeafClass extends MyBaseClass<MyLeafClass> {

    @Override
    MyLeafClass self() {
        return this;
    }

    public MyLeafClass leafMethod() {

        //logic

        return self(); //could also just return this
    }
}
ログイン後にコピー

このようなクラスを使用すると、パターンが使用可能になります:

MyLeafClass mlc = new MyLeafClass().baseMethod().leafMethod();
AnotherLeafClass alc = new AnotherLeafClass().baseMethod().anotherLeafMethod();
ログイン後にコピー

この主な利点は、メソッド呼び出しが可能であることです。同じ特定の戻り値の型を維持しながら、クラス階層の上下に連鎖することができます。

以上がJava で型変数を使用して現在の型を参照するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート