IllegalArgumentException:错误消息没有意义 [英] IllegalArgumentException: the error message does not make sense
问题描述
我正在尝试调试依赖反射的 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
attemptedType
是java.lang.Integer
由于 attemptedType
是您的 runtimeInstance
的类型,我怀疑 classUnderTest
是 DataStructures.StackAr
而 runtimeInstance
是 java.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 classDataStructures.StackAr
attemptedType
isjava.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屋!