JShell - 如何在不替换此类的情况下向现有类添加方法?

时间:2017-02-23 23:25:23

标签: java java-9 jshell

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提示用户关于以警告形式替换类吗?

感谢任何提示或帮助。

2 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分:1)

  

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

您可以使用

执行此操作
/edit

打开一个Jshell编辑板,您可以在其中添加新方法,接受以更新案例中的类定义。 jshell commands还说明了使用nameid修改多个代码段的其他几个属性。添加截图以了解如何执行此操作:

Jshell Edit Pad

  

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

这样一个用例似乎更多地关注IDE而不是基于REPL的jshell,并在JEP#222 jshell: The Java Shell (Read-Eval-Print Loop)

明确提到为非目标
  

超出范围的是图形界面和调试器支持。 JShell API旨在允许IDE和其他IDEhell功能   工具,但jshell工具不是一个IDE。

  

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

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