Java 将Class.forName对象强制转换到此对象实现的接口时的ClassCastException
我想为android创建一些插件示例,因此我有3个项目: ExternalLibInterface-包含Java 将Class.forName对象强制转换到此对象实现的接口时的ClassCastException,java,android,classcastexception,Java,Android,Classcastexception,我想为android创建一些插件示例,因此我有3个项目: ExternalLibInterface-包含IExternalLib,并生成ExternalLibInterface.jar文件 package com.example.externallibinterface; public interface IExternalLib { public String someMethod( String param ); } ExternalLib-包含external
IExternalLib
,并生成ExternalLibInterface.jar
文件
package com.example.externallibinterface;
public interface IExternalLib {
public String someMethod( String param );
}
ExternalLib-包含externallibinterface.jar
和SomeClass实现IExternalLib
,构建到ExternalLib.apk
package com.example.externallib;
import com.example.externallibinterface.IExternalLib;
public class SomeClass implements IExternalLib {
public String someMethod(String arg0) {
return arg0;
}
}
SomeApp-包含externallibinterface.jar
和活动类-我从中加载外部apk和类的应用程序
import com.example.externallibinterface.IExternalLib;
import dalvik.system.PathClassLoader;
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String apkToLoad = null;
String externalPackagePath = "com.example.externallib";
String externalClassPath = "com.example.externallib.SomeClass";
try {
apkToLoad = getPackageManager()
.getApplicationInfo( externalPackagePath, MODE_PRIVATE ).sourceDir;
} catch ( PackageManager.NameNotFoundException e ) {
e.printStackTrace();
}
PathClassLoader pathClassLoader =
new PathClassLoader( apkToLoad,
ClassLoader.getSystemClassLoader() );
try {
Class<?> c = Class.forName( externalClassPath, true, pathClassLoader );
Object someClassInstance = c.newInstance();
//exception ClassCastException here
IExternalLib i = (IExternalLib) someClassInstance;
i.someMethod( "some string" );
} catch (ClassNotFoundException e1) {
e1.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch ( ClassCastException e ) {
e.printStackTrace();
}
}
}
import com.example.externallibinterface.IExternalLib;
导入dalvik.system.PathClassLoader;
公共类MainActivity扩展了活动{
@凌驾
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
字符串apkToLoad=null;
字符串externalPackagePath=“com.example.externallib”;
字符串externalClassPath=“com.example.externallib.SomeClass”;
试一试{
apkToLoad=getPackageManager()
.getApplicationInfo(externalPackagePath,MODE_PRIVATE).sourceDir;
}捕获(PackageManager.NameNotFounde异常){
e、 printStackTrace();
}
PathClassLoader PathClassLoader=
新的PathClassLoader(apkToLoad,
getSystemClassLoader());
试一试{
Class c=Class.forName(externalClassPath,true,pathClassLoader);
对象someClassInstance=c.newInstance();
//exception ClassCastException在此
iexternalib i=(iexternalib)某些类恒量;
i、 someMethod(“somestring”);
}catch(ClassNotFoundException e1){
e1.printStackTrace();
}捕获(实例化异常e){
e、 printStackTrace();
}捕获(非法访问例外){
e、 printStackTrace();
}catch(ClassCastException e){
e、 printStackTrace();
}
}
}
但是当我将对象someClassInstance
转换为IExternalLib
时,我得到了ClassCastException
。
为什么?IExternalLib
定义在第三位(在externallibinterface.jar
中)。请尝试以下操作:
Class<? extends IExternalLib> l_clazz; // our expected class
Class<?> clazz = Class.forName("com.example.externallib.SomeClass"); // our unknown class
// check if our unknown class can be cast to our expected class
if ((l_clazz = clazz.asSubclass(IExternalLib.class)) != null) {
IExternalLib i = l_clazz.newInstance();
i.someMethod( "some string" );
}
Class clazz=Class.forName(“com.example.externallib.SomeClass”);//我们的无名班
//检查未知类是否可以强制转换为预期类
if((l_clazz=clazz.asSubclass(IExternalLib.class))!=null){
IExternalib i=l_clazz.newInstance();
i、 someMethod(“somestring”);
}
当不同的类加载器加载该类时,可能会发生这种情况。确保一次构建整个设置,以便只有一个类装入器负责装入这些类。当您只是将特定的.war文件重新部署到现有系统上时,这种情况经常发生。如果((l_clazz=clazz.asSubclass(iexternalib.class))!=null)给出了ClassCastException,那么你的类不能被强制转换到iexternalib
,你能在那一行之前打印出类名吗clazz.getName()
,肯定还有其他问题clazz.getName()
返回com.example.externallib.SomeClass。所以,我加载了正确的类,但无法将其对象强制转换为接口,接口在这个类中实现。我理解这个问题,只是试图帮助调试。是否确定类路径上没有多个com.example.externallib.SomeClass
s,请在主项目中使用一个新类进行尝试,并查看它是否仍然存在