【问题标题】:Refactor a reference variable in part of code in Eclipse在 Eclipse 中重构部分代码中的引用变量
【发布时间】:2014-05-03 14:07:57
【问题描述】:

我将如何只在部分代码中重命名变量?

例如:

System.out.println("Rectangle 1: " + "\n" + "Width: " + r1.width + "\n" + "Height: " +
        r1.height + "\n" + "Color: " + r1.color + "\n" + "Area and Perimeter: " + 
                r1.getArea(r1.width, r1.height) + ", " + r1.getPerimeter(r1.width, r1.height));

因此,如果我想使用 r2 作为 refVar 为第二个矩形输入相同的内容,有没有办法可以快速做到这一点?我尝试复制和粘贴,然后使用 Alt + Shift + R,但是,它最终改变了所有 r1 refvars。

【问题讨论】:

  • 为什么不创建另一个矩形对象?
  • 是否创建单独的方法可以为传递的 Rectangle 生成此输出选项?看看en.wikipedia.org/wiki/Don%27t_repeat_yourself
  • 我有另一个 r2 对象,只是我想打印他们的详细信息。我应该只使用一个 toString() 方法来返回一个字符串中的所有对象字段吗?编辑:@Pshemo 是的,我想我会这样做

标签: java eclipse refactoring rename


【解决方案1】:

查看don't repeat yourself (DRY) 原则,该原则旨在防止像您这样的情况。与其重命名变量,不如创建单独的方法,该方法将接受任何 Rectangle 并打印其详细信息。

public static void printRectangleDetails(Rectangle r){

    System.out.println("Rectangle 1: " + "\n" + "Width: " + r.width + "\n" + "Height: " +
            r.height + "\n" + "Color: " + r.color + "\n" + "Area and Perimeter: " + 
                    r.getArea(r.width, r.height) + ", " + r.getPerimeter(r.width, r.height));
}

现在您可以在需要时将它与 r1r2 矩形一起使用

printRectangleDetails(r1);
...
printRectangleDetails(r2);

如果由于某种原因您无法创建单独的方法并使用 DRY 原则,您可以执行以下操作:

假设我们有

String foo = "foo";
System.out.println(foo+" hello wordls"+ foo);

String bar = "bar";
System.out.println(foo+" hello wordls"+ foo);

并且您想将第二个打印语句中的foo 替换为bar。在第二个打印语句上使用 Alt + Shift + R (或从菜单:Refactor -> Rename..)将重命名所有 @987654332 @ 参考 。为了防止它重新声明您的 foo 引用(编译器会给您错误,但不要担心,我们稍后会删除它,它仅在重命名过程中有用)就在您想要将 foo 更改为 @ 的语句之前987654335@点赞

String foo = "foo";
System.out.println(foo+" hello wordls"+ foo);

String bar = "bar";
String foo = "whatever";
//     ^^^
System.out.println(foo+" hello wordls"+ foo);

现在在这个新的重复 foo 上使用 Alt + Shift + R 并且 Eclipse 将从这个新参考中查找 foo ,并忽略之前的foos,所以你应该能够看到类似的东西

(如您所见,前两个 foo 未被选中进行重命名)
所以你可以把它改成bar

String foo = "foo";
System.out.println(foo+" hello wordls"+ foo);

String bar = "bar";
String bar = "whatever";
System.out.println(bar+" hello wordls"+ bar);

然后删除这个额外的String bar = "whatever";,因为你不再需要它了。

但要小心。这样,您将在重复的 foo 之后重命名所有 foo 变量,而不仅仅是要重命名的 System.out.println(foo+" hello wordls"+ foo); 中的变量。为了确保您没有更改任何您不想更改的内容,请将您想要更改的代码放在方法的末尾(您确定没有 foo 之后不应更改)。完成后,将更改后的代码移动到您想要的位置。

【讨论】:

  • 如果觉得,如果只是为了打印结果,重写 toString 方法会是一个更好的选择。
  • @user2900314 好吧,这取决于。一般来说,我们覆盖 toString 以创建可以在日志和错误消息中使用的非常简短的对象描述,并且我们创建单独的方法来生成更具描述性的输出/字符串。但是是的,如果 OP 可以更新 Rectangle 类,那么将这个方法添加到它会比在其他类中创建一个更好。
  • 用户可能对只提取几行(这里是 3 行)代码到方法不感兴趣。
  • @ChandrayyaGK DRY 原则描述了在这种情况下应该做什么,与想不想做无关。请记住,好的代码的另一个一般规则是不要创建很长的方法(它们的主体应该在一个屏幕上完全可见)所以只要你觉得可以使用“分而治之”来使代码更具可读性,在这种情况下r1.printDetails();printRectangleDetails(r1) 可以。
  • @ChandrayyaGK 我更新了我的答案以涵盖 OP 无法创建新方法的情况(假设公司出于某种原因禁止它)。看一下,如果这涵盖了您感兴趣的案例。
【解决方案2】:

我建议您使用 Find/Replace 对话框来解决这个问题,它适合您的需要。选择一组语句,然后按 Ctrl + F。将弹出一个查找/替换对话框,注意在 Scope 组中选择了 Selected lines 选项。

您可以使用全部替换替换/查找。但请注意,如果找到它,它也会替换 cmets 中的字符串。

参考下图。

【讨论】:

  • 正如你所说,这种方法是不安全的,因为可能会有误报结果,r1 可以在许多不需要的地方更改。在这种情况下,OP 必须使用此工具对所有搜索结果进行手动迭代,并选择是否应更改。我相信 OP 正试图避免它,并正在寻找一种方法/工具来自动完成它,而不是手动完成。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-22
  • 1970-01-01
  • 2022-01-12
  • 1970-01-01
  • 2016-09-05
  • 1970-01-01
  • 2015-07-05
相关资源
最近更新 更多