20

Guys, here is my problem: I have some class which is used in many places in my project. And I must replace this class with another from jar provided. Is there any ways to refactor this? I suppose this is a simple problem, but I dont know how to solve it.

Its not about replacing source code - what I want is to replace all class usages by class from my library and be able to completely remove my own class. Imagine I have created my own StringUtils and have found out that there is a apache.common StringUtils library, and now I want to use it everywhere in my code. And the signatures of class methods are not a problem: they coincide.

?

2
  • 3
    A global replace on the import statement will do it. Commented Oct 28, 2011 at 9:34
  • 1
    The global replace would only work if the name of the class is the same, surely. So I guess it might answer this specific case, but wouldn't answer "the question"... Commented Nov 18, 2014 at 23:14

5 Answers 5

34

There is this "migrate" function. Right click in whatever class -> Refactor -> Migrate.

It's a bit annoying that you have to create a new migrate set and you can't run it from scratch. But it does exactly what you need.

You pick class or package to migrate and tell it to which class or package it should change. Press run and all usages are rewritten. Then you're free to delete the old class because there will be no usages.

EDIT: In the newer versions it isn't in the context menu anymore. Just go to the menu on top - Refactor - Migrate (or simply pres shift twice and type migrate).

Cheers!

Sign up to request clarification or add additional context in comments.

3 Comments

Neat tool, but it's surprisingly manual-labor for an IntelliJ helper.
I always thought these "migrations" were fixed and would never have thought they can be customized like this... not the best UX design here,-)
Wonderful...It worked beautifully... Thanks a ton!!!..
5

I found it easier to use delete and rename:

  1. Temporarily delete TargetClass (delete without updating usages).

  2. Rename SourceClass to TargetClass (including updating usages).

  3. Restore TargetClass from VCS or local history.

Comments

3

If you are using static methods (like your StringUtils example suggests), delegate to the new class in your previous implementation like

public static String myOldMethod(String argument) { return MyNewClass.myNewMethod(argument); } 

then select Refactor->Inline and select "All invocations and remove the method" in the option dialog. In this way you can handle method name changes and argument order changes are well.

Comments

1

The simplest way is to write a method mapping what you would like to inline.

Say you have a method

enum MyStringUtils { public static boolean containsAnyCase(String searchFor, String searchIn) { // something } } // calling code boolean found = MyStringUtils.containsAnyCase(find, in); 

You want to use StringUtils.containsIgnoreCase however the class name, method name and order arguments are different.

So you change the body of the method to call the desired method instead.

 public static boolean containsAnyCase(String searchFor, String searchIn) { return StringUtils.containsIgnoreCase(searchIn, searchFor); } 

Select the method and <Crtl> + <Alt> + N. This will offer to inline this method everywhere and deletes your method. Your caller now looks like

 boolean found = StringUtils.containsIgnoreCase(in, find); 

This will work even if the original class uses an import of the class, import static of the method or no import at all.

Comments

-1

Although I am not an expert in IntelliJ I can tell you that generally in java the class loading is done sequentially. I mean the class loader is looking for classes sequentially, so if the same class presents in class path several times it will take the first version.

So, it depends on how are you running your application. If for example you are using command line like java -cp lib.jar;myapp.jar com.mycompany.Main and both lib.jar and myapp.jar contain the same class Util the lib.jar version will be used.

If you want to achieve the same effect when running from IDE try to check the project properties. Probably you can control the order of library jars relatively to your project's classes? If not, probably you can add jars to bootstrap classpath. In this case add your lib.jar to bootstrap classpath (just to work on your IDE).

Good luck.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.