Object型とは
Object型とは、Javaを含めた多くのオブジェクト指向プログラミング言語で導入されている、すべてのクラスが共通して継承しているルートクラスです。
Javaでは、継承元のスーパークラスを指定する時はextends句を使用しますが、継承元のクラスを省略した場合は、暗黙的にObjectクラスが継承元になります。
たとえば、JavaのAPIドキュメントで、ファイルの読み込み時などに使用するBufferedInputStreamクラスの継承階層を見ると、最も基底となるクラスがObject型になっているのが分かります。
これはBufferedInputStreamクラスに限らず、他のすべてのJavaクラスで同じようになっています。
どんな方の変数でも入る
Javaにはサブクラス(継承先)のオブジェクトをスーパークラス(継承元)と同じように扱うことができるアップキャストという機能があります。
たとえば、次のようにParentクラスを継承したChildがあったとします。
// スーパークラス(継承元)のクラス
class Parent {
}
// Parentを継承したサブクラス(継承先)
class Child extends Parent {
}
Childクラスのインスタンスは、継承元Parentと同じように扱えるため、次のようにParentクラスの型で宣言された変数に、Childクラスのインスタンスを代入すると、自動的にアップキャストが行われます。
public class Main {
public static void main(String[] args) {
// サブクラス(継承先)のインスタンスを作成
Child child = new Child();
// 継承元の型の変数に代入(アップキャスト)
Parent parent = child;
}
}
そして、冒頭でも述べた通りObject型は全てのクラスのルートなる継承元のクラスであるため、Object型の変数には、どのようなクラスのインスタンスでも格納することが可能です。
public class Main {
public static void main(String[] args) {
// ParentクラスをObject型の変数に代入(アップキャスト)
Parent parent = new Parent();
Object obj1 = parent;
// ChildクラスをObjectに代入(アップキャスト)
// 継承関係にある継承元のクラスであれば、アップキャストが可能
Child child = new Child();
Object obj2 = child;
}
}
型の情報を取得する
Object型の変数にクラスのインスタンスを代入(アップキャスト)し、そのObject型の変数を他のメソッドに渡した場合、渡された側のメソッドでは、当然Object型の変数として引数が渡されるため、変数の中身にどのような型のインスタンスが格納されているかが分かりません。
変数に格納されている値の型情報を取得したい場合、Objectクラスに定義されているgetClass()メソッドを使って取得することができます。
実際に、先ほど作成したParentとChildクラスのインスタンスをObject型の変数に代入(アップキャスト)して試してみましょう。
public class Main {
public static void main(String[] args) {
// Parentクラス
Parent parent = new Parent();
Object obj1 = parent; // Object型の変数に代入(アップキャスト)
System.out.println(obj1.getClass()); // getClass()メソッドで方情報を取得
// Childクラス
Child child = new Child();
Object obj2 = child; // Object型の変数に代入(アップキャスト)
System.out.println(obj2.getClass()); // getClass()メソッドで方情報を取得
}
}
【実行結果】
--------------------
class Parent
class Child
このように、getClass()メソッドを使用して型の情報を取得するとこができ、たとえばObject型の変数に特定の型のインスタンスが格納された時だけ、処理を行うといったことに使用できます。
型の比較
getClass()メソッドで型の情報を取得したら、次はその型が特定のクラス型かどうかチェックする型比較を行ってみましょう。
型の比較は、数値などの比較でも使用する比較演算子の==や!=を使います。
public class Main {
public static void main(String[] args) {
// ChildクラスのインスタンスをObject型の変数に代入
Object obj1 = new Child(); // Object型の変数に代入(アップキャスト)
// obj1が Parentクラスの型と一致するかチェック
if (obj1.getClass() == Parent.class) {
System.out.println("obj1は Parentクラスです");
}
// obj1が Childクラスの型と一致するかチェック
if (obj1.getClass() == Child.class) {
System.out.println("obj1は Childクラスです");
}
}
}
【実行結果】
--------------------
obj1は Childクラスです
継承関係を意識した型の比較
次に、getClass()で取得した型が、特定のクラスまたは、そのクラスを継承したサブクラスであるかをチェックする方法を解説します。
比較演算子の==や!=を使った型比較では、指定したクラスに限定した型比較しか行えないため、継承関係を意識した型比較を行う場合は、instanceof演算子を使用します。
次のコードは、変数obj1 にChildクラスのインスタンスを格納し、instanceof演算子で変数obj1 がParentクラスまたはParentを継承したクラスであるかをチェックする例です。
public class Main {
public static void main(String[] args) throws Exception {
// ChildクラスのインスタンスをObject型の変数に代入
Object obj1 = new Child();
// obj1が Parentクラスの型と一致するかチェック
if (obj1 instanceof Parent) {
System.out.println("obj1は ParentまたはParentを継承したクラスです。");
}
}
}
【実行結果】
--------------------
obj1は ParentまたはParentを継承したクラスです。
さいごに
JavaのObject型についての解説や、正体不明な型のクラスの型比較を行う方法について紹介してきました。
アップキャストを使った、継承元(スーパークラス)の方への代入などはよく使うため、是非覚えておきましょう。
- Object型はすべてのクラスが共通して継承しているルートクラス
- Object型の変数には、すべてのクラスのインスタンスが代入できる
- 型の比較は比較演算子の==が使える
- 継承関係を意識した方の比較を行う場合はinstanceof演算子を使う