Объявление массива Java, например, {A [] aa = new B [10]} - PullRequest
2 голосов
/ 13 декабря 2011

Сегодня я написал простой тест на синтаксис объявления массива, поэтому есть 3 класса:

public class A {
}

public class B extends A {
}

public class C extends A {
}

, и я попытался создать массив, используя следующий синтаксис

A[] aa = new B[10];

Итак, это возможно, но мы можем добавить только экземпляры класса B в этот массив. Если вы попытаетесь добавить экземпляры A или C, вы получите java.lang.ArrayStoreException и вопрос: почему мы можем создать массив с использованием такого синтаксиса и где его можно использовать и получить некоторую прибыль?Спасибо.

Ответы [ 4 ]

4 голосов
/ 13 декабря 2011

Массив содержит тип Bs. Даже если ссылка aa может содержать массивы типа A [], B [] или C [] (поскольку C и B оба расширяют A), во время выполнения массив может содержать только вещи, которые являются Bs.

Класс A не является B. Класс C не является B. Следовательно, исключение времени выполнения.

EDIT:

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

Например:

Animal[] animals;
if (useDogs) {
 animals = new Dog[num];
} else {
 animals = new Cat[num];
}

loadIntoCar(animals);
3 голосов
/ 13 декабря 2011

Причина, по которой этот синтаксис разрешен в языке, заключается в том, что иногда вам все равно, какой подкласс объектов находится в массиве. Правила спецификации языка Java для подтипа массива включают:

Если S и T являются ссылочными типами, то S [] > 1 T [] если S > 1 T .

(где> 1 означает «прямой подтип»).

Это позволяет написать метод, подобный этому:

public void printArray(Object[] array) {
    System.out.print('[');
    boolean first = true;
    for (Object obj : array) {
        if (!first) {
            System.out.print(", ");
        } else {
            first = false;
        }
        System.out.print(String.valueOf(obj));
    }
    System.out.print(']');
}

, а затем вызвать его с помощью:

String[] foo = { "a", "b", "c" };
printArray(foo);

Эта языковая функция имеет нежелательный эффект откладывания проблем ArrayStoreException на время выполнения.

0 голосов
/ 13 декабря 2011

Если вам нужны примеры, взгляните на Arrays .Если Java не допускает полиморфизм массивов, у нас не может быть таких функций, как sort(Object[] a), toString(Object[] a), binarySearch(Object[] a, Object key) и т. Д. Помните, что B и C являются подтипами Object, поэтому вы можетеиспользовать эту функциональность для всех из них.Обратите внимание, что массивы предшествуют шаблонам (Java 1.5.0) и что даже у шаблонов есть свои недостатки (компромисс для Java заключается в том, что вы не можете знать универсальный тип во время выполнения из-за стирания типа).

0 голосов
/ 13 декабря 2011

Типы массивов ковариантны , что означает, что вы можете объявить A [] a = new B [] (Коллекции, наоборот, нет: вы не можете объявить List a = новый список ()).

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...