Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/391.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在eclipse中提取将字段或常量值转换为参数的方法_Java_Eclipse_Refactoring - Fatal编程技术网

Java 如何在eclipse中提取将字段或常量值转换为参数的方法

Java 如何在eclipse中提取将字段或常量值转换为参数的方法,java,eclipse,refactoring,Java,Eclipse,Refactoring,情境:我正在处理遗留代码,并试图提高可读性。以下示例应将意图可视化: private static final String CONSTANT_1 = "anyValue"; private static final String CONSTANT_2 = "anyValue"; private static final String CONSTANT_3 = "anyValue"; private static final String CONSTANT_4 = "anyValue"; pri

情境:我正在处理遗留代码,并试图提高可读性。以下示例应将意图可视化:

private static final String CONSTANT_1 = "anyValue";
private static final String CONSTANT_2 = "anyValue";
private static final String CONSTANT_3 = "anyValue";
private static final String CONSTANT_4 = "anyValue";
private static final String CONSTANT_5 = "anyValue";

private final SomeType someField = new SomeType();

private void contentOfSomeMethods(){
    someMethod(someField, CONSTANT_1, true);
    someMethod(someField, CONSTANT_2, true);
    someMethod(someField, CONSTANT_3, true);
    someMethod(someField, CONSTANT_4, false);
    someMethod(someField, CONSTANT_5, false);
}

private void someMethod(SomeType type, String value, boolean someFlag) { }
想象一下,大约有50个someMethod调用使用了大约50个常量。我想对该代码进行安全自动的重构,以便某些方法的
内容更改为

private void contentOfSomeMethods(){
    doItWith(CONSTANT_1);
    doItWith(CONSTANT_2);
    doItWith(CONSTANT_3);
    doItNotWith(CONSTANT_4);
    doItNotWith(CONSTANT_5);
}
并生成另外两种方法:

private void doItWith(String value) {
    someMethod(someField, value, true);
}

private void doItNotWith(String value) {
    someMethod(someField, value, false);
}
最简单的方法是提取局部变量中某些方法的
contentOfSomeMethods
中的所有常量,然后使用提取方法重构来创建所需的方法。然后内联回本地变量。但是这个解决方案不能扩展

另一种方法是使用搜索并替换为正则表达式,但这不是一种安全的重构,因此我可以在不注意的情况下破坏代码


你有更好的建议吗?你知道Eclipse的一些插件可以做到这一点吗?

我不知道有任何实用程序可以直接做到这一点

我认为使用正则表达式是唯一可行的方法。首先,您需要创建两个目标方法
doItWith
doItNotWith
。然后,您可以突出显示某些方法的方法
contentOfSomeMethods
,点击Ctrl+F,并使用以下正则表达式:

查找:
someMethod\(someField,(\w*),true\)
替换为:
doItWith(\1)

然后

查找:
someMethod\(someField,(\w*),false\)
替换为:
doItNotWith(\1)

确保选中“正则表达式”和“选定行”。下面是它的图片:


正则表达式将函数调用中使用的常量与
(\w*)
匹配,然后在替换过程中使用
\1
。仅在所选行上使用此正则表达式可最大限度地减少中断不相关代码的可能性。

使用正则表达式并验证它

我假设对
someMethod
的每个调用只跨越一行。如果不是,这个方法仍然有用,但速度较慢

复制原始文件

使用ctrl+alt+h显示
someMethod
的调用者并获取他们的计数

执行正则表达式搜索并替换受限于适当区域的内容:
查找:someMethod(someField,([]*常量[0-9]+)[]*,[]*真[]*)[]*
替换:doItWith($1)
查找:someMethod(someField,([]*常量[0-9]+)[]*,[]*假[]*)[]*
将:doitnot替换为(“$1”)

对原始文件和新文件进行区分,仅显示原始文件中已更改的行

diff --changed-group-format='%<' --unchanged-group-format='' original.java refactored.java | wc

diff--changed group format='%唉,我不知道Eclipse中现在有什么允许这样做的。
这是我希望有一天在AutoRefactor中实现的目标:

然而,通往那里的路相当长


我现在知道的唯一方法是提取局部变量,然后提取方法(如您所建议)或使用正则表达式(如其他人所建议)。

我认为正则表达式是唯一的方法。为了最大限度地减少破坏无关代码的机会,您只能对一个选择进行更改。恐怕您是对的。正则表达式的问题也是复杂性。如果每个方法都有三个这样的常量,那么编写一个正则表达式就变得非常困难。如果我用正则表达式提供一个答案并尽量减少影响,可以吗?对我来说可以。如果没有更好的答案,这将对阅读此问题的其他人非常有帮助,因为他们至少有一个可扩展的解决方案。保存操作实际上意味着安全操作吗?谢谢您的解决方案。它特别说明了如何验证结果。这可能对真正的大班很有帮助。然而,手动验证不应该是自动重构的一部分。我希望找到一个不需要手动验证就可以应用的解决方案,因为您可以监督一些事情。@typichsherg使用ctrl+alt+h可以获得多少呼叫者?你从
grep someMethod source.java | wc
中得到了什么?@typichserg我强烈反对这句话:“但是手动验证不应该是自动重构的一部分”@typichserg我强烈反对这句话:“但是手动验证不应该是自动重构的一部分”。您对提交的代码负责,而工具不负责。重构工具可能有bug,或者它可能做了一些你意想不到的事情。经验法则是在提交前总是检查代码。@JnRouvignac:当你谈到提交前检查代码时,我同意你的观点。然而,当您回顾大约200行更改的代码时,您可能会忽略一些想法,因此我希望使用基于工具的代码分解。关于“工具可能有bug”是的,但是编译器也可能有bug,所以在向客户提供软件之前,您是否检查了类文件(并非有意挑逗)?我希望我的工具能正常工作。因此,我扩展了我的陈述:“然而,手动验证不应该是自动重构的一部分(但它仍然是提交工作流的一部分)”