Чтение онлайн

на главную - закладки

Жанры

Программирование на Java

Вязовик Н.А.

Шрифт:

Тело класса содержит объявление одного public final поля length типа int. Кроме того, переопределен метод clone для поддержки интерфейса Cloneable.

Сведем все вышесказанное в формальную запись класса:

[public] class A implements Cloneable,

java.io.Serializable {

public final int length;

// инициализируется при создании

public Object clone {

try {

return super.clone;

}

catch (CloneNotSupportedException e) {

throw new InternalError(e.getMessage);

}

}

}

Таким

образом, экземпляр типа массив является полноценным объектом, который, в частности, наследует все методы, определенные в классе Object, например, toString, hashCode и остальные.

Например:

// результат работы метода toString

System.out.println(new int[3]);

System.out.println(new int[3][5]);

System.out.println(new String[2]);

// результат работы метода hashCode

System.out.println(new float[2].hashCode);

Результатом выполнения программы будет:

[I@26b249

[[I@82f0db

[Ljava.lang.String;@92d342

7051261

Преобразование типов для массивов

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

Ранее подробно рассматривались переходы между примитивными и обычными (не являющимися массивами) ссылочными типами. Хотя массивы являются объектными типами, их также будет полезно разделить по базовому типу на две группы – основанные на примитивном или ссылочном типе.

Имейте в виду, что переходы между массивами и примитивными типами являются запрещенными. Преобразования между массивами и другими объектными типами возможны только для класса Object и интерфейсов Cloneable и Serializable. Массив всегда можно привести к этим трем типам, обратный же переход является сужением и должен производиться явным образом по усмотрению разработчика. Таким образом, интерес представляют только переходы между разными типами массивов. Очевидно, что массив, основанный на примитивном типе, принципиально нельзя преобразовать к типу массива, основанному на ссылочном типе, и наоборот.

Пока не будем останавливаться на этом подробно, однако заметим, что преобразования между типами массивов, основанных на различных примитивных типах, невозможны ни при каких условиях.

Для ссылочных же типов такого строгого правила нет. Например, если создать экземпляр массива, основанного на типе Child, то ссылку на него можно привести к типу массива, основанного на типе Parent.

Child c[] = new Child[3];

Parent p[] = c;

Вообще, существует универсальное правило: массив, основанный на типе A, можно привести к массиву, основанному на типе B, если сам тип A приводится к типу B.

// если допустимо такое приведение:

B b = (B) new A;

//

то допустимо и приведение массивов:

B b[]=(B[]) new A[3];

Применяя это правило рекурсивно, можно преобразовывать многомерные массивы. Например, массив Child[][] можно привести к Parent[][], так как их базовые типы приводимы ( Child[] к Parent[] ) также на основе этого правила (поскольку базовые типы Child и Parent приводимы в силу правил наследования).

Как обычно, расширения можно проводить неявно (как в предыдущем примере), а сужения – только явным приведением.

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

// пример вызовет ошибку компиляции

byte b[]= {1, 2, 3};

int i[]=b;

В таком случае, элементы b[0] и i[0] хранили бы значения разных типов. Стало быть, преобразование потребовало бы копирования с одновременным преобразованием типа всех элементов исходного массива. В результате был бы создан новый массив, элементы которого равнялись бы по значению элементам исходного массива.

Но преобразование типа не может порождать новые объекты. Такие операции должны выполняться только явным образом с применением ключевого слова new. По этой причине преобразования типов массивов, основанных на примитивных типах, запрещены.

Если же копирование элементов действительно требуется, то нужно сначала создать новый массив, а затем воспользоваться стандартной функцией System.arraycopy, которая эффективно выполняет копирование элементов одного массива в другой.

Ошибка ArrayStoreException

Преобразование между типами массивов, основанных на ссылочных типах, может стать причиной одной довольно неочевидной ошибки.

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

Child c[] = new Child[5];

Parent p[]=c;

p[0]=new Parent;

С точки зрения компилятора код совершенно корректен. Преобразование во второй строке допустимо. В третьей строке элементу массива типа Parent присваивается значение того же типа.

Однако при выполнении такой программы возникнет ошибка. Нельзя забывать, что преобразование не меняет объект, изменяется лишь способ доступа к нему. В свою очередь, объект всегда "помнит", от какого типа он был порожден. С учетом этих замечаний становится ясно, что в третьей строке делается попытка добавить в массив Child значение типа Parent, что некорректно.

Поделиться:
Популярные книги

Аватар

Жгулёв Пётр Николаевич
6. Real-Rpg
Фантастика:
боевая фантастика
5.33
рейтинг книги
Аватар

Кир Булычев. Собрание сочинений в 18 томах. Т.7

Булычев Кир
Собрания сочинений
Фантастика:
научная фантастика
6.25
рейтинг книги
Кир Булычев. Собрание сочинений в 18 томах. Т.7

В любви и на войне все средства хороши! Книга 2

Ведуница Ирина
2. Любовь-война
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
В любви и на войне все средства хороши! Книга 2

Гримуар темного лорда IX

Грехов Тимофей
9. Гримуар темного лорда
Фантастика:
попаданцы
альтернативная история
аниме
фэнтези
5.25
рейтинг книги
Гримуар темного лорда IX

Экстремальные ситуации

Малкина-Пых Ирина Германовна
Справочник практического психолога
Научно-образовательная:
психология
5.00
рейтинг книги
Экстремальные ситуации

#Бояръ-Аниме. Газлайтер. Том 24

Володин Григорий Григорьевич
24. История Телепата
Фантастика:
боевая фантастика
попаданцы
аниме
5.40
рейтинг книги
#Бояръ-Аниме. Газлайтер. Том 24

На границе империй. Том 9. Часть 5

INDIGO
18. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 9. Часть 5

Пламенев. Книга 3-7

Карелин Сергей Витальевич
Пламенев
Фантастика:
аниме
уся
фэнтези
сянься
5.00
рейтинг книги
Пламенев. Книга 3-7

Астровитянка

Горькавый Ник
1. Астровитянка
Фантастика:
научная фантастика
9.17
рейтинг книги
Астровитянка

Пламенев. Книга XII

Карелин Сергей Витальевич
12. Пламенев
Фантастика:
аниме
уся
сказочная фантастика
фэнтези
5.00
рейтинг книги
Пламенев. Книга XII

Собрание сочинений. Том 44

Энгельс Фридрих
Научно-образовательная:
философия
5.00
рейтинг книги
Собрание сочинений. Том 44

Герцог и я

Куин Джулия
1. Бриджертоны
Любовные романы:
исторические любовные романы
8.92
рейтинг книги
Герцог и я

Рин. Книга I. Звезда и жернов. Экземпляр для свободного и бесплатного распространения в интернете

Армай Макс
Фантастика:
фэнтези
5.00
рейтинг книги
Рин. Книга I. Звезда и жернов. Экземпляр для свободного и бесплатного распространения в интернете

Дьюма-Ки

Кинг Стивен
Фантастика:
ужасы и мистика
8.90
рейтинг книги
Дьюма-Ки