Как в IDEA переименовать пересекающиеся по названию пакеты?
Несмотря на то, что на первый взгляд эти пакеты являются разными (потому что разнесены по разным модулям), по факту они являются одним пакетом. Это создаёт проблемы. Например, если я попытаюсь переименовать пакет ru.site.my.source.super в Module A , то такой же пакет переименуется и в остальных модулях, потому что это и есть тот же самый пакет. Поэтому я сейчас пытаюсь разграничить пакеты в разных модулях, получив на выходе такой результат:
Module A: ru.site.my.source.one.* Module B: ru.site.my.source.two.* Module C: ru.site.my.source.three.*
Как я могу это сделать? Проблема в том, что это очень сложно: я не могу просто переименовать пакет в одном модуле без того, чтобы он не переименовался бы в другом. По сути приходится вручную пересоздавать структуру пакетов и вручную перетаскивать каждый класс. Есть ли в IDEA какие-либо инструменты, которые позволят мне ускорить данный процесс?
Раздел «Refactor» в IDEA
Эту статью можно рассматривать как краткий обзор c gif-ками по рефакторингам Java-файлов в IDEA для начинающих.
Осторожно, много тяжелых gif-картинок.

«Any fool can write code that a computer can understand. Good programmers write code that humans can understand.” —M. Fowler (1999)
Введение
Цель данной статьи — показать доступные способы рефакторинга для Java-файлов (многие способы будут работать и для других языков). Как использовать эти приемы в реальной жизни показано в замечательном видео Тагира Валеева (ссылка в списке источников).
Думаю, каждый, кто работает в IDEA, знает, что в ней куча способов для рефакторинга кода. И почти уверен, что каждый второй смотрит анонсы новой версии, где красиво показаны новые способы рефакторинга и заглядывал в раздел Refaсtor:

Но не уверен, что все точно знают что и как делают все элементы этого списка, хотя они все детально описаны в справки к idea
В статье представлены фрагменты кода, порядок действий и анимации почти для каждого пункта. Также постарался добавить, где возможно, ссылку на замечательную книгу Refactoring: Improving the Design of Existing Code (Martin Fowler). Чтобы не сильно раздувать трафик пришлось довольно сильно обрезать много gif-картинок, поэтому обязательно смотрите использованный код под катом. Горячие клавиши приведены для Windows/LInux по умолчанию.
Раздел «Refaсtor»
Пойдем сверху вниз по порядку.
Пункт «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"); invoke(", 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 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 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 MyException(); > 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) < MyService service = new MyService(); service.service(); > >
public class Main < public static void main(String[] args) < NewMyService myService = new NewMyService (); myService.service(); >>
- Переименование пакета
Использованный код
package general; 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 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) < Integer 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 sayHello() < 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 sayHello() < 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 < >
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() < >>
Пункт «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("Hello, 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("Hello, 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("Hello, 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("Hello, 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, World!".toUpperCase(); > >
public class ExtractParameter < public static void main(String[] args) < System.out.println(generateText(() ->"Hello, World!")); > private static String generateText(final Supplier 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, World!".toUpperCase(); > >
public class ExtractParameter < public static void main(String[] args) < System.out.println(generateText()); >private static String generateText() < SuppliergetText = () -> "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(String 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.println(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.println(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.out.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
Пункт «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(text); > > >
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.println("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 condition = 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.println("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.println("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 = 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 InnerClass 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 nextClass = 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() < return "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 message = "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 message = 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 InnerClass(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 InnerClass(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) < Listlist = getList(); String message = list.get(0); System.out.println(message); > private static List getList() < ArrayListarrayList = new ArrayList<>(); arrayList.add("Hello, World!"); return arrayList; > >
Пункт «Migrate»
Предоставляет готовые миграции для следующего списка:

А также предоставляет возможность делать свои. Вот, например, правила миграции для JUnit(4.x -> 5.0):

Вот здесь есть подробное видео про миграцию для JUnit(4.x -> 5.0).
Пункт «Lombok» и «Delombok»
Предоставляются плагином “Lombok”. Недавно было объявлено, что теперь он будет входить в стандартную поставку IDEA. Используется при работе с библиотекой кодогенерации “Lombok”.
Пункт «Internationalize»
Используется для интернационализации. К сожалению, в справке не нашел на данный момент информации. IDEA сейчас активно локализуется на другие языки, скорее всего для этого был разработан этот метод.
Список источников
- Прекрасный доклад про атомарный рефакторинг от Тагира Валеева
- Справка IDEA
- Refactoring: Improving the Design of Existing Code (Martin Fowler)
Полезные комбинации в IntelliJ IDEA

Всем нам хорошо известна среда разработки IntelliJ IDEA. В этой заметке я собрал список наиболее полезных клавиш в IDEA, которыми пользуюсь практически каждый день, и без которых работа выполнялась бы намного медленнее. При этом я постарался отсортировать каждый раздел от наиболее часто используемых к наименее.
Keymap: mac — Mac OS X 10.5+ win/linux — Default
⌘ — Command ⌃ — Control ⌥ — Option (Alt) ⇧ — Shift
0. Универсальная комбинация от всех проблем
| Mac OS | Win/Linux | Описание | Примечание |
|---|---|---|---|
| ⌥ + Enterl | Alt + Enter | показать быстрые действия, исправить код |
1. Навигация по коду
| Mac OS | Win/Linux | Описание | Примечание |
|---|---|---|---|
| ⌘ + O | Ctrl + N | открыть класс | |
| ⌘ + ⇧ + O | Ctrl + Shift + N | открыть файл | |
| ⌘ + ⌥ + Left/Right | Ctrl + Alt + Left/Right | назад/вперед по истории навигации | |
| ⌘ + B | Ctrl + B | перейти к декларации (переменной/метода), показать использование переменной/метода | |
| ⌘ + ⌥ + B | Ctrl + Alt + B | перейти к имплементации метода | |
| ⌘ + E | Ctrl + E | последние открытые файлы | |
| ⌘ + ⇧ + E | Ctrl + Shift + E | последние редактированные файлы | |
| ⌘ + F12 | Ctrl + F12 | список методов текущего класса | начать набирать имя метода для фильтрации |
2. Рефакторинг/редактирование/генерация кода
| Mac OS | Win/Linux | Описание | Примечание |
|---|---|---|---|
| ⌃ + ⌥ + O | Ctrl + Alt + O | оптимизировать раздел import | |
| ⌘ + ⌥ + L | Ctrl + Alt + L | автоматически отформатировать код | |
| ⌘ + N | Alt + Insert | сгенерировать код (конструктор, геттер, сеттер, equals, hashCode) | |
| ⇧ + F6 | Shift + F6 | переименовать (класс, метод, поле, переменную), включая все использования и референсы | |
| ⌘ + ⌥ + V | Ctrl + Alt + V | вынести выражение в переменную | |
| ⌃ + O | Ctrl + O | переопределить метод | |
| ⌃ + I | Ctrl + I | имплементировать метод | |
| ⌃ + G | Alt + J | выделить следующее появление текста (next occurence) | удобно подменять одну переменную другой при рефакторинге |
| ⌘ + | Ctrl + / | закомментировать однострочным комментарием | |
| ⌘ + ⇧ + / | Ctrl + Shift + / | закомментировать многострочным комментарием | |
| ⌘ + ⇧ + 8 | Shift + Alt + Insert | переключить режим редактирования (обычный/колонка) | удобно редактировать большие куски выровненного кода, файлов .properties |
| ⌥ + ⌥(зажать) + Up/Down | Ctrl + Ctrl(зажать) + Up/Down | выделить следующую/предыдущую строку в режиме колонки | нажать и отпустить и тут же зажать Option (mac) или Ctrl (win/linux). Удобнее чем, переключаться в режим редактирования колонкой для небольших кусков кода |
3. Прочее
| Mac OS | Win/Linux | Описание | Примечание |
|---|---|---|---|
| ⌃ + R/D | Shift + F10/F9 | запуск/дебаг текущей выбранной конфигурации | |
| ⌃ + ⇧ + R/D | Ctrl + Shift + F10/F9 | запуск/дебаг конфигурации из контекста | |
| ⌃ + ⌥ + R/D | Alt + Shift + F10/F9 | выбор конфигурации и запуск/дебаг | |
| ⌘ + ⇧ + F8 | Ctrl + Shift + F8 | открыть окно брейкпоинтов | |
| ⇧ + ⇧ | Shift + Shift | поиск везде | |
| ⌘ + ⇧ + A | Alt + ` | поиск действий | |
| ⌃ + V | Content Cell | быстрое меню системы контроля версий | |
| ⌘ + K | Ctrl + K | сделать коммит |
Комбинаций клавиш в IDEA очень много, все упомянуть/запомнить почти невозможно. В данном посте я описал только те комбинации, которые помню и которыми пользуюсь сам и без которых не могу представить работу в IDEA. В комментариях пишите самые полезные, на ваш взгляд, комбинации.
IntelliJ IDEA — настройка, горячие клавиши, debugging — введение в Java 025 #
Сегодняшний программист очень сильно отличается от программиста 90-х.
Блокноты сменились мощными инструментами, которые подсказывают нам даже эффективные методы решения. Порой, кажется, что ещё чуть-чуть и людям точно не надо будет учить программирование, потому что Idea сделает всё сама.
Но пока этого не случилось нам стоит потратить немного времени на настройку самого главного инструмента, в котором мы пишем код. Idea может очень многое. Очень. В этой главе мы рассмотрим несколько горячих клавиш, некоторые типы подсказок и базисные вещи, которые нам предлагает рефакторинг и дебаггинг.
Давайте на секунду отвлечёмся от самого кодинга и попробуем настроить наш инструмент для работы с Java и подтянуть наши скилы для работы с ним.

Рефакторинг #
Alt + F6 — одна из самых полезных функций рефакторинг. Переименование переменной во всём коде программы, сколько бы раз она не упоминалась.
Для этого надо выделить название метода, класса или переменной и вызвать из контекстного меню или горячими клавишами безопасное переименование. Очень удобно и для тех случаев, когда класс создан с грамматической ошибкой. IDEA переименовывает и файл и класс одновременно.

Не только hotkeys #
Горячие клавиши очень полезны в работе, но всё же не все функции доступны через клавиши.
Стоит выделить время и посмотреть что может программа: подобрать цветовую гамму, шрифты и их размер, научиться делить окна на рабочие зоны.
Как открыть одновременно 2 класса в IDEA? #
Например мы можем работать одновременно в нескольких классах (файлах). Эта функция доступна нам, если мы правой кнопкой нажмём на вкладку файла в окне, а затем на “Split Vertically” или “Split Horizontally”. Это очень удобно, когда программа состоит из больше, чем одного класса.

Как добавить плагин в intellij idea? #
File -> Settings -> Plugins здесь можно посмотреть, что уже установлено или добавить новый полезный плагин.
Например мне оказался очень полезен плагин Grazie — проверка орфографии.

Проверка правописания в Intellij Idea для русского текста #
File -> Settings -> Editor -> Proofreading
Здесь можно добавить те языки, которые нужны в работе над кодом и документацией.

Горячие клавиши #
“Alt + h + k”. В Idea есть возможность вызвать помощника по горячим клавишам “Alt + h + k” открывает pdf файл, где описаны поддерживаемые вызовы.
Настройка консоли #
Порой выдача в консоли не всегда очевидна или понятна. Или требуется пересчитать элементы. “CTRL + F” поможет нам в поиске определённых символов или слов и подсветит их.

Отладка программы #
Отладка Java кода в IDEA. Основные возможности отладчика.