JavaのObjectとは?
JavaのObjectクラスは、Javaのすべてのクラスが共通して継承しているスーパークラスです。
もしextends句を省略してクラスを作成した場合にも、暗黙的にObjectクラスが継承元になります。
public class SampleClass {
// 上のクラスは次のように宣言されたクラスと同じとなる
// public SampleClass extends Object {
}
たとえば、複数の値を扱うArrayListは次のような継承関係にあります。
幾重にも継承が行われていますが、最も基底となっているクラスはやはりObjectクラスです。
java.lang.Object
└─ java.util.AbstractCollection<E>
└─ java.util.AbstractList<E>
└─ java.util.ArrayList<E>
Objectクラスのメソッド
Objectクラスには、次のメソッドが定義されています。
すべてのクラスがObjectを継承していることから、Javaの全クラスで次のメソッドが使用できます。
メソッド | 説明 |
---|---|
clone | オブジェクトのコピーを作成して返します。 |
equals | 他のオブジェクトが等しいかどうかを比較する。 |
finalize | クラスへの参照が不要となった時に、ガベージ・コレクタによって呼び出される。 アプリから明示的に呼ぶことは基本的にしません。 |
getClass | このオブジェクトのクラス情報を返します。 |
hashCode | オブジェクトのハッシュ値を返します。 |
wait | 現在のスレッドが待機します。 notify()またはnotifyAll()が呼びされるとスレッドを再開。 |
notify | waitで待機させたスレッドを再開します。 複数のスレッドが待機している場合は、どれか1つが再開します。 |
notifyAll | waitで待機させたすべてのスレッドを再開します。 |
toString | オブジェクトの文字列表現を返します。 |
clone() メソッド
cloneメソッドは、自分自身のクラスの型と同じクラスのインスタンスを新たに作成し、Stringやintなどのプロパティ値をコピーして返すメソッドです。
// クローンされるクラスはClonableインターフェイスを実装する必要がある
class Sample implements Cloneable {
String field1 = "A";
String field2 = "B";
// cloneメソッドで自身の値をコピーしたインスタンスを作成
@Override
public Sample clone() {
Sample cloneSample = new Sample();
cloneSample.field1 = this.field1;
cloneSample.field2 = this.field2;
return cloneSample;
}
}
public class Main {
public static void main(String[] args) throws Exception {
// cloneでインスタンスをコピー
Sample sample = new Sample();
Sample cloneSample = sample.clone();
}
}
toString() メソッド
オブジェクトの文字列表現を返すメソッドです。
独自に作成したクラスなどでtoString() メソッドを実装(オーバーライド)し、フィールドの値などを出力しておくことで、デバッグ時やログを出力した際に便利なので、可能であればすべてのクラスに実装しておくようにしましょう。
例えば、ArrayListクラスのtoString()メソッドを呼び出すと、リストの中の要素の文字列表現が次のように取得できます。
public class Main {
public static void main(String[] args) throws Exception {
ArrayList<String> list = new ArrayList<String>();
list.add("apple");
list.add("banana");
list.add("cherry");
System.out.println(list.toString()); //-> [apple, banana, cherry]
}
}
equals() メソッド
オブジェクト同時を比較し等しいかどうかを比較するメソッドです。
Javaではプリミティブ型の変数は、a == bのような比較演算子で内容を比較しますが、String型や、その他の参照型はequals()メソッドで比較しないと、正しい結果を得ることができません。
String a = new String("str1");
String b = new String("str1");
if (a.equals(b))) {
System.out.println("a.equals(b))はtrueです");
}
if (a == b) {
System.out.println("a==bはtrueです");
}
【実行結果】
a.equals(b))はtrueです
クラスの継承
冒頭でも少し触れましたが、Javaをはじめとするオブジェクト指向の言語には「クラスの継承」という概念があります。
クラスの継承は、継承元(スーパークラス)に定義された機能(メソッドやプロパティ)を、継承先(サブクラス)のクラスに引き継ぐことができます。
継承をすることで、共通的なコードを継承元のクラスに定義しておき、継承先のクラスは必要な部分のみを拡張することで、同じようなコードを複数のクラスに記述する必要がなくなり、開発生産性の向上や保守性が上がります。
次のコードはParentクラスを継承元(extends)に、Childクラスを宣言する例です。
さらに継承先のChildクラスでのchildMethod(メソッドでは、Parentクラスのメソッドやフィールドを参照します。
// 継承元とするParentクラス
class Parent {
String field1 = "A";
String field2 = "B";
public void baseMethod() {
System.out.println("Parentのメソッドです");
}
}
// Parentを継承したサブクラス
class Child extends Parent {
public void childMethod() {
// 親クラスのメソッドを呼び出すことができる
baseMethod();
// 親クラスのフィールドも参照可能
System.out.println("field1=" + field1);
}
}
実際にChildクラスのインスタンスを生成して、childMethod()メソッドを呼んでみましょう。
public class Main {
public static void main(String[] args) throws Exception {
Child child = new Child();
child.childMethod();
}
}
【実行結果】
Parentのメソッドです
field1=A
このように、継承先クラスから継承元のメソッドやフィールドが参照できているのが分かります。
Childクラスをさらに継承したクラスを作成して、親子孫のような関係のクラスを作成した場合でも、継承関係がある限り、孫のクラスやその先の継承クラスにまでParentクラスの機能が引き継がれます。
Javaで継承クラスを作成する詳細は次の記事でも紹介しています。
【関連記事】
▶【初心者歓迎】クラスの継承とは?Javaのextendsの使い方を理解しよう!
さいごに
JavaのObjectクラスや継承の概念について解説してきました。
この記事で述べたように、ObjectクラスはJavaのすべてのクラスが継承する大元のクラスです。
ObjectクラスのequalsやtoStringメソッドは、実際のシステム開発の現場でもよく使われるため、是非使い方を覚えておきましょう。
【関連記事】
▶【Java】new演算子の基本的な使い方を理解しよう!【サンプル有り】
▶【JAVA】基本的な知識を身に着ける!16進数について分かりやすく解説。
intやcharなどのプリミティブ型の変数は、intA = intBのように別の変数に自身を代入するだけで、値の句複製ができるが、参照型のクラスは別の変数に自身を代入すだけでは、クラスのインスタンスへの参照がコピーされるだけで、片方の変数の内容を書き換えると、もう一方の変数のクラスの内容も書き変わってしまうため、参照型のクラスを複製する場合はcloneメソッドを使用します。