有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java IllegalArgumentException:错误消息没有意义

我试图调试一个依赖反射的Java应用程序。现在我得到的错误如下:

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) 个答案

  1. # 1 楼答案

    从这些访问器的来源来看,声明字段的类似乎不可从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
    • 在类DataStructures.StackAr中,字段的名称为topOfStack
    • attemptedTypejava.lang.Integer

    因为attemptedType是你的runtimeInstance类型,我怀疑classUnderTestDataStructures.StackAr,而runtimeInstancejava.lang.Integer类型

  2. # 2 楼答案

    位于堆栈顶部的错误的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);
                     }
                 }
    
  3. # 3 楼答案

    仔细阅读错误消息:“无法将intfield DataStructures.StackAr.topOfStack设置为java.lang.Integer

    在分配之前,需要将Integer更改为int