{"id":27218,"date":"2019-04-12T05:08:39","date_gmt":"2019-04-12T05:08:39","guid":{"rendered":"https:\/\/blog.jetbrains.com\/idea\/?p=19531"},"modified":"2019-04-12T05:08:39","modified_gmt":"2019-04-12T05:08:39","slug":"refactoring-extract-variable-in-intellij-idea","status":"publish","type":"idea","link":"https:\/\/blog.jetbrains.com\/pt-br\/idea\/2019\/04\/refactoring-extract-variable-in-intellij-idea","title":{"rendered":"Refactoring: Extract Variable in IntelliJ IDEA"},"content":{"rendered":"<p>As a code base ages, new code is added, and the existing code is modified to meet the business requirements. This can often have a negative impact on the design and structure of the code. Developers may fear\u00a0working with such code as it is difficult to understand, modify, or extend.<\/p>\n<p>As a developer, you can take redundancy and complexity out of your code, by refactoring it. <a href=\"https:\/\/en.wikipedia.org\/wiki\/Code_refactoring\" target=\"_blank\" rel=\"noopener\">Refactoring<\/a> is the process of improving your source code without creating any new functionality. It helps you keep your code <a href=\"https:\/\/en.wikipedia.org\/wiki\/SOLID\" target=\"_blank\" rel=\"noopener\">SOLID<\/a>, <a href=\"https:\/\/en.wikipedia.org\/wiki\/Don%27t_repeat_yourself\" target=\"_blank\" rel=\"noopener\">DRY<\/a>, and easy to maintain. Even though clean code bases and code refactoring is crucial (code maintenance accounts for about 80% of a project\u2019s cost), it is often avoided or put off because it <strong>can<\/strong> break your existing code.<\/p>\n<p>In this blog post,\u00a0we will take a look at how IntelliJ IDEA can help you to refactor your code <strong>safely<\/strong> with Variable refactorings,\u00a0and talk about some of the\u00a0<strong>dos<\/strong> <strong>and don&#8217;ts <\/strong>we need to be aware of. Let&#8217;s get started.<!--more--><\/p>\n<h1>Extract Variable Refactoring<\/h1>\n<p>The Extract Variable refactoring lets you simplify an expression and remove its redundant parts.<\/p>\n<p>If an expression is hard to understand or it is duplicated in several places throughout your code, you can place the result of such expression (or a part of it) into a separate variable that is less complex and easier to understand.<\/p>\n<h2>Introducing a variable for readability<\/h2>\n<p>Let&#8217;s introduce a variable to simplify the expression that assigns a value to the variable <code>result<\/code>. Select the expression you want to extract into another variable, and press Ctrl+Alt+V (on Windows)\/ Cmd+Alt+V (on Mac). You can also choose to define the extracted variable as <code>final<\/code>\u00a0or declared using type <code>var<\/code>. IntelliJ IDEA gives a default name to the extracted variable, which you can then modify:<\/p>\n<p><img decoding=\"async\" class=\"alignnone wp-image-16062\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2019\/04\/idea-mg-basic-extract-var-cover.png\" alt=\"\" width=\"700&quot;\" height=\"280\" data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2019\/04\/idea-mg-basic-extract-var-5ec.gif\" \/><\/p>\n<h2>Reducing duplicate sub-expressions<\/h2>\n<p>IntelliJ IDEA is quick to detect if the expression that you are extracting into another variable is duplicated in multiple places. If it is, then it offers to replace <em>one<\/em> or <em>all<\/em>\u00a0the occurrences of the selected expression. You can also change the default variable name suggested by IntelliJ IDEA.<\/p>\n<p>If you\u00a0are replacing multiple occurrences of an expression, IntelliJ IDEA can detect where and how you have used it. For example, if an expression is used both in the\u00a0<em>then<\/em> and <code>else<\/code> branches of an <code>if<\/code> statement, IntelliJ IDEA extracts and defines it before it starts:<\/p>\n<p><img decoding=\"async\" class=\"alignnone wp-image-16062\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2019\/04\/idea-mg-redundant-code-extract-var-png.png\" alt=\"\" width=\"700&quot;\" height=\"280\" data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2019\/04\/idea-mg-redundant-code-extract-var-5sec.gif\" \/><\/p>\n<p>Part of the expression that you extract into a variable could <em>also<\/em> include a method call. Let&#8217;s have a look at how IntelliJ IDEA can help you replace one or all of these occurrences:<\/p>\n<p><img decoding=\"async\" class=\"alignnone wp-image-16062\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2019\/04\/idea-mg-extract-var-fixedmethod-cover.png\" alt=\"\" width=\"700&quot;\" height=\"280\" data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2019\/04\/idea-mg-extract-var-fixedmethod-5sec.gif\" \/><\/p>\n<h2>Extract variable from field initializer<\/h2>\n<h3>(New in IntelliJ IDEA 2019.1)<\/h3>\n<p>You can find complex expressions in various places, including a field initializer. When you try to simplify such an expression, IntelliJ IDEA will move the extracted variable to an instance initializer. If you think that that&#8217;s unexpected\u00a0\u2013 read on.<\/p>\n<p>If you decompile bytecodes of a class, you&#8217;ll realize that a field (or instance variable) is initialized in a class constructor. So even if you initialize a field with its declaration, the compiler would move its initialization code to the constructor. Also, all the code in the instance initializers is moved to class constructors, in the order\u00a0that they appear in the class. This explains why IntelliJ IDEA moves the extracted variable from a field initializer to an instance initializer, as demonstrated here:<\/p>\n<p><img decoding=\"async\" class=\"alignnone wp-image-16062\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2019\/04\/idea-mg-field-cover.png\" alt=\"\" width=\"700&quot;\" height=\"280\" data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2019\/04\/idea-mg-field-5ec.gif\" \/><\/p>\n<p>Similarly, if a static variable uses a complex expression in its initialization, IntelliJ IDEA can simplify the expression for you. Just select the part of the expression you want to extract in a new extract variable. With static variables, this code would be defined within a static initializer block:<\/p>\n<p><img decoding=\"async\" class=\"alignnone wp-image-16062\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2019\/04\/idea-mg-static-cover.png\" alt=\"\" width=\"700&quot;\" height=\"280\" data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2019\/04\/idea-mg-static-5sec.gif\" \/><\/p>\n<h2>Simplifying expressions with ternary operator<\/h2>\n<h3>(New in IntelliJ IDEA 2019.1)<\/h3>\n<p>Ternary operators offer a concise way to define a simple <code>if<\/code>&#8211;<code>else<\/code> statement. You can evaluate a boolean expression and return a value based on its result. However, a ternary operator can become complex, especially if it includes checks\u00a0\u2013 such as <code>instanceof<\/code> for a variable.<\/p>\n<p>In such cases, IntelliJ IDEA can help you extract a variable and also replace the ternary operator with an <code>if<\/code> statement:<\/p>\n<p><img decoding=\"async\" class=\"alignnone wp-image-16062\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2019\/04\/idea-mg-extract-var-ternary-to-if-cover.png\" alt=\"\" width=\"700&quot;\" height=\"280\" data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2019\/04\/idea-mg-extract-var-ternary-to-if-5sec.gif\" \/><\/p>\n<p>Here&#8217;s a similar example of a seemingly complex ternary operator that includes a null check. Again, IntelliJ IDEA can help you extract a variable and replace the ternary operator with an <code>if<\/code>&#8211;<code>else<\/code> statement:<\/p>\n<p><img decoding=\"async\" class=\"alignnone wp-image-16062\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2019\/04\/idea-mg-extract-var-ternary-to-if-null-cover.png\" alt=\"\" width=\"700&quot;\" height=\"280\" data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2019\/04\/idea-mg-extract-var-ternary-to-if-null-5sec.gif\" \/><\/p>\n<p>However, if the condition used in your ternary operator is not complex (with a null check or <code>instanceof<\/code> operator), it doesn&#8217;t make sense to automatically convert it to an <code>if<\/code>&#8211;<code>else<\/code> statement. The essence of refactoring is to make your code simple to read and maintain. In cases like this, IntelliJ IDEA applies simple refactoring\u00a0\u2013 keeping your ternary operator, and extracting the selected expression into a variable:<\/p>\n<p><img decoding=\"async\" class=\"alignnone wp-image-16062\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2019\/04\/idea-mg-extract-var-ternary-not-to-if-png.png\" alt=\"\" width=\"700&quot;\" height=\"280\" data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2019\/04\/idea-mg-extract-var-ternary-not-to-if-5sec.gif\" \/><\/p>\n<h2>Automatic refactoring is not a magic bullet<\/h2>\n<p>To use variable refactorings in IntelliJ IDEA effectively, you must know when it works safely and when you need to exercise caution.<\/p>\n<p>For example, in the following code, extracting <code>emp.title<\/code> into a variable and replacing <strong>all<\/strong> its occurrences could\u00a0output unexpected results. Calling <code>emp.title<\/code> on line1 and line2, <em>might<\/em> return different values:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"\">void test(Employee emp, Runnable runnable) {\r\n    if (emp != null) {\r\n        log(&quot;Starting &quot; + emp.title);            \/\/ line 1\r\n    }\r\n    runnable.run();                              \r\n    if (emp != null) {\r\n        log(&quot;Finishing &quot; + emp.title);           \/\/ line 2\r\n    }\r\n}<\/pre>\n<p>Similarly, when you extract an expression that includes a method call, IntelliJ IDEA lets you choose whether you want to replace just one occurrence or all of them. Be careful in such cases \u2013 such extraction may change your code behavior, irrespective of whether the method call that you extract into a variable is pure or not.<\/p>\n<p>Impure methods can output different results\u00a0when called with the same parameters. Even for pure functions, the mutable arguments you use to invoke your method might change between its invocations.<\/p>\n<p>Here&#8217;s an example of an impure method <code>variableValue<\/code>, whose return value is dependent on when it is called (since it returns the &#8216;seconds&#8217; value of the time it executes at):<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"\">public class ExtractVarMethodCall {\r\n    public int calcResult(int total) {\r\n        int a = 100;\r\n        int b = a + getVariableValue();\r\n        int c = b + getVariableValue();\r\n        return c;\r\n    }\r\n\r\n    private int getVariableValue() {\r\n        return LocalTime.now().getSecond();\r\n    }\r\n}<\/pre>\n<p>You could refactor the preceding code, as follows:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"\">final var variableValue = getVariableValue();\r\nint b = a + variableValue;\r\nint c = b + variableValue;<\/pre>\n<p>In the preceding refactored code, the method <code>variableValue<\/code> executes once and the same value is used twice\u00a0\u2013 which wasn&#8217;t the intent of the original code. So this code won&#8217;t execute as expected.<\/p>\n<h2>Automated tests to the rescue<\/h2>\n<p>Before you get started with some serious refactoring of your code, please ensure you have an automated test suite set up to ensure all the functionality is still the same after the modifications. <a href=\"https:\/\/www.youtube.com\/watch?v=QDFI19lj4OM\" target=\"_blank\" rel=\"noopener\">Here&#8217;s how<\/a> IntelliJ IDEA can quickly help you to get started with defining unit tests.<\/p>\n<p>Happy refactoring!<\/p>\n","protected":false},"author":921,"featured_media":0,"comment_status":"open","ping_status":"open","template":"","categories":[808,907,2347],"tags":[744,3335,195,3346],"cross-post-tag":[],"acf":[],"_links":{"self":[{"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/idea\/27218"}],"collection":[{"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/idea"}],"about":[{"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/types\/idea"}],"author":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/users\/921"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/comments?post=27218"}],"version-history":[{"count":0,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/idea\/27218\/revisions"}],"wp:attachment":[{"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/media?parent=27218"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/categories?post=27218"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/tags?post=27218"},{"taxonomy":"cross-post-tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/cross-post-tag?post=27218"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}