Когда я впервые начал изучать Java, мне было действительно сложно понять, что такое отражение.
Некоторые книги, даже очень классические, объясняют вещи таким образом, что люди чувствуют себя сбитыми с толку. Возможно, я слишком глуп.
Более того, в Интернете говорится, что механизм отражения придется часто использовать при изучении фреймворков в будущем, что всегда заставляет людей чувствовать себя немного неловко.
Я просто случайно посмотрел несколько глав и видеороликов, объясняющих отражение, и думаю, что могу понять это немного лучше.
Теперь я решил усердно работать, читать и писать одновременно, а также записывать здесь основное содержание и операции.
Я думаю, для такого глупого человека, как я, возможно, лучший способ научиться — это повторять.
Когда я сталкиваюсь с чем-то, чего не понимаю, я останавливаюсь и изучаю это заново. Хотя это отнимает много времени, это также оказывает на меня определенное влияние.
Насколько я понимаю, так называемое отражение предназначено для восстановления полной информации о классе на основе уже созданного объекта.
По крайней мере, для меня я думаю, что польза, которую это приносит, заключается в том, что это позволяет мне понять объектно-ориентированное понимание снизу вверх.
х_х Вот я снова ненавижу этих тупоголовых, они убили все клетки моего мозга.
Класс классЕсли вы хотите завершить отражение, вы должны понимать класс Class
Пример 1. Получение имени пакета и имени класса через объекткласс Тест {
}
публичный класс Демо {
public static void main(String[] args) {
Тест т = новый тест();
System.out.println(t.getClass());
System.out.println(t.getClass().getName());
}
}
Результаты компиляции следующие, просто обратите внимание на то, как компилируется пакет.
Метод getClass() здесь по умолчанию унаследован от класса Object.
В Java класс Object является родительским классом для всех классов. Аналогично, созданные объекты всех классов также являются экземплярами класса Class.
Следовательно, это будет включать в себя концепции восходящей трансформации и нисходящей трансформации.
Здесь также последуют дженерики из-за небезопасности нисходящих приведения.
(Но что я хочу сказать, так это то, что общий дизайн здесь очень великолепен! Блин, синтаксический дизайн всей Java тоже великолепен, супер-отвратителен!!!)
Пример 2: Создание экземпляра класса ClassПоскольку у класса Class нет конструктора, способ создания экземпляра класса Class немного особенный. Есть три способа:
Объект.getClass()}
публичный класс Демо {
public static void main(String[] args) {
//Метод 1:
Тест т = новый тест();
Класс <? расширяет тест> c1 = t.getClass();
System.out.println(c1);
//Метод 2:
//Во избежание специфичности здесь не используется класс Test, а используется класс String из java-библиотеки.
Класс<String> c2 = String.class;
System.out.println(c2);
//Метод 3:
//Метод forName() вызовет исключение
Класс<?> c3 = ноль;
пытаться {
c3 = Class.forName("Тест");
} catch (ClassNotFoundException e) {
е.printStackTrace();
}
System.out.println(c3);
}
}
В классе Class есть метод newInstance(), который можно использовать для создания нового экземпляра объекта класса Class.
Как это сказать? Содержимое объекта Class является отраженным классом. Нам нужно создать новый экземпляр (новый объект) этого класса.
Пример 3: Построение объекта без параметров класса Class //Генерируем ссылку на строку
Строка с = ноль;
пытаться {
//Переносим созданный объект в класс String
//Метод newInstance() выдаст исключение
s = (String) c.newInstance();
} catch (InstantiationException e) {
е.printStackTrace();
} catch (IllegalAccessException e) {
е.printStackTrace();
}
System.out.println("Длина строки: " + s.length());
}
}
При этом создается новый объект в форме без параметров, как и в обычном режиме.
Создание нового объекта с помощью конструктора без аргументов аналогично
Мы знаем, что помимо конструкторов без параметров в классе есть еще параметризованные конструкторы.
Так как же создавать объекты в форме параметров в отражении? Читайте дальше
Пример 4: Параметризованный созданный объект класса Class публичный класс Демо {
//Следующие методы выбрасывают слишком много исключений. В целях компактности кода они выбрасываются здесь непосредственно на виртуальную машину.
public static void main(String[] args) выдает исключение {
Класс<?> c = ноль;
пытаться {
c = Class.forName("java.lang.String");
} catch (ClassNotFoundException e) {
е.printStackTrace();
}
char[] ch = {'h','e','l','l','o'};
Строка с = ноль;
//Получаем параметризованный конструктор объекта Class. Параметры в скобках записываются как: type.class.
Constructor<?> con = c.getConstructor(char[].class);
//Используйте этот метод построения для создания нового строкового объекта, параметром является массив символов
s = (String) con.newInstance(ch);
System.out.println("Созданная строка: " + s);
}
}
Мы по-прежнему используем класс String в качестве примера, поскольку класс String используется чаще и его легче понять.
Здесь необходимо отметить, что конструктор необходимо получить с помощью метода getConstructor().
Что касается типа параметра, то это: исходный тип.класс.
Другой момент заключается в том, что независимо от того, есть ли у него параметры или нет, используемый здесь метод построения должен существовать в исходном классе.
Итак, как мы можем узнать подробную информацию, такую как метод конструктора, обычный метод, унаследованный родительский класс и т. д., в исходном классе? Читайте дальше
Получить структуру классаЧтобы получить структуру класса посредством отражения, нам нужно импортировать новый пакет java.lang.reflect.
Пример 5. Получение конструктора класса публичный класс Демо {
//Следующие методы выбрасывают слишком много исключений. В целях компактности кода они выбрасываются здесь непосредственно на виртуальную машину.
public static void main(String[] args) выдает исключение {
Класс<?> c = ноль;
пытаться {
c = Class.forName("java.lang.Boolean");
} catch (ClassNotFoundException e) {
е.printStackTrace();
}
//Метод getConstructors() возвращает массив конструкторов.
Конструктор<?>[] cons = c.getConstructors();
//Вы можете написать метод печати самостоятельно. Для удобства я использую Arrays.toString().
System.out.println(Arrays.toString(cons));
}
}
публичный класс Демо {
public static void main(String[] args) выдает исключение {
Класс<?> c = ноль;
пытаться {
c = Class.forName("java.lang.Boolean");
} catch (ClassNotFoundException e) {
е.printStackTrace();
}
Class<?>[] in = c.getInterfaces();
System.out.println(Arrays.toString(in));
}
}
публичный класс Демо {
public static void main(String[] args) выдает исключение {
Класс<?> c = ноль;
пытаться {
c = Class.forName("java.lang.Boolean");
} catch (ClassNotFoundException e) {
е.printStackTrace();
}
Метод[] m = c.getMethods();
//Хорошо, на этот раз я буду милосерден и напишу список для распечатки.
for (int i = 0; i <m.length; i++) {
System.out.println(м[я]);
}
}
}
класс Человек {
частное имя строки;
частный возраст;
}
публичный класс Демо {
public static void main(String[] args) выдает исключение {
Класс<?> c = ноль;
пытаться {
c = Class.forName("Человек");
} catch (ClassNotFoundException e) {
е.printStackTrace();
}
Поле [] f = c.getDeclaredFields();
for (int i = 0; i <f.length; i++) {
System.out.println(f[i]);
}
}
}
Метод getDeclaredFielsd() может получать все свойства, а метод getFields() — только общедоступные свойства.
Пример 10. Получите значение атрибута в этом классе. класс Человек {
публичное имя строки;
частный возраст;
public Person(String name, int age) {
это.имя = имя;
this.age = возраст;
}
}
публичный класс Демо {
public static void main(String[] args) выдает исключение {
Человек p = новый Человек("чжансан",12);
Класс<?> c = p.getClass();
//Получаем значение публичного атрибута
Поле f1 = c.getField("имя");
//get(p) указывает, какое значение объекта необходимо получить
Строка str = (String) f1.get(p);
System.out.println("Имя: " + строка);
//Получаем значение частного атрибута
Поле f2 = c.getDeclaredField("возраст");
//возраст – это частная собственность, поэтому установите для проверки безопасности значение true
f2.setAccessible(истина);
int age = (int) f2.get(p);
System.out.println("Возраст: " + возраст);
}
}
Честно говоря, я не нашел в Java никаких знаний, способных ослепить мои титановые глаза.
Каждый раз мне приходится писать кучу утомительного синтаксиса для реализации гаджета, иначе мне придется отчаянно вызывать API и отчаянно выбрасывать исключения.
Сделать код, который недостаточно компактен, громоздким.
Если мне нравится язык, его собственные характеристики должны произвести на меня впечатление, прежде чем я смогу использовать его для создания чего-либо.
Очевидно, Java меня не радует. Возможно, многие программисты вроде меня вынуждены использовать Java.
Просто чтобы успокоить мое одинокое сердце программиста, читайте ниже.
Пример применения отражения 11. Изменение атрибутов посредством отражения класс Человек {
частное имя строки;
публичный человек (строковое имя) {
это.имя = имя;
}
публичная строка toString() {
вернуть «Имя:» + this.name;
}
}
публичный класс Демо {
public static void main(String[] args) выдает исключение {
Человек p = новый Человек("王二狗");
System.out.println(p);
Класс<?> c = p.getClass();
//Определяем свойства, которые нужно изменить
Поле f = c.getDeclaredField("имя");
f.setAccessible(истина);
//Изменяем свойства и передаем объект и значение, которое нужно установить
f.set(p, "Чжан Эрдан");
System.out.println(p);
}
}
класс Человек {
общественная недействительная печать (int i) {
System.out.println("Я пишу числа: " + i);
}
public static voidsay(String str) {
System.out.println("Я говорю: " + str);
}
}
публичный класс Демо {
public static void main(String[] args) выдает исключение {
Человек р = новый Человек ();
Класс<?> c = p.getClass();
//Метод getMethod() должен передать имя метода и тип параметра
Метод m1 = c.getMethod("print", int.class);
//invoke() означает вызов и требует передачи объектов и параметров
m1.invoke(р, 10);
Метод m2 = c.getMethod("say", String.class);
//Ноль здесь означает, что объект не вызывается, то есть статический метод
m2.invoke(null, "твоя сестра");
}
}
Вот демонстрация обычного параметризованного метода и статического метода.
Теперь, когда все параметры записаны, работать с параметрами без параметров стало еще проще. Просто передайте объект напрямую.
Пример 13: Манипулирование массивами посредством отражения публичный класс Демо {
public static void main(String[] args) выдает исключение {
int[] arr = {1,2,3,4,5};
Class<?> c = arr.getClass().getComponentType();
System.out.println("Тип массива: " + c.getName());
int len = Array.getLength(arr);
System.out.println("Длина массива: " + len);
System.out.print("Обход массива: ");
for (int я = 0; я <len; я++) {
System.out.print(Array.get(arr, i) + " ");
}
Система.out.println();
//изменяем массив
System.out.println("Первый элемент перед модификацией: " + Array.get(arr, 0));
Array.set(обр., 0, 3);
System.out.println("Измененный первый элемент: " + Array.get(arr, 0));
}
}
На этом пока все. Книга, которую я прочитал, также включает в себя применение отражения в заводском режиме.
Это не что иное, как замена его методом forName(). Тут особо нечего сказать.
Я новичок в Java и ненавижу отвратительный синтаксис и дизайн Java.
Это все для Android, чтобы заложить основу и адаптироваться к будущей работе.