従業員や医師、だ父と息子の彼ら:私は2つのクラスを定義しました。このようなコード:
class Employee {
// ....
}
class Doctor extends Employee {
// ....
}
そして、私はこのようなmainメソッドを書きました:
public static void main(String[] args) {
Doctor doctor = new Doctor();
Employee employee = new Employee();
System.out.println(doctor.getClass() == new Employee().getClass()); // code 1
System.out.println(employee.getClass() == Employee.class); // code 2
System.out.println(doctor.getClass() == Employee.class); // code 3
}
しかし、唯一code 1
かつcode 2
正確であるとcode 3
例外を呼び出します。
Error:(33, 46) Java: uncomparable type: java.lang.Class<capture#1 extends Doctor> and java.lang.Class<Employee>
そして私は、私が使用することができます知っているequals
この問題に対処するために、私は演算子を使用することはできませんなぜ私が知りたい==
それらを比較します。
あなたが観察行動は正しいのですが、理由を説明するために、我々は、Java言語仕様を参照する必要があります。
§15.8.2。クラスリテラルは言います
タイプ
C.class
、C
クラス、インタフェース、または配列型(§4.3)の名前ですClass<C>
。
§4.3.2。クラスはObject
言います:
メソッド呼出し式の型が
getClass
あるClass<? extends |T|>
場合、T
検索されたクラスまたはインタフェースであるgetClass
(§15.12.1が)と|T|
の消去示しT
(§4.6)を。
キャストの変換(§5.5)によって他のタイプのいずれかのオペランドの型を変換することは不可能であるならば、コンパイル時エラーが発生します。二つのオペランドの実行時の値は必ずしも(両方の値である場合を無視して不均等であろう
null
)。
そこで、我々は、各式のコンパイル時の型を書き留めることができます。
Employee.class
型ですClass<Employee>
。Doctor.class
型ですClass<Doctor>
。employee.getClass()
そして、new Employee().getClass()
タイプの両方がありますClass<? extends Employee>
。これは、Class
表現のいずれかEmployee
を含め、そのサブクラスかをDoctor
。doctor.getClass()
そして、new Doctor().getClass()
タイプの両方がありますClass<? extends Doctor>
。この手段Class
表すいずれかDoctor
そのサブクラス、例えばまたはSurgeon
多分。
今、私たちはすべての3つの動作を説明することができます:
doctor.getClass() == new Employee().getClass()
比較しClass<? extends Doctor>
てClass<? extends Employee>
。第一のタイプは、鋳造変換することにより、第2型に変換することができるので、これは許可されています。employee.getClass() == Employee.class
比較しClass<? extends Employee>
てClass<Employee>
。第二のタイプは、鋳造変換することにより、第1型に変換することができるので、これは許可されています。doctor.getClass() == Employee.class
比較しClass<? extends Doctor>
てClass<Employee>
。これは、コンパイル時エラー(例外ではない)であるように、いずれのタイプは、キャスト変換により相互に変換することができます。
3.上で、もう少し詳細に行く、Class<? extends Doctor>
によって満たすことができClass<Doctor>
たりClass<Surgeon>
、しかしないでClass<Employee>
いるためEmployee
のサブタイプではありませんDoctor
。しかし、あなたがアップキャスト場合、意図した結果を持っている同様の式を書くことができますdoctor
呼び出す前にgetClass
:
((Employee) doctor).getClass() == Employee.class
それが許可されているので、ケース2と同様です。
アップキャストの代わりにダウンキャストによって型エラーを修正するために確かにかなり珍しいです。