Deep Side of Java〜Java 言語再入門 第2回 〜 Java 文法を中心に

Object クラスのメソッド






Object クラスのメソッド

ルートクラスである Object クラスには、特に知っておくべきメソッドとして、次のメソッドが存在する。

protected Object clone()
オブジェクトを複製する。しかし、Object クラスでの定義は例外 CloneNotSupportedException を投げるというものである。だから、複製をちゃんと機能させるためには、この clone メソッドを上書きして実装しなくてはならない。つまり、次のようである。

class SomeClass implements Cloneable {
   int x;
   SomeClass( int n ) { x = n; }
   protected Object clone( ) { return new SomeClass( x ); }
}
この時、Cloneable インターフェイスは、正しく clone メソッドが実装されていることをマークするのに使われる。だから、ちゃんと clone メソッドを実装して、この Cloneable を implements しなくてはならない。

しかし、別な問題もある。それはインスタンス変数として、オブジェクトを保持している場合に、「複製」とは何か、という問題である。つまり、インスタンス変数であるオブジェクトも「複製」するのか否かということである。Java ではこれはクラス作成者に任されている。だから、どちらでも構わないので、用途に合わせて決定すべきである。

class SomeClass implements Cloneable {
   int x;
   String str;
   SomeClass( int n, String s ) { x = n; str = s; }
   protected Object clone( ) { 
       return new SomeClass( x, s );  /* 浅いコピー */
    /* return new SomeClass( x, new String(s) ); 深いコピー */
   }
}
C++ では「コピーコンストラクタ」という暗黙のうちにコンストラクタを呼び出すことになる厄介な問題があったが、Java では複製は clone メソッドによるものに一元化されており、目出度い。(要するに自動変数としてスタック上にポインタではない実体のインスタンスを作成できるので、それに対する代入がコピーなのか、新規に作るのか、という哲学問題があったのである....)

boolean equals( Object obj )
同じ値を保持しているかどうか判定する。オブジェクトの同一比較は、== 演算子でできる。サブクラスで実装しないと意味がない。要するに次の通り。

class SomeClass {
   public int x, y;
   SomeClass( int x, int y ) { this.x = x; this.y = y; }
   boolean equals( Object obj ) {
      if( obj instanceof SomeClass ) {
          SomeClass tgt = (SomeClass)obj;
          if( x == tgt.x && y == tgt.y ) {
               return true;
          }
      }
      return false;
   }
}


protected void finalize()
デストラクタ。説明済み

final class getClass()
そのオブジェクトの実行時のクラス(メタクラス・オブジェクト)を取得する。これは上書き不可。reflection 機能などでよく使う。

String toString()
オブジェクトの文字表現を返す。デフォルトでは「java.lang.Object@2a9835」のようにオブジェクトのクラスとそのオブジェクト番号(ハンドル)が返る。これは頻繁に上書きされる。なぜなら、あるインスタンスを文字列化する時に、このメソッドが呼ばれるからである。つまり、

    SomeClass obj = new SomeClass();
    System.out.println( obj );
のように表示したい時に、obj 型インスタンスは String 型にキャストされる。その時に暗黙のうちにこのメソッドが呼ばれる(つまり、デフォルトの文字列化メソッドとして予約されている)のである。だから、デバッグ用途などでこれを積極的に上書き定義すると良いだろう。

このように Object クラスのメソッドは、それから派生する Java のさまざまなクラスで上書きされており、有用な定義がなされている。どんなクラスのオブジェクトに対してもこれらを使うことが有益であるだけでなく。そのような役割を果たすメソッドの名称として使って行くべきである。



copyright by K.Sugiura, 1996-2006