29

仮定します:

class B
class A extends B
trait T

それからそれは成り立つ:

val a: A with T = new A with T 
a.isInstanceOf[B]  // result is true !

isInstanceOfサブタイプの関係で右側に一致するタイプ(すべてのタイプではない)が少なくとも1つあるかどうかを、メソッドがチェックすると言うのは正しいですか?

一見したところ、タイプの値はA with Tのサブタイプにはなり得ないと思いました。BなぜならA 、と Tは両方のサブタイプではないからですB。しかし、それは-のサブタイプであるか、A または TサブタイプですB-そうですか?

4

2 に答える 2

39

isInstanceOf継承チェーンに対応するエントリがあるかどうかを調べます。のチェーンにA with Tは、、、が含まれるためA、真BTあるa.isInstanceOf[B]必要があります。

編集:

実際に生成されたバイトコードはjavasinstanceofを呼び出すためa instanceof B、javaになります。のようなもう少し複雑な呼び出しa.isInstanceOf[A with T]はです(a instanceof A) && (a instanceof T)

于 2012-07-02T08:35:51.407 に答える
13

一見したところ、タイプAの値とTの値は、Bのサブタイプにはなり得ないと思いました。

ここには2つの誤解があります。まず、インスタンスの静的タイプが次の結果に関係していることisInstanceOf:ありません。明確にするために、実行するとき、タイプa.isInstanceOf[B]であるという事実は関係ありませんaA with T

このメソッドisInstanceOfは、JVMによってバイトコードレベルで実装されます。すべてのインスタンスが保持するクラス情報を調べB、クラスの1つ(インスタンス自体とその祖先のクラス)か、実装されたインターフェースの1つかを確認します。それが「is-a」の関係です。「aはBです」。

技術的にisInstanceOfは、Javaのリフレクションの一部であり、として知られていinstanceofます。

2番目の誤解は、継承がどういうわけか親型を削除できるということです。それは決して起こりません。継承は型を追加するだけで、削除することはありません。タイプA with Tは、、、、、、およびです。A_ したがって、タイプを調べたとしても、 trueを返します。BTAnyValAnyisInstanceOfA with T

于 2012-07-02T13:58:49.710 に答える