Java 静态导入方法的好用例是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/420791/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 14:24:50  来源:igfitidea点击:

What is a good use case for static import of methods?

javastatic-import

提问by Miserable Variable

Just got a review comment that my static import of the method was not a good idea. The static import was of a method from a DA class, which has mostly static methods. So in middle of the business logic I had a da activity that apparently seemed to belong to the current class:

刚刚收到评论评论说我对方法的静态导入不是一个好主意。静态导入是来自 DA 类的方法,该类主要包含静态方法。因此,在业务逻辑中间,我有一个 da 活动,显然似乎属于当前类:

import static some.package.DA.*;
class BusinessObject {
  void someMethod() {
    ....
    save(this);
  }
} 

The reviewer was not keen that I change the code and I didn't but I do kind of agree with him. One reason given for not static-importing was it was confusing where the method was defined, it wasn't in the current class and not in any superclass so it too some time to identify its definition (the web based review system does not have clickable links like IDE :-) I don't really think this matters, static-imports are still quite new and soon we will all get used to locating them.

审阅者并不热衷于我更改代码,我也没有,但我确实同意他的观点。给出不静态导入的一个原因是它在定义方法的地方令人困惑,它不在当前类中也不在任何超类中,因此识别其定义需要时间(基于 Web 的系统没有可点击的IDE 之类的链接 :-) 我真的不认为这很重要,静态导入仍然很新,很快我们都会习惯于定位它们。

But the other reason, the one I agree with, is that an unqualified method call seems to belong to current object and should not jump contexts. But if it really did belong, it would make sense to extend that super class.

但我同意的另一个原因是不合格的方法调用似乎属于当前对象,不应跳转上下文。但如果它真的属于,那么扩展那个超类是有意义的。

So, when doesit make sense to static import methods? When have you done it? Did/do you like the way the unqualified calls look?

所以,当是有意义的静态导入的方法呢?你什么时候做过?你喜欢不合格电话的样子吗?

EDIT: The popular opinion seems to be that static-import methods if nobody is going to confuse them as methods of the current class. For example methods from java.lang.Math and java.awt.Color. But if abs and getAlpha are not ambiguous I don't see why readEmployee is. As in lot of programming choices, I think this too is a personal preference thing.

编辑:流行的观点似乎是静态导入方法,如果没有人会将它们混淆为当前类的方法。例如来自 java.lang.Math 和 java.awt.Color 的方法。但是如果 abs 和 getAlpha 没有歧义,我不明白为什么 readEmployee 是。与许多编程选择一样,我认为这也是个人喜好。

Thanks for your response guys, I am closing the question.

感谢各位大佬的回答,问题结束。

采纳答案by Ross

This is from Sun's guide when they released the feature (emphasis in original):

这是 Sun 发布该功能时的指南(强调原文):

So when should you use static import? Very sparingly!Only use it when you'd otherwise be tempted to declare local copies of constants, or to abuse inheritance (the Constant Interface Antipattern). ... If you overuse the static import feature, it can make your program unreadable and unmaintainable, polluting its namespace with all the static members you import. Readers of your code (including you, a few months after you wrote it) will not know which class a static member comes from. Importing all of the static members from a class can be particularly harmful to readability; if you need only one or two members, import them individually.

那么什么时候应该使用静态导入呢?非常节俭!仅当您试图声明常量的本地副本或滥用继承(常量接口反模式)时才使用它。...如果您过度使用静态导入功能,它会使您的程序不可读和不可维护,您导入的所有静态成员都会污染其命名空间。你的代码的读者(包括你,在你编写它几个月后)不会知道静态成员来自哪个类。从类中导入所有静态成员对可读性特别有害;如果您只需要一两个成员,请单独导入它们。

(https://docs.oracle.com/javase/8/docs/technotes/guides/language/static-import.html)

( https://docs.oracle.com/javase/8/docs/technotes/guides/language/static-import.html)

There are two parts I want to call out specifically:

有两个部分我想特别指出:

  • Use static imports onlywhen you were tempted to "abuse inheritance". In this case, would you have been tempted to have BusinessObject extend some.package.DA? If so, static imports may be a cleaner way of handling this. If you never would have dreamed of extending some.package.DA, then this is probably a poor use of static imports. Don't use it just to save a few characters when typing.
  • Import individual members.Say import static some.package.DA.saveinstead of DA.*. That will make it much easier to find where this imported method is coming from.
  • 当您想“滥用继承”时才使用静态导入。在这种情况下,您是否会想拥有 BusinessObject extend some.package.DA?如果是这样,静态导入可能是一种更简洁的处理方式。如果您从未梦想过扩展some.package.DA,那么这可能是对静态导入的不良使用。不要只是为了在打字时保存几个字符而使用它。
  • 导入个人成员。import static some.package.DA.save而不是DA.*。这将使查找此导入方法的来源变得更加容易。

Personally, I have used this language feature veryrarely, and almost always only with constants or enums, never with methods. The trade-off, for me, is almost never worth it.

就个人而言,我已经使用这个语言功能非常只能用常量或枚举很少,而且几乎总是,从不与方法。对我来说,这种权衡几乎不值得。

回答by Bombe

Static imports are the only “new” feature of Java that I have never used and don't intend to ever use, due to the problems you just mentioned.

由于您刚才提到的问题,静态导入是 Java 唯一的“新”特性,我从未使用过,也不打算使用它。

回答by Joel

I agree that they can be problematic from a readability perspective and should be used sparingly. But when using a common static method they can actually increase readability. For example, in a JUnit test class, methods like assertEqualsare obvious where they come from. Similarly for methods from java.lang.Math.

我同意从可读性的角度来看它们可能有问题,应该谨慎使用。但是当使用常见的静态方法时,它们实际上可以提高可读性。例如,在 JUnit 测试类中,像这样assertEquals的方法很明显它们来自哪里。类似的方法来自java.lang.Math.

回答by kdgregory

They're useful to reduce verbiage, particularly in cases where there are a lot of imported methods being called, and the distinction between local and imported methods is clear.

它们有助于减少冗长,特别是在调用大量导入方法的情况下,并且本地方法和导入方法之间的区别很明显。

One example: code that involves multiple references to java.lang.Math

一个例子:涉及对 java.lang.Math 的多次引用的代码

Another: An XML builder classwhere prepending the classname to every reference would hide the structure being built

另一个:一个 XML 构建器类,其中将类名添加到每个引用将隐藏正在构建的结构

回答by Javamann

I use them when ever I can. I have IntelliJ setup to remind me if I forget. I think it looks much cleaner than a fully qualified package name.

我尽可能使用它们。如果我忘记了,我有 IntelliJ 设置来提醒我。我认为它看起来比完全限定的包名称要简洁得多。

回答by jjnguy

I use it for Color a lot.

我经常将它用于颜色。

static import java.awt.Color.*;

It is very unlikely that the colors will be confused with something else.

颜色不太可能与其他颜色混淆。

回答by davetron5000

You need to use them when:

您需要在以下情况下使用它们:

  • you wish to use a switchstatement with enum values
  • you wish to make your code difficult to understand
  • 您希望使用switch带有枚举值的语句
  • 你想让你的代码难以理解

回答by Rob Hruska

Effective Java, Second Edition, at the end of Item 19notes that you can use static imports if you find yourself heavilyusing constants from a utility class. I think this principle would apply to static imports of both constants and methods.

Effective Java, Second Edition第 19 条末尾指出,如果您发现自己大量使用实用程序类中的常量,则可以使用静态导入。我认为这个原则适用于常量和方法的静态导入。

import static com.example.UtilityClassWithFrequentlyUsedMethods.myMethod;

public class MyClass {
    public void doSomething() {
        int foo= UtilityClassWithFrequentlyUsedMethods.myMethod();
        // can be written less verbosely as
        int bar = myMethod();
    }
}

This has advantages and disadvantages. It makes the code a bit more readable at the expense of losing some immediate information about where the method is defined. However, a good IDE will let you go to the definition, so this isn't much of an issue.

这有优点也有缺点。它使代码更具可读性,但会丢失一些有关方法定义位置的即时信息。然而,一个好的 IDE 会让你去定义,所以这不是什么大问题。

You should still use this sparingly, and only if you find yourself using things from the imported file many, many times.

您仍然应该谨慎使用它,并且仅当您发现自己多次使用导入文件中的内容时。

Edit:Updated to be more specific to methods, as that's what this question is referring to. The principle applies regardless of what's being imported (constants or methods).

编辑:更新为更具体的方法,因为这就是这个问题所指的。无论导入什么(常量或方法),该原则都适用。

回答by Rob Hruska

Another reasonable use for static imports is with JUnit 4. In earlier versions of JUnit methods like assertEqualsand failwere inherited since the test class extended junit.framework.TestCase.

静态导入的另一个合理用途是与 JUnit 4 一起使用。在早期版本的 JUnit 方法中,例如assertEqualsfail自从测试类扩展后就被继承了junit.framework.TestCase

// old way
import junit.framework.TestCase;

public class MyTestClass extends TestCase {
    public void myMethodTest() {
        assertEquals("foo", "bar");
    }
}

In JUnit 4, test classes no longer need to extend TestCaseand can instead use annotations. You can then statically import the assert methods from org.junit.Assert:

在 JUnit 4 中,测试类不再需要扩展TestCase,而是可以使用注释。然后,您可以从org.junit.Assert以下位置静态导入断言方法:

// new way
import static org.junit.Assert.assertEquals;

public class MyTestClass {
    @Test public void myMethodTest() {
        assertEquals("foo", "bar");
        // instead of
        Assert.assertEquals("foo", "bar");
    }
}

JUnit documentsusing it this way.

JUnit文档以这种方式使用它。

回答by Matthias Wuttke

I think static imports are neat for NLS in the gettext-style.

我认为静态导入对于 gettext 样式的 NLS 来说是整洁的。

import static mypackage.TranslatorUtil._;

//...
System.out.println(_("Hello world."));

This both marks the string as a string that has to be extracted and provides an easy and clean way to replace the string with its translation.

这既将字符串标记为必须提取的字符串,又提供了一种简单而干净的方法来用其翻译替换字符串。