Лекция 8. Итераторы, генераторы и модуль itertools.Roman Brovko
Два протокола итераторов: __next__ + __iter__ и __getitem__. Итераторы и цикл for, а также операторы in и not in. Генераторы, оператор-выражение yield. Генераторы как: итераторы, сопрограммы, менеджеры контекста. Модуль itertools.
Лекция 12. Быстрее, Python, ещё быстрее.Roman Brovko
Измерение времени работы кода на Python с помощью модулей timeit, cProfile и line_profiler. Немного о NumPy. JIT и AOT компиляция кода на Python на примере Numba и Cython.
Синтаксис объявления классов. Атрибуты, связанные и несвязанные методы, __dict__, __slots__. Статические методы и методы класса. Свойства, декоратор @property. Наследование, перегрузка методов и функция super. Декораторы классов. Магические методы.
Модули threading, queue и concurrent.futures. Использование потоков для параллельных вычислений на Python. GIL. Параллельность и конкурентность. Модуль asyncio. Модуль multiprocessing.
Olexandra Dmytrenko
QA Automating at EPAM Systems
I'll show you how to switch from writing standard code using good old Java7 into writing it using functional way presented in Java8. The training is counted on beginners in the subject who like discovering the new horizons or for those who want to become more firm in using the new lambda features.
Зачем тестировать? Тестирование в интерпретаторе и доктесты. Модуль unittest. Пакет py.test - на порядок лучше. Тестирование свойств и пакет hypothesis.
The document provides an introduction to XML, explaining that it is a text-based markup language used for data interchange on the web. XML tags identify and label pieces of data, rather than specifying how to display it like HTML tags. Tags can also include attributes to provide additional information. The document gives an example of XML markup for a messaging application to demonstrate how hierarchical data can be represented using nested tags.
Writing great unit tests distinguishes good programmers from great programmers. In this course, you will learn how to write great unit tests with Mockito and JUnit. You take 12 steps with JUnit and 18 steps with Mockito into unit testing proficiency.
Mockito
Step 01 : Set up an Eclipse Project with JUnit and Mockito frameworks. First Green Bar.
Step 02 : Example to start understanding why we need mocks.
Step 03 : What is a stub? Create an unit test using Stub? Disadvantages of Stubs.
Step 04 : Your first Mockito code! Hurrah!!! Lets use Mockito to mock TodoService.
Step 05 : Stubbing variations with Mockito. A few mockito examples mocking List class : Multiple return values, Argument Matchers and throwing exceptions.
Step 06 : Introduction to BDD. Given When Then. BDD Mockito Syntax.
Step 07 : How to verify calls on a mock? Verify how many times a method is called. We will add deleteTodo method to the TodoService.
Step 08 : How to capture an argument which is passed to a mock?
Step 09 : Hamcrest Matchers.
Step 10 : Let's simplify things with Mockito Annotations. @Mock, @InjectMocks, @RunWith(MockitoJUnitRunner.class), @Captor
Step 11 : JUnit Rules. Using MockitoJUnit.rule() instead of @RunWith(MockitoJUnitRunner.class).
Step 12 : Real world Example with Spring
Step 13 : What is a spy? How to spy with Mockito?
Step 14 : Some Theory : Why does Mockito not allow stubbing final and private methods?
Step 15 : Using PowerMock and Mockito to mock a Static Method.
Step 16 : Using PowerMock and Mockito to invoke a private Method.
Step 17 : Using PowerMock and Mockito to mock a constructor.
Step 18 : Good Unit Tests.
JUnit
Step 01 : Need for Unit Testing
Step 02 : Setting up your First JUnit
Step 03 : First Successful JUnit. Green Bar and assertEquals
Step 04 : Refactoring Your First JUnit Test
Step 05 : Second JUnit Example assertTrue and assertFalse
Step 06 : @Before @After
Step 07 : @BeforeClass @AfterClass
Step 08 : Comparing Arrays in JUnit Tests
Step 09 : Testing Exceptions in JUnit Tests
Step 10 : Testing Performance in JUnit Tests
Step 11 : Parameterized Tests
Step 12 : Organize JUnits into Suites
The document discusses XML and DTDs. It defines DTDs as describing the components and guidelines in an XML document by listing elements, attributes and their possible values, entities, and their interactions. It provides examples of element declarations in DTDs using tags like ELEMENT, EMPTY, ANY, and content models. It also distinguishes between internal and external DTDs and when each is generally used.
About Spring in pictures.
Spring is the most popular application development framework for enterprise Java. Millions of developers around the world use Spring Framework to create high performing, easily testable, reusable code.
Spring framework is an open source Java platform and it was initially written by Rod Johnson and was first released under the Apache 2.0 license in June 2003.
Spring is lightweight when it comes to size and transparency. The basic version of spring framework is around 2MB.
The document discusses unit testing methods like stubbing and mocking. It introduces Mockito, a mocking framework that makes creating mock objects easier. Mockito allows generating mock objects, setting mock behavior using matchers, and verifying mock interactions. It also discusses partial mocking with spies and cautions against over-specifying mock behavior, which can lead to brittle tests. PowerMock is introduced as an extension to Mockito that enables mocking additional constructs like static methods.
Лекция 12. Быстрее, Python, ещё быстрее.Roman Brovko
Измерение времени работы кода на Python с помощью модулей timeit, cProfile и line_profiler. Немного о NumPy. JIT и AOT компиляция кода на Python на примере Numba и Cython.
Синтаксис объявления классов. Атрибуты, связанные и несвязанные методы, __dict__, __slots__. Статические методы и методы класса. Свойства, декоратор @property. Наследование, перегрузка методов и функция super. Декораторы классов. Магические методы.
Модули threading, queue и concurrent.futures. Использование потоков для параллельных вычислений на Python. GIL. Параллельность и конкурентность. Модуль asyncio. Модуль multiprocessing.
Olexandra Dmytrenko
QA Automating at EPAM Systems
I'll show you how to switch from writing standard code using good old Java7 into writing it using functional way presented in Java8. The training is counted on beginners in the subject who like discovering the new horizons or for those who want to become more firm in using the new lambda features.
Зачем тестировать? Тестирование в интерпретаторе и доктесты. Модуль unittest. Пакет py.test - на порядок лучше. Тестирование свойств и пакет hypothesis.
The document provides an introduction to XML, explaining that it is a text-based markup language used for data interchange on the web. XML tags identify and label pieces of data, rather than specifying how to display it like HTML tags. Tags can also include attributes to provide additional information. The document gives an example of XML markup for a messaging application to demonstrate how hierarchical data can be represented using nested tags.
Writing great unit tests distinguishes good programmers from great programmers. In this course, you will learn how to write great unit tests with Mockito and JUnit. You take 12 steps with JUnit and 18 steps with Mockito into unit testing proficiency.
Mockito
Step 01 : Set up an Eclipse Project with JUnit and Mockito frameworks. First Green Bar.
Step 02 : Example to start understanding why we need mocks.
Step 03 : What is a stub? Create an unit test using Stub? Disadvantages of Stubs.
Step 04 : Your first Mockito code! Hurrah!!! Lets use Mockito to mock TodoService.
Step 05 : Stubbing variations with Mockito. A few mockito examples mocking List class : Multiple return values, Argument Matchers and throwing exceptions.
Step 06 : Introduction to BDD. Given When Then. BDD Mockito Syntax.
Step 07 : How to verify calls on a mock? Verify how many times a method is called. We will add deleteTodo method to the TodoService.
Step 08 : How to capture an argument which is passed to a mock?
Step 09 : Hamcrest Matchers.
Step 10 : Let's simplify things with Mockito Annotations. @Mock, @InjectMocks, @RunWith(MockitoJUnitRunner.class), @Captor
Step 11 : JUnit Rules. Using MockitoJUnit.rule() instead of @RunWith(MockitoJUnitRunner.class).
Step 12 : Real world Example with Spring
Step 13 : What is a spy? How to spy with Mockito?
Step 14 : Some Theory : Why does Mockito not allow stubbing final and private methods?
Step 15 : Using PowerMock and Mockito to mock a Static Method.
Step 16 : Using PowerMock and Mockito to invoke a private Method.
Step 17 : Using PowerMock and Mockito to mock a constructor.
Step 18 : Good Unit Tests.
JUnit
Step 01 : Need for Unit Testing
Step 02 : Setting up your First JUnit
Step 03 : First Successful JUnit. Green Bar and assertEquals
Step 04 : Refactoring Your First JUnit Test
Step 05 : Second JUnit Example assertTrue and assertFalse
Step 06 : @Before @After
Step 07 : @BeforeClass @AfterClass
Step 08 : Comparing Arrays in JUnit Tests
Step 09 : Testing Exceptions in JUnit Tests
Step 10 : Testing Performance in JUnit Tests
Step 11 : Parameterized Tests
Step 12 : Organize JUnits into Suites
The document discusses XML and DTDs. It defines DTDs as describing the components and guidelines in an XML document by listing elements, attributes and their possible values, entities, and their interactions. It provides examples of element declarations in DTDs using tags like ELEMENT, EMPTY, ANY, and content models. It also distinguishes between internal and external DTDs and when each is generally used.
About Spring in pictures.
Spring is the most popular application development framework for enterprise Java. Millions of developers around the world use Spring Framework to create high performing, easily testable, reusable code.
Spring framework is an open source Java platform and it was initially written by Rod Johnson and was first released under the Apache 2.0 license in June 2003.
Spring is lightweight when it comes to size and transparency. The basic version of spring framework is around 2MB.
The document discusses unit testing methods like stubbing and mocking. It introduces Mockito, a mocking framework that makes creating mock objects easier. Mockito allows generating mock objects, setting mock behavior using matchers, and verifying mock interactions. It also discusses partial mocking with spies and cautions against over-specifying mock behavior, which can lead to brittle tests. PowerMock is introduced as an extension to Mockito that enables mocking additional constructs like static methods.
200 open source проектов спустя: опыт статического анализа исходного кодаAndrey Karpov
Одна из особенностей работы нашей команды — анализ большого количества различных программных проектов. Рассказывать о закрытых коммерческих проектах часто запрещает NDA, а вот об open source можно и нужно говорить. Какие ошибки допускают в open-source-проектах? Какой код более качественный — закрытый или открытый? Нужно ли придерживаться стандартов кодирования, или они давно устарели? Какие ошибки сложнее найти и исправить — сложные архитектурные или простые опечатки? Проанализировав за несколько лет сотни программных проектов от zlib до Chromium, мы готовы поделиться своим опытом и ответить на эти вопросы.
ЛЕКЦИЯ 5. Шаблоны многопоточного программирования
Курс "Параллельные вычислительные технологии" (ПВТ), весна 2015
Сибирский государственный университет телекоммуникаций и информатики
Пазников Алексей Александрович
к.т.н., доцент кафедры вычислительных систем СибГУТИ
http://cpct.sibsutis.ru/~apaznikov
Иван Пузыревский — Введение в асинхронное программированиеYandex
Доклад посвящен основам асинхронного программирования. Мы кратко обсудим историю вопроса: что такое асинхронность, где, почему и зачем она используется. Затем рассмотрим наиболее частые способы построения асинхронных интерфейсов: основанные на callback'ах и на future/promise. В ходе доклада выделим основные используемые концепции, посмотрим на их реализацию и примеры использования. А в конце поговорим о сложностях, которые часто встречаются в асинхронном программировании.
1. Консольный ввод-вывод
Байтовые и символьные потоки
Аналогично языку С++ ввод/вывод в
языке Java выполняется с
использованием потоков. Поток
ввода/вывода - это некоторый
условный канал, по которому
отсылаются и получаются данные.
В Java 2 реализованы 2 типа потоков: байтовые и символьные.
Байтовые потоки предоставляют удобные средства для
обработки, ввода и вывода байтов или других двоичных
объектов. Символьные потоки используются для обработки,
ввода и вывода символов или строк в кодировке Unicode.
Все классы для консольного I/O – пакет java.io: import java.io.*;
1
3. Консольный ввод-вывод
Байтовые потоки.
Абстрактный класс InputStream.
public abstract int read()
throws IOException
Читает 1 байт из вх. потока.
Результат в младшем байте.
public int read (byte[ ] b)
throws IOException
Читает послед-ть байт в
массив b[ ]. Возвращает колво прочитанных байт или -1.
public int read (byte[ ] b,
int off, int len) throws
IOException
Заполняет массив с
указанного байта, читает не
более len символов
public long skip (long n)
throws IOException
Пропускает n байт в потоке
int available ()
Возвращает кол-во
доступных байт в потоке.
void close ()
Закрывает поток ввода.
3
4. Консольный ввод-вывод
Байтовые потоки.
Класс FileInputStream.
FileInputStream(String name) throws FileNotFoundException
FileInputStream (File file) throws FileNotFoundException
В классе FileInputStream переопределяется большая часть
методов класса Input-Stream (в т.ч. абстрактный метод
read() ). Когда создается объект класса FileInputStream, он
одновременно с этим открывается для чтения.
4
5. Консольный ввод-вывод
Байтовые потоки.
Класс FileInputStream.
import java.io.*;
System.out.println("Still Available: " + fp.available());
System.out.println("Total Still Available: " + fp.available());
class FileInputTest
System.out.println("Skipping another 1/4: skip()");
System.out.println("Reading the next 1/4: read(b[ ])");
{public static void main(String args[ ]) throws Exception
fp.skip(size/4);
byte b[ ] = new byte[size/4];
{int size;
System.out.println("Still Available: " + fp.available());
if (fp.read(b) == -1)
InputStream fp = new FileInputStream("FileInputTest.java");
System.out.println("Reading 1/8 into the end of array");
{System.out.println("End of File"); }
sizeif=(f1.read(b, b.length-size/8, size/8) == -1)
fp.available();
for (int i=0; i < size/4; i++)
System.out.println("Total Available Bytes: " + size);
{System.out.println("End of File”); }
{System.out.print((char) b[i]); }
System.out.println("First 1/4Available: "read()");
System.out.println("Still of the file: + f1.available());
for (int i=0; i < }
fp.close(); size/4; i++)
{System.out.print((char) fp.read()); }
}
5
6. Консольный ввод-вывод
Байтовые потоки.
Класс ByteArrayInputStream.
ByteArrayInputStream – это реализация входного потока, в
котором в качестве источника используется массив типа
byte. У этого класса два конструктора, каждый из которых
в качестве первого параметра требует байтовый массив.
ByteArrayInputStream(byte array[ ])
ByteArrayInputStream(byte array[ ], int start, int numBytes)
6
7. Консольный ввод-вывод
Байтовые потоки.
Класс ByteArrayInputStream.
import java.io.*;
class ByteArrayTest
{public static void main(String args [ ]) throws IOException
{byte b[ ] = {0,1,2,3,4,5,6,7,8,9};
ByteArrayInputStream input1 =
new ByteArrayInputStream(b);
ByteArrayInputStream input2 =
new ByteArrayInputStream(b,0,3);
}
}
7
8. Консольный ввод-вывод
Байтовые потоки.
Абстрактный класс OutputStream.
public abstract void write (int
b) throws IOException
Записывает 1 байт в выходной
поток.
public void write (byte[ ] b)
throws IOException
Записывает в поток массив байт
public void write (byte[ ] b, int
off, int len)
throws IOException
Записывает часть массива в
поток (len элементов начиная с
элемента off)
public void flush()
throws IOException
Немедленно выталкивает из
буфера в поток все что накоплено
в буфере.
public void close()
throws IOException
Закрывает поток.
8
9. Консольный ввод-вывод
Байтовые потоки.
Класс FileOutputStream.
Класс FileOutputStream можно применять для записи байтов в
файл. У класса FileOutputStream есть 3 конструктора:
FileOutputStream (String filePath) throws FileNotFoundException
FileOutputStream (File fileObj) throws FileNotFoundException
FileOutputStream (String filePath, boolean append)
throws FileNotFoundException
- filePath – полное имя файла,
- fileObj – объект типа File, который описывает файл
- append (=true – добавление информации в существующий файл)
9
10. Консольный ввод-вывод
Байтовые потоки.
Класс FileOutputStream.
try
{FileInputStream Source = new FileInputStream("infile.dat");
FileOutputStream Dest = new FileOutputStream("outfile.dat");
int c;
while ((c = Source.read()) != -1)
{Dest.write(c); }
}
catch (FileNotFoundException ex)
{… }
finally
{Source.close(); Dest.close(); }
10
11. Консольный ввод-вывод
Байтовые потоки.
Класс ByteArrayOutputStream.
ByteArrayOutputStream( ); - 32 байта
ByteArrayOutputStream(int numBytes);
Метод, записывающий содержимое одного потока в другой:
public void writeTo(OutputStream out) throws IOException
byte buf [ ] = {‘a’,’b’,’c’,’d’};
ByteArrayOutputStream b = new ByteArrayOutputStream();
b.write(buf);
FileOutputStream f = new FileOutputStream(“result.txt”);
b.writeTo(f);
11
12. Консольный ввод-вывод
Символьные потоки.
В Java символы хранятся в кодировке Unicode.
Символьный поток I/O автоматически транслирует
Символы между форматом Unicode и локальной
кодировкой, пользовательского ПК.
12
14. Консольный ввод-вывод
Символьные потоки.
Методы классов Reader и Writer аналогичны методам
классов InputStream и OutputStream с той разницей,
что все аргументы типа byte заменены на аргументы
типа char.
Классы CharArrayReader и CharArrayWriter
соответствуют классам ByteArrayInputStream и
ByteArrayOutputStream с той же разницей.
Классы FileReader и FileWriter являются символьными
версиями потоковых классов FileInputStream и
FileOutputStream.
14
15. Консольный ввод-вывод
Символьные потоки.
Классы InputStreamReader и OutputStreamWriter –
переходники между байтовыми и символьными
потоками. Байтовый поток используется для
физического ввода-вывода, а символьный поток
преобразует байты в символы с учетом
кодировки.
InputStreamReader (InputStream obj)
OutputStreamWriter (OutputStream out)
15
16. Консольный ввод-вывод
Буферизованный ввод-вывод.
В библиотеке Java имеются также буферизованные потоки I/O.
Для буферизованных потоков операции чтения и записи
происходят с буфером, находящимся в памяти.
Когда буфер пуст выполняется реальная операция чтения из
потока, когда буфер полон – реальная операция записи в поток.
Буферизация может быть добавлена к любому байтовому либо
символьному потоку с помощью специальных классов
«оболочек» (“wrappers”). При этом конструктору
буферизованного потока передается не буферизованный поток.
16
18. Консольный ввод-вывод
Пример организации консольного
ввода-вывода
В пакете java.lang есть класс с именем System.
В классе System определены три переменные:
public static InputStream in;
public static PrintStream out;
public static PrintStream err;
System.out и System.err – байтовые потоки, эмулирующие
поддержку локального character set !
System.in – байтовый поток !
18
19. Консольный ввод-вывод
Пример организации консольного
ввода
int a;
String str;
BufferedReader br =
= new BufferedReader( new InputStreamReader( System.in ) );
Буферизованный
Символьный поток
Байтовый поток
поток ввода
ввода
ввода
str = br.readLine();
a = Integer.parseInt(str);
19
20. Консольный ввод-вывод
Пример организации консольного
вывода
Класс PrintStream содержит методы print()
и println() для всех базовых типов данных.
Т.о. для консольного вывода надо вызвать System.out.print()
или System.out.println()
System.out.println (“Значение а = ” +а);
System.out.print (str);
20
21. Консольный ввод-вывод
Класс Scanner начиная с JSDK 1.5
import java.util.Scanner;
…
Scanner sc = new Scanner(System.in);
…
System.out.println(“Input a:”);
int a = sc.nextInt();
System.out.println(“Input str:”);
String str = sc.next();
Подробнее см.
http://docs.oracle.com/javase/1.5.0/docs/api/index.html?java/util/Scanner.html
21
22. Консольный ввод-вывод
Класс File
Класс File представляет имя файла, но не
сам файл (если файл не существует, он не
создается, если существует с ним можно
проводить производить операции через
объект File) !
Конструкторы:
public File(String pathname)
public File(String pathname, String filename)
public File (File parent, String child)
22
23. Консольный ввод-вывод
Класс File
public boolean exists()
Существует ли файл?
public boolean canRead()
Возможен ли доступ на чтение?
public boolean canWrite()
Возможен ли доступ на запись
public boolean isHidden()
Является ли файл скрытым?
public boolean isFile()
Файл?
public boolean isDirectory()
Каталог?
public boolean delete()
Удаляет файл, если он
существует. Каталог удаляется
только если он пуст.
public String[ ] list()
Возвращает список файлов в
каталоге
23
24. Консольный ввод-вывод
Класс File
public boolean mkdir()
Создает пустой каталог
public boolean renameTo
(File newName)
Переименование файла
public boolean setReadOnly()
Устанавливает атрибут ReadOnly
24
25. Сериализация в Java
Что такое сериализация?
Сериализация это процесс сохранения
состояния объекта в последовательность
байт;
десериализация это процесс восстановления
объекта из этих байт. Java Serialization API
предоставляет стандартный механизм для
создания сериализуемых объектов.
25
26. Сериализация в Java
Для чего нужна сериализация?
В Java всё представлено в виде объектов.
Если двум компонентам Java необходимо
общаться друг с другом, то им необходим
механизм для обмена данными.
Следовательно, должен быть универсальный
и эффективный протокол передачи объектов
между компонентами. Сериализация создана
для этого, и компоненты Java используют этот
протокол для передачи объектов.
26
27. Сериализация в Java
3 механизма сериализации
Сериализация
1) используя протокол по
умолчанию
2) модифицируя протокол по
умолчанию
3) создавая свой собственный
протокол
27
28. Сериализация в Java
1) Протокол по умолчанию
Чтобы объект стал сериализуемым,
необходимо, чтобы он реализовывал
интерфейс java.io.Serializable.
Интерфейс Serializable это интерфейсмаркер; в нём не задекларировано ни
одного метода. Но он говорит
сериализующему механизму, что класс
может быть сериализован.
28
29. Сериализация в Java
1) Протокол по умолчанию.
Сохранение объекта
import java.io.Serializable;
import java.util.Date;
import java.util.Calendar;
public class PersistentTime implements Serializable {
private Date time;
public PersistentTime() {
time = Calendar.getInstance().getTime();
}
public Date getTime() {
return time;
}
}
29
30. Сериализация в Java
1) Протокол по умолчанию.
Сохранение объекта
Для сохранения объекта как последовательности байт
используется класс java.io.ObjectOutputStream
Этот класс является фильтрующим потоком (filter
stream) - он окружает низкоуровневый поток байтов
(называемый узловым потоком (node stream)) и
предоставляет нам поток сериализации. Узловые
потоки могут быть использованы для записи в файловую
систему, сокеты и т.д. Это означает, что можно,
например,
передавать разложенные на байты объекты по сети и
затем восстанавливать их на других компьютерах!30
31. Сериализация в Java
1) Протокол по умолчанию.
Сохранение объекта
import java.io.ObjectOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class FlattenTime {
public static void main(String [] args) {
String filename = "time.ser";
PersistentTime time = new PersistentTime();
FileOutputStream fos = null;
ObjectOutputStream out = null;
31
32. Сериализация в Java
1) Протокол по умолчанию.
Сохранение объекта
try {
fos = new FileOutputStream(filename);
out = new ObjectOutputStream(fos);
out.writeObject(time);
//сериализация
out.close();
}
catch(IOException ex) {
ex.printStackTrace();
}
}
}
32
33. Сериализация в Java
1) Протокол по умолчанию.
Восстановление объекта
Для восстановления объекта используется метод
readObject() класса java.io.ObjectInputStream. Метод
считывает последовательность байтов и создает объект,
полностью повторяющий оригинал. Поскольку readObject()
может считывать любой сериализуемый объект,
необходимо его присвоение соответствующему типу. Т.о.,
из
системы, в которой происходит восстановление объекта,
должен быть доступен файл класса. Т.е. при сериализации
не сохраняется ни файл класса объекта, ни его методы,
сохраняется лишь состояние объекта.
33
34. Сериализация в Java
1) Протокол по умолчанию.
Восстановление объекта
import java.io.ObjectInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Calendar;
public class InflateTime {
public static void main(String [] args) {
String filename = "time.ser";
PersistentTime time = null;
FileInputStream fis = null;
ObjectInputStream in = null;
34
35. Сериализация в Java
1) Протокол по умолчанию.
Восстановление объекта
try {
fis = new FileInputStream(filename);
in = new ObjectInputStream(fis);
time = (PersistentTime)in.readObject(); //десериализация
in.close();
}
catch(IOException ex) {
ex.printStackTrace();
}
catch(ClassNotFoundException ex) {
ex.printStackTrace();
}
35
36. Сериализация в Java
1) Протокол по умолчанию.
Восстановление объекта
// распечатать восстановленное время
System.out.println("Время сохранения: " + time.getTime());
System.out.println();
// распечатать текущее время
System.out.println("Текущее время: " +
Calendar.getInstance().getTime());
}
}
36
37. Сериализация в Java
1) Протокол по умолчанию.
Ограничения сериализации
1) Если в состав сериализуемого класса A входит поле класса
B, то класс B тоже должен быть сериализуемым. Иначе в
процессе сериализации возникнет исключение
NotSerializableException .
2) В процессе сериализации/ десериализации не участвуют
статические поля класса, поскольку они фактически
являются не полями объектов (экземпляров класса), а
полями класса в целом.
3) Влияние наследования на сериализацию. Пусть класс A
объявлен, как сериализуемый. От него унаследован класс
B, для которого не указано implements Serializable . От B
порожден класс C - сериализуемый. Тогда при
сериализации будут сохранены все поля классов A и C , но
не B .
37
38. Сериализация в Java
1) Протокол по умолчанию.
Несериализуемые поля
Класс java.lang.Object не реализует Serializable,
поэтому не все объекты Java могут быть
автоматически сохранены.
Например, некоторые системные классы, такие
как Thread, OutputStream и его подклассы, и
Socket - не сериализуемые.
Причина: сериализация таких классов
бессмысленна.
38
39. Сериализация в Java
1) Протокол по умолчанию.
Несериализуемые поля
Проблема: есть класс, который содержит
экземпляр Thread? Можем ли мы в этом случае
сохранить объект такого типа?
Решение: мы имеем возможность сообщить
механизму сериализации о своих намерениях,
пометив объект Thread нашего класса как
несохраняемый - transient.
39
40. Сериализация в Java
1) Протокол по умолчанию.
Несериализуемые поля
import java.io.Serializable;
public class PersistentAnimation implements Serializable, Runnable {
transient private Thread animator;
private int animationSpeed;
public PersistentAnimation(int animationSpeed) {
this.animationSpeed = animationSpeed;
animator = new Thread(this);
animator.start();
}
public void run() { … }
}
40
41. Сериализация в Java
2) Модификация протокола по
умолчанию.
Проблема: как перезапустить анимацию?
Когда мы создаем объект при помощи new,
конструктор объекта вызывается только при
создании нового экземпляра. Читая объект
методом readObject() мы не создаем нового
экземпляра, мы просто восстанавливаем
сохраненный объект. В результате
анимационный поток запустится лишь
однажды, при первом создании экземпляра этого
объекта.
41
42. Сериализация в Java
2) Модификация протокола по
умолчанию.
Решение:
private void writeObject(ObjectOutputStream out)
throws IOException;
private void readObject(ObjectInputStream in)
throws IOException, ClassNotFoundException;
Виртуальная машина при вызове
соответствующего метода автоматически
проверяет, не были ли они объявлены в классе
объекта.
42
43. Сериализация в Java
2) Модификация протокола по
умолчанию.
import java.io.Serializable;
public class PersistentAnimation implements Serializable, Runnable {
transient private Thread animator;
private int animationSpeed;
public PersistentAnimation(int animationSpeed) {
this.animationSpeed = animationSpeed;
startAnimation();
}
public void run() { … }
43
44. Сериализация в Java
2) Модификация протокола по
умолчанию.
private void startAnimation() {
animator = new Thread(this);
animator.start();
}
private void writeObject(ObjectOutputStream out) throws IOException {
out.defaultWriteObject(); //мы не меняем нормальный процесс
}
private void readObject(ObjectInputStream in) throws IOException,
ClassNotFoundException {
in.defaultReadObject();
//мы лишь дополняем его
startAnimation();
}
44
45. Сериализация в Java
2) Модификация протокола по
умолчанию. Запрет сериализации для
класса.
Проблема:
class A implements Serializable {
…
}
class B extends A {
…
}
Как запретить сериализацию для класса В?
45
46. Сериализация в Java
2) Модификация протокола по
умолчанию. Запрет сериализации для
класса.
Решение:
private void writeObject(ObjectOutputStream out) throws IOException
{
throw new NotSerializableException(“Non serializable class!");
}
private void readObject(ObjectInputStream in) throws IOException
{
throw new NotSerializableException (“Non serializable class!");
}
46
47. Сериализация в Java
3) Создание собственного протокола
Вместо реализации интерфейса Serializable, можно
реализовать интерфейс Externalizable, который содержит
два метода:
public void writeExternal(ObjectOutput out) throws
IOException;
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException;
Для создания собственного протокола надо переопределить
эти методы. Здесь ничего не делается автоматически.
Это наиболее сложный, но и наиболее контролируемый
способ.
47
48. Сериализация в Java
Кэширование объектов в потоке
Проблема: Рассмотрим ситуацию, когда объект
однажды уже записанный в поток, спустя какое-то
время записывается в него снова. По умолчанию,
ObjectOutputStream сохраняет ссылки на объекты,
которые в него записываются. Это означает, что
если состояние записываемого объекта,
который уже был записан, будет записано снова,
новое состояние не сохраняется!
48
49. Сериализация в Java
Кэширование объектов в потоке
ObjectOutputStream out = new ObjectOutputStream(...);
MyObject obj = new MyObject(); // должен быть Serializable
obj.setState(100);
out.writeObject(obj); // сохраняет объект с состоянием = 100
obj.setState(200);
out.writeObject(obj); // не сохраняет новое состояние объекта
49
50. Сериализация в Java
Кэширование объектов в потоке
Решение:
1) Можно каждый раз после вызова метода записи
убеждаться в том, что поток закрыт;
2) Можно вызвать метод
objectOutputStream.reset(), который
сигнализирует потоку о том, что необходимо
освободить кэш от ссылок, которые он хранит,
чтобы новые вызовы методов записи
действительно записывали данные. Будьте
осторожны, reset очищает весь кэш объекта,
поэтому все ранее записанные объекты могут
быть перезаписаны заново.
50
51. Сериализация в Java
Производительность
Сериализация « по умолчанию» является
«медленной» операцией. Она в среднем в 2 – 2,5
раза медленнее записи в поток стандартными
средствами ввода-вывода.
Кроме того, так как ссылки на объекты кэшируются
в поток вывода, система не может выполнять сбор
мусора для записанных в поток объектов если
поток не был закрыт. Лучшее решение (как всегда
при помощи операций ввода/вывода) - это как
можно скорее закрывать потоки после выполнения
записи.
51