在现有代码中为常量创建静态导入的简单方法?

时间:2009-05-05 09:11:36

标签: java eclipse

如果我在Foo中有一个常量BAR,我将在C类中使用,我将不得不写

Object o = Foo.BAR + "...";

我可以在Eclipse中使用Ctrl-Shift-M(光标位于BAR上)来创建静态导入,如下所示:

import static Foo.BAR;

Object o = BAR + "....";

我目前正在更新遗留代码,其中有数以千计的这些代码我想转换为静态导入。 Ctrl-Shift-O / Organize导入不会这样做。有没有我错过的技巧?


编辑:实际上,我更喜欢的是告诉Eclipse我想让Ctrl-Shift-M在这个特定类中的所有实例上发挥其魔力,而不仅仅是我放置光标的单个实例。 (这是遗留代码所以这实际上提高了可读性:))


编辑:我发现IntelliJ建议这样做。

9 个答案:

答案 0 :(得分:11)

一个注意事项:过度使用静态导入实际上会使代码的可读性降低(imho),特别是如果常量名称没有明确指出它所属的类或枚举。您还可以从听起来相似甚至名称相同的不同类/枚举中获取常量名称。

所以你强迫读者做的是希望他的IDE能告诉他课程(通过工具提示),或者他们必须导航到它以找出它是什么。打印输出和代码片段的可重复性要低得多。

老实说,由于这些原因,我极少使用静态导入。

答案 1 :(得分:3)

我不知道还有其他任何自动重构来做你正在寻找的东西,但这有两个关键方面 - 一个是添加导入,另一个是从常量中删除类名。

为了添加导入,我建议在每个使用它们的文件包之后粘贴import static application.KeyHolder.*;

为了删除类名,在eclipse中对KeyHolder.*进行Java搜索并搜索字段。然后,您可以执行“KeyHolder”的查找/替换。并替换为“”。为了防止不匹配,请确保替换的项目数等于该文件的匹配数。此外,请确保搜索并在导入后开始。

答案 2 :(得分:2)

发明正则表达式来解决这些问题! =)

您需要编写一个小脚本(或使用IDE正则表达式搜索/替换)。唯一的问题是,如果有许多类需要静态导入,那么它的工作量也一样多。否则,如果只有一个类如FOO.BLAH,那么你可以使用像

这样的正则表达式

(\bFOO\.(\w+)\b) - >替换为第2组($ 2或\ 2或者你的正则表达式搜索者确实捕获替换)。

你可以在这里试试:http://www.gskinner.com/RegExr/。选择替换选项卡并输入$ 2

如果你有这样的表达式,可能会出现问题: FOO f = FOO.blah + "FOO.blah",请注意这一点。

对于文件顶部的import语句,eclipse有一个自动导入功能,它在格式上自动导入,只要导入的名称足够独特,它就可以工作。或者,如果您因为名称太常见而无法使用它,则可以使用perl脚本来代替正则表达式,并预先添加静态导入。

答案 3 :(得分:1)

听起来不错,但是在更改了所有文件后,它们会有多好?也许您应该考虑仅因为其他原因而更改您正在处理的文件。

答案 4 :(得分:0)

如果我遇到这样的挑战,我可能会写一个小程序来为我做这件事。 Ruby和Python(JRuby和Jython?)非常适合这项任务,不过你也可以用Java来完成。

好的,所以这可能会让你至少花费相同的时间来手工操作,但至少你会玩得开心:)。

答案 5 :(得分:0)

Eclipse可以进行全局搜索,并使用正则表达式替换项目中的所有文件。

要在所有文件的开头添加静态导入,您可以自行替换包声明以及静态导入。

然后做一个项目范围的组织导入,你就完成了。

但要小心,如果你做错了,这也可能会造成很大的麻烦。

答案 6 :(得分:-1)

好的东西作为解决方案而出现。我建议使用一个简单的groovy脚本。基本上,语义与解析import语句及它们引用的文件有关。一些基本步骤可能就像

  1. 递归目录中的每个文件。检查文件扩展名是否为.java
  2. 匹配任何以导入
  3. 开头的行
  4. 对于每个这样的行打开相关的源文件(您已经知道了import语句中的路径)。
  5. 使用反射
  6. 匹配静态修改器的字段/方法声明
  7. 在步骤5中找到的匹配项的import语句后添加static。
  8. 如果我有时间,我会尝试发布一个小的groovy脚本来做同样的事情。

答案 7 :(得分:-2)

确保与其他常量类没有冲突

取代所有的“Foo”。空(“”)

在顶部使用此行。为我工作

import static Foo。*

答案 8 :(得分:-3)

我不知道它是否符合您的需求,但您始终可以在界面中定义这些常量,并让所有类只实现此接口。然后使用一些智能RegExp,如其他人建议您可以摆脱所有Foo.出现。

示例:

public interface Foo {
   static final String constant1 = "Some";
   static final String constant2 = "Value";
   //...
}

然后

public class YourClass implements Foo {
   public YourClass() {
      System.out.println("Hello " + constant1);
   }
}