Студопедия  
Главная страница | Контакты | Случайная страница

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатика
ИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханика
ОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторика
СоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансы
ХимияЧерчениеЭкологияЭкономикаЭлектроника

Проверка перед приведением типа

Читайте также:
  1. Battement tendu jete в сторону левой ногой попеременно закрывать назад и вперед
  2. BROADCASTвещание; передача BROADCAST ADVERTISERS REPORT
  3. Double frappe вперед (во второй arabesque во вторую точку зала ) double frappe назад (во второй arabesque в восьмую точку зала)
  4. Double frappe вперед (во второй arabesque во вторую точку зала )double frappe назад (во второй arabesque в восьмую точку зала)
  5. FM передатчик начинающего радиопирата. Часть№2
  6. II. Школа Арканов тренирует зрелых мужчин и женщин, подводя их к следующему шагу вперед по Пути Эволюции
  7. III. ВПЕРЕД И ВВЕРХ
  8. V. Повторная проверка
  9. Або спливу строку для затримання, передбаченого ст. 211 КПК;
  10. Автоматическая коробка передач

Пока Вы видели две формы RTTI включающие:

  1. Стандартное приведение; в виде " (Shape), " которое использует RTTI, чтобы убедиться, что приведение произошло корректно, и выбрасывает исключение ClassCastException, если вы попытались произвести неправильное приведение.
  2. Объект Class представляет тип Вашего объекта. Объект Class может быть опрошен для получения полезной информации.

В C++, классическое приведение " (Shape) " не использует RTTI. В этом случае компилятору сообщается, что объект просто имеет новый тип. В языке Java, который выполняет проверку типа, это приведение часто называется "безопасное нисходящее приведение типа." Причина использования термина "нисходящее приведение" является историческим соглашением диаграммы иерархии классов. Если приведение типа Circle к типу Shape является восходящим, то приведение типа Shape к типу Circle является нисходящим. Однако Вы знаете, что класс Circle является еще и классом Shape, и компилятор свободно позволяет присвоение с восходящим приведением типа, но Вы не знаете, что класс Shape обязательно является классом Circle, так что компилятор не позволит выполнить присвоение с нисходящим приведением без использования явного приведения.

В Java существует третья форма RTTI. Это ключевое слово instanceof которое говорит Вам, что объект является экземпляром конкретного типа. Оно возвращает значение boolean, так, что Вы используете его в форме вопроса следующим образом:

if(x instanceof Dog) ((Dog)x).bark();

Приведенное выше выражение if проверяет, является ли объект x экземпляром класса Dog перед приведением объекта x к типу Dog. Это важно - использовать instanceof перед нисходящим приведением, когда у Вас нет ничего, что могло бы дать информацию о типе объекта; в противном случае приведение может завершится выбросом исключения ClassCastException.

Обычно, Вы можете искать один типом (например, треугольниками, чтобы окрасить их в пурпурный), но Вы можете просто повесить ярлычки на все объекты используя instanceof. Представьте, что у Вас есть группа классов Pet:

//: c12:Pets.javaclass Pet {}class Dog extends Pet {}class Pug extends Dog {}class Cat extends Pet {}class Rodent extends Pet {}class Gerbil extends Rodent {}class Hamster extends Rodent {} class Counter { int i; } ///:~

Класс Counter используется для хранения количества любых классов типа Pet. Вы можете считать, что это переменная Integer которая может быть изменена.

Используя instanceof, все классы Pet могут быть подсчитаны:

//: c12:PetCount.java// Использование instanceof.import java.util.*; public class PetCount { static String[] typenames = { "Pet", "Dog", "Pug", "Cat", "Rodent", "Gerbil", "Hamster", }; // Исключение выбрасывается на консоль: public static void main(String[] args) throws Exception { ArrayList pets = new ArrayList(); try { Class[] petTypes = { Class.forName("Dog"), Class.forName("Pug"), Class.forName("Cat"), Class.forName("Rodent"), Class.forName("Gerbil"), Class.forName("Hamster"), }; for(int i = 0; i < 15; i++) pets.add(petTypes[ (int)(Math.random()*petTypes.length)].newInstance()); } catch(InstantiationException e) { System.err.println("Cannot instantiate"); throw e; } catch(IllegalAccessException e) { System.err.println("Cannot access"); throw e; } catch(ClassNotFoundException e) { System.err.println("Cannot find class"); throw e; } HashMap h = new HashMap(); for(int i = 0; i < typenames.length; i++) h.put(typenames[i], new Counter()); for(int i = 0; i < pets.size(); i++) { Object o = pets.get(i); if(o instanceof Pet) ((Counter)h.get("Pet")).i++; if(o instanceof Dog) ((Counter)h.get("Dog")).i++; if(o instanceof Pug) ((Counter)h.get("Pug")).i++; if(o instanceof Cat) ((Counter)h.get("Cat")).i++; if(o instanceof Rodent) ((Counter)h.get("Rodent")).i++; if(o instanceof Gerbil) ((Counter)h.get("Gerbil")).i++; if(o instanceof Hamster) ((Counter)h.get("Hamster")).i++; } for(int i = 0; i < pets.size(); i++) System.out.println(pets.get(i).getClass()); for(int i = 0; i < typenames.length; i++) System.out.println(typenames[i] + " quantity: " + ((Counter)h.get(typenames[i])).i); }} ///:~

Существуют некоторые ограничения на использование instanceof: Вы можете сравнивать только именованные типы, но не объекты Class. В примере, приведенном выше, Вам может показаться, что это довольно скучно набирать все выражения instanceof, и Вы будете правы. Но не существует способа для правильной автоматизации instanceof созданием массива ArrayList объектов Class и сравнения их. Это не такое сильное ограничение, как Вы можете представить, т.к. Вы, в конечном счете, поймете, что Ваш замысел не будет осуществлен, если Вы прекратите писать множество этих выражений instanceof.

Конечно, этот пример был придуман, Вы, возможно, будете размещать статический член данных в каждом типе и увеличивать его в конструкторе, чтобы сохранить их количество. Вы вполне можете сделать что-то в этом духе, если у Вас есть исходные тексты класса и Вы можете менять их.. Но т.к. это бывает не всегда, Вы можете просто использовать RTTI.




Дата добавления: 2015-09-11; просмотров: 18 | Поможем написать вашу работу | Нарушение авторских прав

Сериализация объектов | Управление сериализацией | Ключевое слово transient | Альтернатива Externalizable | Использование устойчивости | StreamTokenizer | StringTokenizer | Проверка стиля капитализации | Упражнения | Необходимость RTTI |


lektsii.net - Лекции.Нет - 2014-2024 год. (0.007 сек.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав