This article can be thought of as a quick gif on refactoring Java files in IDEA for beginners .
Careful , there are a lot of heavy gifs.
"Any fool can write code that a computer can understand. Good programmers write code that humans can understand." —M. Fowler (1999)
Content
- Edit Property Value (no example)
- Find and Replace Code Duplicate
- Use Interface Where Possible
- Replace Inheritance with Delegation
- Replace Constructor with Factory Method
- Replace Constructor with Builder
, , IDEA, , . , , Refator:
, , idea
, . , , Refactoring: Improving the Design of Existing Code (Martin Fowler). gif-, . Windows/LInux .
«Refator»
.
«Refactor This» (Ctrl+Alt+Shift+T)
. , , . , .
«Rename» (Shift+F6)
, . , , . ( 2 - “Rename Field” “Rename Variable”)
public class Main {
public static void main(String[] args) {
System.out.print("Hello");
invo<caret/>ke(", World");
}
private static void invoke(String text) {
//text
System.out.println(text);
}
}
public class Main {
public static void main(String[] args) {
System.out.print("Hello");
newFunctionName(", World");
}
private static void newFunctionName(String text) {
//text
System.out.println(text);
}
}
public class Main {
public static void main(String[] args) {
System.out.print("Hello");
invoke(", World");
}
private static void invoke(String te<caret>xt) {
//text
System.out.println(text);
}
}
public class Main {
public static void main(String[] args) {
System.out.print("Hello");
invoke(", World");
}
private static void invoke(String newText) {
//newText
System.out.println(newText);
}
}
public class Main {
public static void main(String[] args) {
System.out.print("Hello");
invoke(", World");
}
private static void invoke(String text) {
//text
System.out.println(text);
throw new MyExc<caret>eption();
}
public static class MyException extends RuntimeException {
}
}
public class Main {
public static void main(String[] args) {
System.out.print("Hello");
invoke(", World");
}
private static void invoke(String text) {
//text
System.out.println(text);
throw new NewMyException ();
}
public static class NewMyException extends RuntimeException {
}
}
public class Main {
public static void main(String[] args) {
MyS<caret>ervice service = new MyService();
service.service();
}
}
public class Main {
public static void main(String[] args) {
NewMyService myService = new NewMyService ();
myService.service();
}
}
package gen<caret>eral;
public class Main {
public static void main(String[] args) {
NewMyService service = new NewMyService();
service.service();
}
}
package org.test.java.src;
public class Main {
public static void main(String[] args) {
NewMyService service = new NewMyService();
service.service();
}
}
«Rename File»
. Shift+F6 . (Scope),
public class Main {
public static void main(String[] args) throws IOException {
Path path = Paths.get("src/general/TestFile.txt");
String read = Files.readAllLines(path).get(0);
System.out.println(read);
}
}
public class Main {
public static void main(String[] args) throws IOException {
Path path = Paths.get("src/general/TestFile2.txt");
String read = Files.readAllLines(path).get(0);
System.out.println(read);
}
}
«Change Signature» (Ctrl+F6)
“Change Function Declaration”. IDEA «Change Signature» . :
- - ,
- .
( )
. "R" "Update usages to reflect signature change", .
public class ChangeSignature {
public static void main(String[] args) {
invokeMethod("Hello");
invokeMethod("World");
}
private static void invokeMethod(String text) {
System.out.println(text);
}
}
public class ChangeSignature {
public static void main(String[] args) {
invokeMethod("Hello", null);
invokeMethod("World", null);
}
private static void invokeMethod(String text, String newType) {
System.out.println(text);
}
}
( )
, exception, .
public class ChangeSignature {
public static void main(String[] args) {
invokeMethod("Hello");
invokeMethod("World");
}
private static void invokeMethod(String<caret> text) {
System.out.println(text);
}
}
public class ChangeSignature {
public static void main(String[] args) {
invokeMethod("Hello");
invokeMethod("World");
}
private static void invokeMethod(String text) {
invokeMethod(text, null);
}
private static void invokeMethod(String text, String newName) {
System.out.println(text);
}
}
«Edit Property Value» (Alt + F6)
(Idea 2020.2) . property.value.inplace.editing=true .
«Type Migration» (Ctrl + Shift + F6)
, , .
public class ChangeSignature {
public static void main(String[] args) {
Inte<caret>ger hello = 1;
print(hello);
}
private static void print(Integer text) {
System.out.println(text);
}
}
public class ChangeSignature {
public static void main(String[] args) {
Number hello = 1;
print(hello);
}
private static void print(Number text) {
System.out.println(text);
}
}
«Make Static» (Ctrl + Shift + F6)
. ( Convert To Instance Method)
public class MakeStatic {
public static void main(String[] args) {
MakeStatic makeStatic = new MakeStatic();
makeStatic.sayHello();
}
public void say<caret>Hello() {
System.out.println("Hello, World");
}
}
public class MakeStatic {
public static void main(String[] args) {
MakeStatic makeStatic = new MakeStatic();
MakeStatic.sayHello();
}
public static void sayHello() {
System.out.println("Hello, World");
}
}
«Convert To Instance Method»
( ”Make Static”). .
public class MakeStatic {
public static void main(String[] args) {
sayHello();
}
public static void sa<caret>yHello() {
System.out.println("Hello, World");
}
}
public class MakeStatic {
public static void main(String[] args) {
new MakeStatic().sayHello();
}
public void sayHello() {
System.out.println("Hello, World");
}
}
«Move Classes» (F6)
, , .
package org.example.test.service;
public class TestService {
<caret>
}
package org.example.test;
public class TestService {
}
«Copy Classes» (F5)
, . F5. e, .
«Safe Delete» (Alt+Delete)
, (Alt + Enter), . , , - F2( ) Alt + Enter Alt + Delete. , , . IDEA , IDEA , - Usages Detected. - “Remove Dead Code”
package org.example.test;
public class MainClass {
public static void main(String[] args) {
start();
}
private static void start() {
String unUsedVariable;
System.out.println("Hello, World!");
}
private static void unUsedMethod() {
}
}
<empty>
«Extract/Introduce»
- Extract/Introduce. , . .
«Variable» (Ctrl+Alt+V)
. ( “Extract Variable”).
public class ExtractVariable {
public static void main(String[] args) {
sayHello();
}
private static void sayHello() {
System.out.println("He<caret>llo, World!");
}
}
public class ExtractVariable {
public static void main(String[] args) {
sayHello();
}
private static void sayHello() {
String text = "Hello, World!";
System.out.println(text);
}
}
«Constant» (Ctrl+Alt+C)
.
public class ExtractVariable {
public static void main(String[] args) {
sayHello();
}
private static void sayHello() {
System.out.println("He<caret>llo, World!");
}
}
public class ExtractVariable {
public static final String HELLO_WORLD = "Hello, World!";
public static void main(String[] args) {
sayHello();
}
private static void sayHello() {
System.out.println(HELLO_WORLD);
}
}
«Field» (Ctrl+Alt+F)
.
public class ExtractVariable {
public static void main(String[] args) {
sayHello();
}
private static void sayHello() {
System.out.println("He<caret>llo, World!");
}
}
public class ExtractVariable {
private static String x;
public static void main(String[] args) {
sayHello();
}
private static void sayHello() {
x = "Hello, World!";
System.out.println(x);
}
}
«Parameter» (Ctrl+Alt+P)
() .
public class ExtractVariable {
public static void main(String[] args) {
sayHello();
}
private static void sayHello() {
System.out.println("He<caret>llo, World!");
}
}
public class ExtractVariable {
public static void main(String[] args) {
sayHello("Hello, World!");
}
private static void sayHello(String x) {
System.out.println(x);
}
}
«Functional Parameter»
«Parameter», java.util.function.Supplier, javafx.util.Builder. , .
public class ExtractParameter {
public static void main(String[] args) {
System.out.println(generateText());
}
private static String generateText() {
return "Hello, Wor<caret>ld!".toUpperCase();
}
}
public class ExtractParameter {
public static void main(String[] args) {
System.out.println(generateText(() -> "Hello, World!"));
}
private static String generateText(final Supplier<string> getText) {
return getText.get().toUpperCase();
}
}
«Functional Variable»
«Variable», java.util.function.Supplier javafx.util.Builder.
public class ExtractParameter {
public static void main(String[] args) {
System.out.println(generateText());
}
private static String generateText() {
return "Hello, W<caret>orld!".toUpperCase();
}
}
public class ExtractParameter {
public static void main(String[] args) {
System.out.println(generateText());
}
private static String generateText() {
Supplier<string> getText = () -> "Hello, World!";
return getText.get().toUpperCase();
}
}
«Parameter Object»
, . ( “Introduce Parameter Object”).
public class ExtractParameter {
public static void main(String[] args) {
System.out.println(generateText("Hello", "World!"));
}
private static String generateText(Str<caret>ing hello, String world) {
return hello.toUpperCase() + world.toUpperCase();
}
}
public class ExtractParameter {
public static void main(String[] args) {
System.out.println(generateText(new HelloWorld("Hello", "World!")));
}
private static String generateText(HelloWorld helloWorld) {
return helloWorld.getHello().toUpperCase() + helloWorld.getWorld().toUpperCase();
}
private static class HelloWorld {
private final String hello;
private final String world;
private HelloWorld(String hello, String world) {
this.hello = hello;
this.world = world;
}
public String getHello() {
return hello;
}
public String getWorld() {
return world;
}
}
}
«Method» (Ctrl+Alt+M)
. ( - “Extract Function”).
public class ExtractMethod {
public static void main(String[] args) {
String text = "Hello, World!";
System.out.prin<caret>tln(text);
}
}
public class ExtractMethod {
public static void main(String[] args) {
String text = "Hello, World!";
print(text);
}
private static void print(String text) {
System.out.println(text);
}
}
«Type Parameter»
Kotlin, Java ( , - ).
«Replace Method With Method Object»
. , ( -).
public class ExtractMethod {
public static void main(String[] args) {
String text = "Hello, World!";
print(text);
}
private static void print(String text) {
System.out.p<caret>rintln(text);
}
}
public class ExtractMethod {
public static void main(String[] args) {
String text = "Hello, World!";
print(text);
}
private static void print(String text) {
new Printer(text).invoke();
}
private static class Printer {
private String text;
public Printer(String text) {
this.text = text;
}
public void invoke() {
System.out.println(text);
}
}
}
«Delegate»
.
public class Delegate {
public static void main(String[] args) {
new Delegate().print();
}
private void print() {
System.ou<caret>t.println("Hello, World!");
}
}
public class Delegate {
private final Printer printer = new Printer();
public static void main(String[] args) {
new Delegate().print();
}
private void print() {
printer.print();
}
public static class Printer {
public Printer() {
}
private void print() {
System.out.println("Hello, World!");
}
}
}
«Interface»
. ( , Spring, - )
public class ExtractImpl {
public static void main(String[] args) {
new ExtractImpl().print();
}
public void print() {
System.out.println("Hello, World!");
}
}
public class ExtractImpl implements ExtractInterface {
public static void main(String[] args) {
new ExtractImpl().print();
}
@Override
public void print() {
System.out.println("Hello, World!");
}
}
public interface ExtractInterface {
void print();
}
«Superclass»
«Interface», - (Superclass). “Extract Superclass”.
public class ExtractImpl {
public static void main(String[] args) {
new ExtractImpl().print();
}
public void print() {
System.out.println("Hello, World!");
}
}
public class ExtractImpl extends ExtractAbstr {
public static void main(String[] args) {
new ExtractImpl().print();
}
}
public class ExtractAbstr {
public void print() {
System.out.println("Hello, World!");
}
}
«Subquery as CTE»
Sql, . - , - .
«RSpec 'let'»
Ruby, - , - .
«Inline»
, . “Inline Class”, “Inline Function”, “Inline Variable”.
public class Inline {
public static void main(String[] args) {
print();
}
private static void print() {
new Printer().print();
}
private static class Printer {
public void print() {
String text = "Hello, World!";
System.out.println(t<caret>ext);
}
}
}
public class Inline {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
«Find and Replace code duplicate»
, , .
public class Replace {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
public void print() {
System.out.println("Hello, World!");
}
public void print2() {
System.out.prin<caret>tln("Hello, World!");
}
}
public class Replace {
public static void main(String[] args) {
print2();
}
public void print() {
print2();
}
public static void print2() {
System.out.println("Hello, World!");
}
}
«Invert Boolean»
.
public class Invert {
public static void main(String[] args) {
boolean co<caret>ndition = true;
if (condition) {
System.out.println("Hello, World!");
}
}
}
public class Invert {
public static void main(String[] args) {
boolean condition = false;
if (!condition) {
System.out.println("Hello, World!");
}
}
}
«Pull Member Up»
. “Pull Up Field” “Pull Up Method”. «Pull Member Down».
public class PullMethod {
public static void main(String[] args) {
new InnerClass().print();
}
private static class InnerClass extends AbstClass {
public void print() {
System.out.pri<caret>ntln("Hello, World");
}
}
private static abstract class AbstClass {
}
}
public class PullMethod {
public static void main(String[] args) {
new InnerClass().print();
}
private static class InnerClass extends AbstClass {
}
private static abstract class AbstClass {
public void print() {
System.out.println("Hello, World");
}
}
}
«Pull Member Down»
«Pull Member Up». . ( - “Push Down Method”)
public class PullMethod {
public static void main(String[] args) {
new InnerClass().print();
}
private static class InnerClass extends AbstClass {
}
private static abstract class AbstClass {
public void print() {
System.out.prin<caret>tln("Hello, World");
}
}
}
public class PullMethod {
public static void main(String[] args) {
new InnerClass().print();
}
private static class InnerClass extends AbstClass {
@Override
public void print() {
System.out.println("Hello, World");
}
}
private static abstract class AbstClass {
public abstract void print();
}
}
«Push ITds In»
AsperctJ.
aspect myAspect {
boolean Account.closed = <caret>false;
void Account.close() {
closed = true;
}
}
class Account {
}
aspect myAspect {
boolean Account.closed = false;
}
class Account {
void close() {
closed = true;
}
}
«Use Interface Where Possible»
IDEA , , .
public class ExtractInterface {
public static void main(String[] args) {
InnerClass innerClass = new InnerClass();
print(innerClass);
}
private static void print(InnerClass innerClass) {
innerClass.print();
}
private static class InnerClass implements InnerInterface{
@Override
public void print() {
System.out.println("Hello, World!");
}
}
private static interface InnerInterface{
void print();
}
}
public class ExtractInterface {
public static void main(String[] args) {
InnerInterface innerClass = new InnerClass();
print(innerClass);
}
private static void print(InnerInterface innerClass) {
innerClass.print();
}
private static class InnerClass implements InnerInterface{
@Override
public void print() {
System.out.println("Hello, World!");
}
}
private static interface InnerInterface{
void print();
}
}
«Replace Inheritance with Delegation»
. “Replace Subclass with Delegate” “Replace Superclass with Delegate”.
public class InheritanceDelegation {
public static void main(String[] args) {
InnerClass innerClass = new InnerClass();
print(innerClass);
}
private static void print(InnerClass innerClass) {
innerClass.print();
}
private static class In<caret>nerClass extends AbstractClass {
}
private static class AbstractClass {
public void print() {
System.out.println("Hello, World!");
}
}
}
public class InheritanceDelegation {
public static void main(String[] args) {
InnerClass innerClass = new InnerClass();
print(innerClass);
}
private static void print(InnerClass innerClass) {
innerClass.print();
}
private static class InnerClass {
private final AbstractClass abstractClass = new AbstractClass();
public void print() {
abstractClass.print();
}
}
private static class AbstractClass {
public void print() {
System.out.println("Hello, World!");
}
}
}
«Remove Middleman»
. ( - “Remove Middle Man”).
public class Middleman {
public static void main(String[] args) {
InnerClass innerClass = new InnerClass();
innerClass.print();
}
private static class InnerClass {
private final NextClass next<caret>Class = new NextClass();
public void print() {
nextClass.print();
}
}
private static class NextClass {
public void print() {
System.out.println("Hello, World!");
}
}
}
public class Middleman {
public static void main(String[] args) {
InnerClass innerClass = new InnerClass();
innerClass.getNextClass().print();
}
private static class InnerClass {
private final NextClass nextClass = new NextClass();
public NextClass getNextClass() {
return nextClass;
}
}
private static class NextClass {
public void print() {
System.out.println("Hello, World!");
}
}
}
«Wrap Method Return Value»
-. , .
public class WrapMethodReturnValue {
public static void main(String[] args) {
System.out.println(new MessageFolder().get());
}
private static class MessageFolder {
public String get() {
ret<caret>urn "Hello, World!";
}
}
}
public class WrapMethodReturnValue {
public static void main(String[] args) {
System.out.println(new MessageFolder().get().getValue());
}
private static class MessageFolder {
public Message get() {
return new Message("Hello, World!");
}
public class Message {
private final String value;
public Message(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
}
}
«Encapsulate Field»
getter, setter.
public class EncapsulateField {
public static void main(String[] args) {
System.out.println(new InnerClass().message);
}
private static class InnerClass {
public String m<caret>essage = "Hello, World!";
}
}
public class EncapsulateField {
public static void main(String[] args) {
System.out.println(new InnerClass().getMessage());
}
private static class InnerClass {
private String message = "Hello, World!";
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
}
«Replace Temp with Query»
int size = getActualSize()
size getActualSize(). , . .
public class ReplaceTemp {
public static void main(String[] args) {
String hello = "Hello";
String mes<caret>sage = hello + ", World!";
System.out.println(message);
}
}
public class ReplaceTemp {
public static void main(String[] args) {
String hello = "Hello";
System.out.println(message(hello));
}
private static String message(String hello) {
return hello + ", World!";
}
}
«Replace Constructor with Factory Method»
. , Lombok. ( “Replace Constructor with Factory Function”).
public class ReplaceConstructor {
public static void main(String[] args) {
new InnerClass("Hello", "World").print();
}
private static class InnerClass {
private String message;
public Inner<caret>Class(String hello, String world) {
message = hello + ", " + world;
}
public void print() {
System.out.println(message);
}
}
}
public class ReplaceConstructor {
public static void main(String[] args) {
InnerClass.createInnerClass("Hello", "World").print();
}
private static class InnerClass {
private String message;
private InnerClass(String hello, String world) {
message = hello + ", " + world;
}
public static InnerClass createInnerClass(String hello, String world) {
return new InnerClass(hello, world);
}
public void print() {
System.out.println(message);
}
}
}
«Replace Constructor with Builder»
builder . , Lombok.
public class ReplaceConstructor {
public static void main(String[] args) {
new InnerClass("Hello", "World").print();
}
private static class InnerClass {
private String message;
public InnerC<caret>lass(String hello, String world) {
message = hello + ", " + world;
}
public void print() {
System.out.println(message);
}
}
}
public class ReplaceConstructor {
public static void main(String[] args) {
new InnerClassBuilder().setHello("Hello").setWorld("World").createInnerClass().print();
}
static class InnerClass {
private String message;
public InnerClass(String hello, String world) {
message = hello + ", " + world;
}
public void print() {
System.out.println(message);
}
}
}
public class InnerClassBuilder {
private String hello;
private String world;
public InnerClassBuilder setHello(String hello) {
this.hello = hello;
return this;
}
public InnerClassBuilder setWorld(String world) {
this.world = world;
return this;
}
public ReplaceConstructor.InnerClass createInnerClass() {
return new ReplaceConstructor.InnerClass(hello, world);
}
}
«Generify»
raw- Generic-. java 1.5 .
public class Generify {
public static void main(String[] args) {
List list = getList();
Object message = list.get(0);
System.out.println(message);
}
private static List getList() {
ArrayList arrayList = new ArrayList();
arrayList.add("Hello, World!");
return arrayList;
}
}
public class Generify {
public static void main(String[] args) {
List<string> list = getList();
String message = list.get(0);
System.out.println(message);
}
private static List<string> getList() {
ArrayList<string> arrayList = new ArrayList<>();
arrayList.add("Hello, World!");
return arrayList;
}
}
«Migrate»
:
. , , JUnit(4.x -> 5.0):
«Lombok» «Delombok»
Provided by the plugin "Lombok". It was recently announced that it will now be included in the standard IDEA package. Used when working with the Lombok code generation library.
Item "Internationalize"
Used for internationalization. Unfortunately, I have not found any information in the help at this time. IDEA is now actively localized into other languages, most likely this method was developed for this.
List of sources
Excellent talk about atomic refactoring from Tagir Valeev
Refactoring: Improving the Design of Existing Code (Martin Fowler)