Брюс Эккель - Философия Java3
- Название:Философия Java3
- Автор:
- Жанр:
- Издательство:неизвестно
- Год:неизвестен
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Брюс Эккель - Философия Java3 краткое содержание
Философия Java3 - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
int al[];
Это соответствует ожиданиям программистов на С и С++, привыкших к такому синтаксису. Впрочем, первый стиль, пожалуй, выглядит более логично — он сразу дает понять, что имеется в виду «массив значений типа int». Он и будет использоваться в книге.
Компилятор не позволяет указать точный размер массива. Вспомните, что говорилось ранее о ссылках. Все, что у вас сейчас есть, — это ссылка на массив, для которого еще не было выделено памяти. Чтобы резервировать память для массива, необходимо записать некоторое выражение инициализации. Для массивов такое выражение может находиться в любом месте программы, но существует и особая разновидность выражений инициализации, используемая только в точке объявления массива. Эта специальная инициализация выглядит как набор значений в фигурных скобках. Выделение памяти (эквивалентное действию оператора new) в этом случае проводится компилятором. Например:
int[] al = { 1, 2. 3, 4. 5 }.
Но зачем тогда вообще нужно определять ссылку на массив без самого массива?
int[] а2,
Во-первых, в Java можно присвоить один массив другому, записав следующее:
а2 = al,
В данном случае вы на самом деле копируете ссылку, как показано в примере:
// initialization/ArraysOfPrimitives.java
// Массивы простейших типов.
import static net mindview.util.Print.*;
public class ArraysOfPrimitives {
public static void main(String[] args) { int:: al = { 1. 2, 3. 4, 5 }: int[] a2; a2 = al.
for(int i = 0; i < a2.length, i++)
a2[i] = a2[i] + 1; for(int i = 0; i < al.length; i++)
print("al[" + i +"]=" + al[i]);
}
} /* Output: al[0] = 2 al[l] = 3 al[2] = 4 al[3] = 5 al[4] = 6 *///:-
Массив al инициализируется набором значений, в то время как массив а2 — нет; присваивание по ссылке а2 присваивается позже — в данном случае присваивается другой массив.
Все массивы (как массивы примитивов, так и массивы объектов) содержат поле> которое можно прочитать (но не изменить!) для получения количества элементов в массиве. Это поле называется length. Так как в массивах Java, С и С++ .нумерация элементов начинается с нуля, последнему элементу массива соответстйует индекс length—1. При выходе за границы массива С и С++ не препятствуют «прогулкам в памяти» программы, что часто приводит к печальным последствиям. Но Java защищает вас от таких проблем — при выходе за рамки массива происходит ошибка времени исполнения ( исключение , тема главы 10) 1.
А если во время написания программы вы не знаете, сколько элементов вам понадобится в новом массиве? Тогда просто используйте new для создания его элементов. В следующем примере new работает, хотя в программе создается массив примитивных типов (оператор new неприменим для создания примитивов вне массива):
//: initialization/ArrayNew.java // Создание массивов оператором new. import java util.*;
import static net.mindview util.Print *;
public class ArrayNew {
public static void main(String[] args) { int[] a.
Random rand = new Random(47); a = new int[rand.nextlnt(20)]; print("Длина a = " + a length), print(Arrays.toString(a));
}
} /* Output-Длина a = 18
[0, 0. 0, 0. 0, 0, 0, 0, 0, 0. 0, 0. 0. 0. 0, 0. 0. 0] *///-
Размер массива выбирается случайным образом, с использованием метода Random.nextlnt(), генерирующего число от нуля до переданного в качестве аргумента значения. Так как размер массива случаен, очевидно, что создание массива происходит во время исполнения программы. Вдобавок, результат работы программы позволяет убедиться в том, что элементы массивов простейших типов автоматически инициализируются «пустыми» значениями. (Для чисел и символов это ноль, а для логического типа boolean — false.)
Метод Arrays.toString(), входящий в стандартную библиотеку java.util, выдает печатную версию одномерного массива.
Конечно, в данном примере массив можно определить и инициализировать в одной строке:
int[] а = new int[rand.nextlnt(20)],
Если возможно, рекомендуется использовать именно такую форму записи. При создании массива непримитивных объектов вы фактически создаете массив ссылок. Для примера возьмем класс-обертку Integer, который является именно классом, а не примитивом:
//: initialization/ArrayClassObj java // Создание массива непримитивных объектов import java.util.*;
import static net.mindview util.Print.*,
public class ArrayClassObj {
' public static void main(String[] args) { Random rand = new Random(47); Integer[] a = new Integer[rand.nextlnt(20)]; print("длина a = " + a.length); for(int i = 0; i < a.length; i++)
a[i] = rand.nextlnt(500); // Автоматическая упаковка
print(Arrays.toString(a)),
}
} /* Output (пример) длина а = 18
[55. 193. 361. 461. 429. 368, 200. 22. 207, 288. 128. 51. 89. 309. 278. 498, 361. 20] *///-
Здесь даже после вызова new для создания массива
Integer[] а = new Integer[rand nextlnt(20)];
мы имеем лишь массив из ссылок — до тех пор, пока каждая ссылка не будет инициализирована новым объектом Integer (в данном случае это делается посредством автоупаковки):
a[i] = rand.nextlnt(500);
Если вы забудете создать объект, то получите исключение во время выполнения программы, при попытке чтения несуществующего элемента массива.
Массивы объектов также можно инициализировать списком в фигурных скобках. Существует две формы синтаксиса:
//• i niti ali zati on/ArrayInit java // Инициализация массивов import java.util *;
public class Arraylnit {
public static void main(String[] args) { Integer[] a = {
new Integer(l), new Integer(2), 3, // Autoboxing
}:
Integer[] b = new Integer[]{ new Integer(1), new Integer(2), 3. // Автоматическая упаковка
}:
System. out. pri ntl n (Arrays. toStri ng (a)); System.out println(Arrays.toString(b));
}
} /* Output-[1. 2. 3] [1. 2. 3] *///:-
В обоих случаях завершающая запятая в списке инициализаторов не обязательна (она всего лишь упрощает ведение длинных списков).
Первая форма полезна, но она более ограничена, поскольку может использоваться только в точке определения массива. Вторая форма может использоваться везде, даже внутри вызова метода.
Списки аргументов переменной длины
Синтаксис второй формы предоставляет удобный синтаксис создания и вызова методов с эффектом, напоминающим списки аргументов переменной длины языка С.
Такой список способен содержать неизвестное заранее количество аргументов неизвестного типа. Так как абсолютно все классы унаследованы от общего корневого класса Object, можно создать метод, принимающий в качестве аргумента массив Object, и вызывать его следующим образом:
//. initialization/VarArgs.java
// Использование синтаксиса массивов
// для получения переменного списка параметров.
class А { int i; }
public class VarArgs {
static void printArray(Object[] args) { for(Object obj • args)
System.out print(obj + " "); System out printlnO,
}
public static void main(String[] args) { printArray(new Object[]{
new Integer(47), new Float(3 14), new Double(ll.ll)
}).
printArray(new 0bject[]{"pa3", "два", "три" }); pri ntArray (new Object[]{new AO, new AO, new AO});
}
} /* Output: (Sample) 47 3.14 11.11 раз два три
А@1а46еЗО А@3е25а5 A@19821f *///:-
Видно, что метод print() принимает массив объектов типа Object, перебирает его элементы и выводит их. Классы из стандартной библиотеки Java при печати выводят осмысленную информацию, однако объекты классов в данном примере выводят имя класса, затем символ @ и несколько шестнадцатеричных цифр. Таким образом, по умолчанию класс выводит имя и адрес объекта (если только вы не переопределите в классе метод toString() — см. далее).
Читать дальшеИнтервал:
Закладка: