Early Access Program Features

IntelliJ IDEA 14.1 Introduces Extract Functional Parameter Refactoring

              Extract Surrounding Method: You have two methods that contain nearly identical code. The variance is in the middle of the method. Extract the duplication into a method that accepts a block and yields back to the caller to execute the unique code.

Jay Fields, Shane Harvie

In Java, if we want to replace a block inside a method, the block should have a ‘known shape’ for surrounding code to be able to call it. Let’s perform a code transformation with the following example, step by step:

private void foo() {
  int i = 0;
  <selection>System.out.println(i * i);</selection>
}

  1. Call Extract Method from the block to see the signature (make sure you cancel it afterwards). In our case the signature is (int i) -> void

  1. Find an interface I, which could be implemented with this method

In our case, java.util.function.Consumer<Integer> with a shape (Integer) -> void will do.

  1. Wrap the code block with an anonymous class based on I:

new Consumer<Integer>() {
      public void accept(Integer i) {
          System.out.println(i * i);
      }
}.accept(i);

  1. Extract the anonymous class as parameter.

The result will be:

private void foo(final Consumer<Integer> consumer) {
   int i = 0;
   consumer.accept(i);
}

Now we can pass different implementations of I to the surrounding method, though everything else remains the same. The only tricky part here is to find the interface I. This is how the new Extract Functional Parameter refactoring was born.

When you call this refactoring, it asks you to choose one of the available applicable functional interfaces, and then performs the rest automatically:

Screen Shot 2015-01-23 at 11.55.56.png

With the introduction of lambdas and method references, many functional interfaces were added. To distinguish them from sporadic single-method interfaces that could evolve, IntelliJ IDEA requires them to be marked with @FunctionalInterface or belong to well-known libraries (e.g. Guava, Apache Collections, etc.).

Extract Functional Parameter is already available in IntelliJ IDEA 14.1 EAP. Do give it a try and tell us what you think. Share your feedback on the discussion forum and in our issue tracker.

Develop with Pleasure!