【Java】Generics(ジェネリクス・総称型)の意味や使い方を紹介!
  • facebookページ
  • twitterページ
  • 2021.01.01

    【Java】Generics(ジェネリクス・総称型)の意味や使い方を紹介!

    Generics(ジェネリクス・総称型)とは

    Genericsとは、クラスやメソッドなどの型を、パラメータとして定義できるようにした機能のことです。

    「<>」の中に具体的な型名を付けて利用できます。

    Genericsクラスを定義する方法

    Genericsクラスを定義するには、「パラメータ化された型」と「型変数」の2つを使います。

    パラメータ化された型とは、型パラメータリストをもったクラスのことです。

    クラスの宣言時に、クラス名の後ろに「< 型変数 >」という形で、型パラメータを記述します。

    記述方法は次の通りです。

    パラメータ化されたクラスを使う場合は、インスタンス化する時に型の指定が必要です。

    例えば、String型にする場合は、以下のように記述できます。

    Genericsメソッドを定義する方法

    ジェネリクスメソッドを定義するには、Genericsクラスで定義した型変数を、引数や戻り値に利用しましょう。

    先ほどの、GenericsClassで言えば次のように記述可能です。

    Genericsの使い方

    ここまで、Genericsの定義について紹介しました。

    言葉で説明されても難しいと思うので、実際に使い方を見ていきましょう。

    例えば、次のように記述できます。

    GenericsClassクラスのクラス名の後に「<T>」と記述しました。

    <T>を指定すると、データ型の指定が「Object型」から「T型(型変数)」へ変更できます。

    そして、Mainクラスのmainメソッドで、GenericsClassクラスをインスタンス化するときに、データ型をString型とInteger型で指定しています。

    Genericsを使うので、GenericsClassクラスのオブジェクトを呼び出す「getTメソッド」をキャストすることなく、指定した方で値の代入が可能です。

    上記のプログラムを実行すると、次の結果を取得できます。

    それぞれ、String型とInteger型で使えているのがわかります。

    Genericsの「T」とは?

    前章のプログラムで「<T>」という表現がありました。

    この T とは、Generics型の変数名に使われるネーミングです。

    T は Type の略称です。

    T以外にも、次のようなネーミングがよく使われます。

    Generics型の変数名に使われるネーミング
    • E:Element
    • K:Key
    • V:Value
    • T:Type
    • N:Number
    • S,U:2、3番目

    慣習的に使われるものなので、覚えておくと良いでしょう。

    実際の現場やプロジェクトでも、共通のネーミングを使うことで混乱を避けられるはずです!

    Genericsのワイルドカード型について

    ここでは、Genericsのワイルドカード型について見ていきましょう。

    例として、以下のプログラムを用意しました。

    printStrメソッドで、Collection型のコレクションを受け取った上で、その要素を出力しているプログラムです。

    Collectionは、Genericsを使って型の指定を行っています。

    しかし、使う際にはGenericsの型であるTごとに使う必要があり、少し不便です。

    仮に、Integer型で扱いたい場合は、それぞれ別個で扱わないといけません。

    そこで、便利なのがワイルドカード型を使った方法です。

    ワイルドカードを「?」で表現し、「Collection<?>」します。

    そうすることで、任意の型のコレクションとして扱えるのです。

    先ほどのプログラムを書き換えて実行してみます。

    このように、String型でもInteger型でも使えるようになります!

    Genericsでextendsを使う方法

    Genericsでは、型パラメータを宣言するときに、「extends」が使えます。

    extendsを使うと、データ型として指定できるものを制限可能です。

    例えば、<T extends P>と宣言した場合、データ型として指定できる型は、クラスPを継承したデータ型となります。

    extendsで指定できるクラスは1つだけです。

    複数指定する際は「&」でつなげることでインタフェースを指定できます。

    では、実際にプログラムを実行してみましょう!

    次のように記述できます。

    上記の例では、TはNumber型を継承したデータ型だけを扱えるようになります。

    そのため、Integer型は使えますが、String型は使えません。

    String型を指定した場合、コンパイルエラーになります。

    上記のプログラムを実行した結果は次の通りです。

    Integer型として出力されているのがわかります。

    このように、扱えるデータ型を制限したい場合に、extendsは便利な機能です!

    Genericsでsuperを使う方法

    Genericsでsuperを使うことで、extendsとは逆の動作を実現することも可能です。

    例えば、次のように記述できます。

    gs1というNumber型で指定したインスタンスと、<? super Integer>で指定したgs2インスタンスを用意します。

    そして、gs1をgs2に代入する際に、Object型の変数「obj」を使いました。

    上記のプログラムを実行すると、次のように表示されます。

    Genericsでメソッドで使う方法

    Genericsメソッドを定義する方法」を紹介したように、メソッドでもGenericsは使用可能です。

    使う際は、次のように記述しましょう。

    Genericsクラスと同じように、String型とInteger型で取得できているのがわかります!

    まとめ

    JavaのGenericsについて、クラス・メソッドの定義方法や使い方を解説しました。

    Genericsは、Integer型やString型といったさまざまなデータ型で、同じ処理を実行したい場合に便利です。

    プログラム実行時のエラーが発生する危険がなくなるのも、メリットと言えます。

    ぜひこの記事を参考に、Genericsの使い方を覚えてください!



    優良フリーランス案件多数掲載中!
    フリーランスエンジニアの案件をお探しなら
    ポテパンフリーランス

    この記事をシェア

    • Facebookシェア
    • Twitterシェア
    • Hatenaシェア
    • Lineシェア
    pickup









    ABOUT US

    ポテパンはエンジニアと企業の最適なマッチングを追求する企業です。

    READ MORE