IntelliJ IDEA 2016.2 Help

Change Signature

In this section:

Basics

The Change Signature refactoring combines several different modifications that can be applied to a method signature. You can use this refactoring for the following purposes:

  • To change the method name.
  • To change the method return type.
  • To add new parameters and remove the existing ones.
  • To assign default values to the parameters.
  • To reorder parameters.
  • To change parameter names and types.
  • To propagate new parameters through the method call hierarchy.

When changing a method signature, IntelliJ IDEA searches for all usages of the method and updates all the calls, implementations, and override replacements of the method that can be safely modified to reflect the change.

Example

BeforeAfter
// The function paint() is declared in // the IShape interface. public interface IShape { function paint(g: Graphics): void; } // This function is then called within the // paint() function of the Canvas class. public class Canvas { private var shapes: Vector.<IShape>; public function paint(g: Graphics): void { for each (var shape: IShape in shapes) { shape.paint(g); } } } // Now we are going to show an example of the // Change Signature refactoring for the function // paint() of the IShape interface.
// In this refactoring example we have changed the name of the existing parameter // and introduced two new parameters. Note that the first of the new parameters is // a required parameter while the second is optional because the default value // for it is specified in the function definition. public interface IShape { function paint(graphics:Graphics, wireframe:Boolean, offset:Point = null):void; } // When performing this refactoring, the new parameters were propagated to // the paint() function of the Canvas class. As a result, the signature of // Canvas.paint() has changed. Also note how IShape.paint() within // Canvas.paint() is called now. public class Canvas { private var shapes: Vector.<IShape>; public function paint(g:Graphics, wireframe:Boolean): void { for each (var shape: IShape in shapes) { shape.paint(g, wireframe); } } } // Other results for this refactoring are possible. // For more information, see the discussion that follows.

Initializer, default value, and propagation of new parameters

For each new parameter added to a method, you can specify:

  • A value (or an expression) to be used for initializing the parameter (the Initializer field in IntelliJ IDEA).
  • A default value (or an expression) (the Default value field).

You can also propagate the parameters you have introduced to the methods that call the function whose signature you are changing.

The refactoring result depends on whether you specify the default value and whether you use propagation.

Propagation. New parameters can be propagated to any method that calls the method whose signature you are changing. In such case, generally, the signatures of the calling methods change accordingly.
These changes, however, also depend on the combination of the initializer and the default value set for the new parameters .

Initializer. The value specified in the Initializer field is added to the function definition as the default parameter value. This makes the corresponding parameter an optional parameter. (See the discussion of required and optional parameters in Flex/ActionScript documentation.)

If the default value for the new parameter is not specified (in the Default value field), irrespective of whether or not the propagation is used, the method calls and the signatures of the calling methods don't change.

If both, the initializer and the default value are specified, the refactoring result depends on whether or not the propagation is used:

  • If the propagation is not used, the initializer value don't affect the function calls and the signatures of the calling functions.
  • If the propagation is used, the initializer value is added to the definition of the calling function as the default value for the corresponding parameter (in the same way as in the function whose signature you are changing).

Default value. Generally, this is the value to be added to the method calls.

If the new parameter is not propagated to a calling method, the calls within such method will also use this value.

If the propagation is used, this value won't matter for the method calls within the calling methods.

More refactoring examples

To see how different refactoring settings discussed above affect the refactoring result, let us consider the following examples.

All the examples are a simplified version of the refactoring shown earlier. In all cases, a new parameter wireframe of the type Boolean is added to the function paint() defined in the IShape interface.

In different examples, different combinations of the initializer and the default value are used, and the new parameter is either propagated to Canvas.paint() (which calls IShape.paint()) or not.

InitializerDefault valuePropagation usedResult
falseYes
public interface IShape { function paint(g:Graphics, wireframe:Boolean):void; } // The function paint() in the Canvas class: public function paint(g:Graphics, wireframe:Boolean): void { for each ( var shape: IShape in shapes) { shape.paint(g,wireframe); } }
falseNo
public interface IShape { function paint(g:Graphics, wireframe:Boolean):void; } // The function paint() in the Canvas class: public function paint(g:Graphics): void { for each ( var shape: IShape in shapes) { shape.paint(g,false); } }
trueYes
public interface IShape { function paint(g:Graphics, wireframe:Boolean = true):void; } // The function paint() in the Canvas class: public function paint(g:Graphics): void { for each ( var shape: IShape in shapes) { shape.paint(g); } }
trueNo
public interface IShape { function paint(g:Graphics, wireframe:Boolean = true):void; } // The function paint() in the Canvas class: public function paint(g:Graphics):void { for each ( var shape: IShape in shapes) { shape.paint(g); } }
truefalseYes
public interface IShape { function paint(g:Graphics, wireframe:Boolean = true):void; } // The function paint() in the Canvas class: public function paint(g:Graphics, wireframe:Boolean = true): void { for each ( var shape: IShape in shapes) { shape.paint(g,wireframe); } }
truefalseNo
public interface IShape { function paint(g:Graphics, wireframe:Boolean = true):void; } // The function paint() in the Canvas class: public function paint(g:Graphics): void { for each ( var shape: IShape in shapes) { shape.paint(g,false); } }

Changing a method signature

  1. In the editor, place the cursor within the name of the method whose signature you want to change.
  2. Do one of the following:
    • Press Ctrl+F6.
    • Choose Refactor | Change Signature on the main menu or .
    • Choose Refactor | Change Signature on the context menu.
  3. In the Change Signature dialog, make the necessary changes to the method signature and specify what other, related, changes are required.

    You can:

    • Change the method name. To do that, edit the text in the Name field.
    • Change the method return type by editing the contents of the Return type field.
    • Manage the method parameters using the table and the buttons in the Parameters area:
      • To add a new parameter, click add and specify the properties of the new parameter in the corresponding table row.

        When adding parameters, you may want to propagate these parameters to the methods that call the current method.

        In the PHP context, when the Change signature refactoring is invoked from the constructor of a class, the new parameter can be initialized as a class field. To do that, use the Create and initialize class properties check box:

        • When this check box is selected and you add a parameter, this parameter is initialized as a field. IntelliJ IDEA creates a protected field with the same name as this parameter and adds a line with the following assignment: $this-><parameter_name> = $<parameter_name>;
        • When the check box is cleared, a parameter is added without initialization.

        For example, you have the following constructor:

        class ChangeSignatureNewParam { function __construct() { $a = "Constructor in ChangeSignatureNewParam"; print $a; } }
        If you invoke the Change signature refactoring from the __construct() method and add a new $q parameter, the result will depend on whether you select or clear the Create and initialize class properties check box:

        The Create and initialize class properties check box is selected The Create and initialize class properties check box is cleared
        class ChangeSignatureNewParam { private $q; function __construct( $q ) { $a = "Constructor in ChangeSignatureNewParam"; print $a; $this->q = $q; } }
        class ChangeSignatureNewParam { function __construct( $q ) { $a = "Constructor in ChangeSignatureNewParam"; print $a; } }
      • To remove a parameter, click any of the cells in the corresponding row and click delete.
      • To reorder the parameters, use the arrowUp and arrowDown buttons. For example, if you wanted to put a certain parameter first in the list, click any of the cells in the row corresponding to that parameter, and then click arrowUp the required number of times.
      • To change the name, type, the initializer, or the default value of a parameter, make the necessary edits in the table of parameters (in the fields Name Type, Initializer and Default value respectively).
    • Propagate new method parameters (if any) along the hierarchy of the methods that call the current method.

      (There may be methods that call the method whose signature you are changing. These methods, in their turn, may be called by other methods, and so on. You can propagate the changes you are making to the parameters of the current method through the hierarchy of calling methods and also specify which calling methods should be affected and which shouldn't.)

      To propagate a new parameter:

      1. Click the Propagate Parameters button propagateParameters.
      2. In the left-hand pane of the Select Methods to Propagate New Parameters dialog, expand the necessary nodes and select the check boxes next to the methods you want the new parameters to be propagated to.

        To help you select the necessary methods, the code for the calling method and the method being called is shown in the right-hand part of the dialog (in the Caller Method and Callee Method panes respectively).

        As you switch between the methods in the left-hand pane, the code in the right-hand pane changes accordingly.

      3. Click OK.
  4. To perform the refactoring right away, click Refactor.

    To see the expected changes and make the necessary adjustments prior to actually performing the refactoring, click Preview.

See Also

Last modified: 23 November 2016