Ильдар Хабибуллин - Java 7 [Наиболее полное руководство]
- Название:Java 7 [Наиболее полное руководство]
- Автор:
- Жанр:
- Издательство:БХВ-Петербург
- Год:2012
- ISBN:978-5-9775-0735-6
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Ильдар Хабибуллин - Java 7 [Наиболее полное руководство] краткое содержание
Java 7 [Наиболее полное руководство] - читать онлайн бесплатно ознакомительный отрывок
Интервал:
Закладка:
public static int sum(int... args){ int result = 0;
for (int k: args) result += k; return result;
}
При обращении к методу мы просто записываем нужное число аргументов через запятую.
public static void main(string[] args){
System.out.println("Sum1 = " + sum(1, 2, 3, 4, 5, 6));
System.out.println("Sum2 = " + sum(100, 90, 80, 70));
}
Где видны переменные
В языке Java нестатические переменные разрешено объявлять в любом месте кода между операторами. Статические переменные могут быть только полями класса, а значит, не должны объявляться внутри методов и блоков. Какова же область видимости (scope) переменных? Из каких методов мы можем обратиться к той или иной переменной? В каких операторах использовать? Рассмотрим на примере листинга 2.6 разные случаи объявления переменных.
Листинг 2.6. Видимость и инициализация переменных
class ManyVariables{
static int x = 9, y; // Статические переменные — поля класса.
// Они известны во всех методах и блоках класса. // Поле y получает значение 0.
static{ // Блок инициализации статических переменных.
// Выполняется один раз при первой загрузке класса // после инициализаций в объявлениях переменных. x = 99; // Этот оператор выполняется в блоке вне всякого метода!
int a = 1, p; // Нестатические переменные — поля экземпляра.
// Известны во всех методах и блоках класса,
// в которых они не перекрыты другими переменными // с тем же именем.
// Поле p получает значение 0.
{ // Блок инициализации экземпляра.
// Выполняется при создании каждого экземпляра // после инициализаций при объявлениях переменных. p = 999; // Этот оператор выполняется в блоке вне всякого метода!
}
static void f(int b){ // Параметр метода b — локальная переменная,
// известная только внутри метода. int a = 2; // Это вторая переменная с тем же именем "a".
// Она известна только внутри метода f()
// и здесь перекрывает первую "a".
int c; // Локальная переменная, известна только в методе f().
// Не получает никакого начального значения // и должна быть определена перед применением.
{ int c = 555; // Сшибка! Попытка повторного объявления.
int x = 333; // Локальная переменная, известна только в этом блоке.
}
// Здесь переменная x уже неизвестна. for (int d = 0; d < 10; d++){
// Переменная цикла d известна только в цикле. int a = 4; // Ошибка!
int e = 5; // Локальная переменная, известна только в цикле for.
e++; // Инициализируется при каждом выполнении цикла.
System.out.println("e = " + e); // Выводится всегда "e = 6".
}
// Здесь переменные d и e неизвестны.
}
public static void main(string[] args){
int a = 9999; // Локальная переменная, известна только внутри
// метода main().
f (a) ;
}
}
Обратите внимание на то, что переменные класса и экземпляра неявно присваивают нулевые значения. Символы неявно получают значение ’ \u0000 ’, логические переменные — значение false, ссылки получают неявно значение null.
Локальные же переменные неявно не инициализируются. Они должны либо явно присваивать значения, либо определяться до первого использования. К счастью, компилятор замечает неопределенные локальные переменные и сообщает о них.
Внимание!
Поля класса при объявлении обнуляются, локальные переменные автоматически не инициализируются.
В листинге 2.6 появилась еще одна новая конструкция: блок инициализации экземпляра (instance initialization). Это просто блок операторов в фигурных скобках, но записывается он вне всякого метода, прямо в теле класса. Этот блок выполняется при создании каждого экземпляра, после static-блоков и инициализации при объявлении переменных, но до выполнения конструктора. Он играет такую же роль, как и static-блок для статических переменных. Зачем же он нужен, ведь все его содержимое можно написать в начале конструктора? Он применяется в тех случаях, когда конструктор написать нельзя, а именно в безымянных внутренних классах.
Вложенные классы
В этой главе уже несколько раз упоминалось, что в теле класса можно сделать описание другого, вложенного (nested) класса. А во вложенном классе можно снова описать вложенный, внутренний (inner) класс и т. д. Эта "матрешка" кажется вполне естественной, но вы уже поднаторели в написании классов, и у вас возникает масса вопросов.
□ Можем ли мы из вложенного класса обратиться к членам внешнего класса? Можем, для того это все и задумывалось.
□ А можем ли мы в таком случае определить экземпляр вложенного класса, не определяя экземпляры внешнего класса? Нет, не можем, сначала надо определить хоть один экземпляр внешнего класса, матрешка ведь!
□ А если экземпляров внешнего класса несколько, как узнать, с каким экземпляром внешнего класса работает данный экземпляр вложенного класса? Имя экземпляра вложенного класса уточняется именем связанного с ним экземпляра внешнего класса. Более того, при создании вложенного экземпляра операция new тоже уточняется именем внешнего экземпляра.
□ А?..
Хватит вопросов, давайте разберем все по порядку.
Все вложенные классы можно разделить на вложенные классы-члены класса (member classes), описанные вне методов, и вложенные локальные классы (local classes), описанные внутри методов и/или блоков. Локальные классы, как и все локальные переменные, не являются членами класса.
Классы-члены могут быть объявлены статическими с помощью модификатора static. Поведение статических классов-членов ничем не отличается от поведения обычных классов, отличается только обращение к таким классам. Поэтому они называются вложенными классами верхнего уровня (nested top-level classes), хотя статические классы-члены можно вкладывать друг в друга. В них можно объявлять статические члены. Используются они обычно для того, чтобы сгруппировать вспомогательные классы вместе с основным классом.
Все нестатические вложенные классы называются внутренними (inner). В них нельзя объявлять статические члены.
Локальные классы, как и все локальные переменные, известны только в блоке, в котором они определены. Они могут быть безымянными (anonymous classes).
В листинге 2.7 рассмотрены все эти случаи.
class Nested{
static private int pr; // Переменная pr объявлена статической,
// чтобы к ней был доступ из статических классов A и AB.
String s = "Member of Nested";
// Вкладываем статический класс.
static class A{ // Полное имя этого класса — Nested.A
private int a = pr;
String s = "Member of A";
// Во вложенный класс A вкладываем еще один статический класс. static class AB{ // Полное имя класса — Nested.A.AB
private int ab = pr;
String s = "Member of AB";
}
}
// В класс Nested вкладываем нестатический класс. class B{ // Полное имя этого класса — Nested.B
private int b = pr;
String s = "Member of B";
// В класс B вкладываем еще один класс.
class BC{ // Полное имя класса — Nested.B.BC
private int bc = pr;
String s = "Member of BC";
}
void f(final int i){ // Без слова final переменные i и j
Читать дальшеИнтервал:
Закладка: