B04 Исключения. Потоки. Массивы.ppt
- Количество слайдов: 21
1 Java for Beginners 4. Исключения. Потоки. Параметризация классов. Массивы.
Интерфейсы n n n n 2 Интерфейс – аналог полностью абстрактного типа, позволяющий описать схожее поведение у неродственных типов. Интерфейс позволяет смоделировать эффект множественного наследования, не порождая связанных с таким наследованием проблем. Определение интерфейса может содержать только заголовки методов (без их реализации) и константы (т. е. поля public static final, но явно указывать эти модификаторы не обязательно). Все методы интерфейса являются public abstract без специального объявления. Любой тип может расширять (extends) только один тип-предок, но может реализовать (implements) любое число интерфейсов. Интерфейс может расширять (extends) любое число интерфейсов более высокого уровня. Если тип реализует интерфейс, он либо должен содержать реализации всех методов интерфейса, либо должен быть объявлен как abstract (предполагая, что оставшиеся методы интерфейса будут реализованы в подклассах). Можно объявить переменную интерфейсного типа, присвоить ей объект любого класса, реализующего данный интерфейс, но использовать только те методы, которые объявлены в интерфейсе.
3 Интерфейсы пример определения и использования interface Directions { int RIGHT=1; int LEFT=2; int UP=3; int DOWN=4; } interface Moveable { void move(Directions where, int how. Long); } class Point implements Moveable { private int x, y; public void move(Directions where, int how. Long) { . . } class Planet extends Body implements Moveable { private double r, alpha, theta; public void move(Directions where, int how. Long) { . . Moveable body = new Planet();
4 Классы исключений n Исключения в Java являются объектами с собственной иерархией классов: Throwable Exception Runtime. Exception n Error - прочие классы исключений Класс Error включает серьезные ошибки выполнения, которые должны приводить к завершению программы и, как правило, не должны перехватываться. Класс Runtime. Exception – менее серьезные ошибки (например, деление на ноль), которые можно перехватить и обработать. Эти два класса (и их потомки) называются непроверяемыми исключениями (невозможно предсказать, в каких методах они могут возникнуть). Остальные классы являются проверяемыми, и программист обязан указать в объявлении метода, какие прерывания в нем могут возникнуть.
5 Структурная обработка исключений n Общая структура блока обработки исключений (примерно одинаковая для большинства современных языков): try { Нормальные операторы, при выполнении которых может возникнуть исключение; } catch (Тип_исключения имя) { Анализ и обработка исключения. Возможно, возбуждает (throw) другое исключение, более точно указывая его причину. } catch (Другой_тип_исключения имя) { . . . } finally { Операторы которые должны быть выполнены при выходе из блока в любом случае, было исключение или не было. } В заголовке метода должен быть список всех типов проверяемых исключений, которые могут возникнуть при выполнении метода или быть переданы с нижнего уровня. public My. Method(параметры) throws My. Exception {. . . } n
6 Структурная обработка исключений n При вызове метода, содержащего список исключений throws, в вызывающем методе для каждого типа исключений может быть сделано одно из трех действий: ¨ обработать исключение через try-catch-finally, не допуская его выход на более высокий уровень; ¨ объявить это исключение в своем списке throws, не обрабатывая его (предполагается обработка на более высоком уровне); ¨ обработать исключение, возбудить на его основе исключение другого типа, объявив его в своем списке throws. n n Если ничего этого не сделано, может быть диагностирована ошибка компиляции метода. При возникновении исключения интерпретатор ищет соответствующий catch по стеку вызовов методов, начиная с нижнего уровня. Если обработчик не найден, Java выполняет обработку по умолчанию (что чаще всего подразумевает прекращение выполнения программы).
7 Класс java. io. File n public class File Служит для выполнения операций с файлом или каталогом как целым: создание, удаление, переименование, проверка/установка атрибутов, проверка существования, получение размера файла, получение списка файлов в каталоге и т. п. ¨ Конструкторы: по заданному пути, по двум путям (к родительскому каталогу и к потомку), по объекту File (описывающему каталог) и пути к потомку. ¨ Разделители пути зависят от используемой ОС. Для Windows это '\'. ¨ n Некоторые методы: boolean exists(), delete(), rename. To(File dest); boolean is. File(), is. Directory(), mkdir(); boolean create. New. File(); - создает новый файл, если файла с таким именем еще нет в каталоге; ¨ String[] list() - возвращает массив имен файлов (и подкаталогов) в данном каталоге. В конструкторе можно указать фильтр имен; ¨ File[] list. Files() - возвращает массив файлов в данном каталоге. ¨ ¨ ¨
8 Пример использования класса File n Программа выдает список всех файлов типа *. txt из каталога d: tmp. n Чтобы задать фильтр имен, нужен класс, реализующий метод accept интерфейса Filename. Filter. Можно не заводить отдельный класс для этого, а сделать это в основном классе приложения. public class List. Txt implements Filename. Filter{ public boolean accept(File dir, String name) { return name. ends. With(". txt"); } public static void main (String[] args) { File f = new File("d: \tmp"); Filename. Filter filter = new List. Txt(); String flist[] = f. list(filter); for (int i = 0; i < flist. length; i++) { System. out. println(flist[i]); } } }
9 Базовые классы потоков данных n n java. io. Input. Stream, java. io. Output. Stream – абстрактные методы ввода/вывода байтовых потоков, которые могут быть связаны с файлами, памятью, другими потоками и т. п. public abstract class Input. Stream : некоторые методы: public abstract int read() – чтение 1 байта с ожиданием; при EOF возвращает -1. ¨ public int read(byte[] b) – чтение в массив с ожиданием; возвращает число прочитанных байтов; при EOF возвращает -1, при отсутствии данных - 0. ¨ public long skip(long n) – пропуск n байтов. ¨ public void close(). ¨ n public abstract class Output. Stream : некоторые методы: public abstract void write(int b) – выводит в поток младший байт b. ¨ public void write(byte[] b) – выводит в поток все байты массива b. ¨ public void flush() – форсирует выдачу из буферов. ¨ public void close(). ¨ n n Методы могут генерировать исключения IOException. От этих абстрактных классов порождается сложная иерархия подклассов потоков ввода и вывода.
10 Некоторые подклассы потоков n public class File. Input. Stream, File. Output. Stream Служат для выполнения байт-ориентированных операций ввода/вывода с файлом. ¨ Конструкторы: по объекту File, по строке пути к файлу. ¨ Разделители пути зависят от используемой ОС. ¨ n public class Filter. Input. Stream, Filter. Output. Stream являются суперклассами для конкретных классов, обрабатывающих данные после ввода или перед выводом; ¨ конструируются на базе объектов Input. Stream, Output. Stream: конструктор Filter. Input. Stream(Input. Stream in) и аналогично для вывода. ¨ n public class Buffered. Input. Stream, Buffered. Output. Stream ¨ n подклассы Filter. . . Stream. Повышают эффективность работы с файлами за счет буферизации ввода/вывода public class Print. Stream ¨ подкласс Filter. Output. Stream. Содержит методы форматирования различных типов данных при выводе.
11 Пример: копирование файла n n Программа копирует файл, заданный первым параметром командной строки, в тот же каталог, присваивая копии имя, заданное вторым параметром. Методы работы с потоками могут возбуждать исключения ввода/вывода. Их следует хотя бы объявить в throws, а закрытие файлов вынести в finally. public class Copy. File { private static final int BUF_SIZE = 10000000; public static void main(String[] args) throws IOException { byte buf[] = new byte[BUF_SIZE]; File input. File = new File(args[0]); File output. File = new File(input. File. get. Parent(), args[1]); File. Input. Stream in = new File. Input. Stream(input. File); File. Output. Stream out = new File. Output. Stream(output. File); int c; try { while ((c = in. read(buf, 0, BUF_SIZE)) != -1) out. write(buf, 0, c); } finally { in. close(); out. close(); } } }
12 Классы java. io. Reader, java. io. Writer n n Отличаются от Input. Stream, Output. Stream тем, что ориентированы на ввод/вывод символов UNICODE, а не байтов, т. е. должны применяться при работе с текстовыми файлами. Например, для Input. Stream: abstract int read(); - возвращает один байт (0 -255 при удачном вводе, -1 если конец файла); ¨ int read(byte[] b, int off, int len); - читает байты в отрезок массива b, возвращает количество прочитанных байтов (-1 если конец файла). ¨ Для Reader: int read(); - возвращает один символ (-1 если конец файла); ¨ abstract int read(char[] cbuf, int off, int len); - читает символы в отрезок массива cbuf, возвращает количество прочитанных символов (-1 если конец файла). ¨ n Reader, Writer порождают иерархию классов, аналогичную иерархии Input. Stream, Output. Stream.
13 Стандартные ввод и вывод n System. in ¨ ¨ Стандартный поток ввода; Относится к классу Input. Stream, поэтому организовать форматированный ввод не так просто, например: Input. Stream. Reader is = new Input. Stream. Reader(System. in); Buffered. Reader input = new Buffered. Reader(is); String name. Str = input. read. Line(); Класс Input. Stream. Reader преобразует поток байтов в поток символов; ¨ Класс Buffered. Reader организует буферизованный ввод, что позволяет вводить сразу строку символов. ¨ n System. out, System. err ¨ ¨ n Стандартные потоки вывода и ошибок; Относятся к классу Print. Stream, поэтому позволяют выводить что угодно с автоматическим преобразованием в строку. Имеются методы перенаправления стандартных потоков: set. In(Input. Stream in); ¨ set. Out(Print. Stream out), set. Err(Print. Stream err). ¨
14 Пример использования System. in, System. out import java. io. *; public class Console. Input { public static void main(String[] args) throws IOException { Buffered. Reader data. In = new Buffered. Reader( new Input. Stream. Reader(System. in)); String name = ""; System. out. println("Введите ваше имя: "); name = data. In. read. Line(); System. out. println("Привет, " + name +"!"); } }
15 Произвольный доступ к файлам n public class java. io. Random. Access. File; Никак не связан с иерархиями потоков данных; Служит для выполнения операций произвольного доступа к файлу; ¨ Конструкторы: ¨ ¨ n n n Random. Access. File(File file, String mode); Random. Access. File(String name, String mode); Параметр mode – один из режимов "r", "rwd", "rws". ¨ ¨ n r – только чтение; rw – чтение и запись; rwd – каждое изменение данных немедленно пишется на диск; rws – каждое изменение данных или метаданных немедленно пишется на диск. Некоторые методы: ¨ ¨ ¨ чтение и запись различных типов данных (read, read. Boolean, read. Char, read. Double, read. Byte и т. п. ); seek(long pos); get. File. Pointer(); length(); set. Length(long new. Length);
16 Параметризованные типы n n Другие названия в литературе: "generics", "настраиваемые типы", "универсальные типы". Для работы с данными разных типов (например, для создания стека "чего угодно") можно обращаться к объектам класса Object. Но при этом возникают две проблемы: невозможно ограничить тип данных в конкретном случае (например, использовать стек только для int); ¨ для использования объектов нужно вручную выполнять приведение типов от Object к более конкретному. ¨ n n n Имеется возможность описывать классы, интерфейсы и методы, указывая в качестве параметра в угловых скобках тип данных. Это похоже на шаблоны в C++, но отличается по реализации. Информация о типе-параметре используется при компиляции Javaпрограммы (для проверок и приведения типов), но в компилированной программе вся эта информация стирается. Имеются ограничения на использование параметризованных типов, в частности: ¨ ¨ нельзя объявлять массивы настраиваемого типа; нельзя подставлять примитивные типы (int, double, …), но можно подставлять типы-обертки (Integer, Double, …).
17 Пример параметризованного класса n Описание класса: class Gen<T> { T obj; // Поле - объект типа Т Gen(T obj) { // Конструктор this. obj = obj; } T get. Obj() { // Возвратить объект: return obj; } void show. Type() { // Показать тип Т: System. out. println("Type of T is " + obj. get. Class(). get. Name()); } } n Использование класса: class Generic { public static void main(String[] args) { Gen<Integer> int. Var = new Gen<Integer>(100); Gen<String> str. Var = new Gen<String>("Hello!"); int. Var. show. Type(); System. out. println(int. Var. get. Obj()); str. Var. show. Type(); System. out. println(str. Var. get. Obj()); } }
18 Вспомогательный класс java. util. Arrays n n Содержит статические методы для копирования, сравнения, сортировки массивов, для быстрого (бинарного) поиска в сортированном массиве. Приведенные ниже методы (public static) перегружены для массивов всех примитивных типов. ¨ ¨ ¨ ¨ n int[] copy. Of(int[] arr, int new. Length) – копирование в новый массив; int[] copy. Of. Range(int[] arr, int from, int to) – копирование части массива; void fill(int[] arr, int value) – заполнение заданным значением; boolean equals(int[] arr 1, int[] arr 2) - сравнение содержимого двух массивов; String to. String(int[] arr) – преобразование в строку; void sort(int[] arr) – сортировка по возрастанию; int binary. Search(int[] arr, int key) – бинарный поиск в сортированном массиве. Пример: short[] my. Arr = {125, -15, 222, 221, 0, 1, -5, -10, 100, 98, 13, 98, 5}; Arrays. sort(my. Arr); short key = 98; int index = Arrays. binary. Search(my. Arr, key);
19 Интерфейс Comparable<T> n n Для сортировки и поиска в массивах произвольного типа необходимо придать смысл сравнению двух элементов этого типа. Для этого класс элементов должен реализовать интерфейс Comparable<T>, определяющий метод сравнения: ¨ int compare. To(T obj) – возвращает: n n отрицательное число при this < obj; 0 при this == obj; положительное число при this > obj. Тогда можно применять методы: public static void sort(Object[] a); ¨ public static int binary. Search(Object[] a, Object key); ¨
20 Пример использования Comparable<T> class Full. Name implements Comparable<Full. Name> { String first, last; Full. Name(String first, String last) {this. first = first; this. last = last; } public int compare. To(Full. Name obj) { if ((this. last. compare. To(obj. last)) < 0 || (this. last. equals(obj. last)) && (this. first. compare. To(obj. first) < 0)) return -1; if ((this. last. compare. To(obj. last)) > 0 || (this. last. equals(obj. last)) && (this. first. compare. To(obj. first) > 0)) return 1; return 0; } } class Search. Objects { public static void main(String[] args) { Full. Name[] my. Arr = {new Full. Name("Сергей", "Дроздов"), new Full. Name("Анна", "Никифорова"), new Full. Name("Валерий", "Хашковский")}; Arrays. sort(my. Arr); Full. Name key = new Full. Name("Анна", "Никифорова"); int index = Arrays. binary. Search(my. Arr, key); System. out. println(index); } }
21 Задания 1. Написать консольное приложение, которое читает строки текста из заданного файла (не более 1000 строк), сортирует строки по убыванию длины и выводит результат в другой заданный файл. 2. Написать консольное приложение, которое читает целые числа из файла (по одному числу в строке, всего не более 500 чисел), выводит количество введенных чисел, сортирует числа по убыванию, а затем в цикле запрашивает у пользователя порядковый номер числа и выводит соответствующее число. Работа завершается, когда пользователь вводит -1.
B04 Исключения. Потоки. Массивы.ppt