IllegalArgumentException: сообщение об ошибке не имеет смысла - PullRequest
3 голосов
/ 14 июля 2011

Я пытаюсь отладить Java-приложение, использующее Reflection. Сейчас я получаю следующую ошибку:

java.lang.IllegalArgumentException: Can not set int field DataStructures.StackAr.topOfStack to java.lang.Integer
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:146)
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:150)
    at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:37)
    at sun.reflect.UnsafeIntegerFieldAccessorImpl.getInt(UnsafeIntegerFieldAccessorImpl.java:38)
    at sun.reflect.UnsafeIntegerFieldAccessorImpl.get(UnsafeIntegerFieldAccessorImpl.java:18)
    at java.lang.reflect.Field.get(Field.java:358)

Последние строки запущенного приложения:

Field f = classUnderTest.getDeclaredField(processFieldName(var));
f.setAccessible(true);
Long value = (Long) f.get(runtimeInstance);

Сообщение об ошибке немного вводит в заблуждение, и я не уверен, почему в нем упоминается операция set, тогда как я пытаюсь предварительно выполнить get.

Я подозреваю, что runtimeInstance не является объектом ожидаемого класса. Но это сообщение об ошибке выбрасывает меня.

Кто-нибудь сталкивался с этой проблемой раньше? Любые подсказки?

PS1: точная строка, вызывающая исключение, такова:

Long value = (Long) f.get(runtimeInstance);

PS2: processFieldName(var) обрабатывает правильное имя поля, т.е. удаляет некоторые артефакты из строки с именем поля, например this. и т. Д.

Ответы [ 3 ]

5 голосов
/ 14 июля 2011

Из источника этих средств доступа кажется, что класс, объявляющий поле, нельзя назначить из класса runtimeInstance:

if (! (This.field.getDeclaringClass ()).isAssignableFrom (paramObject.getClass ())))
throwSetIllegalArgumentException (paramObject);

field - это поле, которое вы хотите получить из экземпляра, paramObject - это ваш runtimeInstance.

Таким образом, если объявленный класс поля не является классом или суперклассом paramObject, вы получите это сообщение.

Любой шанс, что ваш paramObject являетсяInteger здесь?

Редактировать: вот некоторый исходный код из OpenJDK (должен быть похож на Oracle), чтобы объяснить сообщение:

  protected String getSetMessage(String attemptedType, String attemptedValue) {
         String err = "Can not set";
         if (Modifier.isStatic(field.getModifiers()))
             err += " static";
         if (isFinal)
             err += " final";
         err += " " + field.getType().getName() + " field " + getQualifiedFieldName() + " to ";
         if (attemptedValue.length() > 0) {
             err += "(" + attemptedType + ")" + attemptedValue;
         } else {
             if (attemptedType.length() > 0)
                 err += attemptedType;
             else
                 err += "null value";
         }
         return err;
     }

Принимая ваше сообщение java.lang.IllegalArgumentException: Can not set int field DataStructures.StackAr.topOfStack to java.lang.Integer, мы находим, что:

  • поле типа int
  • имя поля topOfStack в классе DataStructures.StackAr
  • attemptedType равно java.lang.Integer

Поскольку attemptedType является типом вашего runtimeInstance, я подозреваю, classUnderTest равен DataStructures.StackAr, тогда как runtimeInstance имеет тип java.lang.Integer.

1 голос
/ 14 июля 2011

Исходный код Java для ошибки, которую вы получаете на вершине стека, может показаться, что runtimeInstance - это не тот же класс, что и classUnderTest:

protected void ensureObj(Object o) {
                 // NOTE: will throw NullPointerException, as specified, if o is null
                if (!field.getDeclaringClass().isAssignableFrom(o.getClass())) {
                     throwSetIllegalArgumentException(o);
                 }
             }
0 голосов
/ 14 июля 2011

Внимательно прочитайте сообщение об ошибке: «Не удается установить int поле DataStructures.StackAr.topOfStack в java.lang. Целое число »

Вам необходимо изменить Integer на int перед его назначением.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...