Федеральное агентство связи ФЕДЕРАЛЬНОЕ ГОСУДАРСТВЕННОЕ БЮДЖЕТНОЕ
ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ ВЫСШЕГО ОБРАЗОВАНИЯ «САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ ТЕЛЕКОММУНИКАЦИЙ ИМ. ПРОФ. М. А. БОНЧ-БРУЕВИЧА» (СПбГУТ)
Факультет инфокоммуникационных сетей и систем Кафедра программной инженерии и вычислительной техники
ЛАБОРАТОРНАЯ РАБОТА №9
по дисциплине «Разработка Java-приложений управления телекоммуникациями»
Выполнил: студент 3-го курса дневного отделения группы ИКПИ-85
Коваленко Леонид Александрович Преподаватель:
доцент кафедры ПИиВТ Белая Татьяна Иоанновна
Санкт-Петербург
2020
Цель работы Ознакомиться с возможностями механизма рефлексии и
нововведениями Java 1.5.
Ход работы
Задание №0.
Классы Array и CircularLinkedList уже содержат конструкторы, в которых указывается длина вектора (элементы при этом заполняются значениями по умолчанию — нулями), поэтому это задание выполнено.
Задание №1.
Задача: изменить реализации некоторых классов в пакете так, чтобы они стали вложенными — в простом варианте решается рассмотрением подхода стандартных библиотек.
Например, возьмем java.util.ArrayList для рассмотрения. Он содержит следующие вложенные классы:
1. ArrayListSpliterator — класс для разделения элементов списка. Не проходили, смотрим дальше.
2. SubList — класс части списка. Грубо говоря, подсписок списка с «указателем» (дополнительная память не выделяется). Т. е. изменение списка отражается на SubList и обратно. Не проходили, смотрим дальше.
3. ListItr — итератор по списку с реализованным методом remove(), также стандартные методы итератора, также методы для перемещения в обратном направлении. Проходили, смотрим дальше.
4. Itr — итератор по списку с реализованным методом remove(), также стандартные методы итератора, но без методов для перемещения по списку в обратном направлении.
Обращая внимания на эти классы, можно сделать следующие выводы:
1.Итераторы проходили, поэтому их можно вложить в класс списка и класс массива (что нами было сделано ещё в работе №5).
2.Unmodifiable и Synchronized никуда не вкладываем, т. к. в стандартной
библиотеке Java они вынесены в Collections: Collections.unmodifiableList и Collections.synchronizedList.
2
Задание №2.
В классе Vectors перегрузим фабричный метод createInstance, чтобы он кроме длины вектора получал ссылку типа IVector, по которой средствами рефлексии определял реальный класс объекта, находил в нем конструктор и создавал объект не средствами фабрики, а средствами рефлексии и того же класса, что и переданный параметр. Если конструктор с единственным параметром типа int отсутствует, то будем использовать фабрику (вызывать предыдущую версию метода).
Заменим вызовы createInstance на вызовы новой версии так, чтобы создавались объекты того же типа, что и первый операнд операции.
Код приведен в табл. 1.
Таблица 1 — Код vectors/Vectors.java package vectors;
import java.io.IOException; import java.io.Writer; import java.io.Reader; import java.io.InputStream; import java.io.OutputStream;
import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.PrintWriter; import java.io.StreamTokenizer;
import java.lang.reflect.Constructor;
public class Vectors {
// Умножение вектора на число
public static IVector mul(IVector array, double number) { int size = array.size();
IVector r = createInstance(size, array); try {
for (int i = 0; i < size; ++i) { r.set(i, array.get(i) * number);
}
}
catch(Exception e) { System.out.println(e.getMessage());
}
return r;
}
// Сложение двух векторов
public static IVector sum(IVector array, IVector arg) throws IncompatibleVectorSizesException {
int size = array.size(); if (size != arg.size()) {
throw new IncompatibleVectorSizesException("IncompatibleVectorSizesException", array.size(), arg.size());
}
IVector r = createInstance(size, array); try{
3
for (int i = 0; i < size; ++i) { r.set(i, array.get(i) + arg.get(i));
}
}
catch(Exception e) { System.out.println(e.getMessage());
}
return r;
}
// Скалярное произведение двух векторов
public static double mul(IVector array, IVector arg) throws IncompatibleVectorSizesException {
int size = array.size(); if (size != arg.size()) {
throw new IncompatibleVectorSizesException("IncompatibleVectorSizesException", array.size(), arg.size());
}
double r = 0; try {
for (int i = 0; i < size; ++i) {
r += array.get(i) * arg.get(i);
}
}
catch(Exception e) {
System.out.println(e.getMessage());
}
return r;
}
// Метод записи вектора в байтовый поток
public static void outputVector(IVector v, OutputStream out) throws IOException {
DataOutputStream dos = new DataOutputStream(out); int len = v.size();
dos.writeInt(len); try{
for (int i = 0; i < len; ++i) { dos.writeDouble(v.get(i));
}
}
catch(Exception e) { System.out.println(e.getMessage());
}
dos.flush();
}
// Метод чтения вектора из байтового потока
public static IVector inputVector(InputStream in) throws IOException { DataInputStream dis = new DataInputStream(in);
int len = dis.readInt();
IVector result = createInstance(len); try {
for (int i = 0; i < len; ++i) { result.set(i, dis.readDouble());
}
}
catch(Exception e) { System.out.println(e.getMessage());
}
return result;
}
// Метод записи вектора в символьный поток
4
public static void writeVector(IVector v, Writer out) throws IOException
{
PrintWriter pw = new PrintWriter(out); int len = v.size();
pw.print(len); try{
for (int i = 0; i < len; ++i) { pw.print(' '); pw.print(v.get(i));
}
}
catch(Exception e) { System.out.println(e.getMessage());
}
pw.flush();
}
// Метод чтения вектора из символьного потока
public static IVector readVector(Reader in) throws IOException { StreamTokenizer token = new StreamTokenizer(in);
int t = token.nextToken();
IVector v = createInstance((t != StreamTokenizer.TT_EOF) ? (int) token.nval : 0);
t = token.nextToken(); try {
for (int i = 0; t != StreamTokenizer.TT_EOF; ++i, t = token.nextToken()) {
if (t == StreamTokenizer.TT_NUMBER) { v.set(i, token.nval);
}
}
}
catch(Exception e) { System.out.println(e.getMessage());
}
return v;
}
// Метод установки фабрики векторов
public static void setVectorFactory(VectorFactory arg) { factory = arg;
}
//Метод создания вектора фабрики векторов public static IVector createInstance(int n) {
return factory.createVector(n);
}
//Перегруженный метод создания вектора фабрики векторов public static IVector createInstance(int n, IVector vector) {
try { return
vector.getClass().getConstructor(int.class).newInstance(n); } catch (Exception e) {
e.printStackTrace();
return Vectors.createInstance(n);
}
}
// Метод, возвращающий неизменяемый вектор
public static IVector unmodifiableVector(IVector vector) { return new UnmodifiableVector(vector);
}
// Метод, возвращающий безопасный с точки зрения многопоточности вектор
5
public static IVector concurrentVector(IVector vector) { return new ConcurrentVector(vector);
}
// Ссылка на текущую фабрику векторов
private static VectorFactory factory = new ArrayFactory();
}
Создадим файл FactoryTest.java для проверки работы рефлексии и фабрики векторов (табл. 2).
Таблица 2 — Файл FactoryTest.java
import vectors.Vectors; import vectors.Array;
import vectors.CircularLinkedList; import vectors.CircularLinkedListFactory;
public class FactoryTest {
public static void main(String[] args) throws Exception { System.out.println("By default. ArrayFactory?: " +
(Vectors.createInstance(10) instanceof Array));
System.out.println("By default. CircularLinkedListFactory?: " + (Vectors.createInstance(10) instanceof CircularLinkedList));
Vectors.setVectorFactory(new CircularLinkedListFactory()); System.out.println("After change. ArrayFactory?: " +
(Vectors.createInstance(10) instanceof Array)); System.out.println("After change. CircularLinkedListFactory?: " +
(Vectors.createInstance(10) instanceof CircularLinkedList)); Array array = new Array(5);
array.set(0, 1); array.set(1, 2); array.set(2, 3); array.set(3, 4); array.set(4, 5);
System.out.println("Type(Array * Array) is Array?: " + (Vectors.createInstance(5, Vectors.sum(array, array)) instanceof Array));
CircularLinkedList list = new CircularLinkedList(5); list.set(0, 1);
list.set(1, 2); list.set(2, 3); list.set(3, 4); list.set(4, 5);
System.out.println("Type(List * List) is List?: " + (Vectors.createInstance(5, Vectors.sum(list, list)) instanceof CircularLinkedList));
}
}
Результат компиляции и запуска приведен на рис. 1.
Рисунок 1 — Компиляция и запуск FactoryTest.java
6