简体   繁体   中英

Is there a way to replace class by another one in Intellij Idea?

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.

?

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!

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.

I found it to be easy to use delete and rename:

  • Temporarily delete TargetClass (delete without usages).
  • Rename SourceClass to TargetClass with usages.
  • Restore TargetClass from VCS or local history.

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM