Java
 Computer >> コンピューター >  >> プログラミング >> Java

ObjectクラスはなぜJavaの全クラスのスーパークラスなのか?理由と主要メソッドを解説

java.lang.Object クラスは、Javaのクラス階層におけるルート(最上位)に位置するスーパークラスで、java.lang パッケージに含まれています。標準ライブラリのクラスも、開発者が独自に定義したクラスも、すべてこの Object クラスの子孫(サブクラス)となります。明示的に extends を書かなくても、すべてのクラスは自動的に Object を継承します。

Objectクラスがスーパークラスである理由

1. 再利用性(Reusability)

  • すべてのオブジェクトには、比較・複製・文字列化など、共通して必要となる基本的な機能があります。これらを毎回開発者がゼロから実装するのは大きな負担です。
  • そこで当時のSun Microsystems(現Oracle)は、こうした共通機能を汎用的なロジックとして実装済みの Object クラスを提供しました。
  • 各メソッドにはすべてのサブクラスに共通する汎用的な処理が組み込まれており、そのまま使ってもよいし、サブクラスの要件に合わなければオーバーライドして独自の動作に差し替えることもできます。

2. 実行時ポリモーフィズム(多態性)の実現

  • Object 型はあらゆるクラスのインスタンスを受け入れられるため、「任意の型のオブジェクトを引数として受け取り、戻り値として返す」ような汎用的なメソッドを1つだけ書けば済みます。これにより、実行時に実際のオブジェクトの型に応じた振る舞いを実現できます。

Objectクラスが提供する主なメソッド

2つのオブジェクトの比較

  • public boolean equals(Object obj)

ハッシュコードの取得

  • public int hashCode()

実行時クラス情報の取得

  • public final Class<?> getClass()

オブジェクト情報の文字列表現の取得

  • public String toString()

オブジェクトの複製(クローン作成)

  • protected Object clone() throws CloneNotSupportedException

後始末処理(リソース解放)

  • protected void finalize() throws Throwable

他スレッドによる notify() 呼び出しまで現在のスレッドを待機させる

  • public final void wait() throws InterruptedException

指定時間(ミリ秒)だけ待機させる

  • public final void wait(long timeout) throws InterruptedException

ミリ秒+ナノ秒で指定した時間だけ待機させる

  • public final void wait(long timeout, int nanos) throws InterruptedException

オブジェクトのロックが利用可能になったことを、待機中の1つのスレッドへ通知する

  • public final void notify()

オブジェクトのロックが利用可能になったことを、待機中のすべてのスレッドへ通知する

  • public final void notifyAll()

wait() / notify() / notifyAll() の3つは、マルチスレッド環境でのスレッド間通信(協調動作)を実現するためのメソッドであり、synchronized ブロック内で使用するのが基本です。

コード例

次の例では、Object クラスの equals()、hashCode()、toString()、clone() をオーバーライドした Thing クラスを定義し、それぞれの動作を確認しています。

class Thing extends Object implements Cloneable {
    public String id;

    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    public boolean equals(Object obj) {
        boolean result = false;
        if ((obj != null) && obj instanceof Thing) {
            Thing t = (Thing) obj;
            if (id.equals(t.id)) result = true;
        }
        return result;
    }

    public int hashCode() {
        return id.hashCode();
    }

    public String toString() {
        return "This is: " + id;
    }
}

public class Test {
    public static void main(String args[]) throws Exception {
        Thing t1 = new Thing(), t2;
        t1.id = "Raj";
        t2 = t1;                  // 同一参照:t1 == t2 かつ t1.equals(t2)
        t2 = (Thing) t1.clone();  // 別オブジェクト:t2 != t1 だが t1.equals(t2)
        t2.id = "Adithya";        // 内容も不一致:t2 != t1 かつ !t1.equals(t2)

        Object obj = t2;
        System.out.println(obj);  // toString() が呼ばれる
    }
}

コードのポイント

  • equals() をオーバーライドする場合は、hashCode() も整合性が取れるように一緒にオーバーライドするのが鉄則です(等しいオブジェクトは同じハッシュコードを持つべきため)。
  • clone() は Cloneable インターフェースを実装しないと CloneNotSupportedException がスローされます。
  • println() にオブジェクトを渡すと自動的に toString() が呼び出されるため、オーバーライドしておくとデバッグやログ出力が格段に読みやすくなります。

実行結果

This is: Adithya

このように、Object クラスはすべてのJavaオブジェクトに共通する土台となる機能を一括して提供することで、開発者の負担を軽減しつつ、言語全体の一貫性とポリモーフィズムを支えています。

  1. Java 9における@Deprecatedアノテーションの改善点とは?新要素「since」「forRemoval」を徹底解説

    @Deprecatedアノテーションとはクラス、メソッド、フィールドなど、プログラム内のあらゆる要素に付与できる@Deprecatedアノテーションは、「その要素はもはや使用すべきではない」ことを示すためのものです。要素が非推奨とされる主な理由は以下の通りです。使用すると危険であり、エラーを引き起こす可能性がある将来のバージョンで互換性がなくなる可能性がある将来のバージョンで削除される可能性があるより優れた、効率的な代替手段がすでに提供されているJava 9で追加された2つの新しい要素Java 9では、@DeprecatedアノテーションにsinceとforRemovalという2つの新しい属性

  2. Javaのsuperキーワードとは?使い方とサンプルコードを徹底解説

    JavaのsuperキーワードとはJavaにおけるsuperキーワードは、サブクラスから直接の親クラス(スーパークラス)のメンバーやコンストラクタへアクセスするために使われる重要なキーワードです。主な役割は以下の3つです。親クラスのインスタンス参照:super変数は、直近の親クラスのインスタンスを参照します。親クラスのメソッド呼び出し:superを使うことで、オーバーライドされた親クラスのメソッドを呼び出せます。親クラスのコンストラクタ呼び出し:super()は親クラスのコンストラクタとして機能し、子クラスのコンストラクタ内では必ず最初の行に記述する必要があります。特に、オーバーライドされたメ