代码之家  ›  专栏  ›  技术社区  ›  khachik

现有公共方法

  •  3
  • khachik  · 技术社区  · 6 年前

    我面对的是一个非常神秘的 java.lang.NoSuchMethodError 在下面粘贴的代码中。同样的方法,通过反射调用,按预期工作:

    Widget a = getTextBoxWidget();
    com.google.gwt.user.client.ui.UIObject uio = a; // Widget extends UIObject
    for (java.lang.reflect.Method method : uio.getClass().getMethods()) {
        if (method.getName().equals("getElement")) {
            System.err.println("Method " + method.getName() + ":" + 
                               method.getDeclaringClass().getName());
            System.err.println("Modifier " + 
                               java.lang.reflect.Modifier.toString(method.getModifiers()));
            System.err.println("Parameter count: " + method.getParameterCount());
            System.err.println("Parameter types: " + Arrays.asList(method.getParameterTypes()));
            System.err.println("Return type: " + method.getReturnType());
            try {
                Object result = method.invoke(uio, new Object[0]);
                System.err.println("Invocation successful: " + result);
                Object result2 = method.invoke(uio, new Object[0]);
                System.err.println("Invocation successful2: " + result2);
            } catch (Exception e) {
                System.err.println("Failed to invoke getElement: " + e);
                e.printStackTrace(System.err);
            }
        }
    }
    // until here everything is good and it seems that 
    // we can call getElement and get the result, but...
    Object result3 = uio.getElement(); // line 470, here I get java.lang.NoSuchMethodError
    

    输出:

    Method getElement:com.google.gwt.user.client.ui.UIObject
    Modifier public
    Invocation successful: <result here>
    Invocation successful2: <result here>
    Parameter count: 0
    Parameter types: []
    Return type: class com.google.gwt.dom.client.Element
    

    堆栈跟踪:

    java.lang.NoSuchMethodError: com.google.gwt.user.client.ui.UIObject.getElement()Lcom/google/gwt/user/client/Element;
    at com.pyx4j.widgets.client.ValueBoxBase.setAriaLabel(ValueBoxBase.java:470)
    

    可能的原因是什么?
    uio.getClass().getClassLoader() sun.misc.Launcher$AppClassLoader, id=151 method.getDeclaringClass().getClassLoader() 是相同的,具有相同的ID。

    一起跑步 -verbose:class 显示 UIObject 从预期要加载的任何位置加载的类。里面的主要版本 UIObject.class 是52,与运行时主版本(1.8)匹配

    1 回复  |  直到 6 年前
        1
  •  3
  •   Karol Dowbecki    6 年前

    在编译和运行时,代码实际上可能不同。

    反射输出表明 UIObject.getElement() 方法返回类型为 com.google.gwt.dom.client.Element 然而,jvm抱怨它想要 com.google.gwt.user.client.Element . 注意 dom user 子包位于完全限定类名的中间。

    如果没有 covariant relation 在这两种类型之间,如前一种扩展后一种,可能存在错误。由于第470行分配给 Object 是的。也许会有一个 ClassCastException 如果实际返回类型用于声明 result3 在第470行。