ClassCastException when casting Class.forName object to interface implemented by this object

你说的曾经没有我的故事 提交于 2019-12-12 19:08:56

问题


I want to create some plugin example for android, so I have 3 projects for it:

ExternalLibInterface - contains IExternalLib, and builds to externallibinterface.jar file

  package com.example.externallibinterface;    
  public interface IExternalLib {
    public String someMethod( String param );
  }

ExternalLib - contains externallibinterface.jar and SomeClass implements IExternalLib, builds to 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.

   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. Why? IExternalLib is defined in 3rd place (in externallibinterface.jar).


回答1:


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. Please see this for more insight can't cast to implemented interface




回答2:


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" );
}


来源:https://stackoverflow.com/questions/12383376/classcastexception-when-casting-class-forname-object-to-interface-implemented-by

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!