|
Spec-Zone .ru
спецификации, руководства, описания, API
|
Вот несколько типичных проблем, с которыми встречаются разработчики с объяснениями того, почему происходить и как разрешить их.
пример генерирует FieldTroubleIllegalArgumentException. вызывается, чтобы установить поле, которое имеет ссылочный тип Integer со значением типа примитива. В неотражательном эквиваленте Integer val = 42, компилятор преобразовал бы (или поле) тип примитива 42 к ссылочному типу как new Integer(42) так, чтобы его проверка типа приняла оператор. При использовании отражения введите проверку, только происходит во времени выполнения, таким образом, нет никакой возможности к полю значения.
import java.lang.reflect.Field;
public class FieldTrouble {
public Integer val;
public static void main(String... args) {
FieldTrouble ft = new FieldTrouble();
try {
Class<?> c = ft.getClass();
Field f = c.getDeclaredField("val");
f.setInt(ft, 42); // IllegalArgumentException
// production code should handle these exceptions more gracefully
} catch (NoSuchFieldException x) {
x.printStackTrace();
} catch (IllegalAccessException x) {
x.printStackTrace();
}
}
}
$ java FieldTrouble
Exception in thread "main" java.lang.IllegalArgumentException: Can not set
java.lang.Object field FieldTrouble.val to (long)42
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException
(UnsafeFieldAccessorImpl.java:146)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException
(UnsafeFieldAccessorImpl.java:174)
at sun.reflect.UnsafeObjectFieldAccessorImpl.setLong
(UnsafeObjectFieldAccessorImpl.java:102)
at java.lang.reflect.Field.setLong(Field.java:831)
at FieldTrouble.main(FieldTrouble.java:11)
Чтобы устранить это исключение, проблематичная строка должна быть заменена следующим вызовом :
f.set(ft, new Integer(43));
isAssignableFrom() возвратится false в этом тесте, который может использоваться программно, чтобы проверить, возможно ли определенное преобразование: Integer.class.isAssignableFrom(int.class) == false
Точно так же автоматическое преобразование от примитивного до ссылочного типа также невозможно в отражении.
int.class.isAssignableFrom(Integer.class) == false
Проницательный читатель может заметить это если
$ java FieldSpy java.lang.String count
java.lang.NoSuchFieldException: count
at java.lang.Class.getField(Class.java:1519)
at FieldSpy.main(FieldSpy.java:12)
Class.getField() и методы возвращают общедоступное задействованное поле (я) class, перечисления, или интерфейса, представленного Class объект. Получать все объявленные поля (но не наследованный) в Class, используйте метод. может быть брошен, если попытка предпринимается, чтобы получить или установить значение a private или иначе недоступное поле или установить значение a final поле (независимо от его модификаторов доступа).
import java.lang.reflect.Field;
public class FieldTroubleToo {
public final boolean b = true;
public static void main(String... args) {
FieldTroubleToo ft = new FieldTroubleToo();
try {
Class<?> c = ft.getClass();
Field f = c.getDeclaredField("b");
// f.setAccessible(true); // solution
f.setBoolean(ft, Boolean.FALSE); // IllegalAccessException
// production code should handle these exceptions more gracefully
} catch (NoSuchFieldException x) {
x.printStackTrace();
} catch (IllegalArgumentException x) {
x.printStackTrace();
} catch (IllegalAccessException x) {
x.printStackTrace();
}
}
}
$ java FieldTroubleToo
java.lang.IllegalAccessException: Can not set final boolean field
FieldTroubleToo.b to (boolean)false
at sun.reflect.UnsafeFieldAccessorImpl.
throwFinalFieldIllegalAccessException(UnsafeFieldAccessorImpl.java:55)
at sun.reflect.UnsafeFieldAccessorImpl.
throwFinalFieldIllegalAccessException(UnsafeFieldAccessorImpl.java:63)
at sun.reflect.UnsafeQualifiedBooleanFieldAccessorImpl.setBoolean
(UnsafeQualifiedBooleanFieldAccessorImpl.java:78)
at java.lang.reflect.Field.setBoolean(Field.java:686)
at FieldTroubleToo.main(FieldTroubleToo.java:12)
final поля от того, чтобы быть установленным после инициализации class. Однако, Field как объявляют, расширяется AccessibleObject который обеспечивает возможность подавить эту проверку.