Вчера круг друзей задал вопрос:
Для следующего списка, как добавить целое число в список?
ArrayList<String> list = new ArrayList<String>();
Есть несколько ответов:
- 1. Не знаю (непрофессиональный ответ)
- 2. Жесткая вилка (непрофессиональный ответ)
- 3. Измените String на Integer и добавьте его (вопреки первоначальному замыслу вопроса)
- 4. Измените строку на объект, вы можете добавить любой тип (вопреки первоначальному замыслу вопроса)
- 5. Строка заменена подстановочными знаками
- 6. Отражение
Я ничего не скажу о 1 и 2, это относится к делу! Три метода 3, 4 и 5 противоречат первоначальному замыслу вопроса.Если его можно изменить, то мы можем напрямую создать три ArrayList. 6 Отражение, это бесконечно близко, так какое же это имеет отношение к отражению? Давайте посмотрим на следующие примеры:
public static void main(String[] args) {
ArrayList list=new ArrayList();
ArrayList<String> str_list=new ArrayList<String>();
ArrayList<Integer> int_list=new ArrayList<Integer>();
ArrayList<Object> obj_list=new ArrayList<Object>();
//对象比较
System.out.println(list == str_list);
System.out.println(list == int_list);
System.out.println(list == obj_list);
//对象的运行时class比较
System.out.println(list.getClass() == str_list.getClass());
System.out.println(list.getClass() == int_list.getClass());
System.out.println(list.getClass() == obj_list.getClass());
}
результат:
false
false
false
true
true
true
На самом деле три приведенных выше легко понять.Адреса разных объектов в памяти должны быть разными,поэтому все они ложные.Следующие три верные?Да,правда,что наводит на вопрос в кругу друзей . Почему три разных объекта, их getClass одинаковый, разве не должно быть три разных hashCode? Это на самом делеОбщие проблемы времени компиляции и времени выполнения.
Для дженериков,Универсальные шаблоны допустимы только на этапе компиляции.После компиляции универсальный тип коллекции дегенерируется; причина: из-за механизма стирания универсальных шаблонов JVM JVM не знает общей информации во время выполнения..
Следовательно: общий тип в коллекции java предназначен для ограничения неправильного ввода пользователя и действителен только во время компиляции;
Вернемся к началу вопроса, как мы можем поместить объект Integer в список, определенный выше? Поскольку дженерики в коллекции допустимы во время компиляции, мы можем вставить их таким образом, чтобы обойти компиляцию. Итак, как обойти проверку времени компиляции? Ответ заключается в использовании отражения; мы знаем, что механизм отражения JAVA относится к:
«В рабочем состоянии для любого класса можно знать все свойства и методы этого класса; для любого объекта можно вызывать любые его методы и свойства; такое динамическое получение информации и динамический вызов методов объекта называются функциями , Механизм отражения для языка java.
Хорошо, давайте еще раз посмотрим на программу:
ArrayList<String> str_list=new ArrayList<String>();
//获取类信息
Class c=str_list.getClass();
//获取add方法
Method m=c.getMethod("add", Object.class);
//运行时调用add方法
m.invoke(str_list, 20);
//输出当前str_list
System.out.println(str_list);
результат:
[20]
Как видно из результатов, мы выполнили задачу по добавлению Integer в список.
[Общий, отражение, время компиляции, время выполнения]
Всем отличных выходных!