【问题标题】:Can I use refactoring to exchange the type of a variable for another?我可以使用重构来将一个变量的类型交换为另一个变量吗?
【发布时间】:2023-04-06 15:59:01
【问题描述】:

Android Studio 提供了强大的重构功能,例如 Rename。我可以使用它来更改变量、字段、参数的名称,但是我似乎找不到重命名类型的方法。例如:

LinearLayout layout = (LinearLayout) v.findViewById(....);
// ........
// A bunch of code using `layout` many times

如何快速将LinearLayout 重构为RelativeLayout 并将其也应用于其余代码?我可以对字段做同样的事情吗?

【问题讨论】:

    标签: java android-studio refactoring


    【解决方案1】:

    对于 Kotlin 文件中的 Type Migration

    假设您想在以下函数中将输入参数从String 更改为Int

    fun getValue(key: String){
    }
    
    1. 将光标放在要更改的类型(本例中为字符串)

    2. 右键 > 重构 > 改变 签名。或使用以下快捷方式执行此步骤:

      • Mac: + F6
      • Windows:Ctrl + F6(未测试)
    3. 完成步骤 2 将打开此窗口,单击以蓝色突出显示的行:

    1. 将类型替换为您想要的任何内容,然后单击重构

    【讨论】:

      【解决方案2】:

      简答

      你要找的函数是Type Migration

      Type Migration 可以通过右键单击变量或字段的类型,然后选择Refactor -> Type Migration 来执行。或者,您可以使用以下键盘快捷键:

      • 在 Mac 上:Shift + + F6
      • 在 Windows 上:Shift + Ctrl + F6

      只需选择要迁移到的类型,点击重构,Android Studio 就会开始发挥它的魔力!


      长而详细的答案

      您似乎误解了 Rename 的实际作用。

      Rename 可用于逐字重命名元素。因此,您可以使用它更改变量、参数、方法或类的名称。例如,如果您有一个名为Foo 的类,并且您想将其名称更改为Bar,您可以使用Rename 轻松完成。

      但你不能重命名LinearLayout,因为它是框架类,当然不能修改。然而,这根本不应该是一个问题,因为您实际上并不想重命名LinearLayout,是吗?您真正想要做的是将类型从LinearLayout 更改为RelativeLayout。还有另一个非常有用的重构功能可以做到这一点,它被称为 Type Migration

      您可以执行 Type Migration,方法是右键单击要交换其类型的任何变量,然后选择 Refactor -> Type Migration kbd>。之后会弹出一个对话框,您可以输入要迁移到的类型,在您的情况下为RelativeLayout。然后只需单击Refactor,Android Studio 就会开始发挥它的魔力。可能会有一个额外的弹出窗口通知您代码中无法自动迁移的所有内容。只需浏览冲突列表,完成后点击 Ignore 并手动修复这些冲突。

      这是一个类型迁移的例子。我从这段代码开始:

      private LinearLayout mLayout;
      
      private void doStuff(ViewGroup container) {
          LinearLayout layout = (LinearLayout) container.findViewById(0);
      
          layout.setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View v) {
                  ...
              }
          });
      
          mLayout = layout;
          fooTheBar(layout);   
      }
      
      private void fooTheBar(LinearLayout layout) {
          ...
      }
      

      现在我对doStuff() 中的局部变量layout 执行了类型迁移RelativeLayout。结果如下所示:

      private RelativeLayout mLayout;
      
      private void doStuff(ViewGroup container) {
          // Here is the only conflict which could not be refactored automatically.
          // I had to change the cast to RelativeLayout manually.
          RelativeLayout layout = (LinearLayout) container.findViewById(R.id.linearLayout);
      
          layout.setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View v) {
                  ...
              }
          });
      
          mLayout = layout;
          fooTheBar(layout);
      }
      
      private void fooTheBar(RelativeLayout layout) {
          ...
      }
      

      如您所见,Type Migration 做得很好。 fooTheBar()的字段类型甚至参数类型都更改为RelativeLayout。只有一场冲突。 Android Studio 无法自动更改 doStuff() 顶部的演员表类型。我不得不手动修复它。正如我之前提到的,我在执行重构时被警告过这种冲突。

      您当然可以问自己为什么它可以自动更改字段和参数的类型但不能更改强制转换的类型,但是如果您考虑一下这实际上很有意义:

      它无法自动迁移的部分代码是(LinearLayout) container.findViewById(R.id.linearLayout)。这种方法当然会查找 ID 为 R.id.linearLayoutViewView 可能在布局 xml 中定义,也可能在运行时动态添加到 container,但无论如何,它不能自动重构而不会破坏功能。这是只有开发人员才能决定如何处理的事情,这就是您被警告的原因。

      【讨论】:

      • 太好了,谢谢!我没有想到 right-click 在类型而不是字段上,这就是为什么 Type Migration 选项未被注意到的原因。
      • 这在 Java 文件上工作得很好,但是,在 Kotlin 文件中没有选项 type migration。 Kotlin 的任何解决方法?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-31
      • 1970-01-01
      • 1970-01-01
      • 2016-03-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多