【问题标题】:Change class from one to another at run time在运行时将类从一个更改为另一个
【发布时间】:2019-12-12 01:38:48
【问题描述】:

我正在参与的一个项目中遇到一种情况,在该项目中,在一个插件系统中,一个特定的类被实例化并在其中执行重载函数。我想根据用户配置的条件使用 2 组不同的功能。因此,我需要在运行时在 2 个类之间切换。

我尝试在构造函数中将一个函数的类设置为另一个函数

a.class = b.class;

但事实证明,在 Java 中,类是最终的,不能更改

error: cannot assign a value to final variable class

我也尝试使用这里提出的一些想法:

Change class type at runtime

但他们并没有真正解决这个问题。

EntryPoint.java

public class EntryPoint {
    public static void main(String[] args) {
        System.out.println(new a().the_func());
    }
}

a.java

public class a {
    public a() {
        a.class = b.class;
    }

    public int the_func() {
        return 22;
    }
}

b.java

public class b extends a {
    @Override
    public int the_func() {
        return -1;
    }
}

此代码的预期结果(如果有效)将是 EntryPoint 程序输出“-1”。反而会抛出错误,因为 a 的类不能被 b 的类替换。

我不确定这是否是 Java 设计的限制,或者是否有办法根据条件在该类中将一个类无缝替换为另一个类。

补充一点,插件系统本身不能修改,因为没有其他插件需要在运行时在两个类之间切换。

【问题讨论】:

  • 您要做的是定义一个接口并拥有实现该接口的子类。如果您使用的是 Spring,Boot 让这变得微不足道;如果你不是,SPI 使它易于管理。
  • @chrylis 我会调查一下,我特别想避免为此使用接口,因为在实际的插件系统中,类需要扩展,而接口不能扩展类。跨度>
  • 您仍然可以使用类来执行此操作,但在这种情况下,插件系统有缺陷,应该基于接口。
  • @chrylis 所以这里的问题是,插件系统将实例化任何定义为插件的东西,并且接口不能被实例化,所以这实际上是不可能的,因为目标是,基于某些条件之后类被实例化,要么使用一个或另一个的方法。
  • 另外补充一下,这是一个名为 RuneLite 的开源项目,因此您可以查看插件系统以供参考。考虑到这是一个开源项目的规模和广泛使用,我认为插件系统不会改变。

标签: java class object inheritance extends


【解决方案1】:

由于类的常量和最终性质,这是 Java 中的一个限制,它很容易使任何习惯使用具有这些语言特性的 C#/C++ 的人感到困惑。我绕过它。我最终为插件管理器编写了一个插件管理器,专门用于在其他类之间进行选择和实例化。这并不像我希望的那样优雅,但它确实有效。这是代码,'g.java'是插件管理器的插件管理器。

EntryPoint.java

public class EntryPoint {
    public static void main(String[] args) {
        new g();
    }
}

一个.java

public class a {
    public int the_func() {
        return 22;
    }
}

b.java

public class b extends a {
    @Override
    public int the_func() {
        return -1;
    }
}

g.java

// plugin loader simulation
public class g {
    public g() {
        System.out.println(new b().the_func());
    }
}

【讨论】:

    猜你喜欢
    • 2013-10-28
    • 1970-01-01
    • 2012-12-04
    • 1970-01-01
    • 1970-01-01
    • 2015-01-27
    • 1970-01-01
    • 1970-01-01
    • 2022-07-17
    相关资源
    最近更新 更多