IllegalArgumentException:错误消息没有意义 [英] IllegalArgumentException: the error message does not make sense

查看:70
本文介绍了IllegalArgumentException:错误消息没有意义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试调试依赖反射的 Java 应用程序.现在我得到的错误如下:

java.lang.IllegalArgumentException:无法将 int 字段 DataStructures.StackAr.topOfStack 设置为 java.lang.Integer在 sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:146)在 sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:150)在 sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:37)在 sun.reflect.UnsafeIntegerFieldAccessorImpl.getInt(UnsafeIntegerFieldAccessorImpl.java:38)在 sun.reflect.UnsafeIntegerFieldAccessorImpl.get(UnsafeIntegerFieldAccessorImpl.java:18)在 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. 等等.

解决方案

从这些访问器的来源看来,声明该字段的类似乎不能从 runtimeInstance 的类中分配:<块引用>

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

field 似乎是你想从实例中获取的字段,paramObject 是你的 runtimeInstance.

因此,如果字段的声明类不是 paramObject 的类或超类,您将收到该消息.

你的 paramObject 有可能是一个 Integer 吗?

这里有一些来自 OpenJDK 的源代码(应该类似于 Oracle 的),以解释消息:

 protected String getSetMessage(字符串尝试类型,字符串尝试值){String err = "无法设置";如果 (Modifier.isStatic(field.getModifiers()))错误+=静态";如果(是最终的)错误+=最终";err += " " + field.getType().getName() + " field " + getQualifiedFieldName() + " to ";如果 (attemptedValue.length() > 0) {错误+=("+尝试类型+)"+尝试值;} 别的 {如果 (attemptedType.length() > 0)错误 += 尝试类型;别的错误+=空值";}返回错误;}

获取您的消息 java.lang.IllegalArgumentException: Can not set int field DataStructures.StackAr.topOfStack to java.lang.Integer 我们发现:

  • 该字段的类型为 int
  • 该字段的名称是 topOfStack 类中的 DataStructures.StackAr
  • attemptedTypejava.lang.Integer

由于 attemptedType 是您的 runtimeInstance 的类型,我怀疑 classUnderTestDataStructures.StackArruntimeInstancejava.lang.Integer 类型.

I am trying to debug a Java application that is relying on Reflection. Right now the error I get is the following:

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)

THe last lines of the application running are:

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

The error message is a bit misleading and I am not sure why it is mentioning a set operation whereas I am trying to preform a get.

I am suspecting that the runtimeInstance is not an object of the expected class. But that error message is throwing me away.

Has anyone encountered this issue before? Any clues?

PS1: The exact line causing the exception is this one:

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

PS2: processFieldName(var) processes the correct name of the field, i.e. it removes some artefacts from a string with the field name like this. and so on.

解决方案

From the source of those accessors it seems that the class declaring the field is not assignable from the runtimeInstance's class:

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

field seems to be the field you want to get from the instance, paramObject is your runtimeInstance.

Thus, if the declaring class of the field isn't the class or a super class of the paramObject you'd get that message.

Any chance your paramObject is an Integer here?

Edit: here's some source code from OpenJDK (should be similar to Oracle's), to explain the message:

  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;
     }

Taking your message java.lang.IllegalArgumentException: Can not set int field DataStructures.StackAr.topOfStack to java.lang.Integer we find that:

  • the field is of type int
  • the field's name is topOfStack in class DataStructures.StackAr
  • attemptedType is java.lang.Integer

Since attemptedType is the type of your runtimeInstance I suspect classUnderTest is DataStructures.StackAr whereas runtimeInstance is of type java.lang.Integer.

这篇关于IllegalArgumentException:错误消息没有意义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆