Вы находитесь на странице: 1из 40

ПРИМЕРНЫЙ ПЕРЕЧЕНЬ ВОПРОСОВ ДЛЯ ПРОВЕДЕНИЯ

ЭКЗАМЕНА ПО КУРСУ «РАЗРАБОТКА КРОСС-ПЛАТФОРМЕННЫХ

ПРИЛОЖЕНИЙ»

1. Популярные кросс-платформенные технологии.

2. Технология Java. Виртуальная машина Java.


Java Virtual Machine (сокращенно Java VM, JVM) — виртуальная машина Java —
основная часть исполняющей системы Java, так называемой Java Runtime
Environment (JRE). Виртуальная машина Java исполняет байт-код Java,
предварительно созданный из исходного текста Java-программы компилятором Java
(javac). JVM может также использоваться для выполнения программ, написанных на
других языках программирования. Например, исходный код на языке Ada может быть
скомпилирован в байт-код Java, который затем может выполниться с помощью JVM.

Java[прим. 1] — строго типизированный объектно-ориентированный язык


программирования общего назначения, разработанный компанией Sun Microsystems (в
последующем приобретённой компанией Oracle). Разработка ведётся сообществом,
организованным через Java Community Process; язык и основные реализующие его
технологии распространяются по лицензии GPL. Права на торговую марку принадлежат
корпорации Oracle.
Приложения Java обычно транслируются в специальный байт-код, поэтому они могут
работать на любой компьютерной архитектуре, для которой существует
реализация виртуальной Java-машины. Дата официального выпуска — 23 мая 1995 года.
Занимает высокие места в рейтингах популярности языков программирования (2-е место в
рейтингах IEEE Spectrum (2020)[3] и TIOBE (2021)[4]).

3. Примитивные типы данных. Преобразования базовых типов


данных.
Явные и неявные преобразования
Когда в одной операции вовлечены данные разных типов, не всегда необходимо
использовать операцию преобразования типов. Некоторые виды преобразований
выполняются неявно, автоматически.

Автоматически без каких-либо проблем производятся расширяющие преобразования


(widening) - они расширяют представление объекта в памяти. Например:

byte b = 7;
int d = b; // преобразование от byte к int

Расширяющие автоматические преобразования представлены следующими цепочками:


byte -> short -> int -> long

int -> double

short -> float -> double

char -> int


Явные преобразования
Во всех остальных преобразованиях примитивных типов явным образом применяется
операция преобразования типов. Обычно это сужающие преобразования (narrowing) от
типа с большей разрядностью к типу с меньшей разрядностью:

1
2
long a = 4;
int b = (int) a;
3. Операции языка Java. Условные конструкции.
В языке Java используются следующие условные конструкции: if..else и switch..case

Операции языка Java


Большинство операций в Java аналогичны тем, которые применяются в других си-
подобных языках. Есть унарные операции (выполняются над одним
операндом), бинарные — над двумя операндами, а также тернарные —
выполняются над тремя операндами. Операндом является переменная или
значение (например, число), участвующее в операции. Рассмотрим все виды
операций.

Арифметические операции

 +операция сложения двух чисел, например: z=x+y


 -операция вычитания двух чисел: z=x-y
 *операция умножения двух чисел: z=x*y
 /операция деления двух чисел: z=x/y
 %получение остатка от деления двух чисел: z=x%y
 ++ (префиксный инкремент)Предполагает увеличение переменной на единицу,
например, z=++y (вначале значение переменной y увеличивается на 1, а затем ее
значение присваивается переменной z)
 ++ (постфиксный инкремент)также, увеличение переменной на единицу,
например, z=y++ (вначале значение переменной y присваивается переменной z, а
потом значение переменной y увеличивается на 1)
 -- (префиксный декремент)уменьшение переменной на единицу, например, z=--
y (вначале значение переменной y уменьшается на 1, а потом ее значение
присваивается переменной z)
 -- (постфиксный декремент)z=y-- (сначала значение переменной y присваивается
переменной z, а затем значение переменной y уменьшается на 1)

Логические операции над числами

 & (логическое умножение)Умножение производится поразрядно, и если у обоих


операндов значения разрядов равно 1, то операция возвращает 1, иначе
возвращается число 0. Например:

int a1 = 2; //010

int b1 = 5;//101

System.out.println(a1&b1); // результат 0

int a2 = 4; //100

int b2 = 5; //101

System.out.println(a2 & b2); // результат 4

^ (логическое исключающее ИЛИ)

Также эту операцию называют XOR, нередко ее применяют для простого


шифрования:
 | (логическое сложение)Данная операция также производится по двоичным
разрядам, но теперь возвращается единица, если хотя бы у одного числа в данном
разряде имеется единица (операция «логическое ИЛИ»). Например:

~ (логическое отрицание)Поразрядная операция, инвертирующая все разряды


числа: если значение разряда равно 1, то оно становится равным нулю, и наоборот.

Операции сдвига

Операции сдвига также производятся над разрядами чисел. Сдвиг может


происходить вправо и влево.

 a<<b — сдвигает число a влево на b разрядов. Например,


выражение 4<<1сдвигает число 4 (которое в двоичном представлении 100) на
один разряд влево, в результате получается число 1000 или число 8 в
десятичном представлении.
 a>>b — смещает число a вправо на b разрядов. Например, 16>>1 сдвигает число
16 (которое в двоичной системе 10000) на один разряд вправо, то есть в итоге
получается 1000 или число 8 в десятичном представлении.
 a>>>b — в отличие от предыдущих типов сдвигов данная операция представляет
беззнаковый сдвиг — сдвигает число a вправо на b разрядов. Например,
выражение -8>>>2 будет равно 1073741822.

Таким образом, если исходное число, которое надо сдвинуть в ту или другую
строну, делится на два, то фактически получается умножение или деление на два.
Поэтому подобную операцию можно использовать вместо непосредственного
умножения или деления на два, так как операция сдвига на аппаратном уровне
менее дорогостоящая операция в отличие от операции деления или умножения.

Операции сравнения

В операциях сравнения сравниваются два операнда, и возвращается значение


типа boolean — true, если выражение верно, и false, если выражение неверно.

 ==данная операция сравнивает два операнда на равенство: c=a==b;

c равно true, если a равно b, иначе c будет равно false

 !=c=a!=b; (c равно true, если a не равно b, иначе c будет равно false)


 <c=a<b; (c равно true, если a меньше b, иначе c будет равно false)
 >c=a>b; (c равно true, если a больше b, иначе c будет равно false)
 <=c=a<=b; (c равно true, если a меньше или равно b, иначе c будет равно false)
 >=c=a>=b; (c равно true, если a больше или равно b, иначе c будет равно false)

Кроме собственно операций сравнения в Java также определены логические


операторы, которые возвращают значение типа boolean. Выше мы рассматривали
поразрядные операции над числами. Теперь же рассмотрим эти же операторы при
операциях над булевыми значениями:
 |c=a|b; (c равно true, если либо a, либо b (либо и a, и b) равны true, иначе c
будет равно false)
 &c=a&b; (c равно true, если и a, и b равны true, иначе c будет равно false)
 !c!=b; (c равно true, если b равно false, иначе c будет равно false)
 ^c=a^b; (c равно true, если либо a, либо b (но не одновременно) равны true,
иначе c будет равно false)
 ||c=a||b; (c равно true, если либо a, либо b (либо и a, и b) равны true, иначе c
будет равно false)
 &&c=a&&b; (c равно true, если и a, и b равны true, иначе c будет равно false)

Здесь у нас две пары операций | и || (а также & и &&) выполняют похожие


действия, однако же они не равнозначны.

Выражение c=a|b; будет вычислять сначала оба значения — a и b и на их основе


выводить результат.

В выражении же c=a||b; вначале будет вычисляться значение a, и если оно


равно true, то вычисление значения b уже смысла не имеет, так как у нас в любом
случае уже c будет равно true. Значение b будет вычисляться только в том случае,
если a равно false

То же самое касается пары операций &/&&. В выражении c=a&b; будут вычисляться


оба значения — a и b.

В выражении же c=a&&b; сначала будет вычисляться значение a, и если оно


равно false, то вычисление значения b уже не имеет смысла, так как значение c в
любом случае равно false. Значение b будет вычисляться только в том случае,
если a равно true

Таким образом, операции || и && более удобны в вычислениях, позволяя


сократить время на вычисление значения выражения и тем самым повышая
производительность. А операции | и & больше подходят для выполнения
поразрядных операций над числами.

Операции присваивания

В завершении рассмотрим операции присваивания, которые в основном


представляют комбинацию простого присваивания с другими операциями:

 =просто приравнивает одно значение другому: c=b;


 +=c+=b; (переменной c присваивается результат сложения c и b)
 -=c-=b; (переменной c присваивается результат вычитания b из c)
 *=c*=b; (переменной c присваивается результат произведения c и b)
 /=c/=b; (переменной c присваивается результат деления c на b)
 %=c%=b; (переменной c присваивается остаток от деления c на b)
 &=c&=b; (переменной c присваивается значение c&b)
 |=c|=b; (переменной c присваивается значение c|b)
 ^=c^=b; (переменной c присваивается значение c^b)
 <<=c<<=b; (переменной c присваивается значение c<<b)
 >>=c>>=b; (переменной c присваивается значение c>>b)
 >>>=c>>>=b; (переменной c присваивается значение c>>>b)

5. Циклы в языке Java.

Циклы в Java
Теперь рассмотрим циклы в Java. В этом ЯП их есть несколько типов:

 while — цикл с предусловием;


 do..while — цикл с постусловием;
 for — цикл со счетчиком (цикл для);
 for each.. — цикл “для каждого…” — разновидность for для
перебора коллекции элементов.
while, do.. while и for можно использовать в качестве
безусловных циклов.
6. Понятие класса. Синтаксис объявления класса в
языке Java.
Модификаторы класса.
7. Использование классов в основной программе.
Члены класса.
Модификаторы полей класса. Примеры
использования. Объявление
атрибутов класса.
8. Объявление методов класса. Модификаторы
методов.
Переопределение методов.
9. Блоки инициализации, их назначение и виды. Типы
конструкторов. Особенности объявления внутренних
классов. Назначение
анонимных классов, объявление, примеры
использования.
10. Реализация концепции абстракции в языках
программирования.
Место абстракций в архитектуре программных
продуктов. Объявление
абстрактного класса и его методов.
11. Особенности модификаторов абстрактного класса.
12. Последовательность инициализации блоков
класса. Объявление
интерфейса. Примеры использования интерфейсов.
Отличия интерфейсов и
абстрактных классов.

Классы, объекты, методы


Java является объектно-ориентированным языком, поэтому такие понятия как "класс" и
"объект" играют в нем ключевую роль. Любую программу на Java можно представить
как набор взаимодействующих между собой объектов.

Шаблоном или описанием объекта является класс (class), а объект


представляет экземпляр класса. Можно провести следующую аналогию. У нас у всех
есть некоторое представление о машине - наличие двигателя, шасси, кузова и т.д. Есть
некоторый шаблон auto - этот шаблон можно назвать классом. Реально же
существующий автомобиль auto_solaris (фактически экземпляр данного класса)
является объектом этого класса.

Определение класса

Класс определяется с помощью ключевого слова сlass. Вся функциональность класса


представлена его членами - полями (полями называются переменные класса) и
методами

Например, класс Book мог бы иметь следующее описание :

class Book
{
public String name;
public String author;
public int year;

public void Info(){


System.out.printf("Книга '%s' (автор %s) была издана в %d году \n",
name, author, year);
}
}
this. Это ключевое слово представляет ссылку на текущий объект

Создание объекта

Чтобы непосредственно использовать класс в программе, надо создать его объект.


Процесс создания объекта двухступенчатый: вначале объявляется переменная данного
класса, а затем с помощью ключевого слова new и конструктора непосредственно
создается объект, на который и будет указывать объявленная переменная :

Book b; // объявление переменной определенного типа/класса


b = new Book(); // выделение памяти под объект Book

Модификаторы метода - public, protected, private

Модификаторы метода определяют уровень доступа. В зависимости от того, какой


уровень доступа предоставляет тот или иной метод, выделяют:

 public : открытый — общий интерфейс для всех пользователей данного класса;


 protected : защищённый — внутренний интерфейс для всех наследников данного
класса;
 private : закрытый — интерфейс, доступный только изнутри данного класса.

Абстрактный класс, abstract class

Абстрактный класс в объектно-ориентированном программировании — базовый класс,


который не предполагает создания экземпляров. Абстрактные классы реализуют на
практике один из принципов ООП — полиморфизм.

public abstract class Price


{
public abstract int getPriceCode();

public abstract double summPrice(int days);

public int bonusPrice(int days)


{
return 1;
}
}

Переопределение метода, Override

В реализации ReleasePrice, наследующего свойства класса Price, "реализуем"


абстрактные методы и "переопределяем" метод с использованием
аннотации @Override :

Конструктор бывает с параметрами и без парамаетров.


Прежде всего, вам нужно понять, что существует два типа модификаторов:>

1. Модификаторы доступа
2. Модификаторы без доступа
И существует три типа модификаторов доступа и три типа модификаторов отсутствия
доступа

1. Доступ к Modifiesrs
o общедоступный
o защищено
По умолчанию
o
Частное
o
2. Модификатор отсутствия доступа

статический

Финал

аннотация

Итак, когда мы говорим об абстрактном классе, к абстрактному классу могут быть
применены только общедоступные модификаторы доступа и модификаторы доступа по
умолчанию.
3,4Тыс. просмотров
Интерфейс описывает только поведение. У него нет состояния. А у
абстрактного класса состояние есть: он описывает и то, и другое.
Абстрактный класс связывает между собой и объединяет классы,
имеющие очень близкую связь. В то же время, один и тот же
интерфейс могут реализовать классы, у которых вообще нет ничего
общего.
Классы могут реализовывать сколько угодно интерфейсов, но
наследоваться можно только от одного класса.
Интерфейс – это контракт, в рамках которого части программы, зачастую написанные
разными людьми, взаимодействуют между собой и со внешними приложениями.
Интерфейсы работают со слоями сервисов, безопасности, DAO и т.д. Это позволяет
создавать модульные конструкции, в которых для изменения одного элемента не
нужно трогать остальные.

Новички часто спрашивают, чем интерфейс отличается  от абстрактного класса.


Интерфейсы в Java компенсируют отсутствие множественного наследования
классов. У класса-потомка может быть только один абстрактный класс-родитель, а
вот интерфейсов класс может применять (имплементировать) сколько угодно.

Интерфейс на Java объявляют примерно так же, как и класс:

public interface MyInterface {

void do_something(){
// ...
}

default void say_goodbye(String userName) {


System.out.println("Пока, "+userName+"! Заходи ещё.");
}

13. Шаблоны в языке Java.


Паттерны бывают разные, т.к. решают разные проблемы. Обычно
выделяют следующие категории:

 Порождающие
Эти паттерны решают проблемы обеспечения гибкости создания
объектов

 Структурные

Эти паттерны решают проблемы эффективного построения связей


между объектами

 Поведенческие

Эти паттерны решают проблемы эффективного взаимодействия


между объектами

14. Методы с шаблонами. Ограниченный


неизвестный параметр.
Соглашение по именам параметров.
Методы с шаблонами

Шаблоны могут применяться и в методах. Типы аргументов


можно делать параметрическими. Пример:
void aMethod(Vector < E> vect);

или так:
void aMethod(Vector < ?> vect);

Рекомендуется использовать неизвестный параметр < ?> в


случаях, когда от него не зависят другие аргументы и
возвращаемое значение. Если такая зависимость имеется, то
следует использовать формальный параметр < E>.

15. Обработка исключений в языке Java.


16. Организация обработки ошибок в языке Java.
Виды исключений.
17. Ключевые идентификаторы.
18. Иерархия исключений. Дерево наследования
классов обработки
исключений.
19. Конструкция try … catch.
Обработка исключений в Java основана на использовании в
программе следующих ключевых слов:

 try – определяет блок кода, в котором может произойти


исключение;
 catch – определяет блок кода, в котором происходит обработка
исключения;
 finally – определяет блок кода, который является необязательным,
но при его наличии выполняется в любом случае независимо от
результатов выполнения блока try.
Эти ключевые слова используются для создания в программном коде
специальных обрабатывающих конструкций: try{}catch, try{}catch{}finally,
try{}finally{}.

 throw – используется для возбуждения исключения;


 throws – используется в сигнатуре методов для предупреждения, о
том что метод может выбросить исключение.
20. Подклассы Exception.
Только подклассы класса Throwable могут быть возбуждены или перехвачены.
Простые типы—int, char и т.п., а также классы, не являющиеся подклассами
Throwable, например, String и Object, использоваться в качестве исключений не
могут. Наиболее общий путь для использования исключений—создание своих
собственных подклассов класса Exception. Ниже приведена программа, в
которой объявлен новый подкласс класса Exception.
class MyException extends Exception {
private int detail;
MyException(int a) {
detail = a:
}
public String toString() {
return "MyException["+detail+"]";
}
}

class ExceptionDemo {
static void compute(int a) throws MyException {
System.out.println("called computer+a+").");
if (a > 10) throw new MyException(a);
System.out.println("normal exit.");
}

public static void main(String args[]) {


try {
compute(1);
compute(20);
}
catch (MyException e) {
System.out.println("caught" + e);
}
}
}

21. Базовые объекты языка Java.


Что же такое объект?

Объект — это сгруппированные вместе данные и методы для того,


чтобы эти данные обрабатывать. Когда мы говорим о данных, имеем в
виду переменные, конечно.

Про методы объекта говорят: это «поведение объекта». Состояние


объекта (переменные объекта) принято менять только с помощью
методов того же объекта. Менять переменные объекта напрямую (не
через методы объекта) считается дурным тоном.

У каждого объекта, как и у каждой переменной, есть тип. Этот тип


определяется один раз при создании объекта и поменять его в
дальнейшем нельзя. Типом объекта считается его класс.

22. Классы-обертки.

Все вы знаете, что в Java есть 8 примитивных типов, которые не


являются классами. С одной стороны, это хорошо: они простые и
занимают мало места, а с другой — иногда нужны именно классы. Зачем
именно они, вы узнаете в следующей лекции.

Так что же делать?

Начиная с пятой версии, в Java у примитивных типов появились классы-


близнецы. Каждый такой класс хранит внутри одно поле со значением
определенного типа. Такие классы еще называют типами-обертками,
потому что они как бы оборачивают примитивные значения в классы.
23. Строки.
Класс String в Java предназначен для работы со строками в Java. Все
строковые литералы, определенные в Java программе (например, "abc")
— это экземпляры класса String. Давай посмотрим на его ключевые
характеристики:

1. Класс реализует интерфейсы Serializable и CharSequence.


Поскольку он входит в пакет java.lang, его не нужно
импортировать.
2. Класс String в Java — это final класс, который не может иметь
потомков.
3. Класс String — immutable класс, то есть его объекты не могут быть
изменены после создания. Любые операции над объектом String,
результатом которых должен быть объект класса String, приведут к
созданию нового объекта.
4. Благодаря своей неизменности, объекты класса String являются
потокобезопасными и могут быть использованы в многопоточной
среде.
5. Каждый объект в Java может быть преобразован в строку через
метод toString, унаследованный всеми Java-классами от
класса Object.

24. Стандартные классы и утилиты.


Их очень много. Можно выделить File, Popup, parser, path,
list, graphics, fonts, normalizer и так далее.
Утилиты: Queve, Map, List Package java.util
25. Основные Java пакеты.
Пакет (Package) в Java — это способ объединить группу классов,
интерфейсов и подпакетов. С помощью пакетов создаются группы
связанных классов, интерфейсов, перечислений и так далее.
Подпакеты — это пакеты, находящиеся в другом пакете. Они не
импортируются по умолчанию, но при необходимости их можно
импортировать вручную. Спецификация доступа не
предоставляется отдельным членам подпакета, они
рассматриваются как разные пакеты.

Некоторые виды пакетов в Java:

 java.lang — по умолчанию поставляется в комплекте с Java.


 java.io — содержит классы, методы и другие элементы,
связанные с вводом-выводом.

Зачем нужны пакеты?


 Во избежание конфликтов имен.
 Для обеспечения контролируемого доступа.
 Чтобы добиться инкапсуляции данных.
26. Сборка мусора. Основные понятия.
27. Особенности настройки и реализации в языке Java.
28. Управление памятью в языке Java, принципы
автоматического
освобождения памяти.

Процесс сборки мусора в Java


Сборка мусора в Java автоматически выделяет и освобождает
память, поэтому разработчикам не нужно писать отдельную
программу для управления памятью, что является одним из
основных преимуществ программирования на Java. Каждый раз,
когда Java-программа запускается на JVM, объекты создаются в
куче (heap) и представляют собой часть памяти, предназначенную
для программы. Со временем некоторые предметы больше не
понадобятся. Сборщик мусора находит эти неиспользуемые
объекты и удаляет их, чтобы освободить память.

Освобождение памяти можно описать тремя основными процессами:

1. Маркировка.
2. Обычное удаление.
3. Удаление с уплотнением.

Маркировка — это процесс идентификации частей памяти, которые


используются и не используются сборщиком мусора. Обычно
маркировка является первым этапом. Обычное удаление — процесс
удаления объектов, на которые нет ссылок, с оставлением в
свободном пространстве объектов и указателей, на которые есть
ссылки. Удаление с уплотнением — помимо удаления объектов, на
которые нет ссылок, оно сжимает оставшиеся объекты, на которые
имеются ссылки, перемещая объекты вместе, чтобы сделать новое
выделение памяти намного проще и быстрее.
29. Время жизни объектов. Удаление объектов из памяти.

В объектно-ориентированном программировании (ООП) время жизни


объекта (или жизненный цикл) объекта - это время между созданием объекта и его
уничтожением. Правила для времени жизни объекта значительно различаются
между языками, в некоторых случаях между реализациями данного языка, а время жизни
конкретного объекта может меняться от одного запуска программы к другому.
В некоторых случаях время жизни объекта совпадает с временем жизни переменной,
имеющей этот объект в качестве значения (как для статических переменных, так и
для автоматических переменных), но в целом время жизни объекта не привязано к времени
жизни какой-либо одной переменной. Во многих случаях – и по умолчанию во многих
объектно-ориентированных языках, особенно в тех, которые используют сборку мусора (GC) –
объекты размещаются в куче, а время жизни объекта не определяется временем жизни
данной переменной: значение переменной, содержащей объект, фактически
соответствует ссылке наобъект, а не сам объект, и уничтожение переменной просто
уничтожает ссылку, а не базовый объект.

30. Настройка и параметры сборки мусора в языке Java.


Запуск сборщика мусора

JVM обычно запускает сборщик мусора при низком уровне свободной


памяти. Но работа сборщика мусора не гарантирует, что всегда будет
оставаться достаточно свободной памяти. Если памяти недостаточно
даже после восстановления, JVM генерирует исключение
OutOfMemoryError. Обратите внимание, что перед генерированием
исключения JVM обязательно запускает сборщик мусора как минимум 1
раз. Вы можете запросить запуск сборщика мусора, но вы не можете
принудительно задавать это действие.
Запрос запуска сборщика мусора
Для запроса вы можете вызвать один из следующих методов:
System.gc()
Runtime.getRuntime().gc()
31. Коллекции языка Java, основные интерфейсы.
32. Интерфейс Collection. Итераторы.
33. Интерфейс списка, множества, очереди.
34. Основные реализации коллекций языка Java.
Синхронизированные коллекции.
Java Collection — это фреймворк, который обеспечивает
унифицированную архитектуру для хранения и управления группой
объектов. По своей сути, это набор классов и интерфейсов, которые
обеспечивают стандартный способ представления коллекций объектов и
управления ими на языке Java. Также фреймворк помогает в реализации
часто используемых структур данных, таких как List, Set и Map. Java
Collection Framework включает несколько интерфейсов и классов. Вот
список некоторых из них:

Интерфейсы
Интерфейсы в Java Collection Framework определяют общее поведение и
операции, которые могут выполняться с коллекциями. Сюда входят
добавление или удаление элементов, повторение элементов в
коллекции и многое другое.

 Collection: корневой (root) интерфейс в иерархии коллекций,


представляющий группу объектов, известных как элементы.
 List: упорядоченная коллекция элементов, допускающая
дублирование.
 Set: коллекция элементов, не допускающих дублирования.
 Map: коллекция пар ключ-значение (key-value), где каждый ключ
уникален.
 Queue: очередь — это структура данных, которая используется для
хранения элементов в порядке появления (First-In-First-Out, FIFO).
В этот список вошли далеко не все, а только наиболее используемые
интерфейсы в Java Collection Framework. Теперь давайте подробно
рассмотрим каждый их них.

Collection
Коллекция (Collection) представляет собой группу объектов, известных
как ее элементы. Это объект, который может содержать ссылки на
другие объекты. Интерфейс Collection является корнем иерархии
коллекций. Это базовый интерфейс для всех коллекций в Java Collection
Framework. Он определяет основные методы, которые должны быть
реализованы во всех коллекциях, такие как add(), remove() и
contains().
List (список) — это упорядоченный набор объектов, каждый элемент
которого занимает определенную позицию в списке. Интерфейс List
расширяет интерфейс Collection и добавляет в него несколько методов
для работы со списками, таких как методы доступа к элементам по их
положению в списке и методы поиска и сортировки списков. List может
содержать повторяющиеся элементы, доступ к этим элементам
можно получить по их положению в списке.
Set в Java Collection Framework — это неупорядоченное множество
уникальных элементов, в котором не допускаются повторяющиеся
элементы. Интерфейс Set расширяет интерфейс Collection и добавляет
в него несколько методов, таких как методы проверки наличия элемента
в множестве (set) и методы добавления и удаления элементов из
множества.

java.util.Queue
Queue (очередь) — это структура данных, которая используется для
хранения элементов в порядке их появления (FIFO). Это означает, что
первый элемент, добавленный в очередь, будет первым удаленным.
Java Collection Framework включает в себя несколько интерфейсов,
которые определяют общее поведение для разных типов коллекций.
Некоторые из них входят в группу интерфейсов java.util.Collection:
 java.util.List
 java.util.set
 java.util.Queue
У каждой коллекции есть своя реализация.
35. Реализации интерфейса List.
36. Реализации интерфейса Set.
37. Реализации интерфейса Queue.
38. Реализации интерфейса Map.
// Создаем Map
Map<String, Integer> map = new HashMap <>();
// Добавляем элементы в Map
map.put("apple", 1);
map.put("banana", 2);
map.put("orange", 3);
// Печать Map
System.out.println("Map: " + map);
// Получаем значение для определенного ключа
int value = map.get( "banana" );
System.out.println("Value for 'banana': " + value);
// Удаляем элемент из Map
map.remove("orange");
// Печать обновленной карты
System.out.println( "Map: " + map);

Queue<String> queue = new LinkedList<>();

// Добавление элементов в очередь


queue.add("apple");
queue.add("banana");
queue.add("orange");
// Печатаем очередь
System.out.println("Queue: " + queue);
// Удаляем элемент из очереди
String element = queue.remove();
System.out.println("Removed element: " + element);
// Печатаем обновленную очередь
System.out.println("Queue: " + queue);
import java.util.Set;
import java.util.HashSet;

public class SetExample {


public static void main(String[] args) {
// Создаем новый set
Set<String> stringSet = new HashSet<>();

// Добавляем несколько элементов в set


stringSet.add("Jan");
stringSet.add("Feb");
stringSet.add("March");
stringSet.add("April");

// Проверяем наличие в set элемента "March"


if (stringSet.contains("March")) {
System.out.println("The set contains the element
'March'");
}

// Удаляем элемент "April" из set


stringSet.remove("April");

// Опять проверяем наличие элемента "April" в set


if (!stringSet.contains("April")) {
System.out.println("The set no longer contains the
element 'April'");
}
}

import java.util.List;
import java.util.ArrayList;

public class ListExample {


public static void main(String[] args) {
// Создаем новый список
List<String> stringList = new ArrayList<>();

// Добавляем несколько элементов в список


stringList.add("India");
stringList.add("UAE");
stringList.add("London");
stringList.add("US");
// Печатаем первый элемент в списке
System.out.println("First element: " +
stringList.get(0));

// Удаляем второй элемент из списка


stringList.remove(1);

// Печатаем второй элемент в списке


System.out.println("Second element: " +
stringList.get(1));
}
}

39. Устаревшие коллекции. Синхронизированные


коллекции.
В методах таких коллекций присутствует ключевое слово
synchronized. Устаревшие коллекции являются
синхронизированными.

40. Потоки ввода-вывода в языке Java. Работа с файлами.


В Java основной функционал работы с потоками
сосредоточен в классах из пакета java.io.
Объект, из которого можно считать данные, называется
потоком ввода, а объект, в который можно записывать
данные, - потоком вывода. Например, если надо считать
содержание файла, то применяется поток ввода, а если
надо записать в файл - то поток вывода.

В основе всех классов, управляющих потоками байтов,


находятся два абстрактных класса: InputStream
(представляющий потоки ввода) и OutputStream
(представляющий потоки вывода)

Но поскольку работать с байтами не очень удобно, то для


работы с потоками символов были добавлены абстрактные
классы Reader (для чтения потоков символов) и Writer (для
записи потоков символов).

Все остальные классы, работающие с потоками, являются


наследниками этих абстрактных классов. Основные классы
потоков:

41. Чтение и запись файлов. Буферизуемые потоки.

Класс FileOutputStream
Главное назначение класса FileOutputStream — запись байтов в
файл. Ничего сложного :) FileOutputStream является одной из
реализаций абстрактного класса OutputStream. В конструкторе объекты
этого класса принимают либо путь к целевому файлу (в который и нужно
записать байты), либо объект класса File.

Класс FileInputStream
У класса FileInputStream назначение противоположное — чтение
байтов из файла. Так же как FileOutputStream наследует OutputStream,
этот класс происходит от абстрактного класса InputStream.
Буферизированные потоки нужны прежде всего для оптимизации
ввода-вывода. Обращение к источнику данных, например, чтение из
файла, — дорогостоящая в плане производительности операция. И
каждый раз обращаться к файлу для чтения по одному байту
расточительно. Поэтому BufferedInputStream считывает данные не по
одному байту, а блоками и временно хранит их в специальном буфере.
Это позволяет нам оптимизировать работу программы за счет того, что
мы уменьшаем количество обращений к файлу.

42. Сериализация объектов. Работа с файловой системой.


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

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

Сериализация. Класс ObjectOutputStream


Для сериализации объектов в поток используется класс
ObjectOutputStream. Он записывает данные в поток.
Для создания объекта ObjectOutputStream в конструктор
передается поток, в который производится запись:

1
ObjectOutputStream(OutputStream out)
Для записи данных ObjectOutputStream использует ряд
методов, среди которых можно выделить следующие:

void close(): закрывает поток

void flush(): очищает буфер и сбрасывает его содержимое в


выходной поток

void write(byte[] buf): записывает в поток массив байтов

void write(int val): записывает в поток один младший байт из


val

void writeBoolean(boolean val): записывает в поток значение


boolean

void writeByte(int val): записывает в поток один младший


байт из val
void writeChar(int val): записывает в поток значение типа
char, представленное целочисленным значением

void writeDouble(double val): записывает в поток значение


типа double

void writeFloat(float val): записывает в поток значение типа


float

void writeInt(int val): записывает целочисленное значение


int

void writeLong(long val): записывает значение типа long

void writeShort(int val): записывает значение типа short

void writeUTF(String str): записывает в поток строку в


кодировке UTF-8

void writeObject(Object obj): записывает в поток отдельный


объект

Эти методы охватывают весь спектр данных, которые


можно сериализовать.
В зависимости от того, что должен представлять объект File
- файл или каталог, мы можем использовать один из
конструкторов для создания объекта:

1
2
3
File(String путь_к_каталогу)
File(String путь_к_каталогу, String имя_файла)
File(File каталог, String имя_файла)

boolean createNewFile(): создает новый файл по пути,


который передан в конструктор. В случае удачного
создания возвращает true, иначе false

boolean delete(): удаляет каталог или файл по пути, который


передан в конструктор. При удачном удалении возвращает
true.

boolean exists(): проверяет, существует ли по указанному в


конструкторе пути файл или каталог. И если файл или
каталог существует, то возвращает true, иначе возвращает
false
String getAbsolutePath(): возвращает абсолютный путь для
пути, переданного в конструктор объекта

String getName(): возвращает краткое имя файла или


каталога

String getParent(): возвращает имя родительского каталога

boolean isDirectory(): возвращает значение true, если по


указанному пути располагается каталог

boolean isFile(): возвращает значение true, если по


указанному пути находится файл

boolean isHidden(): возвращает значение true, если каталог


или файл являются скрытыми

long length(): возвращает размер файла в байтах

long lastModified(): возвращает время последнего


изменения файла или каталога. Значение представляет
количество миллисекунд, прошедших с начала эпохи Unix

String[] list(): возвращает массив файлов и подкаталогов,


которые находятся в определенном каталоге
File[] listFiles(): возвращает массив файлов и подкаталогов,
которые находятся в определенном каталоге

boolean mkdir(): создает новый каталог и при удачном


создании возвращает значение true

boolean renameTo(File dest): переименовывает файл или


каталог

43. Многопоточное программирование в языке Java,


основные
понятия.
44. Процесс. Поток. Организация потоков. Создание
нового потока.
45. Создание многопоточных приложений.
46. Управление потоками при многопоточном
программировании в
языке Java. Синхронизация.
Многопоточные приложения создаются в win 32 api.
Большинство языков программирования поддерживают
такую важную функциональность как многопоточность, и
Java в этом плане не исключение. При помощи
многопоточности мы можем выделить в приложении
несколько потоков, которые будут выполнять различные
задачи одновременно. Если у нас, допустим, графическое
приложение, которое посылает запрос к какому-нибудь
серверу или считывает и обрабатывает огромный файл, то
без многопоточности у нас бы блокировался графический
интерфейс на время выполнения задачи. А благодаря
потокам мы можем выделить отправку запроса или любую
другую задачу, которая может долго обрабатываться, в
отдельный поток. Поэтому большинство реальных
приложений, которые многим из нас приходится
использовать, практически не мыслимы без
многопоточности.
Класс Thread
В Java функциональность отдельного потока заключается в
классе Thread. И чтобы создать новый поток, нам надо
создать объект этого класса. Но все потоки не создаются
сами по себе. Когда запускается программа, начинает
работать главный поток этой программы. От этого главного
потока порождаются все остальные дочерние потоки.

С помощью статического метода Thread.currentThread() мы


можем получить текущий поток выполнения:

1
2
3
4
5
public static void main(String[] args) {
Thread t = Thread.currentThread(); // получаем главный
поток
System.out.println(t.getName()); // main
}
По умолчанию именем главного потока будет main.

Для управления потоком класс Thread предоставляет еще


ряд методов. Наиболее используемые из них:

getName(): возвращает имя потока

setName(String name): устанавливает имя потока

getPriority(): возвращает приоритет потока

setPriority(int proirity): устанавливает приоритет потока.


Приоритет является одним из ключевых факторов для
выбора системой потока из кучи потоков для выполнения. В
этот метод в качестве параметра передается числовое
значение приоритета - от 1 до 10. По умолчанию главному
потоку выставляется средний приоритет - 5.

isAlive(): возвращает true, если поток активен


isInterrupted(): возвращает true, если поток был прерван

join(): ожидает завершение потока

run(): определяет точку входа в поток

sleep(): приостанавливает поток на заданное количество


миллисекунд

start(): запускает поток, вызывая его метод run()

Yield
Метод Thread.yield() загадочный и редко используемый. Существует
много вариаций его описания в интернете. Вплоть до того, что некоторые
пишут про какую-то очередь потоков, в которой поток переместится вниз
с учётом их приоритетов. Кто-то пишет, что поток изменит статус с
running на runnable (хотя разделения на эти статусы нет, и Java их не
различает). Но на самом деле всё куда неизвестнее и в каком-то смысле
проще.

Sleep - Засыпание потока


Поток в процессе своего выполнения может засыпать. Это самой
простой тип взаимодействия с другими потоками. В операционной
системе, на которой установлена виртуальная Java машина, где
выполняется Java код, есть свой планировщик потоков, называемый
Thread Scheduler. Именно он решает, какой поток когда запускать.
Прерывание потока или Thread.interrupt
Всё дело в том, что пока поток ожидает во сне, кто-то может захотеть
прервать это ожидание. На этот случай мы обрабатываем такое
исключение. Сделано это было после того, как метод Thread.stop
объявили Deprecated, т.е. устаревшим и нежелательным к
использованию. Причиной тому было то, что при вызове метода stop
поток просто "убивался", что было очень непредсказуемо. Мы не могли
знать, когда поток будет остановлен, не могли гарантировать
консистентность данных.

Join — Ожидание завершения другого потока


Самым простым типом ожидания является ожидание завершения
другого потока.

Синхронизация потоков происходит через метод Synchronized и


ожидание по локу.
47. Мониторы и условия. Пулы потоков и очередь действий.
Получается, что для целей синхронизации между потоками Java
использует некий механизм, который называется "Монитор". С каждым
объектом ассоциирован некоторый монитор, а потоки могут его
заблокировать "lock" или разблокировать "unlock"
Далее важно понять, каким образом объект в Java может быть связан с
монитором. У каждого объекта в Java есть заголовок (header) — своего
рода внутренние метаданные, которые недоступны программисту из
кода, но которые нужны виртуальной машине, чтобы работать с
объектами правильно.

Таким образом, как мы видим, монитор — это действительно механизм


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

Пул потоков 
В Java потоки сопоставляются с потоками системного уровня, которые
являются ресурсами операционной системы. Если мы создаем потоки
бесконтрольно, у нас могут быстро закончиться эти ресурсы.
Операционная система также выполняет переключение контекста между
потоками — для эмуляции параллелизма. Упрощенный взгляд
заключается в том, что чем больше потоков мы создаем, тем меньше
времени каждый поток тратит на выполнение реальной работы.
Шаблон пула потоков помогает экономить ресурсы в многопоточном
приложении и сдерживать параллелизм в определенных
предопределенных пределах.
Когда мы используем пул потоков, мы пишем наш параллельный код в
виде параллельных задач и отправляем их на выполнение
экземпляру пула потоков.Этот экземпляр управляет несколькими
повторно используемыми потоками для выполнения этих задач.

48. Построение кросс-платформенных графических интерфейсов.


Для создания любой пользовательской графической системы необходимо:
1. Выводить на экран (отрисовывать) различные примитивы (точки, линии,
многоугольники и т.д.), изображения (растровая графика, векторная
графика), текст.
2. Получать информацию с устройств ввода (клавиатура, мышь, тач-панель и
т.п.)
3. В некоторых случаях может понадобиться дополнительно иметь
возможность проигрывать звук, взаимодействовать с функциями
операционной системой, например, получать/задавать буфер обмена,
выводить уведомления и т.д.
4. Делать это все максимально быстро, иначе наш интерфейс будет
медленным и неудобным в использовании:)
Для создании Desktop версии нам необходимо создать консольный проект или проект
Windows Forms, в качестве среды разработки будем использовать Microsoft Visual Studio
2019 (никто не запрещает использовать любую другую среду). Создаем консольный
проект .NET Framework версии 4.0 или выше (можно использовать .NET Core проекты)
Нужно с помощью вспомогательных библиотек создать кроссплатформенное
приложение. У нас должны быть общие классы либо общий проект. Обязательно нужно
протестировать получившееся приложение и попробовать эмулировать его на другие
платформы.

49. Библиотека Swing.


Swing — библиотека для создания графического интерфейса для программ на языке Java.
Swing был разработан компанией Sun Microsystems. Он содержит ряд
графических компонентов (англ. Swing widgets), таких, как кнопки, поля ввода, таблицы и т. д.
Swing относится к библиотеке классов JFC, которая представляет собой набор библиотек для
разработки графических оболочек. К этим библиотекам относятся Java 2D, Accessibility-
API, Drag & Drop-API и AWT.

Архитектура[править | править код]
Look and Feel
Архитектура Swing разработана таким образом, что вы можете изменять «look and feel[en]»
(L&F) вашего приложения. «Look» определяет внешний вид компонентов, а «Feel» — их
поведение. Sun’s JRE предоставляет следующие L&F[1]:

 CrossPlatformLookAndFeel — это родной L&F для Java-приложений (так же называется


Metal). Он используется по умолчанию, обеспечивая стандартное поведение компонентов
и их внешний вид вне зависимости от платформы, на которой запускается приложение.
 SystemLookAndFeel — в этом случае приложение использует L&F, он является родным
для системы, на котором запущено приложение. Системный L&F определяется во время
выполнения. Для Windows используется «Windows» L&F, он имитирует особенности
конкретной системы, на которой запущен — классический Windows, XP, или Vista.
Для Linux и Solaris используется «GTK», если установлен GTK 2.2 или более поздняя
версия, в противном случае используется «Motif».
 Synth — основа для создания собственных L&F.
 Multiplexing — предоставляет возможность использования различных L&F одновременно.

50. Окно JFrame. Панель содержимого. Менеджеры размещения


компонентов. Ручное размещение элементов.

Окно JFrame
Каждая GUI-программа запускается в окне и по ходу работы может открывать несколько
дополнительных окон.
В библиотеке Swing описан класс JFrame, представляющий собой окно с рамкой и строкой
заголовка (с кнопками «Свернуть», «Во весь экран» и «Закрыть»). Оно может изменять
размеры и перемещаться по экрану.
об окнах Swing

Конструктор JFrame() без параметров создает пустое окно. Конструктор JFrame(String


title) создает пустое окно с заголовком title.
Чтобы написать простейшую программу, выводящую на экран пустое окно, нам потребуется
еще три метода:
setSize(int width, int height) — устанавливает размеры окна. Если не задать
размеры, окно будет иметь нулевую высоту независимо от того, что в нем находится и
пользователю после запуска придется растягивать окно вручную. Размеры окна включают
не только «рабочую» область, но и границы и строку заголовка.
setDefaultCloseOperation(int operation) — позволяет указать действие, которое
необходимо выполнить, когда пользователь закрывает окно нажатием на крестик. Обычно в
программе есть одно или несколько окон при закрытии которых программа прекращает
работу. Для того, чтобы запрограммировать это поведение, следует в качестве
параметра operation передать константу EXIT_ON_CLOSE, описанную в классе JFrame.
setVisible(boolean visible) — когда окно создается, оно по умолчанию невидимо.
Чтобы отобразить окно на экране, вызывается данный метод с параметром true. Если
вызвать его с параметром false, окно снова станет невидимым.
Теперь мы можем написать программу, которая создает окно, выводит его на экран и
завершает работу после того, как пользователь закрывает окно.
import javax.swing.*;public class MyClass {public static void main (String []
args) {JFrame myWindow = new JFrame("Пробное
окно");myWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);myWindow.setSi
ze(400, 300);myWindow.setVisible(true);}}
Обратите внимание, для работы с большинством классов библиотеки Swing понадобится
импортировать пакет java.swing.*
Как правило, перед отображением окна, необходимо совершить гораздо больше действий,
чем в этой простой программке. Необходимо создать множество элементов управления,
настроить их внешний вид, разместить в нужных местах окна. Кроме того, в программе
может быть много окон и настраивать их все в методе main() неудобно и неправильно,
поскольку нарушает принцип инкапсуляции: держать вместе данные и команды, которые их
обрабатывают. Логичнее было бы, чтобы каждое окно занималось своими размерами и
содержимым самостоятельно. Поэтому классическая структура программы с окнами
выглядит следующим образом:
В файле SimpleWindow.java:
public class SimpleWindow extends JFrame {SimpleWindow(){super("Пробное
окно");setDefaultCloseOperation(EXIT_ON_CLOSE);setSize(250, 100);}}
В файле Program.java:
public class Program {public static void main (String [] args) {JFrame
myWindow = new SimpleWindow();myWindow.setVisible(true);}}

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


наследником JFrame и настраивающее свой внешний вид и поведение в конструкторе
(первой командой вызывается конструктор суперкласса). Метод main() содержится в
другом классе, ответственном за управление ходом программы. Каждый из этих классов
очень прост, каждый занимается своим делом, поэтому в них легко разбираться и легко
сопровождать (т.е. совершенствовать при необходимости).
Обратите внимание, что метод setVisible() не вызывается в классе SimpleWindow, что
вполне логично: за тем, где какая кнопка расположена и какие размеры оно должно иметь,
следит само окно, а вот принимать решение о том, какое окно в какой момент выводится на
экран — прерогатива управляющего класса программы.

Панель содержимого
Напрямую в окне элементы управления не размещаются. Для этого служит панель
содержимого, занимающая все пространство окна*. Обратиться к этой панели можно
методом getContentPane() класса JFrame. С помощью метода add(Component
component) можно добавить на нее любой элемент управления.
В примерах этого занятия мы будем использовать только один элемент управления —
кнопку (не вдаваясь в подробности ее устройства). Кнопка описывается классом JButton и
создается конструктором с параметром типа String — надписью.
Добавим кнопку в панель содержимого нашего окна
командами:
JButton newButton
= new JButton();getContentPane().add(newButto
n);
В результате получим окно с кнопкой. Кнопка
занимает всю доступную площадь окна. Такой
эффект полезен не во всех программах, поэтому необходимо изучить различные способы
расположения элементов на панели.

Менеджер последовательного размещения FlowLayout


Самый простой менеджер размещения — FlowLayout. Он размещает добавляемые на
панель компоненты строго по очереди, строка за строкой, в зависимости от размеров
панели. Как только очередной элемент не помещается в текущей строке, он переносится на
следующую. Лучше всего пронаблюдать это на примере. Изменим конструктор
класса SimpleWindow следующим образом:
SimpleWindow(){super("Пробное
окно");setDefaultCloseOperation(EXIT_ON_CLOSE);JPanel panel
= new JPanel();panel.setLayout(new FlowLayout());panel.add(new JButton("Кнопк
а"));panel.add(new JButton("+"));panel.add(new JButton("-"));panel.add(new JB
utton("Кнопка с длинной надписью"));setContentPane(panel);setSize(250, 100);}
Менеджеры расположения описаны в пакете
java.awt. Не забывайте импортировать нужные
классы.
Пронаблюдайте за поведением окна,
появляющегося после запуска программы. Четыре
кнопки в нем расположены как слова в текстовом
редакторе (при выравнивании по центру). Эффект
будет лучше заметен, если изменять размеры окна во время работы программы.
Проанализируем текст примера. Новый менеджер расположения FlowLayout создается
конструктором без параметров. Обратите внимание, в программе не используется
промежуточная переменная. То есть вместо двух команд:
FlowLayout newLayout = new FlowLayout();panel.setLayout(newLayout);
Мы используем одну:
panel.setLayout(new FlowLayout());
Это вполне допустимо в тех случаях, когда в дальнейшем нам не потребуется обращаться к
создаваемому объекту (что справедливо для данного примера). Мы создаем менеджер
расположения, тут же привязываем его к панели — и все. Теперь панель и менеджер сами
найдут друг с другом общий язык.
о взаимоотношениях панели и ее менеджера

Точно также мы добавляем на панель новые кнопки. Мы нигде больше не пытаемся


обратиться к этим кнопкам в программе, поэтому заводить под них переменные нет смысла.
Метод setContentPane(JPanel panel) позволяет заменить панель содержимого окна.

Если в качестве менеджера размещения панели установить null, элементы не будут


расставляться автоматически. Координаты каждого элемента необходимо в этом случае
указать явно, при этом они никак не зависят от размеров панели и от координат других
элементов. По умолчанию координаты равны нулю (т.е. элемент расположен в левом
верхнем углу панели). Размер элемента также необходимо задавать явно (в противном
случае его ширина и высота будут равны нулю и элемент отображаться не будет).
Координаты элемента можно задать одним из следующих методов:
setLocation(int x, int y),
setLocation(Point point)
Эти методы работают аналогично, устанавливая левый верхний угол элемента в точку с
заданными координатами. Разница в способе задания точки. Можно представить точку
двумя целыми числами, а можно объектом класса Point. Класс Point по сути
представляет собой ту же пару чисел, его конструктор имеет вид Point(int x, int y).
Получить доступ к отдельной координате можно методами getX() и getY().
Можно задаться вопросом: зачем использовать класс Point, если можно просто передать
пару чисел? Но дело в том, что многие полезные методы возвращают результат —
координаты некоторой точки — в виде объекта этого класса. Например,
метод getLocation(), возвращающий координаты элемента. Предположим, нам нужно
поместить элемент b в точности в то место, которое занимает элемент a. Этого легко
добиться одной строкой:
b.setLocation(a.getLocation());
Размер элемента задается одним из двух методов:
setSize(int width, int height),
setSize(Dimension size)
Эти методы работают одинаково — разница, как и в прошлый раз, в способе передачи
параметра. Класс Dimension, аналогично классу Point, просто хранит два числа, имеет
конструктор с двумя параметрами: Dimension(int width, int height) и позволяет
получить доступ к своим составляющим — ширине и высоте — с помощью простых
методов getWidth() и getHeigth(). Для того, чтобы получить текущий размер элемента,
можно воспользоваться методом getSize(), возвращающего объект класса Dimension.
Элемент b можно сделать точно такого же размера, как элемент a, выполнив команду:
b.setSize(a.getSize());
Создадим панель, с которой не будет связано никакого менеджера размещения и вручную
разместим на ней две кнопки:
SimpleWindow(){super("Пробное
окно");setDefaultCloseOperation(EXIT_ON_CLOSE
);JPanel panel
= new JPanel();panel.setLayout(null);JButton
button
= new JButton("Кнопка");button.setSize(80,

30);button.setLocation(20,20);panel.add(button);button = new JButton("Кнопка
с длинной надписью");button.setSize(120,
40);button.setLocation(70,50);panel.add(button);setContentPane(panel);setSize
(250, 150);}
Мы используем одну и ту же переменную button для обращения к обеим кнопкам (причем,
второй раз ее описывать не нужно). В самом деле, осуществив все необходимые операции с
первой кнопкой и зная, что обращаться к ней нам больше не понадобится, мы используем
«освободившуюся» переменную для манипуляций со второй.

51. Введение в JavaFX 2.0.


52. Основные компоненты. Обработка событий. Построение
интерфейсов с помощью библиотеки JavaFX.

Что такое JavaFX?


JavaFX — это по сути инструментарий GUI для Java.
JavaFX нацелен на создание игр и настольных приложений на Java. По
сути им заменят Swing из-за предложенного нового инструмента GUI для
Java. Также, он позволяет нам стилизовать файлы компоновки GUI (XML)
и сделать их элегантнее с помощью CSS, подобно тому, как мы
привыкли к сетевым приложениям. JavaFX дополнительно работает с
интегрированной 3D-графикой, а также аудио, видео и встроенными
сетевыми приложениями в единый инструментарий GUI… Он прост в
освоении и хорошо оптимизирован. Он поддерживает множество
операционных систем, а также Windows, UNIX системы и Mac OS.
Особенности JavaFX:
 JavaFX изначально поставляется с большим набором частей
графического интерфейса, таких как всякие там кнопки, текстовые
поля, таблицы, деревья, меню, диаграммы и т.д., что в свою
очередь сэкономит нам вагон времени.
 JavaFX часто юзает стили CSS, и мы сможем использовать
специальный формат FXML для создания GUI, а не делать это в
коде Java. Это облегчает быстрое размещение графического
интерфейса пользователя или изменение внешнего вида или
композиции без необходимости долго играться в коде Java.
 JavaFX имеет готовые к использованию части диаграммы, поэтому
нам не нужно писать их с нуля в любое время, когда вам нужна
базовая диаграмма.
 JavaFX дополнительно поставляется с поддержкой 3D графики,
которая часто полезна, если мы разрабатываем какую-то игру или
подобные приложения.
 Stage — по сути это окружающее окно, которое используется как
начальное полотно и содержит в себе остальные компоненты. У
приложения может быть несколько stage, но один такой компонент
должен быть в любом случае. По сути Stage является основным
контейнером и точкой входа.
 Scene — отображает содержание stage (прям матрёшка). Каждый
stage может содержать несколько компонентов — scene, которые
можно между собой переключать. Внутри это реализуется графом
объектов, который называется — Scene Graph (где каждый элемент
— узел, ещё называемый как Node).
 Node — это элементы управления, например, кнопки метки, или
даже макеты (layout), внутри которых может быть несколько
вложенных компонентов. У каждой сцены (scene) может быть один
вложенный узел (node), но это может быть макет (layout) с
несколькими компонентами. Вложенность может быть
многоуровневой, когда макеты содержат другие макеты и обычные
компоненты. У каждого такого узла есть свой идентификатор,
стиль, эффекты, состояние, обработчики событий.
53. Рефлексия в языке Java.
54. Использование Java Reflection API. Анализ классов во время
исполнения Java программы.
55. Описание класса «Class», назначение рефлексии, исследование
классов с помощью механизма рефлексии, создание экземпляров классов
средствами рефлексии. Примеры использования.
Рефлексия в Java — это механизм, с помощью которого
можно вносить изменения и получать информацию о классах,
интерфейсах, полях и методах во время выполнения, при этом не
зная имен этих классов, методов и полей. Кроме того, Reflection API
дает возможность создавать новые экземпляры классов, вызывать
методы, а также получать или устанавливать значения полей

Java Reflection API


Рефлексия — мощная концепция, которая лежит в основе большинства
современных Java/Java EE фреймворков и библиотек. Например, для Java
классическими примерами являются:

Ограничения при работе с рефлексией в Java


Почему мы не должны использовать рефлексию в обычном программировании,
когда уже есть доступ к интерфейсам и классам. Причин несколько:

1. Низкая производительность — поскольку рефлексия в Java определяет


типы динамически, то она сканирует classpath, чтобы найти класс для
загрузки, в результате чего снижается производительность программы.
2. Ограничения системы безопасности — рефлексия требует разрешения
времени выполнения, которые не могут быть доступны для систем,
работающих под управлением менеджера безопасности (Java Security
Manager).
3. Нарушения безопасности приложения — с помощью рефлексии мы
можем получить доступ к части кода, к которой мы не должны получать
доступ. Например, мы можем получить доступ к закрытым полям класса и
менять их значения. Это может быть серьезной угрозой безопасности.
4. Сложность в поддержке — код, написанный с помощью рефлексии трудно
читать и отлаживать, что делает его менее гибким и трудно
поддерживаемым.

Java Reflection: Работа с классами


Объект java.lang.Class является точкой входа для всех операций рефлексии. Для
каждого типа объекта, JVM создает неизменяемый
экземпляр java.lang.Class который предоставляет методы для получения свойств
объекта, создания новых объектов, вызова методов.
В этом разделе мы рассмотрим важные методы при работе с java.lang.Class:

 Все типы в Java, включая примитивные типы и массивы имеют связанный с


ними java.lang.Class объект. Если мы знаем название класса во время
компиляции, то сможем получить объект следующим образом:

Java

1 Class mClassObject = SomeObject.class


 Если мы не знаем имя во время компиляции, но знаем имя класса во
время выполнения, то можно сделать так:

Java

1 Class mClassObject = Class.forName("здесь имя класса")

При использовании метода Class.forName() мы должны указать полное имя класса.


То есть имя класса, включая все имена пакетов. Например,
если SomeObject находится в пакете com.javadevblog.app, то полным именем вашего
класса является строка: com.javadevblog.app.SomeObject.
Метод Class.forName() может бросить исключение ClassNotFoundException если класс не
будет найден в classpath во время выполнения.

Получаем название класса


С помощью объекта Class мы можем можете получить имя класса двумя способами:
Методом getName() , который вернет полное имя класса с пакетом:
Java

1 String fullClassName = mClassObject.getName();

И с помощью метода getSimpleName(), который вернет только название класса без


имени пакета:
Java

1 String justClassName = mClassObject.getSimpleName();

Работа с модификаторами доступа


Мы можем получить доступ к модификаторам доступа с помощью Class объекта.
Модификаторы представляют собой ключевые слова public, static, private и т.д.
Мы можем получить модификаторы с помощью метода getModifiers():
Java
1 Class mClassObject = SomeObject.class

2 int classModifiers = mClassObject.getModifiers();

Результат выполнения находится в переменной int, где каждый модификатор — это


битовый флаг, который может быть установлен или сброшен. Мы можем проверить
модификаторы, используя следующие методы в классе java.lang.reflect.Modifier:
Java

1 Modifier.isAbstract(int modifiers)

2 Modifier.isFinal(int modifiers)

3 Modifier.isInterface(int modifiers)

4 Modifier.isNative(int modifiers)

5 Modifier.isPrivate(int modifiers)

6 Modifier.isProtected(int modifiers)

7 Modifier.isPublic(int modifiers)

8 Modifier.isStatic(int modifiers)

9 Modifier.isStrict(int modifiers)

10 Modifier.isSynchronized(int modifiers)

11 Modifier.isTransient(int modifiers)

12 Modifier.isVolatile(int modifiers)

В параметры метода просто передадим modifiers и каждый из этих методов


вернет true или false.

 JUnit – фреймворк для модульного тестирования. Он использует рефлексию


для парсинга аннотаций (например, @Test) для получения описанных
программистом тестовых методов и дальнейшего их выполнения.
 Spring – фреймворк для разработки приложений на Java платформе, в
основе которого лежит внедрение зависимостей (инверсия управления).

Список можно продолжать бесконечно: от веб-контейнеров до решения задач


объектно-реляционного отображения (ORM). Их всех объединяет одно: они
используют Java рефлексию, потому что не имеют доступа и представления к
определенных пользователем классах, методах, интерфейсах и т.д.

Вам также может понравиться