【Java】レッスン3-5:ジェネリクスの基礎を理解しよう

ながみえ

一つ前のページではメソッドのオーバーロードについて学習しました。

今回は ジェネリクス について見ていきましょう。

Lesson1:基礎文法編
Lesson2:制御構造編
Lesson3:メソッド編

 ・Lesson3-1:メソッドの基本を確認しよう
 ・Lesson3-2:メソッドの戻り値を理解しよう
 ・Lesson3-3:真偽値を返すメソッドを理解しよう
 ・Lesson3-4:メソッドのオーバーロードを理解しよう
 ・Lesson3-5:ジェネリクスを理解しよう ◁今回はココ
 ・確認問題3-☆1:石取りゲームを作ろう
 ・確認問題3-☆2:丁半賭博ゲームを作ろう
Lesson4:コレクション編
Lesson5:クラス

<<前のページ

学習記事一覧

次のページ>>

ジェネリクスとは何か|型のパラメータ化で汎用的なコードを実現

Javaで複数の型に対応したクラスやメソッドを作りたいときに役立つのがジェネリクス(Generics)です。

ジェネリクスを使えば、型を抽象化して再利用可能なコードを記述でき、キャストの手間や型エラーを減らすことができます。

本記事では、型パラメータの基本構文から、使い方の具体例、配列やコレクションへの応用までを初心者にもわかりやすく解説します。

これを学べば、安全で柔軟なコード設計が可能になり、開発効率と保守性を大幅に向上させられるでしょう。

それでは、型の壁を超えるプログラミングの世界へ一歩踏み出しましょう。

ジェネリクスの概要|型をパラメータとして扱う仕組み

ジェネリクス とはメソッドやクラスに、intやStringなどの「型」を変数として渡す仕組みです。

これにより異なるデータ型に応じたコードの再利用が可能になります。

例えば、通常であれば整数型や文字列型など異なる型に対応するために複数のメソッドを定義する必要がありますが、ジェネリクスを使うことで一つのメソッドで対応できます。

型の汎用性を持たせたい場面で非常に便利です。

ジェネリクスは、以下のように<T>を使って定義します。

private static <T> void メソッド名(T 引数) {
    // このメソッドの処理内容
}

このメソッドは引数の型を自由に指定でき、異なるデータ型に対応します。

ジェネリクスの使い方|型に依存しない汎用メソッドのコード例

ジェネリクスの基本構文はメソッド名の前に<T>という「型パラメータ」を指定しますが、この<T>はジェネリクスを利用した際に実際の型として置き換わります。

たとえばTStringに置き換えた場合には、printMessage("Hello")のように文字列を扱うことができます。

またIntegerに置き換えた場合にはprintMessage(123)といった具合に整数を処理可能です。

以下のコードではジェネリクスを使って異なる型の値を出力するメソッドを作成しています。

public class Main {
    public static void main(String[] args) {	// メインメソッド
        printMessage("こんにちは");	// 引数に文字列を指定して呼び出し
        printMessage(123);			// 引数に整数を指定して呼び出し
        printMessage(45.67);		// 引数に小数を指定して呼び出し
    }
    private static <T> void printMessage(T n) {	// ジェネリクスを用いたメソッド
        System.out.println("メッセージ: " + n);
    }
}

このコードを実行すると以下のように出力されます。

メッセージ:こんにちは
メッセージ:123
メッセージ:45.67

このコードではprintMessageメソッドが異なるデータ型(文字列、整数、小数)に対応していることが確認できます。

このようにジェネリクスを使用することで、型に依存しないメソッドが簡潔に書けるようになります。

ジェネリクスを使うメリット|安全で再利用性の高いコード設計

ジェネリクスを使う最大のメリットは型の安全性コードの再利用性の向上です。

ジェネリクスを利用することで、コンパイル時に型チェックが行われるため、実行時エラーを未然に防ぐことが可能です。

またコードの再利用性が向上し、同じ機能を持つメソッドやクラスを複数の型に対応させやすくなります。

まとめ|安全で汎用的なコード設計の基礎

今回の学習では、ジェネリクスの基本概念、型に依存しない汎用メソッドの作成方法、そしてジェネリクスを使うことによる安全性や再利用性の向上について学びました。

これにより複数の型に対応できる柔軟なコードを設計しつつ、型エラーを防ぎ、保守性の高いプログラムを書けるようになります。

ジェネリクスは規模の大きな開発や汎用的なライブラリ作成にも役立つ重要な技術です。

ここで得た知識を活かし、さらに応用力を高める学習を続けていきましょう。

練習問題|ジェネリクスで型に依存しない配列処理を作ってみよう

ジェネリクスの機能を利用して異なる型の配列の要素数を取得するプログラムを作成しましょう。

このプログラムでは、文字列、整数、小数の配列を作成し、それぞれの配列の要素数を取得して表示します。

この問題の要件

以下の要件に従ってコードを完成させてください。

  1. ジェネリクスを利用した countElements メソッドを作成し、任意の型の配列の要素数を返すこと。
  2. 配列の要素数は array.length を使用して取得すること。
  3. main メソッド内で以下の配列を定義すること。
    • 文字列の配列 {"こんにちは", "ジェネリクス", "Java"}
    • 整数の配列 {1, 2, 3, 4, 5}
    • 小数の配列 {1.1, 2.2, 3.3}
  4. 各配列の要素数を countElements メソッドを使って取得し、出力すること。

ただし、以下のような実行結果となること。

文字列の配列の要素数: 3
整数の配列の要素数: 5
小数の配列の要素数: 3

この問題を解くヒント

1からコードを組み立てることが難しい場合は、以下のヒントを開いて参考にしましょう。

Q
ヒント1【コードの構成を見る】

正解のコードは上から順に以下のような構成となっています。
(※下記の□はコード内のインデントを表しています)

1:Mainクラスの定義
  □ mainメソッドの定義
  □ □ String型の配列wordsを作成し、要素「こんにちは」「ジェネリクス」「Java」を格納
  □ □ 「文字列の配列の要素数: 」とcountElementsメソッドで取得したwordsの要素数を出力
  □ □ Integer型の配列numbersを作成し、要素1, 2, 3, 4, 5を格納
  □ □ 「整数の配列の要素数: 」とcountElementsメソッドで取得したnumbersの要素数を出力
  □ □ Double型の配列decimalsを作成し、要素1.1, 2.2, 3.3を格納
  □ □ 「小数の配列の要素数: 」とcountElementsメソッドで取得したdecimalsの要素数を出力
  □ ジェネリクスを使用したcountElementsメソッドの定義
  □ □ 配列arrayの長さ(要素数)をarray.lengthで取得し、戻り値として返す

Q
ヒント2【穴埋め問題にする】

以下のコードをコピーし、コメントに従ってコードを完成させて下さい。

public class Main {
    public static void main(String[] args) {
        // 文字列の配列を作成
        /*【穴埋め問題1】
        ここにString型の配列wordsを作成し、「こんにちは」「ジェネリクス」「Java」を格納してください。
        */
        // countElementsメソッドを使って要素数を出力
        System.out.println("文字列の配列の要素数: " + countElements(words));

        // 整数の配列を作成
        /*【穴埋め問題2】
        ここにInteger型の配列numbersを作成し、1, 2, 3, 4, 5の値を格納してください。
        */
        // countElementsメソッドを使って要素数を出力
        System.out.println("整数の配列の要素数: " + countElements(numbers));

        // 小数の配列を作成
        /*【穴埋め問題3】
        ここにDouble型の配列decimalsを作成し、1.1, 2.2, 3.3の値を格納してください。
        */
        // countElementsメソッドを使って要素数を出力
        System.out.println("小数の配列の要素数: " + countElements(decimals));
    }
    
    /*【穴埋め問題4】
    ここにジェネリクスを使ったcountElementsメソッドを定義し、配列の要素数をarray.lengthで返すコードを書いてください。
    */
}

このヒントを見てもまだ回答を導き出すのが難しいと感じる場合は、先に正解のコードと解説を見て内容を理解するようにしましょう。

練習問題の解答と解説

この問題の正解コードとその解説は以下の通りです。

クリックして開いて確認してください。

Q
正解コード
public class Main {
    public static void main(String[] args) {
        // 文字列の配列を作成
        String[] words = {"こんにちは", "ジェネリクス", "Java"};
        // countElementsメソッドを使って要素数を出力
        System.out.println("文字列の配列の要素数: " + countElements(words));

        // 整数の配列を作成
        Integer[] numbers = {1, 2, 3, 4, 5};
        // countElementsメソッドを使って要素数を出力
        System.out.println("整数の配列の要素数: " + countElements(numbers));

        // 小数の配列を作成
        Double[] decimals = {1.1, 2.2, 3.3};
        // countElementsメソッドを使って要素数を出力
        System.out.println("小数の配列の要素数: " + countElements(decimals));
    }
    private static <T> int countElements(T[] array) {
        // 配列の長さ(要素数)を返す
        return array.length;
    }
}
Q
正解コードの解説

コードをブロックごとに分割して解説します。

クラスとメインメソッドの定義

public class Main {
    public static void main(String[] args) {

ここではMainクラスと、その中に含まれるmainメソッドを定義しています。

mainメソッドはJavaプログラムが最初に実行するエントリーポイントです。

文字列の配列を作成し要素数をカウント

String[] words = {"こんにちは", "ジェネリクス", "Java"};
System.out.println("文字列の配列の要素数: " + countElements(words));

ここではString型の配列wordsを定義し、「こんにちは」「ジェネリクス」「Java」の3つの要素を格納しています。

その後countElementsメソッドを使って配列の要素数をカウントし、結果を出力します。

整数の配列を作成し要素数をカウント

Integer[] numbers = {1, 2, 3, 4, 5};
System.out.println("整数の配列の要素数: " + countElements(numbers));

ここではInteger型の配列numbersを定義し、1から5までの整数を格納しています。

同様にcountElementsメソッドを使用して要素数を出力します。

小数の配列を作成し要素数をカウント

Double[] decimals = {1.1, 2.2, 3.3};
System.out.println("小数の配列の要素数: " + countElements(decimals));

Double型の配列decimalsを定義し、小数3つを格納しています。

countElementsメソッドを用いてこの配列の要素数も出力しています。

ジェネリクスを使った要素数カウントメソッドの定義

private static <T> int countElements(T[] array) {
    return array.length;
}

ここで定義しているのがジェネリクスを用いたcountElementsメソッドです。

<T>と記述することで配列の要素の型を特定の型に固定せず、どの型の配列も引数として受け取れるようにしています。

Tは「任意の型」を意味する型パラメータで、配列の型に依存せずにcountElementsメソッドが動作することを可能にしています。

もっと分かりやすい学習サイトにするために

この記事を読んで「ここが分かりにくかった」「ここが難しかった」等の意見を募集しています。

世界一わかりやすいJava学習サイトにするため、ぜひ 問い合わせフォーム からご意見下さい。

<<前のページ

学習記事一覧

次のページ>>

記事URLをコピーしました