Подтвердить что ты не робот

Как работает `isInstanceOf`?

Предположим, что:

class B
class A extends B
trait T

Тогда оно выполняется:

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

Можно ли сказать, что метод isInstanceOf проверяет, существует ли хотя бы один тип (не все типы), который соответствует правой стороне в отношении подтипа?

Сначала я думал, что значение с типом A with T не может быть подтипом B, потому что A и T не оба подтипа B. Но это A или T является подтипом B - это правильно?

4b9b3361

Ответ 1

isInstanceOf выглядит, если в цепочке наследования есть соответствующая запись. Цепочка A with T включает A, B и T, поэтому a.isInstanceOf[B] должно быть истинным.

изменить:

На самом деле сгенерированный байт-код вызывает javas instanceof, поэтому в java он будет a instanceof B. Более сложным вызовом типа a.isInstanceOf[A with T] будет (a instanceof A) && (a instanceof T).

Ответ 2

Сначала я подумал, что значение с типом A с T не может быть подтип B

Здесь есть два неправильных представления. Во-первых, что статический тип экземпляра имеет какое-либо отношение к результату isInstanceOf: его нет. Чтобы быть ясным, при выполнении a.isInstanceOf[B] факт, что a имеет тип A with T, не имеет значения.

Метод isInstanceOf реализуется на уровне байт-кода JVM. Он рассматривает информацию о классе, которую несет каждый экземпляр, и проверяет, является ли B одним из классов (класс самого экземпляра и его предков) или одним из реализованных интерфейсов. Что отношение "есть-a": "a есть B".

Технически, isInstanceOf является частью отражения Java, где он известен как instanceof.

Второе заблуждение - наследование может каким-то образом удалить родительский тип. Этого никогда не бывает: наследование только добавляет типы, никогда не удаляет их. Тип A with T - это a, a B, a T, a AnyVal и a Any. Поэтому даже если isInstanceOf посмотрел тип A with T, он все равно вернет true.