Назад Зміст Вперед

7.14. Оператор instanceof

Іноді тип об'єкта корисно з'ясуватипід час виконання. Наприклад, в одному потоці виконання об'єкти різних типів можуть формуватися, а в іншому потоці виконання - використовуватися. В такому випадку зручно з'ясувати тип кожного об'єкта, одержуваного в обробному потоці виконання. Тип об'єкта під час виконання не менш важливо з'ясувати і в тому випадку, коли потрібно приведення типів. У Java неправильне приведення типів тягне за собою появу помилки під час виконання. Більшість помилок приведення типів може бути виявлено на стадії компіляції. Але приведення типів в межах ієрархії класів може стати причиною помилок, які виявляються тільки під час виконання. 

Наприклад, суперклас А може породжувати два підкласи: В і С. Отже, приведення об'єкта класу В або С до типу А цілком допустимо, але приведення об'єкту класу В до типу С (і навпаки) - невірно. А оскільки об'єкт типу А може посилатися на об'єкти типу В і С, то як під час виконання дізнатися, на який саме тип робиться посилання перед тим, як виконати приведення до типу С? Це може бути об'єкт типу А, В або С. Якщо це об'єкт типу В, то під час виконання буде згенеровано виняток. Для вирішення цього питання в java надається оператор часу виконання instanceof, який має наступну загальну форму:
посилання_на_об'єкт instanceof тип
де посилання_на_об'єкт позначає посилання на екземпляр класу, а тип - конкретний тип цього класу. Якщо посилання_на_об'єкт відноситься до зазначеного типу або може бути приведена до нього, то обчислення оператора instanceof дає в підсумку логічне значення true, а інакше - логічне значення false. Таким чином, оператор instanceof - це засіб, за допомогою якого програма може отримати відомості про об'єкт під час виконання. У наступному прикладі програми демонструється застосування оператора instanceоf:
// Застосування оператора instanceof
class А {
int i, j;
}
class B {
int i, j;
}
class С extends А {
int k;
}
class D extends А {
int k;
}
class InstanceOf {
public static void main (String args [] ) {
}
А a = new А();
B b = new B();
С c = new С();
D d = new D();
if (a instanceof А)
System.out.println ("a є екземпляром А");
if (b instanceof В)
System.out.println ("b є екземпляром В");
if (c instanceof С)
System.out.println ("c є екземпляром С");
if (c instanceof А)
System.out.println ("c можно привести до типу А");
if (a instanceof С)
System.out.println ("a можно привести до типу С");
    System.out.println ( );
// порівняти з породженими типами
А оb ;
оb= d; // посилання на об'єкт d
System.out.println ("ob тепер посилається на d");
if(ob instanceof D)
System.out.println("ob є экземпляром D");
   System.out.println() ;
оb =c; // посилання на С
   System.out.println("ob тепер посилаєтся на с");
if (ob instanceof D)
System.out.println("ob можно привести до типу D");
else
System.out.println("ob не можна привести до типу D");
if (ob instanceof А)
System.out.println("ob можно привести до типу А");
   System.out.println();
//всі обєкти можуть бути приведені до типу Object
if ( a instanceof Object )
System.out.println ( " a можна привести до типу Object");
if ( b instanceof Object )
System.out.println ( " b можна привести до типу Object");
if ( c instanceof Object )
System.out.println ( " c можна привести до типу Object");
if ( d instanceof Object )
System.out.println ( " d можна привести до типу Object");
}
}
Більшість програм не потребує оператора instanceof, оскільки типи об'єктів зазвичай відомі заздалегідь. Але цей оператор може стати в нагоді при розробці узагальнених процедур, що оперують об'єктами зі складної ієрархія класів.
.