3

tl; dr:如何在不替换此类的情况下向现有类添加方法?

说明

当我在 JShell 中运行以下命令时:

public class TestClass {}

打印以下输出:

created class TestClass

再次运行此命令会给出以下输出:

modified class TestClass

让我们用一种方法创建类,如下所示:

public class TestClass {
    public static void testMethod1() {
        System.out.println("In testMethod1");
    }      
}

值得一提的是,输出与之前的类覆盖略有不同:

replaced class TestClass

运行testMethod1成功结束,并In testMethod1在控制台打印。

现在我想在TestClass不丢失的情况下将新方法添加到现有的testMethod1. 所以我运行以下代码段:

public class TestClass {
    public static void testMethod2() {
        System.out.println("In testMethod2");
    }      
}

...并且testMethod1丢失了,因为整体TestClass已被替换。

如何在不覆盖现有类的情况下向现有类添加新方法?如果我写了 10 种方法怎么办?我是否应该在要添加到类的新方法旁边写下现有方法?JShell 不应该以警告的形式提示用户要替换的类吗?

任何提示或帮助表示赞赏。

4

2 回答 2

3

JShell 无法做到这一点,我认为这不是大多数人想要的。如果您想定期合并到现有代码中,您可能希望使用一个能够保持源代码完整并从头开始编译源代码的编辑器。除了编译的字节码之外,JShell 还需要跟踪所有类型的源代码信息,以便满足您的需求。例如,如果您添加了一个已经作为桥接方法实现的方法作为定义泛型方法的结果会发生什么?

消息与替换修改不同的原因是因为 JShell 使用 HotSwap 只能在类不改变其形状时应用,即声明具有相同签名的相同方法和字段。

于 2017-02-24T09:51:37.377 回答
1

如何在不覆盖现有类的情况下向现有类添加新方法?

您可以使用

/edit

这将打开一个 Jshell 编辑板,您可以在其中添加新方法并接受以更新您的案例中的类定义。jshell命令name还说明了使用它们的或编辑多个片段的其他几个属性id。添加有关如何执行此操作的屏幕截图:

Jshell 编辑板

如果我写了 10 种方法怎么办?我是否应该在要添加到类的新方法旁边写下现有方法?

这样的用例似乎更关注 IDE 而不是基于 REPL 的 jshell,并且在 JEP#222 jshell 上明确提到为非目标:Java Shell (Read-Eval-Print Loop)

超出范围的是图形界面和调试器支持。JShell API 旨在允许 IDE 和其他工具中的 JShell 功能,但 jshell 工具并非旨在成为 IDE。


JShell 不应该以警告的形式提示用户要替换的类吗?

正如评论中提到的那样,第二个@Elliot,显然现在还没有。虽然这听起来很有趣,恕我直言,但必须同样权衡实施它的想法,同时不要降低工具的性能。@Rafael的回答提供了关于维持这种开销的提示。

于 2017-09-09T06:15:58.783 回答