提取参数
最后修改时间:2023 年 9 月 7 日重构 | 摘录| 范围
CtrlAlt0P
重构 | 摘录| 功能参数
CtrlAltShift0P
提取参数重构允许您提取方法的新参数。
您还可以使用提取功能参数重构。在这种情况下,IntelliJ IDEA 分析所选代码,找出提取片段的方法签名,找到具有此方法签名的所有功能接口,并根据所选接口使用匿名类包装代码片段并使用此匿名类作为参数。
在编辑器中,将插入符号放在要作为参数引入的表达式内。
按或转到重构 | 摘录| 范围。如果您想提取功能参数,请按或转到“重构 | ”。摘录| 功能参数。CtrlAlt0PCtrlAltShift0P
指定参数的名称,在“提取参数”弹出窗口中选择必要的选项。当您调用此重构时,IntelliJ IDEA 还会显示您可以用来配置更多选项。
例如,如果您不想更改现有方法调用,请选中“通过重载方法委托”复选框。
如果需要,按更改新参数的类型。(如果在此步骤中您想返回编辑参数名称,请按。)ShiftTabTab
提取参数示例
提取新参数时,您可以将参数引入到现有方法中,也可以使用“通过重载方法委托”选项来保存原始方法并使用您的参数定义新方法。
让我们用新参数替换"Hello, World!"
方法中的字符串值。该值将传递给更新后的方法调用中的方法。generateText ()
text
"Hello, World!"
generateText("Hello, World!")
前 | 后 |
---|---|
|
|
前 | 后 |
---|---|
|
|
现在让我们通过重载方法来使用Delegate。在这种情况下,将创建一个新的重载方法,并在该方法的定义中提取新参数(第二个方法generateText()
)。现有方法的签名generateText()
没有改变。然而,该方法本身已被修改。现在,它调用新generateText()
方法并在此调用中将值传递"Hello, World!"
给它。generateText()
请注意, (方法中)的现有调用print()
不会更改。
前 | 后 |
---|---|
|
|
前 | 后 |
---|---|
|
|
功能参数示例
System.out.println(s);
让我们在inside上执行重构Hello.printHello()
。
IntelliJ IDEA 会查找具有适当方法签名的所有功能接口(String) -> void
,并建议您选择其中之一。Person
(在本例中,选择了接口。)
结果,所选片段System.out.println(s);
被基于接口的匿名类包装Person
。该匿名类作为参数传递给printHello()
inside的调用printText()
。
Person
作为参数添加到printHello()
,并且最初选择的代码片段被替换为对接口方法的调用sayHello()
。
提示
@FunctionalInterface
仅建议标有 或属于知名库(如 Guava、Apache Collections 等)的接口。
前 | 后 |
---|---|
|
|
如果您希望在方法声明中提供一个字段作为新参数,则在方法调用中该字段将显示为类实例的字段。
如果类成员不可访问(例如,在上面的示例中,该字段是私有的),它将被插入到方法调用中,但会突出显示为错误,使该文件无法编译。
如果您使用提取参数重构带有 getter 的字段,系统将提示您一个扩展对话框。该对话框有一个选项组将表达式中使用的字段替换为它们的 getter:
不替换:任何字段都不会被对 getter 的调用替换。
替换使用上下文中无法访问的字段:只有无法从使用上下文直接访问的字段才会被调用 getter 替换。
替换所有字段:所有字段都将替换为对 getter 的调用。
对局部变量应用重构将调用带有附加复选框的“提取参数”对话框:
替换所有出现的情况(<number_of_occurrences> 出现次数):如果启用,所选变量的所有出现情况都将替换为参数,并且“删除变量定义”复选框处于启用状态。否则,只有选定的变量用法才会被参数替换。
删除变量定义:如果启用,变量定义将被删除。
使用变量初始化器来初始化参数:如果启用,变量初始化器将用于初始化方法调用中的参数。
如果应用于作为实际方法参数的类实例或表达式,则使用提取参数重构可能会产生意想不到的副作用。例如,如果有这样的代码:
class AClass {
int field;
int method() {
return field;
}
}
class Usage {
void method(List list) {
int sum = 0;
for(Iterator it = list.iterator(); it.hasNext(); ) {
sum += ((AClass) it.next()).method();
}
}
}
重构后的代码应用到该字段field
:
class AClass {
int field;
int method(int newfield) {
return newfield;
}
}
class Usage {
void method(List list) {
int sum = 0;
for(Iterator it = list.iterator; it.hasNext(); ) {
sum += ((AClass) it.next()).method(((AClass) it.next()).field);
}
}
}
迭代器值增加了两倍,这实际上不是您期望的行为。
但是,IntelliJ IDEA 可以成功使用临时变量并解决诸如递增/递减/赋值操作和 new 关键字使用等情况。例如:
public int myMethod(List list) {
return list.size();
}
public void anotherMethod() {
myMethod(new ArrayList());
}
重构后的相同代码如下所示:
public int myMethod(List list, int newPar) {
return list.size();
}
public void anotherMethod() {
final ArrayList list = new ArrayList();
myMethod(list, list.size());
}
新变量list
已创建,并且用于方法调用的所有参数均使用此变量提供。
提取参数对话框 (Java)
使用此对话框指定提取参数的设置。
物品 | 描述 |
---|---|
参数类型 | 指定新参数的类型。通常,您不需要更改 IntelliJ IDEA 建议的类型。 |
姓名 | 指定新参数的名称。 |
替换所有出现的地方 | 选择此选项可替换方法中出现的所有选定表达式。 |
宣布最终 | 选择此选项来声明参数 |
通过重载方法进行委托 | 选择此选项可保持现有方法调用不变。 结果,将创建一个新的重载方法,并将新参数添加到该方法的定义中。具有旧签名的方法将被保留。对新方法的调用将添加到旧方法中。必要的值(或表达式)将被传递给此调用中的新方法。 |
如果表达式包含对具有 getter 的类字段的直接调用,则以下选项可用。 | |
请勿更换 | 选择此选项可使用对字段的直接调用,而不管范围上下文如何。 |
替换使用上下文中无法访问的字段 | 选择此选项可仅在无法直接访问字段的情况下使用对 getter 的调用。 |
替换所有字段 | 选择此选项可使用对 getter 的调用。 |
当重构表达式包含局部变量时,以下选项可用。 | |
删除变量定义 | 选择此选项可删除局部变量的定义。 |
使用变量初始化器来初始化参数 | 选择此选项可在更正的方法调用中使用所选变量的默认值。
|
提取参数对话框 (Groovy)
使用此对话框指定与 Groovy 中的提取参数重构相关的选项和设置。
物品 | 描述 |
---|---|
类型 | 指定新参数的类型。通常,您不需要更改 IntelliJ IDEA 建议的类型。 |
姓名 | 指定新参数的名称。 |
宣布最终 | 选择此选项来声明参数 |
通过重载方法进行委托 | 选择此选项可保持现有方法调用不变。 结果,将创建一个新的重载方法,并将新参数添加到该方法的定义中。具有旧签名的方法将被保留。对新方法的调用将添加到旧方法中。必要的值(或表达式)将被传递给此调用中的新方法。 |
删除不再使用的参数 <name> | 选中此复选框可删除参数。 |
使用显式返回语句 | 如果该方法返回一个值,则此复选框处于活动状态。 |
参数 | 在此区域中,选择要传递给新方法/函数的参数。
|
上移/下移 | 使用这些按钮可以更改参数的顺序。 |
签名预览 | 在此只读字段中,查看新方法/函数的声明。 |
感谢您的反馈意见!