简体   繁体   English

有没有办法在 Intellij Idea 中用另一个类替换类?

[英]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.我必须用另一个提供的 jar 替换这个类。 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.想象一下,我已经创建了自己的 StringUtils 并发现有一个 apache.common StringUtils 库,现在我想在我的代码中到处使用它。 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 ).只需转到顶部的菜单 - 重构 - 迁移(或只需按两次 shift 并键入migrate )。

Cheers!干杯!

If you are using static methods (like your StringUtils example suggests), delegate to the new class in your previous implementation like如果您使用的是静态方法(如您的 StringUtils 示例所建议的那样),请委托给您之前实现中的新类,例如

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.然后选择 Refactor->Inline 并在选项对话框中选择“All invocations and remove the method”。 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).临时删除 TargetClass(删除不使用)。
  • Rename SourceClass to TargetClass with usages.使用用法将 SourceClass 重命名为 TargetClass。
  • Restore TargetClass from VCS or local history.从 VCS 或本地历史记录恢复 TargetClass。

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.您想使用 StringUtils.containsIgnoreCase 但是类名、方法名和顺序参数是不同的。

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.选择方法和 <Crtl> + <Alt> + N。这将提供在任何地方内联此方法并删除您的方法。 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.这将工作,即使原来的类使用import类的import static方法或根本没有进口。

Although I am not an expert in IntelliJ I can tell you that generally in java the class loading is done sequentially.尽管我不是 IntelliJ 专家,但我可以告诉您,通常在 Java 中,类加载是按顺序完成的。 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.例如,如果您使用像java -cp lib.jar;myapp.jar com.mycompany.Main这样的命令行,并且 lib.jar 和 myapp.jar 都包含相同的 Util 类,则将使用 lib.jar 版本。

If you want to achieve the same effect when running from IDE try to check the project properties.如果您想在从 IDE 运行时达到相同的效果,请尝试检查项目属性。 Probably you can control the order of library jars relatively to your project's classes?也许您可以控制相对于项目类的库 jar 的顺序? If not, probably you can add jars to bootstrap classpath.如果没有,您可能可以将 jar 添加到引导类路径中。 In this case add your lib.jar to bootstrap classpath (just to work on your IDE).在这种情况下,将您的 lib.jar 添加到引导类路径(只是为了在您的 IDE 上工作)。

Good luck.祝你好运。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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