0

我们将部分功能打包在一个外部库中,并附加到我们的项目中。该库不能以任何方式更改。其中有两个类位于其中:com.myorg.Grandpacom.myorg.Dad扩展com.myorg.Grandpa。在库扩展之外还有一些com.myorg.Grandson扩展类和其他一些类。com.myorg.Dadcom.myorg.Grandpa

我反编译com.myorg.Grandpa类并向它添加一个新方法new_method()。然后我尝试使用new_method()incom.myorg.Grandson但 IDEA 不允许我这样做,因为 Grandson extends Dad 扩展了图书馆的 Grandpa 不包含new_method(). 我试图从图书馆中删除爷爷,但令人惊讶的是,IDEA 一句话也没说,并成功编译了一个项目,尽管事实上爸爸在图书馆的边界上扩展了不存在的类。

问题是如何在不删除图书馆内的爷爷的情况下强迫爸爸续展新爷爷?

4

3 回答 3

0

你可以

  • Dad在and之间添加一个抽象类GrandSon: Extend Dad,并在子类中添加您的方法。然后GrandSon从该子类派生。

  • 将 的实例放入一个新类中,并让您的 IDE 为聚合实例Dad创建委托方法。Dad再次将您的新方法添加到新类中。

还有另一种可能:

  • 如果您必须在适当的位置修改类,请使用aspectj编织代码:aspectj 在运行时更改字节码(它不需要源代码)。这样您就可以添加方法或字段。
于 2013-06-26T13:27:34.313 回答
0

它必须首先出现在类加载器中。

如果在您的项目中,IDEA 应该首先加载您的类。您也可以尝试为您的课程创建一个单独的库并将其包含在您的项目中。

另请参阅:http: //www.jetbrains.com/idea/webhelp/configuring-module-dependencies-and-libraries.html

于 2013-06-26T13:13:57.643 回答
0

事实是您正在复制具有完整包签名的类,因此您将获得类加载器首先加载的类。我知道在 Websphere 中您可以调整类加载器的优先级,但在您的情况下不能说。

无论如何,为什么不直接不反编译呢?您通过反编译/自定义导致自己与外部库和不良做法(可能是版权问题)的硬耦合。此外,如果库得到更新,您将不得不重新构建您的自定义类。

选项:

创建您自己的实现,例如:

  1. 创建一个接口,复制 Grandpa 中的所有方法以及您需要的方法。

  2. 扩展 Grandpa 类并从您的接口实现添加的方法,所有其他方法将保持不变。

  3. 从您自己的类层次结构中扩展所有其他扩展类。

  4. 不要使用库公共类,而是使用您的接口作为命名

这样,您就可以创建自己的库界面,如果它发生变化,您就知道在哪里进行更改。

你甚至可以在没有接口的情况下做到这一点,它是一种包装功能,这取决于你需要实现什么。

无论如何,我会尝试通过自己的代码而不是弄乱库来解决它,这样做是不值得的,如果一个新程序员接手该项目,他们将需要很多时间来找出原因以及它的行为方式。

现在,如何构建类层次结构可能会有所不同,但这取决于您需要的特定实现,因此您必须发布有关库是什么以及您尝试添加的内容的更详细数据如果你期待一些更具体的答案......

问候

于 2013-06-26T12:58:26.720 回答