【问题标题】:Java extends programmaticallyJava 以编程方式扩展
【发布时间】:2016-08-24 06:42:13
【问题描述】:

我想知道以某种方式替换 Java 的“extends”关键字,以便基于参数(文件、环境变量、db ......基本上任何东西)动态扩展类。这是否可能,因为使用类加载器或调用构造函数无法实现这一点。我不是在问“我应该使用接口还是超类层次结构”,而是在 JAVA 引擎盖下的真正含义是什么,因为没有任何好的描述,只是古老的继承术语:

https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html

【问题讨论】:

  • 你会根据这个参数在课堂上做什么?为什么你不能只为不同的参数创建一个类的多个实例? (简短的回答是:不,你不能。继承是在编译时烘焙到类中的属性)
  • 你为什么要这样做?这是用于动态代理之类的吗?
  • @AndyTurner 可能是注释和反映?
  • 这听起来像是一个史诗般的 XY 问题。请说明您要解决的问题,而不是解决问题的中间步骤。这里的简短回答是响亮的不。更长的答案是肯定的,这是可能的,但需要大量且容易出错的加载时间编织。
  • @Zoltan:如果你能提供一个具体的例子来说明你正在做什么以及你遇到的限制(在另一个问题中,这个问题已经出现了),人们可以提供具体的建议处理这些限制。开放式“extends 是什么”可能无法帮助您解决这些问题。

标签: java class dynamic hierarchy


【解决方案1】:

“替换extends关键字”的唯一方法是在运行时动态创建类,这是完全可能的,但并非易事。 Vert.x 是一个广泛使用动态生成类的项目的一个很好的例子。

从这个意义上说,Java 并不是作为一种动态语言而设计的。有几种动态语言(其中一些可以在 JVM 上运行),例如 JavaScript。

其实扩展的真正含义...

没有深入探讨 OOP 的长篇论文,当您说 Derived extends Base 时,这意味着 Derived 继承了 Base 的公共和受保护 API(然后可以添加)以及该 API 的实现API。这意味着期望看到Base 实例的代码可以接受Derived 实例,因为Derived“是”Base。此链接是在编译时创建的。在运行时,实例化Derived 的实例涉及实例化Base 实例所涉及的所有管道,再加上Derived 的附加管道。

【讨论】:

  • 感谢您的回答,我会研究这个 Vert.x 项目。
【解决方案2】:

要实现这一点,您需要根据条件维护类的各种版本,并且您还必须自定义类加载器,因为当您发现必须加载特定实例时,您需要加载该类JVM启动时默认类加载器不会加载。

最好维护类的多个版本并让 JVM 完美地完成它的工作。

【讨论】:

    【解决方案3】:

    你不能用像 Java 这样的语言来做到这一点。关于“继承”的信息不仅被编译器使用,还被“硬烘焙”到编译后的字节码中。

    如果你真的想要这种“动态”元编程;你最好使用允许你这样做的语言;而不是“违反”一种从未打算用于这种用法的语言。

    用一些愚蠢的比较:仅仅因为你碰巧知道“螺丝”和“锤子”......你不会开始用锤子把那些螺丝钉进墙上,对吗?相反,您会寻找一种比锤子更适合“螺丝”的工具。

    如果您仍然希望您的代码在 JVM 中运行;您可能会考虑使用 jython 或 jruby 之类的语言。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-02
      • 2019-11-18
      • 2018-03-26
      • 2020-08-12
      • 2021-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多