我们将一部分功能打包在外部库中,并将其附加到我们的项目中。该库无法以任何方式更改。其中包括两个类:com.myorg.Grandpa
和com.myorg.Dad
,其中包含com.myorg.Grandpa
。另外还有com.myorg.Grandson
扩展com.myorg.Dad
以及扩展com.myorg.Grandpa
以外的其他几个类。
我反编译com.myorg.Grandpa
类并为其添加新方法new_method()
。
然后我尝试在new_method()
中使用com.myorg.Grandson
,但IDEA不会让我这样做,因为Grandson扩展了Dad,它扩展了不包含new_method()
的图书馆爷爷。
我试图从图书馆删除爷爷,令人惊讶的是IDEA没有说一句话并成功编写了一个项目,尽管在图书馆的边界内,爸爸扩展了现有的课程。
问题是如何强制爸爸扩展新爷爷而不删除图书馆内的那个?
答案 0 :(得分:0)
事实是,您正在复制具有完整包签名的类,因此您将获得类加载器首先加载的类。我知道在Websphere中你可以调整类加载器的优先级,但在你的情况下不能说。
无论如何,为什么不在没有反编译的情况下这样做呢?您通过反编译/自定义使自己与外部库和不良实践(可能是版权问题)硬耦合。此外,如果库得到更新,您将无法重建自定义类。
选项:
创建您自己的实现,例如:
创建一个界面,复制爷爷中的所有方法以及您需要的方法。
扩展Grandpa类并从您的界面实现添加的方法,所有其他方法将保持不变。
从您自己的班级hierarchie扩展所有其他扩展类。
使用您的界面作为命名
通过这种方式,您可以创建自己的库接口,如果它发生变化,您就知道在哪里进行更改。
你甚至可以在没有界面的情况下完成它,它包含了功能,它取决于你需要实现的目标。
无论如何,我会尝试通过自己的代码来解决它,而不是弄乱库,只是不值得做这样的技巧,如果一个新的程序员接受这个项目,他们将需要很多时间来找出原因和行为。
现在,如何构建类层次结构可能会有所不同,但它取决于您需要的具体实现,因此您必须发布有关库是什么以及您尝试添加的内容的更详细数据如果你期待一些更具体的答案......
此致
答案 1 :(得分:0)
它必须首先出现在类加载器中。
如果您的项目中有IDEA,则应首先加载您的课程。您也可以尝试为您的类创建一个单独的库,并将其包含在您的项目中。
另请参阅:http://www.jetbrains.com/idea/webhelp/configuring-module-dependencies-and-libraries.html
答案 2 :(得分:0)
你可以
在Dad
和GrandSon
之间添加一个抽象类:扩展Dad
,并在子类中添加您的方法。然后从该子类派生GrandSon
。
将Dad
的实例放在新类中,让IDE为聚合的Dad
实例创建委托方法。再次将您的新方法添加到新类中。
还有另一种可能性:
aspectj
编织代码:aspectj在运行时更改字节代码(它不需要源代码)。这样您就可以添加方法或字段。