Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/392.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java CastCastException在强制转换到从其他类加载器加载的类时_Java_Groovy_Classloader - Fatal编程技术网

Java CastCastException在强制转换到从其他类加载器加载的类时

Java CastCastException在强制转换到从其他类加载器加载的类时,java,groovy,classloader,Java,Groovy,Classloader,我编写了一个库,它的一个API方法将Class作为参数,然后在这个方法的主体中创建了这个类的一个实例: void foo(Class scriptClass) { Script script = scriptClass.newInstance(); // do stuff with the script object } 问题是,虽然scriptClass是Script类的子类,但我得到ClassCastException,因为scriptClass是由与Script不同的类加载器加载

我编写了一个库,它的一个API方法将
Class
作为参数,然后在这个方法的主体中创建了这个类的一个实例:

void foo(Class scriptClass) {
  Script script = scriptClass.newInstance();
  // do stuff with the script object
}

问题是,虽然
scriptClass
Script
类的子类,但我得到
ClassCastException
,因为
scriptClass
是由与
Script
不同的类加载器加载的。解决此类冲突的通常方法是什么?

除非类是相同的,它是相同的,它是相同的类实例,因此,由相同的类装入器装入,否则不能强制转换

通用类加载器

使用一个已经有
groovy.Script
的类加载器,因此当任何子类加载器使用这个类时,它都是公共类

使用
URLClassLoader
时,请使用以下构造函数:
URLClassLoader(URL[]URL,ClassLoader parent)
使脚本使用现有类

其他类加载器

如果以上不可行,您可以使用反射(因为JRE类很常见)。但请记住,这是大量的样板代码,应该保持在最低限度


因此,底线是检查类加载器结构,并尝试将常见的东西放在常见的位置。

不清楚您的“scriptClass”到底是“Script”还是它的子类。如果是后者,那么您基本上只需要在加载“scriptClass”之前确保JVM加载了“Script”。如果“脚本”还没有被加载,你的“奇数”类加载器将自己加载它,从而产生你的问题。如果已加载,则在这两种情况下都将使用已加载(由系统类加载器加载)的版本。

除非使用相同的父类加载器(以及相同的
脚本
类实例),否则无法解决此问题:就JVM而言,由两个不同类加载器加载的同一个类是不同的类。@Joachim Sauer因此类似于方法第一行中的
scriptClass.getClassLoader().getParent().loadClass('groovy.Script')
,应该可以解决这个问题,即使另一个类加载器已经加载了
Script
,我也没有足够的上下文来回答这个问题,但我对此表示怀疑。问题是,包含
foo
的类必须由与
scriptClass
相同的类加载器加载(或者更准确地说:它们必须共享一个加载
Script
类的公共父(或祖先)类加载器),您只需使用一个公共的祖先对象,如果没有其他问题,+1通用类加载器是唯一有效的解决方案。他可以用Groovy编写框架,但最终,他会遇到另一个类型必须匹配的地方(例如在
脚本
实例上调用方法时)。@Aarondigula实际上框架是用Groovy编写的,方法是从Groovy脚本调用的。之所以使用不同的类加载器,是因为库是作为jar添加的。只需将现有的类加载器设置为库的新类加载器的父类即可。这将解决问题。