[英]ClassCastException when casting Class.forName object to interface implemented by this object
I want to create some plugin example for android, so I have 3 projects for it:我想为 android 创建一些插件示例,所以我有 3 个项目:
ExternalLibInterface - contains IExternalLib
, and builds to externallibinterface.jar
file ExternalLibInterface - 包含IExternalLib
,并构建到externallibinterface.jar
文件
package com.example.externallibinterface;
public interface IExternalLib {
public String someMethod( String param );
}
ExternalLib - contains externallibinterface.jar
and SomeClass implements IExternalLib
, builds to externallib.apk
ExternalLib - 包含externallibinterface.jar
和SomeClass implements 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 - contains externallibinterface.jar
and class for activity - application where I load external apk and class from it. 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();
}
}
}
But when I cast Object someClassInstance
to IExternalLib
I get ClassCastException
.但是当我将Object someClassInstance
为IExternalLib
我得到ClassCastException
。 Why?为什么? IExternalLib
is defined in 3rd place (in externallibinterface.jar
). IExternalLib
定义在第三位(在externallibinterface.jar
)。
Try the following:请尝试以下操作:
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" );
}
It could happen when different class loaders are loading the class.当不同的类加载器加载类时可能会发生这种情况。 Make sure to build the whole setup at once so that only one class loader is responsible for loading the classes.确保一次构建整个设置,以便只有一个类加载器负责加载类。 It happens frequently when you are just re-deploying a particular .war file onto a existing system.当您只是将特定的 .war 文件重新部署到现有系统上时,这种情况经常发生。 Please see this for more insight can't cast to implemented interface请参阅此了解更多信息无法转换为已实现的接口
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.