Опубликован: 11.12.2003 | Уровень: специалист | Доступ: платный
Лекция 13:

Пакет java.lang

< Лекция 12 || Лекция 13: 12345 || Лекция 14 >

Class

В запущенной программе Java каждому классу соответствует объект типа Class. Этот объект содержит информацию, необходимую для описания класса – поля, методы и т.д.

Класс Class не имеет открытого конструктора – объекты этого класса создаются автоматически Java-машиной по мере загрузки описания классов из class -файлов. Получить экземпляр Class для конкретного класса можно с помощью метода forName():

public static Class forName(String name, boolean initialize, ClassLoader loader) – возвращает объект Class, соответствующий классу, или интерфейсу, с названием, указанным в name необходимо указывать полное название класса или интерфейса, используя переданный загрузчик классов. Если в качестве загрузчика классов loader передано значение null, будет взят ClassLoader, который применялся для загрузки вызывающего класса. При этом класс будет инициализирован, только если значение initialize равно true и класс не был инициализирован ранее.

Зачастую проще и удобнее воспользоваться методом forName(), передав только название класса: public static Class forName(String className),– при этом будет использоваться загрузчик вызывающего класса и класс будет инициализирован (если до этого не был).

public Object newInstance() – создает и возвращает объект класса, который представляется данным экземпляром Class. Создание будет происходить с использованием конструктора без параметров. Если такового в классе нет, будет брошено исключение InstantiationException. Это же исключение будет брошено, если объект Class соответствует абстрактному классу, интерфейсу, или какая-то другая причина помешала созданию нового объекта.

Каждому методу, полю, конструктору класса также соответствуют объекты, список которых можно получить вызовом соответствующих методов объекта Class: getMethods(), getFields(), getConstructors(), getDeclaredMethods() и т.д. В результате будут получены объекты, которые отвечают за поля, методы, конструкторы объекта. Их можно использовать для формирования динамических вызовов Java – этот механизм называется reflection . Необходимые классы содержатся в пакете java.lang.reflection.

Рассмотрим пример использования этой технологии:

package demo.lang;
interface Vehicle {
   void go();
}
class Automobile implements Vehicle {
   public void go() {
      System.out.println("Automobile go!");
   }
}
class Truck implements Vehicle {
   public Truck(int i) {
      super();
   }
   public void go() {
      System.out.println("Truck go!");
   }
}
public class VehicleStarter {
   public static void main(String[] args) {
      Vehicle vehicle;
      String[] vehicleNames = {"demo.lang.Automobile", 
         "demo.lang.Truck", "demo.lang.Tank"};
      for(int i=0; i<vehicleNames.length; i++) {
         try {
            String name = vehicleNames[i];
            System.out.println("look for class for: " + name);
            Class aClass = Class.forName(name);
            System.out.println("creating vehicle...");
            vehicle = (Vehicle)aClass.newInstance();
            System.out.println("create vehicle: " + vehicle.getClass());
            vehicle.go();
         } catch(ClassNotFoundException e) {
            System.out.println("Exception: " + e);
         } catch(InstantiationException e) {
            System.out.println("Exception: " + e);
         }
      }
   }
}
Пример 13.3.

Если запустить эту программу, на экран будет выведено следующее:

look for class for: demo.lang.Automobile 
creating vehicle...
create vehicle: class demo.lang.Automobile
Automobile go!
look for class for: demo.lang.Truck
creating vehicle...
Exception: java.lang.InstantiationException
look for class for: demo.lang.Tank
Class not found: java.lang.ClassNotFoundException: demo.lang.Tank
Пример 13.4.

В этом примере делается попытка создать с помощью reflection три объекта. Имена классов, от которых они должны быть порождены, записаны в массив vehicleNames. Объект класса Automobile был успешно создан, причем, дальнейшая работа с ним велась через интерфейс Vehicle. Класс Truck был найден, но при попытке создания объекта было брошено, а затем обработано исключение java.lang.InstantiationException, поскольку конструктор без параметров отсутствует. Класс java.lang.Tank определен не был и поэтому при попытке получить соответствующий ему объект Class было выброшено исключение java.lang.ClassNotFoundException.

Классы-обертки

Во многих случаях предпочтительней работать именно с объектами, а не с примитивными типами. Так, например, при использовании коллекций просто необходимо значения примитивных типов представлять в виде объектов.

Для этих целей и предназначены так называемые классы-обертки. Для каждого примитивного типа Java существует свой класс-обертка . Такой класс является неизменяемым (если необходим объект, хранящий другое значение, его нужно создать заново), к тому же имеет атрибут final – от него нельзя наследовать класс. Все классы-обертки (кроме Void ) реализуют интерфейс Serializable, поэтому объекты любого (кроме Void ) класса-обертки могут быть сериализованы. Все классы-обертки содержат статическое поле TYPE, ссылающееся на объект Class, соответствующий примитивному оборачиваемому типу.

Также классы-обертки содержат статические методы для обеспечения удобного манипулирования соответствующими примитивными типами, например, преобразование к строковому виду.

В таблице 13.1 приведены примитивные типы и соответствующие им классы-обертки.

Таблица 13.1. Примитивные типы и соответствующие им классы-обертки.
Класс-обертка Примитивный тип
Byte byte
Short short
Character char
Integer int
Long long
Float float
Double double
Boolean boolean

При этом классы-обертки числовых типов Byte, Short, Integer, Long, Float, Double наследуются от одного класса – Number. В нем объявлены методы, возвращающие числовое значение во всех числовых форматах Java ( byte, short, int, long, float и double ).

Все классы-обертки реализуют интерфейс Comparable. Все классы-обертки числовых типов имеют метод equals(Object), сравнивающий примитивные значения объектов.

Рассмотрим более подробно некоторые из классов-оберток.

Integer

Наиболее часто используемые статические методы:

  • public static int parseInt(String s) – преобразует строку, представляющую десятичную запись целого числа, в int ;
  • public static int parseInt(String s, int radix) – преобразует строку, представляющую запись целого числа в системе счисления radix, в int.

Оба метода могут возбуждать исключение NumberFormatException, если строка, переданная на вход, содержит нецифровые символы.

Не следует путать эти методы с другой парой похожих методов:

public static Integer valueOf(String s)
public static Integer valueOf(String s, 
                              int radix)

Данные методы выполняют аналогичную работу, только результат представляют в виде объекта-обертки.

Существует также два конструктора для создания экземпляров класса Integer:

  • Integer(String s) – конструктор, принимающий в качестве параметра строку, представляющую числовое значение.
  • Integer(int i) – конструктор, принимающий числовое значение.

public static String toString(int i) – используется для преобразования значения типа int в строку.

Далее перечислены методы, преобразующие int в строковое восьмеричное, двоичное и шестнадцатеричное представление:

  • public static String toOctalString(int i) – восьмеричное;
  • public static String toBinaryString(int i) – двоичное;
  • public static String toHexString(int i) – шестнадцатеричное.

Имеются также две статические константы:

  • Integer.MIN_VALUE – минимальное int значение;
  • Integer.MAX_VALUE – максимальное int значение.

Аналогичные константы, описывающие границы соответствующих типов, определены и для всех остальных классов-оберток числовых примитивных типов.

public int intValue() возвращает значение примитивного типа для данного объекта Integer. Классы-обертки остальных примитивных целочисленных типов – Byte, Short, Long – содержат аналогичные методы и константы (определенные для соответствующих типов: byte, short, long ).

Рассмотрим пример:

public static void main(String[] args) {
   int i = 1;
   byte b = 1;
   String value = "1000";
   Integer iObj = new Integer(i);
   Byte bObj = new Byte(b);
   System.out.println("while i==b is " + 
                      (i==b));
   System.out.println("iObj.equals(bObj) is "
                      + iObj.equals(bObj));
   Long lObj = new Long(value);
   System.out.println("lObj = " + 
                      lObj.toString());
   Long sum = new Long(lObj.longValue() + 
                       iObj.byteValue() + 
                       bObj.shortValue());
   System.out.println("The sum = " + 
                      sum.doubleValue());
}

В данном примере произвольным образом используются различные варианты классов-оберток и их методов. В результате выполнения на экран будет выведено следующее:

while i==b is true
iObj.equals(bObj) is false
lObj = 1000
The sum = 1002.0

Оставшиеся классы-обертки числовых типов Float и Double, помимо описанного для целочисленных примитивных типов, дополнительно содержат определения следующих констант (они подробно разбирались в лекции 4):

  • NEGATIVE_INFINITY – отрицательная бесконечность;
  • POSITIVE_INFINITY – положительная бесконечность;
  • NaN – нечисловое значение.

Кроме того, другой смысл имеет значение MIN_VALUE – вместо наименьшего значения оно представляет минимальное положительное (строго > 0) значение, которое может быть представлено этим примитивным типом.

Кроме классов-оберток для примитивных числовых типов, таковые определены и для остальных примитивных типов Java.

Character

Реализует интерфейсы Comparable и Serializable.

Из конструкторов имеет только один, принимающий char в качестве параметра.

Кроме стандартных методов equals(), hashCode(), toString(), содержит только два нестатических метода:

  • public char charValue() – возвращает обернутое значение Character;
  • public int compareTo(Character anotherCharacter) – сравнивает обернутые значения char как числа, то есть возвращает значение return this.valueanotherCharacter.value.

Также для совместимости с интерфейсом Comparable метод compareTo() определен с параметром Object:

  • public int compareTo(Object o) – если переданный объект имеет тип Character, результат будет аналогичен вызову compareTo((Character)o), иначе будет брошено исключение ClassCastException, так как Character можно сравнивать только с Character.

Статических методов в классе Character довольно много, но все они просты и логика их работы понятна из названия. Большинство из них - это методы, принимающие char и проверяющие всевозможные свойства. Например:

public static boolean isDigit(char c) 
// проверяет, является ли char цифрой.

Эти методы возвращают значение истина или ложь, в соответствии с тем, выполнен ли критерий проверки.

Boolean

Представляет класс-обертку для примитивного типа boolean.

Реализует интерфейс java.io.Serializable и во всем напоминает аналогичные классы-обертки.

Для получения примитивного значения используется метод booleanValue().

Void

Этот класс-обертка, в отличие от остальных, не реализует интерфейс java.io.Serializable. Он не имеет открытого конструктора. Более того, экземпляр этого класса вообще не может быть получен. Он нужен только для получения ссылки на объект Class, соответствующий void. Эта ссылка представлена статической константой TYPE.

Делая краткое заключение по классам-оберткам, можно сказать, что:

  • каждый примитивный тип имеет соответствующий класс-обертку ;
  • все классы-обертки могут быть сконструированы как с использованием примитивных типов, так и с использованием String, за исключением Character, который может быть сконструирован только по char ;
  • классы-обертки могут сравниваться с использованием метода equals() ;
  • примитивные типы могут быть извлечены из классов-оберток с помощью соответствующего метода xxxxValue() (например intValue() );
  • классы-обертки также являются классами-утилитами, т.е. предоставляют набор статических методов для работы с примитивными типами;
  • классы-обертки являются неизменяемыми.
< Лекция 12 || Лекция 13: 12345 || Лекция 14 >
Вадим Кудаев
Вадим Кудаев

Добрый день! Начал проходить курс "Программирование на Java". Как я понимаю,курс создавался приблизительно в 2015 году. Не потерял ли данный курс свою актуальность? Стоит ли проходить его в 2023 году, или же лучше найти что-то более новое?

Федор Антонов
Федор Антонов

Здравствуйте!

Записался на ваш курс, но не понимаю как произвести оплату.

Надо ли писать заявление и, если да, то куда отправлять?

как я получу диплом о профессиональной переподготовке?

Данила Некрасов
Данила Некрасов
Россия, Пермь, ПНИПУ
Сергей Федоров
Сергей Федоров
Россия