java - 在编译时名称已知且在运行时扩展其他类的类

时间:2017-05-24 07:29:52

标签: java

我希望创建一个propriertary adapter(super)类的开源实现(子类)。我有两个不同的要求:

  1. 我需要在运行时扩展子类,而不是在编译时扩展子类
  2. 必须在编译时知道我的子类的类名。
  3. 用例:由于超类拥有专有许可,我不能在我的开源项目的构建中包含其源代码或引用预构建的二进制文件。我的子类的实际运行时使用将发生在专有的闭​​源框架代码中。该框架将按名称创建我的子类的实例。出于这个原因,我的子类名称需要提前知道。

    后一个问题似乎排除了像cglib这样在运行时创建新类名的方法。

    示例代码:

    package com.proprietary;
    public class Adapter {}
    
    package org.free;
    public class AdapterImpl
        // com.proprietary is not available at compile time
        // extends com.proprietary.Adapter 
    {}
    
    package com.proprietary;
    public class Framework {
    
         public static void main(String[] args) {
             // Simplified: class name is not hard-coded in reality,
             // but comes from external config
             Class c = Class.forName("org.free.AdapterImpl");
             ...
         }
    }
    

2 个答案:

答案 0 :(得分:2)

也许请查看ByteBuddy

您可以动态“制作”新类,其功能可以帮助您支持约束:

  • 使用input_a = 'Hell(o) how a(re) you ? (.)' output_a = [] i = 0 while i<len(input_a): if input_a[i] !="(": output_a.append(input_a[i]) i=i+1 continue else: if input_a[i+1].isalpha(): i=i+1 while input_a[i]!=")": output_a.append(input_a[i]) i =i+1 i = i+1 else: while input_a[i]!=")": output_a.append(input_a[i]) i=i+1 output_a = "".join(output_a) 加载第三方专有类而不在代码中链接它,将类名称作为配置点传递
  • Naming strategy可让您控制生成的类名称
  • Class.forName Implementation intercept(插入您的自定义代码。

示例:

)

答案 1 :(得分:1)

你正在走下错误的兔子洞。

首先,这是不可能的:您无法在运行时扩展类。课程的性质是“固定的”#34;在编译时;然后编写一个包含&#34; nature&#34;的.class文件。之后无法更改。 C级有C级;你无法提升&#34; C在运行时突然说出C extends D

除此之外:只有在打算利用多态时,才能使子类有意义。

意义:

class A { }
class B extends A {}

有意义......当您的客户代码&#34;处理类名A和B(大部分时间)。

因此,除非我们谈论某个框架,否则你的&#34;对象需要扩展A以允许在该框架中进行集成,因此强制您的B扩展A&#34;稍后在&#34;上没有太多的好处。因为如上所述:在你的源代码(编译器视图)中,B不会是A;因此,您无法编写任何代码,这些代码可以从B扩展A中受益。

所以,&#34;最接近&#34;我可以在这里看到的东西:使用组合。您的类应包含指向该库类的实例的字段;并使用reflection创建该实例。

然后你的类提供了一个漂亮,干净的界面来访问可以在A中找到的行为。