我可以使用重构来将变量的类型换成另一个变量吗?

kir*_*wka 19 java refactoring android-studio

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

LinearLayout layout = (LinearLayout) v.findViewById(....);
// ........
// A bunch of code using `layout` many times
Run Code Online (Sandbox Code Playgroud)

我怎样才能快速重构LinearLayoutRelativeLayout,并将它应用到代码太多的休息吗?我可以为田地做同样的事情吗?

Xav*_*ler 28

简答

你正在寻找的功能是Type Migration!

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

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

只需选择要迁移到的类型,单击重构,Android Studio即可开始发挥其魔力!


长而详细的答案

你似乎误解了Rename实际上做了什么.

Rename可以用来字面重命名元素.因此,您可以使用它更改变量,参数,方法或类的名称.例如,如果您有一个名为的类,Foo并且您想要更改其名称,则Bar可以轻松地使用Rename.

但是你不能重命名,LinearLayout因为它是框架类,当然不能修改.但这应该不是问题,因为你实际上并不想重命名LinearLayout,是吗?你真正想要做的是从更改类型LinearLayoutRelativeLayout.并且还有另一个非常有用的重构功能,它被称为Type Migration.

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

这是一个Type Migration工作的例子.我开始使用这段代码:

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) {
    ...
}
Run Code Online (Sandbox Code Playgroud)

现在我执行Type MigrationRelativeLayout的局部变量layoutdoStuff().结果如下:

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) {
    ...
}
Run Code Online (Sandbox Code Playgroud)

正如你所看到的Type Migration那样做得很好.字段的类型甚至参数的类型fooTheBar()已更改为RelativeLayout.只有一次冲突.Android Studio无法自动更改最顶层的演员类型doStuff().我必须手动修复它.正如我之前提到的那样,在执行重构时我被警告了这个冲突.

你当然可以问问自己为什么它可以自动改变字段和参数的类型但是不能改变演员的类型,但是如果你考虑它实际上很有意义:

它无法自动迁移的代码部分是(LinearLayout) container.findViewById(R.id.linearLayout).这种方法当然会查找View带有id的a R.id.linearLayout.这View可以在布局xml中定义,也可以container在运行时动态添加,但在任何情况下都不能自动重构而不会有破坏功能的风险.这只是开发人员可以决定如何处理的事情,这就是你被警告的原因.