Н.А. Вязовик - Программирование на Java
Скачивание начинается... Если скачивание не началось автоматически, пожалуйста нажмите на эту ссылку.
Жалоба
Напишите нам, и мы в срочном порядке примем меры.
Описание книги "Программирование на Java"
Описание и краткое содержание "Программирование на Java" читать бесплатно онлайн.
public class Test {
public Test() {
System.out.println("Test()");
}
public Test(int x) {
this();
System.out.println("Test(int x)");
}
}
После выполнения выражения new Test(0) на консоли появится:
Test()
Test(int x)
В заключение рассмотрим применение модификаторов доступа для конструкторов. Может вызвать удивление возможность объявлять конструкторы как private. Ведь они нужны для генерации объектов, а к таким конструкторам ни у кого не будет доступа. Однако в ряде случаев модификатор private может быть полезен. Например:
* private -конструктор может содержать инициализирующие действия, а остальные конструкторы будут использовать его с помощью this, причем прямое обращение к этому конструктору по каким-то причинам нежелательно;
* запрет на создание объектов этого класса, например, невозможно создать экземпляр класса Math ;
* реализация специального шаблона проектирования из ООП Singleton, для работы которого требуется контролировать создание объектов, что невозможно в случае наличия не- private конструкторов.
Инициализаторы
Наконец, последней допустимой конструкцией в теле класса является объявление инициализаторов. Записываются объектные инициализаторы очень просто – внутри фигурных скобок.
public class Test {
private int x, y, z;
// инициализатор объекта {
x=3;
if (x>0)
y=4;
z=Math.max(x, y);
}
}
Инициализаторы не имеют имен, исполняются при создании объектов, не могут быть вызваны явно, не передаются по наследству (хотя, конечно, инициализаторы в родительском классе продолжают исполняться при создании объекта класса-наследника).
Было указано уже три вида инициализирующего кода в классах – конструкторы, инициализаторы переменных, а теперь добавились объектные инициализаторы. Необходимо разобраться, в какой последовательности что выполняется, в том числе при наследовании. При создании экземпляра класса вызванный конструктор выполняется следующим образом:
если первой строкой идет обращение к конструктору родительского класса (явное или добавленное компилятором по умолчанию), то этот конструктор исполняется;
в случае успешного исполнения вызываются все инициализаторы полей и объекта в том порядке, в каком они объявлены в теле класса;
если первой строкой идет обращение к другому конструктору этого же класса, то он вызывается. Повторное выполнение инициализаторов не производится.
Второй пункт имеет ряд важных следствий. Во-первых, из него следует, что в инициализаторах нельзя использовать переменные класса, если их объявление записано позже.
Во-вторых, теперь можно сформулировать наиболее гибкий подход к инициализации final -полей. Главное требование – чтобы такие поля были проинициализированы ровно один раз. Это можно обеспечить в следующих случаях:
если инициализировать поле при объявлении;
если инициализировать поле только один раз в инициализаторе объекта (он должен быть записан после объявления поля);
если инициализировать поле только один раз в каждом конструкторе, в первой строке которого стоит явное или неявное обращение к конструктору родителя. Конструктор, в первой строке которого стоит 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 по ссылке. Однако если изменять не состояние объекта, а саму ссылку, то результат будет другим:
public void process(Point p)
{
p = new Point(4,5);
}
public void test() {
Point p = new Point(1,2);
Подписывайтесь на наши страницы в социальных сетях.
Будьте в курсе последних книжных новинок, комментируйте, обсуждайте. Мы ждём Вас!
Похожие книги на "Программирование на Java"
Книги похожие на "Программирование на Java" читать онлайн или скачать бесплатно полные версии.
Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем.
Отзывы о "Н.А. Вязовик - Программирование на Java"
Отзывы читателей о книге "Программирование на Java", комментарии и мнения людей о произведении.