【问题标题】:A simple way to create static imports for constants in existing code?为现有代码中的常量创建静态导入的简单方法?
【发布时间】:2023-03-20 17:04:01
【问题描述】:

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

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

我可以在 Eclipse 中使用 Ctrl-Shift-M(将光标放在 BAR 上)来创建静态导入:

import static Foo.BAR;

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

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


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


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

【问题讨论】:

  • +1 用于简单地提到 Ctrl-Shift-M
  • 顺便说一句:对于那些在这里磕磕绊绊的人: ctrl-shift-m 正是为此而工作,将光标放在 BAR 上,按下它,你的静态导入(在 eclipse luna 中测试)在这里得到了更好的描述: codeaffine.com/2012/03/28/how-do-you-import-static-in-eclipse

标签: java eclipse


【解决方案1】:

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

所以你强迫读者做的是希望他的 IDE 会告诉他类(例如,通过工具提示),或者他们必须导航到它以找出它是什么。打印输出和代码 sn-ps 变得不那么可读了。

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

【讨论】:

  • 我知道这些事情。在这种特殊情况下,我有一个密钥持有者类,其密钥常量无处不在 - 因此您的关注不是问题,而是相反:D
  • 当问题是“我如何使用静态导入来做到这一点”时,我不认为“不要使用静态导入”是一个值得投票的答案。
  • 保护人们免受善意但被误导的目的是一种由来已久的回答问题的技巧。
  • 我不同意 - 我认为静态导入所有常量会使代码更具可读性。牺牲真正的代码简洁性和可读性来改进打印输出和代码 sn-ps 是可笑的。大多数情况下,常量的名称就足够了 - 如果我想找出它的来源,使用 IDE 不难找到它。
  • 有很多流畅的库,其中静态导入对于可读性至关重要(例如 Mockito、Hamcrest、Fest)。在这些情况下,我使用 eclipse 收藏夹来轻松管理静态导入,但是转换类中所有合格实例的方法肯定会很有用。
【解决方案2】:

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

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

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

【讨论】:

  • 其实它是 eclispe 中的一个可配置选项。您可以在使用“星形”导入之前声明所需的静态导入数量。我认为默认为 8。我已将其降低到 3 以供使用。
【解决方案3】:

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

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

这样的正则表达式

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

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

如果你有这样的表达式,可能会出现问题: FOO f = FOO.blah + "FOO.blah",所以要小心。

至于文件顶部的导入语句,eclipse 有一个自动导入功能,它会自动导入格式,只要导入的名称足够唯一,它就可以工作。或者,如果由于名称太常见而无法使用它,则可以只使用 perl 脚本来执行正则表达式,并在静态导入之前添加。

【讨论】:

  • 现在你有两个问题;-)
  • 不使用 Eclipse 中的重构工具意味着您忽略了 Eclipse 对您的代码的了解,而只处理原始源代码的文本表示。叹息。
  • 嗯,有时你想做的重构在 Eclipse 中是不支持的(虽然我觉得你在这里的这个特殊用例应该得到支持)
【解决方案4】:

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

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

然后在项目范围内组织导入,一切就绪。

不过要小心,如果你做错了,这也会造成很大的混乱。

【讨论】:

    【解决方案5】:

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

    【讨论】:

      【解决方案6】:

      如果我面临这样的挑战,我可能会编写一个小程序来为我做这件事。 Ruby 和 Python(JRuby 和 Jython?)非常适合这项任务,尽管您也可以在 Java 中完成。

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

      【讨论】:

        【解决方案7】:

        嗯,作为解决方案突然出现的东西。我建议使用一个简单的 groovy 脚本。基本上,语义与解析导入语句及其引用的文件有关。一些基本步骤可能像

        1. 递归目录中的每个文件。检查文件扩展名是否为.java
        2. 匹配任何以 import 开头的行
        3. 为每一行打开相关的源文件(您已经知道导入语句中的路径)。
        4. 使用反射匹配静态修饰符的字段/方法声明
        5. 在步骤 5 中找到的匹配项的导入语句后添加静态。

        如果我有时间,我会尝试发布一个小的 groovy 脚本来做同样的事情。

        【讨论】:

          【解决方案8】:

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

          替换所有的“Foo”。带空(“”)

          在顶部使用这条线。为我工作

          导入静态 Foo.*

          【讨论】:

          • 这不会删除“Foo”。来自源文件中的各个位置。
          • 如果 Foo 是一个常量类如何替换所有的“Foo”。用空(“”)并在顶部使用上面的行?
          • 选择“编辑”->“查找/替换”,或者按“Ctrl+F”。使用“Foo”作为查找文本,使用“”(空)作为替换文本,然后单击全部替换按钮。然后在导入部分添加 - import static Foo.* 。 Thorbjørn Ravn Andersen,每个 IDE 都支持替换所有功能。不能接受你的观点。
          • 在文本级别上执行此操作完全忽略了使用 IDE 的全部意义。如果这是我想静态导入的唯一来自 Foo 的东西怎么办?
          • 这只是一个技巧,可能不是极客的做法。我认为这将有助于您在字面上成千上万的这些,并且您不想要 Eclipse 以外的 IDE 以及当您的客户或老板等待您快速交付产品时。你比我更了解上下文。因此,仅当您认为这种方式有用时才使用。否则就忘了它。
          【解决方案9】:

          我不知道它是否符合您的需求,但您始终可以在接口中定义这些常量,并让您的所有类都实现该接口。然后按照其他人的建议使用一些智能 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);
             }
          }
          

          【讨论】:

          • 那将是一种可怕的编码方式——不要仅仅为了访问静态最终常量而创建和实现接口。
          • 我知道。我只是按照OP的想法。还是谢谢。
          猜你喜欢
          • 1970-01-01
          • 2016-10-25
          • 1970-01-01
          • 2017-12-07
          • 1970-01-01
          • 1970-01-01
          • 2013-10-05
          • 2023-01-26
          • 1970-01-01
          相关资源
          最近更新 更多