Глава 11 представила новую концепцию "рефлексии" в Java 1.1 и показала, как использовать эту концепцию для поиска методов в конкретном классе — либо полный список всех методов, либо его подмножество (имена которых совпадают с ключевыми словами, которые мы указали). Главное преимущество этого примера заключается в том, что он автоматически отображает все методы, не заставляя нас проходить через всю структуру наследования и проверять каждый базовый класс. Таким образом, это действительно эффективный инструмент для экономии времени программирования: поскольку большинство имён методов в Java составлено очень подробно и полно, этот подход позволяет эффективно находить методы, содержащие специальное ключевое слово. Если найдено имя, соответствующее требованиям, можно сразу же получить информацию о нём из онлайн-справочной системы.
Однако у того примера из главы 11 есть недостаток: он не использует AWT и является чистым приложением командной строки. Здесь мы создадим улучшенную версию с графическим интерфейсом пользователя (GUI), которая будет автоматически обновляться при наборе символов и позволит выполнять операции вырезания и вставки в результате поиска:```java //: DisplayMethods.java // Отображение методов любого класса внутри окна. // Динамическое уточнение поиска. import java.awt.; import java.awt.event.; import java.applet.Applet; import java.lang.reflect.Method; import java.io.IOException;
публичный класс DisplayMethods расширяет Applet {
Класс cl;
Метод[] m;
Конструктор[] ctor;
Строка[] n = новый Строка[0];
Поле ввода
имя = новый Поле ввода(40),
поиск_по = новый Поле ввода(30);
Чекбокс сброс =
новый Чекбокс("Сброс квалификаторов");
Область вывода результаты = новый Область вывода(40, 65);
публичный void инициализировать() {
сброс. установить_состояние(истинно);
имя. добавить_текстовый_слушатель(новый ИмяL());
поиск_по. добавить_текстовый_слушатель(новый Поиск_ПоL());
сброс. добавить_элементный_слушатель(новый СбросL());
Панель
верхняя = новый Панель(),
нижняя = новый Панель(),
п = новый Панель();
верхняя. добавить(новый Надпись("Законченное имя класса:"));
верхняя. добавить(имя);
нижняя. добавить(
новый Надпись("Строка для поиска:"));
нижняя. добавить(поиск_по);
нижняя. добавить(сброс);
п. установить_размещение(новый Горизонтальное_размещение());
п. добавить(верхняя, Горизонтальное_размещение. СЕВЕР);
п. добавить(нижняя, Горизонтальное_размещение. ЮГ);
установить_размещение(новый Горизонтальное_размещение());
добавить(п, Горизонтальное_размещение. СЕВЕР);
``` добавить(результаты, Горизонтальное_размещение.ЦЕНТР);
}
внутренний класс ИмяL реализует Текстовый_слушатель {
публичный void текстовое_значение_изменилось(Текстовое_событие e) {
Строка nm = имя.получить_текст().обрезать();
если(длина(nm) == 0) {
результаты.установить_текст("Нет совпадений");
n = новый Строка[0];
вернуть;
}
попробовать {
cl = Класс.для_названия(nm);
} захватить (Класс_не_найден_exception ex) {
результаты.установить_текст("Нет совпадений");
вернуть;
}
m = cl.получить_методы();
ctor = cl.получить_конструкторы();
// Преобразование в массив строк:
n = новый Строка[m.длина + ctor.длина];
для(int i = 0; i < m.длина; i++)
n[i] = m[i].получить_строку();
для(int i = 0; i < ctor.длина; i++)
n[i + m.длина] = ctor[i].получить_строку();
повторное_отображение();
}
}
void повторное_отображение() {
// Создание набора результатов:
Строка[] rs = новый Строка[n.длина];
Строка найти = поиск_по.получить_текст();
int j = 0;
// Выбор из списка, если найдено:
для (int i = 0; i < n.длина; i++) {
если(найти == null)
rs[j++] = n[i];
ещё если(n[i].индекс_нахождения(найти) != -1)
rs[j++] = n[i];
}
результаты.установить_текст("");
если(сброс.получить_состояние() == истинно)
для (int i = 0; i < j; i++)```markdown
результаты.append(
Стрип_квалификаторов.strip(rs[i]) + "\n");
ещё // Оставить квалификаторы
для (int i = 0; i < j; i++)
результаты.append(rs[i] + "\n");
}
внутренний класс СтрипL implements Элементный_слушатель {
```
```markdown
## Класс StripQualifiers
Класс `StripQualifiers` предназначен для работы с отформатированными строками и удалением лишних символов.
### Конструктор
```java
public StripQualifiers(String qualified) {
st = new StreamTokenizer(new StringReader(qualified));
st.ordinaryChar(' ');
}
```
Этот конструктор принимает строку `qualified`, которая затем передается в объект `StreamTokenizer`. Метод `ordinaryChar` используется для указания пробела как обычного символа.
```
Продолжение кода:
```java
public void itemStateChanged(ItemEvent e) {
reDisplay();
}
}
``````markdown
public void itemStateChanged(ItemEvent e) {
reDisplay();
}
}
класс SearchForL реализует TextListener {
public void textValueChanged(TextEvent e) {
reDisplay();
}
}
публичный статический void главный(строка[] аргументы) {
DisplayMethods апплет = новое DisplayMethods();
Frame aFrame = новое Frame("Display Methods");
aFrame.addWindowListener(
новое WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
aFrame.add(апплет, BorderLayout.CENTER);
aFrame.setSize(50 Yöntemler);
апплет.init();
апплет.start();
aFrame.setVisible(true);
}
}
```
Примечание: В данном контексте использована спецификация для перевода Java кода в русский язык, однако стоит отметить, что такой подход может быть неправильным с точки зрения программирования. Обычно код остается на английском языке даже при переводе всего документа на другой язык. Однако, если требуется строго следовать правилам перевода, как указано выше, то данный вариант будет корректным.```markdown
## Класс StripQualifiers
Класс `StripQualifiers` предназначен для работы с отформатированными строками и удалением лишних символов.
### Конструктор
```java
public StripQualifiers(String qualified) {
st = new StreamTokenizer(new StringReader(qualified));
st.ordinaryChar(' ');
}
```
Этот конструктор принимает строку `qualified`, которая затем передается в объект `StreamTokenizer`. Метод `ordinaryChar` используется для указания пробела как обычного символа.
```### Получение следующего значения
Метод `getNext()` позволяет получить следующее значение из потока:
```java
public String getNext() {
String s = null;
try {
if (st.nextToken() != StreamTokenizer.TT_EOF) {
switch (st.ttype) {
case StreamTokenizer.TT_EOL:
s = null;
break;
case StreamTokenizer.TT_NUMBER:
s = Double.toString(st.nval);
break;
case StreamTokenizer.TT_WORD:
s = new String(st.sval);
break;
default: // одиночный символ в ttype
s = String.valueOf((char) st.ttype);
}
}
} catch (IOException e) {
System.out.println(e);
}
return s;
}
```
### Удаление квалификаторов
Метод `strip` позволяет удалить квалификаторы из строки:
```java
public static String strip(String qualified) {
StripQualifiers sq = new StripQualifiers(合格的字符串);
String s = "", si;
while ((si = sq.getNext()) != null) {
int lastDot = si.lastIndexOf('.');
if (lastDot != -1)
si = si.substring(lastDot + 1);
s += si;
}
return s;
}
```
---
Программа использует класс `StripQualifiers` для удаления лишних квалификаторов из строки. Этот класс может использоваться как часть более крупной программы для очистки строковых данных.
```Для полноты перевода следует отметить, что данный текст является описанием класса `StripQualifiers` и его методов, а также контекста использования этого класса в программе. В данном случае, описание графического интерфейса пользователя (GUI) было пропущено, так как исходный текст не содержал такого описания. Пользователи заметят, что программа не использует никаких кнопок или других компонентов для запуска поиска. Это связано с тем, что как текстовые поля, так и флажки постоянно отслеживаются соответствующими объектами "слушателей" (`Listeners`). Любое изменение сразу приводит к обновлению списка результатов. При изменении значения в поле `name`, новое значение будет зафиксировано в классе `NameL`. Если это значение не пустое, то оно используется в методе `Class.forName()`, чтобы попытаться найти соответствующий класс. В процессе ввода текста имя может оказаться незаконченным, что вызывает ошибку в `Class.forName()`, которая "бросает" исключение. Исключение ловится, а `TextArea` устанавливается в состояние `Nomatch` (не совпадает). Однако при введении корректного имени (учитывая регистр букв) метод `Class.forName()` успешно выполняется, а методы `getMethods()` и `getConstructors()` возвращают массивы объектов типа `Method` и `Constructor`. Каждый объект этих массивов преобразуется в строку через метод `toString()` (что создает полную сигнатуру метода или конструктора), и два списка объединяются в массив `n` — самостоятельный массив строк.Этот массив `n` является частью класса `DisplayMethods`, и он используется для обновления отображения при вызове метода `reDisplay()`. Если были изменены компоненты `Checkbox` или `searchFor`, их "слушатели" просто вызывают метод `reDisplay()`. Метод `reDisplay()` создаёт временный массив, содержащий строку с названием `rs` (где `rs` означает "набор результатов" — `Result Set`). Набор результатов либо прямым образом копируется из `n` (если нет ключевого слова `find`), либо выбирается из строки `n`, содержащей ключевое слово `find`. В конце происходит проверка компонента `strip Checkbox`, чтобы узнать, хочет ли пользователь удалить лишние части имени (по умолчанию значение установлено как "да"). Если ответ положительный, то используется метод `StripQualifiers.strip()`, в противном случае список просто отображается.В методе `init()`, возможно, кажется, что требуется много работы при установлении макета. Однако фактическое размещение компонентов может потребовать минимальной работы. Преимущество использования `BorderLayout` заключается в том, что он позволяет пользователю менять размер окна, особенно увеличивая `TextArea` (текстовое поле). Это означает, что мы можем изменять размеры таким образом, чтобы не было необходимости прокручивать экран, чтобы видеть более длинные имена.
При программировании вы можете заметить, что особенно важно иметь этот инструмент запущенным, так как он предоставляет один из лучших способов понять, какой метод следует использовать.
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )