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

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

Жанры

Программирование на Java
Шрифт:

если инициализировать поле при объявлении;

если инициализировать поле только один раз в инициализаторе объекта (он должен быть записан после объявления поля);

если инициализировать поле только один раз в каждом конструкторе, в первой строке которого стоит явное или неявное обращение к конструктору родителя. Конструктор, в первой строке которого стоит this, не может и не должен инициализировать final -поле, так как цепочка this -вызовов приведет к конструктору с super, в котором эта инициализация обязательно присутствует.

Для иллюстрации порядка исполнения инициализирующих конструкций рассмотрим следующий

пример:

public class Test {

{

System.out.println("initializer");

}

int x, y=getY;

final int z; {

System.out.println("initializer2");

}

private int getY {

System.out.println("getY "+z);

return z;

}

public Test {

System.out.println("Test");

z=3;

}

public Test(int x) {

this;

System.out.println("Test(int)");

// z=4; - нельзя! final-поле уже

// было инициализировано

}

}

После выполнения выражения new Test на консоли появится:

initializer

getY 0

initializer2

Test

Обратите внимание, что для инициализации поля y вызывается метод getY, который возвращает значение final -поля z, которое еще не было инициализировано. Поэтому в итоге поле y получит значение по умолчанию 0, а затем поле z получит постоянное значение 3, которое никогда уже не изменится.

После выполнения выражения new Test(3) на консоли появится:

initializer

getY 0

initializer2

Test

Test(int)

Дополнительные свойства классов

Рассмотрим в этом разделе некоторые особенности работы с классами в Java. Обсуждение данного вопроса будет продолжено в специальной лекции, посвященной объектной модели в Java.

Метод main

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

Такой входной точкой, по аналогии с языками C/C++, является метод main. Пример его объявления:

public static void main(String[] args) { }

Модификатор static в этой лекции не рассматривался и будет изучен позже. Он позволяет вызвать метод main, не создавая объектов. Метод не возвращает никакого значения, хотя в C есть возможность указать код возврата из программы. В Java для этой цели существует метод System.exit, который закрывает виртуальную машину и имеет аргумент типа int.

Аргументом метода main является массив строк. Он заполняется дополнительными параметрами, которые были указаны при вызове метода.

package test.first;

public class Test {

public static void main(String[] args) {

for (int i=0; i<args.length; i++) {

System.out.print(args[i]+" ");

}

System.out.println;

}

}

Для вызова программы виртуальной машине передается в качестве параметра имя класса, у которого объявлен метод main. Поскольку это имя класса, а не имя файла, то не должно указываться никакого расширения ( .class или .java ) и расположение класса записывается через

точку (разделитель имен пакетов), а не с помощью файлового разделителя. Компилятору же, напротив, передается имя и путь к файлу.

Если приведенный выше модуль компиляции сохранен в файле Test.java, который лежит в каталоге test\first, то вызов компилятора записывается следующим образом:

javac test\first\Test.java

А вызов виртуальной машины:

java test.first.Test

Чтобы проиллюстрировать работу с параметрами, изменим строку запуска приложения:

java test.first.Test Hello, World!

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

Hello, World!

Параметры методов

Для лучшего понимания работы с параметрами методов в Java необходимо рассмотреть несколько вопросов.

Как передаются аргументы в методы – по значению или по ссылке? С точки зрения программы вопрос формулируется, например, следующим образом. Пусть есть переменная и она в качестве аргумента передается в некоторый метод. Могут ли произойти какие-либо изменения с этой переменной после завершения работы метода?

int x=3;

process(x);

print(x);

Предположим, используемый метод объявлен следующим образом:

public void process(int x) {

x=5;

}

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

Напомним, что примитивные переменные являются истинными хранилищами своих значений и изменение значения одной переменной никогда не скажется на значении другой. Параметр метода process, хоть и имеет такое же имя x, на самом деле является полноценным хранилищем целочисленной величины. А потому присвоение ему значения 5 не скажется на внешних переменных. То есть результатом примера будет 3 и аргументы примитивного типа передаются в методы по значению. Единственный способ изменить такую переменную в результате работы метода – возвращать нужные величины из метода и использовать их при присвоении:

public int doubler(int x) {

return x+x;

}

public void test {

int x=3;

x=doubler(x);

}

Перейдем к ссылочным типам.

public void process(Point p)

{

p.x=3;

}

public void test {

Point p = new Point(1,2);

process(p);

print(p.x);

}

Ссылочная переменная хранит ссылку на объект, находящийся в памяти виртуальной машины. Поэтому аргумент метода process будет иметь в качестве значения ту же самую ссылку и, стало быть, ссылаться на тот же самый объект. Изменения состояния объекта, осуществленные с помощью одной ссылки, всегда видны при обращении к этому объекту с помощью другой. Поэтому результатом примера будет значение 3. Объектные значения передаются в Java по ссылке. Однако если изменять не состояние объекта, а саму ссылку, то результат будет другим:

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

Warhammer: Битвы в Мире Фэнтези. Омнибус. Том 2

Коллектив авторов
Warhammer Fantasy Battles
Фантастика:
фэнтези
5.00
рейтинг книги
Warhammer: Битвы в Мире Фэнтези. Омнибус. Том 2

Америго Веспуччи. Фернан Магеллан

Цвейг Стефан
Проза:
историческая проза
5.00
рейтинг книги
Америго Веспуччи. Фернан Магеллан

Хроники Иберлена (Трилогия)

Бочаров Анатолий Юрьевич
Хроники Иберлена
Фантастика:
фэнтези
героическая фантастика
5.00
рейтинг книги
Хроники Иберлена (Трилогия)

Ответная операция. В погоне за Призраком

Ардаматский Василий Иванович
11. Библиотека приключений
Проза:
военная проза
5.00
рейтинг книги
Ответная операция. В погоне за Призраком

Корсаков

Кощеев Владимир
1. Корсаков
Фантастика:
альтернативная история
аниме
попаданцы
5.00
рейтинг книги
Корсаков

Том 1. Русская литература

Луначарский Анатолий Васильевич
1. Собрание сочинений в восьми томах
Документальная литература:
критика
5.00
рейтинг книги
Том 1. Русская литература

Сокровище

Касслер Клайв
9. Дирк Питт
Детективы:
боевики
7.00
рейтинг книги
Сокровище

Неучтенный элемент. Том 5

NikL
5. Антимаг. Вне системы
Фантастика:
фэнтези
5.00
рейтинг книги
Неучтенный элемент. Том 5

Княжий пир

Никитин Юрий Александрович
1. Княжеский пир
Фантастика:
фэнтези
7.17
рейтинг книги
Княжий пир

Сатанизм для интеллигенции

Кураев Андрей Вячеславович
Научно-образовательная:
религиоведение
7.00
рейтинг книги
Сатанизм для интеллигенции

Другая история науки. От Аристотеля до Ньютона

Калюжный Дмитрий Витальевич
Научно-образовательная:
история
5.50
рейтинг книги
Другая история науки. От Аристотеля до Ньютона

Время умирать

Смит Уилбур
7. Кортни
Приключения:
прочие приключения
8.33
рейтинг книги
Время умирать

Облава на волка

Серегин Михаил Георгиевич
Детективы:
боевики
5.00
рейтинг книги
Облава на волка

В тени пророчества. Дилогия

Кусков Сергей Анатольевич
Путь Творца
Фантастика:
фэнтези
3.40
рейтинг книги
В тени пророчества. Дилогия