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:

  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:

  1. Extract the anonymous class as parameter.

The result will be:

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!

This entry was posted in EAP Releases, New Features and tagged , . Bookmark the permalink.

7 Responses to IntelliJ IDEA 14.1 Introduces Extract Functional Parameter Refactoring

  1. ks says:

    Cool feature!

    “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.).”

    To prioritize well-known would be one thing but to require @FunctionalInterface seems a bit much. I’d like to be able to search and pick from the ‘sporadic’ interfaces defined by my project w/o having to go through and annotate everything (as simple as it may be to do so). The available interfaces list should be: @FunctionalInteface, followed by well-known, followed by project interfaces, followed by ‘sporadic’ one-offs.

  2. Anna Kozlova says:

    Thanks!

    Actually at first I thought exactly like you. Then I’ve got 1000 single-method interfaces in IDEA project and each of them should be checked: this slowed down everything a lot and didn’t bring much value: I extract strategies into “well-known” interfaces rather than e.g. into listeners, do you?

    Anna

    • ks says:

      Maybe if the current project interfaces were considered ‘well-known’ ?? I see your point that scanning dozens/hundreds of dependency jars would be inhibitive.

  3. Lars says:

    Please make this for Scala!

  4. Alex Dommasch says:

    It would be great to have “Extract Functional Variable” as well (e.g., convert a block of code into a local-variable lambda). Use case: having similar code patterns scattered around that have variable “cores”; would like to extract cores into lambdas in each case, and then extract method once (and let IDEA find code duplicates).

    I managed to abuse “Extract Method”, “Extract Functional Variable”, “Inline Method” in various combinations to achieve the same effect, but it would be nice to have it more direct. (And what would be *really* amazing is if IDEA could identify potential extracted lambdas automatically when looking for code duplicates – but that’s a lot to ask.)

Leave a Reply

Your email address will not be published. Required fields are marked *