Философия Java

         

Использование литералов класса


Интересно посмотреть, как будет выглядеть пример PetCount.java, переписанный с использованием литералов класса. В результате код получается гораздо лучше:

//: c12:PetCount2.java // Использование литералов класса. import java.util.*;

public class PetCount2 { public static void main(String[] args) throws Exception { ArrayList pets = new ArrayList(); Class[] petTypes = { // Литералы класса: Pet.class, Dog.class, Pug.class, Cat.class, Rodent.class, Gerbil.class, Hamster.class, }; try { for(int i = 0; i < 15; i++) { // Смещение на 1, чтобы исключить класс Pet.class: int rnd = 1 + (int)( Math.random() * (petTypes.length - 1)); pets.add( petTypes[rnd].newInstance()); } } catch(InstantiationException e) { System.err.println("Cannot instantiate"); throw e; } catch(IllegalAccessException e) { System.err.println("Cannot access"); throw e; } HashMap h = new HashMap(); for(int i = 0; i < petTypes.length; i++) h.put(petTypes[i].toString(), new Counter()); for(int i = 0; i < pets.size(); i++) { Object o = pets.get(i); if(o instanceof Pet) ((Counter)h.get("class Pet")).i++; if(o instanceof Dog) ((Counter)h.get("class Dog")).i++; if(o instanceof Pug) ((Counter)h.get("class Pug")).i++; if(o instanceof Cat) ((Counter)h.get("class Cat")).i++; if(o instanceof Rodent) ((Counter)h.get("class Rodent")).i++; if(o instanceof Gerbil) ((Counter)h.get("class Gerbil")).i++; if(o instanceof Hamster) ((Counter)h.get("class Hamster")).i++; } for(int i = 0; i < pets.size(); i++) System.out.println(pets.get(i).getClass()); Iterator keys = h.keySet().iterator(); while(keys.hasNext()) { String nm = (String)keys.next(); Counter cnt = (Counter)h.get(nm); System.out.println( nm.substring(nm.lastIndexOf('.') + 1) + " quantity: " + cnt.i); } } } ///:~

Здесь, массив typenames был удален за счет того, что строка имени типа достается из объекта Class. Заметьте, что система может различать классы и интерфейсы.

Вы также видите, что создание petTypes не нужно окружать блоком try, т.к. оно вычисляется во время компиляции, и, потому, не может выбросить никаких исключений, в отличие от метода Class.forName().

Когда объекты Pet динамически созданы, Вы видите, что случайное число ограничено 1 и petTypes.length и не включает 0. Это потому, что 0 ссылается на Pet.class, и, наверное, базовый класс Pet нам не интересен. Однако, т.к. Pet.class является частью petTypes, в результате, все классы Pet посчитаны.



Содержание раздела