【问题标题】:How does Java generate signatures for Methods?Java 如何为方法生成签名?
【发布时间】:2010-10-01 13:43:25
【问题描述】:

我有一个带有静态最终方法 getAll 的 Java 类:

public static final Vector<Category> getAll(Context context, ContentValues where) {
    ArrayList<Integer> IDs = null;

    if(where != null && where.containsKey(DatabaseAdapter.KEY_PRODUCT)) {
        IDs = OvertureItem.getAll(context, DatabaseAdapter.TABLE_PRODUCT_CATEGORY, new String[] { DatabaseAdapter.KEY_CATEGORY }, where);
    } else {
        IDs = OvertureItem.getAll(context, DatabaseAdapter.TABLE_CATEGORIES, where);
    }

    Vector<Category> categories = new Vector<Category>();

    for(Integer id: IDs) {
        categories.add(Category.get(context, id));
    }

    return categories;        
}

现在我想将 null 作为 where 语句的值提交,以便稍后在代码中忽略它。无论如何,在这种方法的测试用例中,我有:

Vector<Category> categories = Category.getAll(context, null);

这反过来又给了我一个 NoSuchMethodError。我不知道它为什么这样做。我唯一能想象的是,我提交的 null 与上述方法的签名不匹配。但是我该如何克服呢?我已经考虑过重载。但这只会以重写大部分代码而告终。至少当我这样做的时候,我是怎么想的。

对此有何建议?

菲尔

附:这是我得到的堆栈跟踪:

java.lang.NoSuchMethodError: com.sap.catalogue.model.Category.getAll
at com.sap.overture.test.model.CategoryTest.testGetAll(CategoryTest.java:59)
at java.lang.reflect.Method.invokeNative(Native Method)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:169)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:154)
at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:430)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1447)

【问题讨论】:

  • 查看logcat输出。异常是否由其他故障引起,例如验证错误?

标签: java android junit method-signature


【解决方案1】:

如果该方法在编译时不存在,则代码将无法编译。

如果您在运行时得到NoSuchMethodError,那么这表明您正在运行的Category 类的版本与您正在编译的Category 类的版本不同。

你的设置是什么样的 - 这个类在同一个项目中吗?你是从另一个项目中复制 JAR 吗?

【讨论】:

  • +1 - 但它不只是“建议”这个。 AFAIK,没有其他合理的解释。
  • Category 类在主项目(android 应用程序)中。测试位于与主应用程序直接相关的测试项目中。这有点奇怪,因为所有其他测试都没有问题地通过。另外,我不做任何事情,比如在运行时更改课程。这是一个普通的模型类。保存数据和管理数据的逻辑。
  • @Stephen 我不喜欢用 0.1% 的可能性来谈论绝对,因为我没有想到什么,或者 philgiese 有一些尴尬的设置 :)
  • @philgiese 您是否尝试过清理两个项目并重新编译?该方法是否也被重载了?
  • 我已经对这两个项目进行了全面清理,没有任何更改。 getAll() 方法确实被重载了。在超类 OvertureItem 中还有一个 getAll() 方法。但是超类中的方法需要三个参数而不是两个。
【解决方案2】:

真正的答案

所以我现在终于想通了,它并不像我预期的那么明显。我开始怀疑,我编写的任何新方法的每个新测试用例何时都会给我 NoSuchMethodError。于是我再深入一点,然后突然想到:“我改变了android应用程序的包名”。我认为只要我在 AndroidManifest.xml 中保持属性正确,这不会对测试项目产生任何影响,但我错了!

实际上,当您的应用程序包命名为 com.foo.bar.app 时,您的测试包必须命名为 com.foo.bar.app.test!发生的事情是,我的旧配置以某种方式使用了 bin/ 文件夹中的类。我想,当我清理项目时它们应该被删除,但它们没有。这样,所有旧的测试用例仍然可以通过,只有新的测试用例会给我 NoSuchMethodError。在我手动删除 bin/ 文件夹后,我遇到了一大堆错误。然后我重命名了包含测试用例的包,并对项目进行了全面的清理/重建,等等,一切又恢复了正常。

感谢所有提示!我真的很感谢你的帮助,这让我一直在挖掘问题的根源。希望这里能帮助到以后遇到同样问题的人。

菲尔

【讨论】:

    猜你喜欢
    • 2011-05-26
    • 1970-01-01
    • 1970-01-01
    • 2011-05-04
    • 1970-01-01
    • 2016-06-29
    • 1970-01-01
    • 2010-11-20
    • 1970-01-01
    相关资源
    最近更新 更多