2017-05-14 83 views
0

我在我的应用程序的主要活动如下代码:增加了新的(部分重构后)的代码,现在越来越ClassNotFoundException的一类,它根本不存在

package com.myself.foo.myapp; 

import com.someotherfellow.hisapp.OtherClass; 
// more imports here 

public class MainActivity extends ActionBarActivity { 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     Object bar = new OtherClass(blah, this, YetAnotherClass.class); 
     // ... 
    } 
} 

当我建立并启动它(使用Eclipse和ADT),该应用程序崩溃,未处理ClassNotFoundException。该logcat的告诉我缺少的类是

com.myself.foo.myapp.OtherClass

哪位是一个不存在的类。简单的类名是来自其他包的类的名称,但它的前缀是我的包名称。很明显,这个课程永远不会被发现。

当我将鼠标悬停在代码中的构造函数调用OtherClass上时,Eclipse显示了正确的类名,并带有正确的程序包前缀。

两种封装都存在于同一个源代码树的源文件,相应的路径是:

~/src/myapp/src/com/myself/foo/myapp/MainActivity.java 
~/src/myapp/src/com/someotherfellow/hisapp/OtherClass.java 

是什么造成这种行为,我怎么能解决这个问题?


编辑:只是出于好奇,我已经重构代码,移动OtherClass到安卓试图找到它的包。现在,我得到:

java.lang.InstantiationException:java.lang.Class中<com.myself.foo.myapp.OtherClass>没有无参数的构造

这确实是真的,构造的OtherClass需要三个参数,如调用中提供的。

它看起来像是由于某种原因,JVM调用new OtherClass()(带有零参数),它与该类的任何已知构造函数都不匹配。如果OtherClass驻留在不同的包中,则JVM将尝试在当前包中找到名为OtherClass的类,并具有匹配的构造函数签名。但是,如果OtherClass位于同一个包中,那么JVM至少会选择正确的类,但显然找不到匹配的构造函数。

这引出了一个问题:什么导致JVM寻找零参数构造函数?

请注意,OtherClass不是Android组件:它不属于任何属于Android框架的类,并且不在Manifest中的任何位置引用。 OtherClassObject的直接后代,并实现了自定义接口。

+0

编译错误没有到来,所以在编译期间没有运行时间,所以你可以检查运行时间类路径 –

+0

@gatisahu具体应该看什么设置?请注意,这两个包共享相同的根路径(〜/ src/maypp/src),问题似乎是有些东西正在将合格的类名更改为与我将其导入的不同包。 – user149408

回答

0

我相信我发现了这个错误。在导入新代码之前,该应用已经工作。

我导入的代码是在其主要活动中混合了UI和功能的应用程序。 OtherClass是我只保留功能的活动的精简版本。

OtherClass最初名为MainActivity,与我的应用程序的主要活动相同。我使用Eclipse中的Refactor功能将其重命名为OtherClass

令我惊讶的是,我发现我的清单如下:

<activity 
     android:name=".OtherClass" 
     android:label="@string/app_name" > 
     <intent-filter> 
      <action android:name="android.intent.action.MAIN" /> 

      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 
    </activity> 

显然,两个相同的类名(不包括包名),与本地参考的同时,困惑Eclipse和它改变Manifest中的名称(它应该保持不变)。这就解释了原因:

  • 关于com.myself.foo.myapp.OtherClass缺失的原始消息是因为此处的包是该应用的默认包,因为它的清单。
  • 在移动OtherClass以确保找到它之后,Android仍然期望这个类是一个Activity,该类(与其他Android系统组件一样)预计具有零参数构造函数。

将我的Manifest中的Activity的名称更改为MainActivity后,错误消失了。

教训:当两个班在不同的包具有相同的简单名称有本地引用这些类,重命名他们中的一个可能混淆的Eclipse。

建议:在重构之前确认所有内容。重构后,查看差异并查看更改是否正确。这可能会为您节省数小时的调试时间!