Главная страница

Ревью потоки в JAVA. Ревью 4 - карточки. Что такое поток


Скачать 47.29 Kb.
НазваниеЧто такое поток
АнкорРевью потоки в JAVA
Дата03.10.2022
Размер47.29 Kb.
Формат файлаdocx
Имя файлаРевью 4 - карточки.docx
ТипДокументы
#712092

Что такое поток?


поток (stream) - абстракция, которая используется для чтения или записи информации (файлов, сокетов, текста консоли и т.д.).

Какие существуют виды потоков ввода/вывода?


Разделяют два вида потоков ввода/вывода:

байтовые - java.io.InputStream, java.io.OutputStream;

символьные - java.io.Reader, java.io.Writer.

Назовите основные предки потоков ввода/вывода.


Байтовые: java.io.InputStream, java.io.OutputStream;

Символьные: java.io.Reader, java.io.Writer;

Что такое InputStream и OutputStream?


Абстрактные классы InputStream и OutputStream нужны для того, чтобы абстрагировать различные способы ввода и вывода, независимо от того, является ли поток файлом, веб- страницей или картинкой.

InputStream используется для считывания информации.

OutputStream используется для записи информации.

Стандартные потоки ввода/вывода?


Java предоставляет следующие три стандартных потока:

- Стандартный ввод – используется для перевода данных в программу пользователя, клавиатура обычно используется в качестве стандартного потока ввода, представленного в виде System.in.

- Стандартный вывод – производится для вывода данных, полученных в программе пользователя, и обычно экран компьютера используется в качестве стандартного потока вывода, представленного в виде System.out.

- Стандартная ошибка – используется для вывода данных об ошибке, полученной в программе пользователя, чаще всего экран компьютера служит в качестве стандартного потока сообщений об ошибках, представленного в виде System.err.

Классы байтовых потоков ввода и что они делают? - 10 шт


InputStream - абстрактный класс, описывающий поток ввода;

BufferedInputStream - буферизованный входной поток;

ByteArrayInputStream позволяет использовать буфер в памяти (массив байтов) в качестве источника данных для входного потока;

DataInputStream - входной поток для байтовых данных, включающий методы для чтения стандартных типов данных Java;

FileInputStream - входной поток для чтения информации из файла;

FilterInputStream - абстрактный класс, предоставляющий интерфейс для классов-надстроек, которые добавляют к существующим потокам полезные свойства;

ObjectInputStream - входной поток для объектов;

StringBufferInputStream превращает строку (String) во входной поток данных InputStream;

PipedInputStream реализует понятие входного канала;

PushbackInputStream - разновидность буферизации, обеспечивающая чтение байта с последующим его возвратом в поток, позволяет «заглянуть» во входной поток и увидеть, что оттуда поступит в следующий момент, не извлекая информации.

SequenceInputStream используется для слияния двух или более потоков InputStream в единый.

Классы байтовых потоков вывода и что они делают? - 9 шт


OutputStream - это абстрактный класс, определяющий потоковый байтовый вывод;

BufferedOutputStream - буферизированный выходной поток;

ByteArrayOutputStream - все данные, посылаемые в этот поток, размещаются в предварительно созданном буфере;

DataOutputStream - выходной поток байт, включающий методы для записи стандартных типов данных Java;

FileOutputStream - запись данных в файл на физическом носителе;

FilterOutputStream - абстрактный класс, предоставляющий интерфейс для классов-надстроек, которые добавляют к существующим потокам полезные свойства;

PrintStream - выходной поток, включающий методы print() и println();

ObjectOutputStream - выходной поток для записи объектов;

PipedOutputStream реализует понятие выходного канала.

Классы символьных потоков ввода и что они делают? - 10 шт


Reader - абстрактный класс, описывающий символьный ввод;

BufferedReader - буферизованный входной символьный поток;

CharArrayReader - входной поток, который читает из символьного массива;

FileReader - входной поток, читающий файл;

FilterReader - абстрактный класс, предоставляющий интерфейс для классов-надстроек;

InputStreamReader- входной поток, транслирующий байты в символы;

LineNumberReader - входной поток, подсчитывающий строки;

PipedReader - входной канал;

PushbackReader - входной поток, позволяющий возвращать символы обратно в поток;

StringReader - входной поток, читающий из строки.

Классы символьных потоков вывода и что они делают? - 8 шт


Writer - абстрактный класс, описывающий символьный вывод;

BufferedWriter - буферизованный выходной символьный поток;

CharArrayWriter - выходной поток, который пишет в символьный массив;

FileWriter - выходной поток, пишущий в файл;

FilterWriter - абстрактный класс, предоставляющий интерфейс для классов-надстроек;

OutputStreamWriter - выходной поток, транслирующий байты в символы;

PipedWriter - выходной канал;

PrintWriter - выходной поток символов, включающий методы print() и println();

StringWriter - выходной поток, пишущий в строку;

Как работает метод read()


Метод read() - возвращает значение целого типа очередного символа, доступного во входном потоке; Метод read(byte arr) - метод для массового считывания данных, который считывает максимум байтов (не более arr.length) из потока, входящих данных в аргумент массива arr и возвращает фактическое количество байтов, считанных из потока;

Что делает метод read? Почему он возвращает int, а не byte?

Почему он не может возвращать byte?


Тип Int необходим для возможности выделять признак конца потока. Т.к. тип byte является знаковым, то его диапазон составляет [-128; 127], ([1000_0000; 0111_1111]), но если этот байт поместить в младший байт типа int, то диапазон значений становится [0; 255].

Что делает метод available()?


int available() - возвращает количество байтов ввода, доступные в данный момент для чтения

Что вернет метод read(), если он считывает файл и ему встречается байт равный -1?


-1 в типе int = 1111_1111__1111_1111__1111_1111__1111_1111 (32 единицы = - 2 147 483 648)
-1 в байте, помещенном в int = 0000_0000__0000_0000__0000_0000__1111_1111
или 255. (8 единиц = 255)

Какие перегрузки есть у метода read(), как они работают? Что возвращает перегруженый метод с массивом?


int read()- возвращает представление очередного доступного символа во входном потоке в виде целого числа.

int read(char[] buffer)- пытается прочесть максимум buffer.length символов из входного потока в массив buffer. Возвращает количество символов, в действительности прочитанных из потока.

int read(char[] buffer, int offset, int length)- пытается прочесть максимум length символов, расположив их в массиве buffer, начиная с элемента offset. Возвращает количество реально прочитанных символов.

close() – метод закрывает поток.

Почему важно закрывать потоки?


При завершении работы с потоком его надо закрыть с помощью метода close(), который определен в интерфейсе Closeablevoid close() throws IOException

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

Какие потоки можно не закрывать (не вызывать метод close())?


Не нужно закрывать обычный Stream из Stream API. Не нужно закрывать тот поток, который объявлен в try-with-resources. OutputStream – пустой метод close()

Что такое System.in, что такое System.out?


System.in — это "стандартный" поток ввода и объект InputStream. Этот поток уже открыт и готов к подаче входных данных. Обычно этот поток соответствует вводу с клавиатуры или другому источнику ввода, заданному окружением хоста или пользователем.
System.out — это "стандартный" поток вывода и объект PrintStream. Этот поток уже открыт и готов к приему выходных данных. Обычно этот поток соответствует выводу на дисплей или другому месту вывода, указанному окружением хоста или пользователем.

что делает flush? выполнится ли flush если мы сделаем close?


Flush очищает буфер и скидывает содержимое в поток
Да,выполнится
В соответствии с документами java, вызывая close() на любом потоке java.io, автоматически вызывает flush().

Гарантируется ли запись данных в файл при вызове flush?


flush(), очищает все потоки данных и полностью их записывает, а также дает новое пространство для новых потоков во временном расположении буфера.

Но если буффер пустой (/ не попали данные через write) – то ничего записано не будет

Можно ли flush() для небуферизированного потока и что будет?


В переводе на русский означает, что flush() вызывает чистку буфера вызывая метод реализованный в самой ОС поверх которой работает JVM. При этом даже отсутствие буфера в самом потоке не означает, что не будет использоваться в качестве буфера кэш диска на уровне ОСи или даже ниже. Использование flush() – хороший тон поскольку, девелопер не знает есть ли буфер на уровне ОС

Чем отличаются и что общего у InputStream, OutputStream, Reader, Writer?


InputStream и его наследники - совокупность для получения байтовых данных из различных источников;

OutputStream и его наследники - набор классов, определяющих потоковый байтовый вывод;

Reader и его наследники определяют потоковый ввод символов Unicode;

Writer и его наследники определяют потоковый вывод символов Unicode.


Какие интерфейсы реализует InputStream/ OutputStream/ Reader/ Writer?


InputStream реализует интерфейсы: Closeable и AutoCloseable

OutputStream реализует интерфейсы: Closeable, Flushable, AutoCloseable

Reader реализует интерфейсы: Closeable, AutoCloseable, Readable

Writer реализует интерфейсы: Closeable, Flushable, Appendable, AutoCloseable

Пример адаптера и декоратора из IO


Декоратор — это структурный паттерн, который позволяет добавлять объектам новые поведения на лету, помещая их в объекты-обёртки. inputstream, bytearrayinputstream, stringbuilderinputstreams и так далее являются основными элементами.

Filterinputstream - это базовый класс для классов декораторов. Фильтр входных потоков (например, bufferedinput stream) может выполнять дополнительные функции при чтении потоков или записи в них. Он реализует все те же методы, что и InputStream, который лежит в нём, но позволяет к ним добавить доп. функционал. Конкретно его используют для какой-либо модификации данных из InputStream (т.е. фильтрации).

Адаптеры: OutputStreamWriter легко «адаптирует» два интерфейса классов Writer и OutputStream друг другу.

Класс InputStreamReader — это классический адаптер, он адаптирует InputStream и Reader

На каком паттерне основана иерархия потоков ввода/вывода?


Объекты классов Java, которые используются для ввода/вывода, для обеспечения необходимой функциональности наслаиваются друг на друга. Такая модель взаимодействия объектов поддерживается в паттерне «Декоратор». В этом паттерне при создании потока нужно использовать несколько объектов.

Конструкторы и методы класса File.



1 File(File parent, String child) - Конструктор создает новый экземпляр файла из родительского абстрактного пути и строки дочернего пути.

2 File(String pathname) - Конструктор создает новый экземпляр файла, преобразовывая указанную строку pathname в абстрактный путь.

3 File(String parent, String child) - Конструктор создает новый экземпляр файла из строки родительского пути и строки дочернего пути.

4 File(URI uri) - Конструктор создает новый экземпляр файла, преобразовывая данный файл: URI в абстрактный путь.
Класс File имеет ряд методов, которые позволяют управлять файлами и каталогами. Рассмотрим некоторые из них:

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

boolean delete(): удаляет каталог или файл по пути, который передан в конструктор. При удачном удалении возвращает true.

boolean exists(): проверяет, существует ли по указанному в конструкторе пути файл или каталог. И если файл или каталог существует, то возвращает true, иначе возвращает false

Конструкторы и методы класса File. (продолжение)



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): переименовывает файл или каталог

Расскажи про класс File? Как создать новый файл на жестком диске?


Класс File, определенный в пакете java.io, не работает напрямую с потоками. Его задачей является управление информацией о файлах и каталогах. Хотя на уровне операционной системы файлы и каталоги отличаются, но в Java они описываются одним классом File.

Для создания нового файла, во время инициализации объекта File, мы должны предоставить ему имя файла, а затем создать сам новый файл вызовом метода createNewFile().
Создать файл в Java с помощью объекта File можно тремя способами:

1. Передав в объект абсолютный путь
2. Указать только имя файла
3. Указать относительный путь

Как удалить директорию с файлами? Что если в ней есть вложенные директории?


Java не может удалять папки с данными в них. Чтобы удалить директорию с файлами, сначала необходимо удалить сами файлы в папке, а затем и саму папку.

Если требуется удаление папок с файлами нужно писать рекурсивный метод

Абсолютный и относительный путь


Абсолютный путь всегда содержит корневой элемент и полный список каталогов, для нахождения файла.
Например: "c:\\windows\\projects\\note.txt" — это абсолютный путь. Для проверки, является ли путь абсолютным, есть метод isAbsolute().
Относительный путь необходимо соединить с другим путем, чтобы получить доступ к файлу. Например, joe/foo — это относительный путь.
Без дополнительной информации, программа не сможет достоверно определить местоположение каталога joe/foo в файловой системе.

Что такое канонический путь?


Метод getCanonicalPath() является частью класса Path . Эта функция возвращает канонический путь к указанному объекту файла. Если путь к объекту файла — Canonical, он просто возвращает путь к текущему объекту файла. Канонический путь всегда абсолютен и уникален, функция удаляет «.» «..» с пути, если есть. Каноническая форма существующего файла может отличаться от канонической формы того же несуществующего файла, и каноническая форма существующего файла может отличаться от канонической формы того же файла, когда он удаляется.

В чём отличие File от Path?


Path, по большому счету, — это переработанный аналог класса File. Работать с ним значительно проще, чем с File.

1. из него убрали многие утилитные (статические) методы, и перенесли их в класс Files.

2. в Path были упорядочены возвращаемые значения методов. В классе File методы возвращали то String, то boolean, то File — разобраться было непросто.

Например, был метод getParent(), который возвращал родительский путь для текущего файла в виде строки. Но при этом был метод getParentFile(), который возвращал то же самое, но в виде объекта File! Это явно избыточно. Поэтому в интерфейсе Path метод getParent() и другие методы работы с файлами возвращают просто объект Path. Никакой кучи вариантов — все легко и просто.


Files(относится к NIO)


Files — это утилитный класс, куда были вынесены статические методы из класса File. Files — это примерно то же, что и Arrays или Collections, только работает он с файлами, а не с массивами и коллекциями :)

Он сосредоточен на управлении файлами и директориями. Используя статические методы Files, мы можем создавать, удалять и перемещать файлы и директории.
В Java есть специальный класс (File), с помощью которого можно управлять файлами на диске компьютера – он устаревший, и вместо него рекомендуется использовать Path

Что вы знаете о RandomAccessFile?


Класс RandomAccessFile наследуется напрямую от Object и не наследуется от вышеприведенных базовых классов ввода\вывода. Предназначен для работы с файлами, поддерживая произвольный доступ к их содержимому.
Работа с классом RandomAccessFile напоминает использование совмещенных в одном классе потоков DataInputStream и DataOutputStream (они реализуют те же интерфейсы DataInput и DataOutput). Кроме того, метод seek() позволяет переместиться к определенной позиции и изменить хранящееся там значение.
При использовании RandomAccessFile необходимо знать структуру файла. Класс RandomAccessFile содержит методы для чтения и записи примитивов и строк UTF-8.

Какие есть режимы доступа к файлу?

RandomAccessFile может открываться в режиме чтения ("r") или чтения/записи ("rw"). Также есть режим "rws", когда файл открывается для операций чтения-записи и каждое изменение данных файла немедленно записывается на физическое устройство.

В каких пакетах лежат классы-потоки?


Классы потоков ввода\вывода лежат в java.io; С JDK 7 добавлен более современный способ работы с потоками - Java NIO. Классы лежат в java.nio. Для работы с архивами используются классы из пакета java.util.

Что вы знаете о классах-надстройках?


Классы-надстройки наделяют существующий поток дополнительными свойствами. Примеры классов: BufferedOutputStream, BufferedInputStream, BufferedWriter - буферизируют поток и повышают производительность.

Какие классы позволяют преобразовать байтовые потоки в символьные и обратно?


1) OutputStreamWriter - мост между классом OutputStream и классом Writer. Символы, записанные в поток, преобразовываются в байты.
2) InputStreamReader - аналог для чтения. При помощи методов класса Reader читаются байты из потока InputStream и далее преобразуются в символы.

Какой класс-надстройка позволяет читать данные из входного байтового потока в формате примитивных типов данных?


Для чтения байтовых данных (не строк) применяется класс DataInputStream. В этом случае необходимо использовать классы из группы InputStream.
Для преобразования строки в массив байтов, пригодный для помещения в поток ByteArrayInputStream, в классе String предусмотрен метод getBytes(). Полученный ByteArrayInputStream представляет собой поток InputStream, подходящий для передачи DataInputStream.
При побайтовом чтении символов из форматированного потока DataInputStream методом readByte() любое полученное значение будет считаться действительным, поэтому возвращаемое значение неприменимо для идентификации конца потока. Вместо этого можно использовать метод available(), который сообщает, сколько еще осталось символов.
Класс DataInputStream позволяет читать элементарные данные из потока через интерфейс DataInput, который определяет методы, преобразующие элементарные значения в форму последовательности байтов. Такие потоки облегчают сохранение в файле двоичных данных.
Конструктор: DataInputStream(InputStream stream)Методы: readDouble(), readBoolean(), readInt()

Какой класс-надстройка позволяет ускорить чтение/запись за счет использования буфера?


Для этого используются классы, позволяющие буферизировать поток:java.io.BufferedInputStream(InputStream in) || BufferedInputStream(InputStream in, int size),java.io.BufferedOutputStream(OutputStream out) || BufferedOutputStream(OutputStream out, int size),java.io.BufferedReader(Reader r) || BufferedReader(Reader in, int sz),java.io.BufferedWriter(Writer out) || BufferedWriter(Writer out, int sz)

Что вы знаете об интерфейсе FilenameFilter?


Интерфейс FilenameFilter применяется для проверки попадает ли объект File под некоторое условие. Этот интерфейс содержит единственный метод boolean accept(File pathName). Этот метод необходимо переопределить и реализовать.

Какой класс предназначен для работы с элементами файловой системы (ЭФС)?


В отличие от большинства классов ввода/вывода, класс File работает не с потоками, а непосредственно с файлами. Данный класс позволяет получить информацию о файле: права доступа, время и дата создания, путь к каталогу. А также осуществлять навигацию по иерархиям подкаталогов. Класс java.io.File может представлять имя определённого файла, а также имена группы файлов, находящихся в каталоге. Если класс представляет каталог, то его метод list() возвращает массив строк с именами всех файлов.
Для создания объектов класса File можно использовать один из следующих конструкторов:File(File dir, String name) - указывается объект класса File (каталог) и имя файлаFile(String path) - указывается путь к файлу без указания имени файлаFile(String dirPath, String name) - указывается путь к файлу и имя файлаFile(URI uri) - указывается объекта URI, описывающий файл

Какой символ является разделителем при указании пути к ЭФС?


Для различных систем символ разделителя различается. Вытащить его можно используя file.separator, а так же в статическом поле File.separator. Для Windows это '\'.
*На stackoverflow встречал утверждение со ссылкой на документацию, что можно безопасно использовать слэш '/' для всех систем. В комментарии читатель подтвердил это.

Основные отличия между Java IO и Java NIO


IO
1) Блокирующий ввод-вывод Потоки ввода/вывода (streams) в Java IO являются блокирующими. Это значит, что когда в потоке выполнения (tread) вызывается read() или write() метод любого класса из пакета java.io.*, происходит блокировка до тех пор, пока данные не будут считаны или записаны.

2) Потокоориентированный ввод-вывод. Потокоориентированный ввод/вывод подразумевает чтение/запись из потока/в поток одного или нескольких байт в единицу времени поочередно. Данная информация нигде не кэшируются. Таким образом, невозможно произвольно двигаться по потоку данных вперед или назад. Если вы хотите произвести подобные манипуляции, вам придется сначала кэшировать данные в буфере.

NIO
1) Неблокирующий ввод-вывод Неблокирующий режим Java NIO позволяет запрашивать считанные данные из канала (channel) и получать только то, что доступно на данный момент, или вообще ничего, если доступных данных пока нет.

2) Буфероориентированный ввод-вывод.
3) Селекторы
Селекторы в Java NIO позволяют одному потоку выполнения мониторить несколько каналов ввода. Вы можете зарегистрировать несколько каналов с селектором, а потом использовать один поток выполнения для обслуживания каналов, имеющих доступные для обработки данные, или для выбора каналов, готовых для записи.

(Java NIO) Что такое каналы?


1) Каналы (channel) - открытое соединение с источником или адресатом ввода/вывода.
2) Через каналы осуществляется ввод вывод данных.
3) Вывод данных: вы --> буфер --> канал.
4) Ввод данных: канал --> буфер --> вы.

Разница в IO при работе с файлом и директорией.


Базовая сущность файловой системы - это файл. Для работы с этой сущностью существует класс java.io.File. Этот класс представляет собой как простые файлы, так и директории (папки). Создание объекта класса File не создает файл непосредственно в файловой системе. boolean success = file.createNewFile();

File dir = new File("a/b/c/d"); boolean success = dir.mkdir();

Граница значения байта вообще и которые используются в IO?


Может принимать одно из 256 (от 0 до 255, но в джаве используется знаковый байт поэтому значения – -2^7 – 2^7-1). Байт в IO 0..255

BuferedReader и BuferedWriter, их методы и отличия от стримов.


BufferedReader/BufferedWriter - наследник Reader/Writer добавляющий методы чтения и записи целых строк, а не отдельных символов. буферизуя прочитанные символы, чтобы обеспечить эффективное считывание символов, массивов и строк. Можно указать в конструкторе вторым параметром размер буфера.

InputStream/OutputStream - потоки читающие, пишущие байты. Читать и писать они могут все, т.к. все записано в байтах.

В каких случаях использовать reader и scanner?


Экземпляры класса java.io.BufferedReader предназначены для чтения потока символов с буферизацией (символов, массивов и строк).

Экземпляры класса java.util.Scanner предназначены для разбора данных на составляющие с учетом форматов, шаблонов, разных разделителей. Входные данные для Scanner могут быть файлы, потоки байтов, потоки символов, строки.

Есть ли у сканера буфер?


У сканера есть буфер, но он довольно маленький — всего 1024 символа.

Для чего нужен Scanner? Что такое токен в Scanner?

Для получения (считывания) данных введенных пользователем в виде String, byte, short, int, long, float, double

Класс Scanner используется для получения (считывания) данных введенных пользователем в виде String, byte, short, int, long, float, double. Сканер выполняет поиск токенов во входной строке. Токен (или маркер) представляет собой серию цифровых или буквенно-цифровых символов, которая заканчивается разделителем.


В чем отличие Scanner от BufferedReader?


Scanner позволяет разобрать строку на составляющие (токены), с помощью различных разделителей. Он не синхронизирован и , также не выбрасывает исключения.
BufferedReader предназначен для чтения потока символов с буферизацией.

java.util.Scanner - это в первую очередь сканер текста. Он использует регулярные выражения, чтобы выделить нужные типы данных из строки: nextInt(), nextDouble() и т.д.
java.io.BufferedReader просто читает последовательность символов. Это быстрее, чем Scanner, но расшифровывать это нужно вручную.

Что такое сериализация и десериализация?


Сериализация - это процесс сохранения состояния объекта в последовательность байт.
Десериализация - это процесс восстановления объекта из этих байт.

Зачем вообще нужна сериализация?

Данные в памяти "живут", до момента завершения приложения. Сериализация позволяет записать объекты в файлы и, таким образом, восстановить их затем.
2) Сериализация предоставляет универсальный механизм обмена данными между компонентами приложения или узлами в интернете.

Какие условия "благополучной" сериализации объекта?


Чтобы обладать способностью к сериализации, класс должен реализовывать интерфейс-метку Serializable. Так же все атрибуты и подтипы сериализуемого класса должны быть сериализуемы. Если класс предок был несереализуемым, то этот суперкласс должен содержать доступный (public, protected) конструктор без параметров для инициализации полей.

Какие классы позволяют архивировать объекты?


DeflaterOutputStream, InflaterInputStream, ZipInputStream, ZipOutputStream, GZIPInputStream, GZIPOutputStream.
Пример из http://www.concretepage.com/java/how_to_zip_file_java

Что делать, если одно из полей сериализовывать не нужно.


Это поле нужно пометить ключевым словом transient.
И оно не будет сериализовано.

Как сериализовать объект класса?


Нужно пометить его маркерным классом Serializable

Как сериализовать статическое поле?


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

Можно ли сериализовать final поле? Можно ли сериализовать и десериализовать final переменную с помощью Externalizable?


Поля с модификатором final сериализуются как и обычные. За одним исключением - их невозможно десериализовать при использовании Externalizable, поскольку final-поля должны быть инициализированы в конструкторе, а после этого в readExternal изменить значение этого поля будет невозможно. Соответственно, если необходимо сериализовать объект с final-полем неоходимо использовать только стандартную сериализацию.

Что если я не хочу сериализовывать поле? Что если при десериализации поменять тип?


Если добавить к полю ключевое слово transient – такое поле не сериализуется. В таком случае будет выкинут InvalidClassException

Сериализация как выполняется? Перечислить шаги, которые выполняет механизм сериализации при сериализации объекта (что за чем записывается в поток)


1) Запись метаданных: указание, что это сериализация, версия сериализации, указание "сейчас начнется объект".
2.1) Запись рекурсивно данных о классе объекта "снизу вверх": класс -> super -> supersuper и т.д пока не будет достигнут java.lang.Object. Сам класс Object не пишется.
2.2) При описании пишется имя класса, имена и тип его полей, примитивных и ссылок. Для ссылок просто указывается, что "там объект", без описания класса.
3.1) Запись значений данных в экземпляре, "сверху вниз": parent -> sub -> subsub...
3.2) Если поле - ссылка на объект, то рекурсивно идет запись объекта: описания полей "снизу вверх", затем написание значений "сверху вниз".

Какие форматы сериализации существуют?


1. JSON - JavaScript Object Notation
2. XML
3. BinarySON - тот же JSON только в двоичном представлении.
4. YAML - Yet Another Markup Language

Чем отличаются методы восстановления объекта в интерфейсах Serializable и Externalizable?


1) Serializible не использует конструктор объекта - он просто восстанавливает его полностью из последовательности байтов.
2.1) Externalizible вначале вызывает public конструктор объекта без параметров, а затем наполняет поля объекта значениями.
2.2) Если у класса не будет public конструктора без параметров, при попытке десериализовать объект выпадет java.io.InvalidClassException.

Чем отличаются интерфейсы Serializable и Externalizable?


1) Externalizable extends Serializable
2) Интерфейс Serializable полностью реализует виртуальная машина JVM.
3) Интерфейс Externalizable имеет методы writeExternal() и readExternal(), которые позволяют вручную указать - какие поля записывать. Это может в том числе повысит производительность.

А что если у нас Serializable класс содержит поля, в которых объекты не Serializable?


1) В таком случае код скомпилируется.
2) Но в рантайме при попытке сериализации , когда мы дойдем до этого поля и объекта, мы получим NotSerializableException.

Какие поля в классе Java не сериализуются?


1) static поля - они часть класса, а не объекта. Следовательно, они не указывают на состояние объекта.
2) transient поля - модификатор как раз и говорит о том, что "это поле не отмечает состояние объекта". Следовательно, его не нужно сериализовать.

Что за интерфейс Serializable?


1) Интерфейс java.io.Serializable - это интерфейс-маркер, в нем нет методов.
2) Если класс реализует интерфейс, это говорит сериализующему механизму, что этот класс можно сериализовать.

Что такое клонирование. Как реализовано клонирование в Java?


Иногда нужно на основе существующего объекта создать второй такой же, то есть - создать его клон. Этот процесс в Java называется клонированием.
Клонировать объект в Java можно тремя способами:
1. Переопределение метода clone() и реализация интерфейса Cloneable; 2. Использование конструктора копирования;
3. Использовать для клонирования механизм сериализации;

Клонирование объекта. Глубокое и поверхностное.


Поверхностное копирование
копирует настолько маленькую часть, насколько это возможно. По умолчанию, копирование в Java является поверхностным, т.е Object class не знает о структуре
класса, которого он копирует.
Глубокое копирование дублирует всё. Глубокое копирование — это две коллекции, в одну из которых дублируются все элементы оригинальной коллекции. Мы хотим сделать копию, при которой внесение любых изменений в копию не затронет оригинальную коллекцию.

Чем отличается копирование от клонирования?


При копировании объектов, мы создаем не новый объект, а объект, который ссылается на копируемый. Т.е изменения, которые мы произведем во втором объекте, будут так же отражены и в первом.
При клонировании, мы создаем отдельную копию первого объекта, но со своей собственной ссылкой. При этом каждый объект будет иметь свою собственную ссылку.


Можно ли клонировать String, массив String?


Класс String представляет неизменяемую строку. Нет смысла клонировать String. Если вы чувствуете, что вам нужно клонировать его, вы можете просто повторно использовать ту же ссылку и добиться того же эффекта.
Даже если бы вы могли clone s1 как s2, тогда s1 != s2 все равно был бы true. Они по-прежнему будут ссылками на отдельные объекты.
Массив String клонировать можно, т.к он реализует интерфейс Cloneable

Глубокое клонирование требует выполнения следующих правил:


Нет необходимости копировать отдельно примитивные данные;

Все классы-члены в оригинальном классе должны поддерживать клонирование. Для каждого члена класса должен вызываться super.clone() при переопределении метода clone();

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

Переопределение метода clone() и реализация интерфейса Cloneable();

Использование конструктора копирования;

Использовать для клонирования механизм сериализации

Какие копии создаются методом clone() в Java по умолчанию


По умолчанию, клонирование в Java является поверхностным, т.е. класс Object не знает о структуре класса, которого он копирует. Клонирование такого типа осуществляется JVM по следующим правилам:

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

Если класс помимо членов примитивных типов содержит члены ссылочных типов, то тогда копируются ссылки на объекты этих классов. Следовательно, оба объекта будут иметь одинаковые ссылки.

Thread и Runnable, что выбрать? Зачем нужно два вида реализации многопоточности?


Thread - это класс, некоторая надстройка над физическим потоком.

Runnable - это интерфейс, представляющий абстракцию над выполняемой задачей.

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


написать администратору сайта