有一个库有一个基类(让我们称之为CBase)执行某些任务,并且可以创建扩展此CBase类的类。
对于我来说,CBase的行为是不够的,所以我想创建我自己的CBase类(我们称之为MyCBase),它们具有相同的方法和成员,但这些方法不会做同样的事情。
直到现在一切正常。但阻止我的是我想用MyCBase取代CBase。但是,我有很多扩展CBase的类,我不想全部改变它们。
是否有可能在运行时用MyCBase替换CBase? 那么
public class A extends CBase {}
变为
public class A extends MyCBase {}
我可以使用代码增强功能执行此操作吗? (就像我们在运行时向类添加方法一样。是否也可以通过这种方式更改继承?)
感谢您的帮助!
修改
我想为框架编写一个插件,这就是为什么我想在运行时更改继承。这样,框架的用户可以使用我的插件而无需更改其源代码(将其类的继承从CBase更改为MyCBase)
编辑2
是否可以这样做:?
CtClass cc = CtClass.forName("pkg.AClass");
cc.setSuperclass(CtClass.forName("mylib.MyCBase"));
cc.compile();
答案 0 :(得分:1)
我不是专家。可能你可以扩展ClassLoader
。但我强烈建议不要这样做。替换将触及您的许多课程,但在代码阅读和应用程序执行中将会很清楚。
我认为由于你有很多类扩展CBase
,所以还有改进架构的空间。人们正在尝试从其他库中删除依赖项或将其保持为非常小。因为在这种情况下,您可以轻松切换到另一个库或添加自己的功能。
答案 1 :(得分:0)
我认为你不能在运行时更改类的扩展。我建议更改对象的扩展或构建一个界面,其中包含您需要的所有内容
答案 2 :(得分:0)
如果您控制源代码,则更改所有派生类很简单:
如果你不能这样做(例如因为某些派生类在你无法控制的库中),你可以用自己的实现替换CBase的实现。只需在项目中创建一个相同包和名称的类(类加载器按顺序搜索类路径,并使用正确的包的第一个类和它找到的名称)。然而,这种方法非常脆弱,因为编译器无法检查旧版本和新版本的CBase之间的二进制兼容性。加载类时,JVM将检查此兼容性,但由于类仅在需要时加载,因此很难测试您的更改。 (这就是为什么我不推荐这种方法,如果有其他选择)。
您也可以在加载类时更改类操作类文件,这样会更加脆弱,编译器会允许您使用MyBase可能具有的任何其他功能。 ==>绝对不是个好主意。