27

考虑下面的类

public final class Constant {
  public static final String USER_NAME="user1";
  //more constant here
}

包 B 中的此类。

现在我将在包 A 中使用它。考虑以下两种可以使用的方法。

方法1-使用import B.Constant

import B.Constant;

public class ValidateUser {
public static void main(String[] args) {
   if(Constant.USER_NAME.equals("user1")){

   }
  }
 }

方法2-使用import static B.Constant.USER_NAME;

import static B.Constant.USER_NAME;

public class ValidateUser {
public static void main(String[] args) {
   if(USER_NAME.equals("user1")){

   }
 }
}

我的问题是在这种情况下,正常导入与静态导入有什么区别或优势吗?

4

8 回答 8

36

importnormal和 an之间的唯一区别import static是后者用于将static某些其他类或接口的成员(尤其是常量)移动到作用域中。是否使用它取决于您;我喜欢它,因为它使课程的主体更短,但 YMMV。

当它们编译成相同的字节码时,使用它们没有性能优势或损失(除非可能在编译时,就好像你关心那样)。

于 2013-09-16T10:25:29.740 回答
20

主要区别是可读性Constant.USER_NAMEUSER_NAME.

文档

使用得当,静态导入可以通过删除类名重复的样板来使您的程序更具可读性。

但无论如何,尽量避免做

import static B.Constant.*;

因为它可以用您导入的所有静态成员污染其命名空间。

于 2013-09-16T10:23:56.680 回答
11

我很少使用静态导入,并且仅在它们实际上使代码更容易理解的地方使用。

根据甲骨文:

http://docs.oracle.com/javase/1.5.0/docs/guide/language/static-import.html

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

这里需要注意的要点:

  • 当您需要频繁访问一两个类的静态成员时使用它
  • 使用得当,静态导入可以让你的程序更具可读性

评论者@Donal Fellows 恰当地说,使用 IDE 管理静态导入的风险较小。我同意现代 IDE 已经走了很长一段路,并且将消除管理依赖关系和跟踪方法回调给父级的许多痛苦。

于 2013-09-16T10:25:00.080 回答
4

例如,数学类中的所有方法都是静态的,我们将它们都称为 Math.mathod()。但是如果我们像这样导入数学类:import static java.lang.Math.*;我们不必在方法之前添加数学:

import static java.lang.Math.*;

public class Program {

    public static void main(String args[]) {

        System.out.println(sqrt(25));
        System.out.println(log(100));
        System.out.println(PI);
    }
}
于 2013-09-16T10:30:25.127 回答
2

静态导入让您避免使用类名限定静态成员。

导入静态成员后,您可以在代码中使用它而无需类名前缀。

好的例子:

import static sample.SampleStaticValues.NUM_ZERO;
…

enum OddEven {odd,even}


//need not do SampleConstants.NUM_ZERO due to static import feature
if(num % 2 == NUM_ZERO){
   System.out.println("The num " + num + " is: " + OddEven.even);
}

  package sample;
  public class SampleStaticValues {
  public static int NUM_ZERO = 0;
  public static int NUM_ONE = 0;
}
于 2013-09-16T10:25:19.157 回答
1

静态导入用于节省您的时间和打字。如果您讨厌一次又一次地键入相同的内容,那么您可能会发现这样的导入很有趣。

导入允许 java 程序员在没有包限定的情况下访问包的类。

静态导入功能允许在没有类限定的情况下访问类的静态成员。

让我们借助以下示例来理解这一点:

示例 1:没有静态导入

class Demo1{
   public static void main(String args[])
   {
      double var1= Math.sqrt(5.0);
      double var2= Math.tan(30);
      System.out.println("Square of 5 is:"+ var1);
      System.out.println("Tan of 30 is:"+ var2);
   }
}

输出:

Square of 5 is:2.23606797749979
Tan of 30 is:-6.405331196646276

示例 2:使用静态导入

import static java.lang.System.out;
import static java.lang.Math.*;
class Demo2{
   public static void main(String args[])
   {
      //instead of Math.sqrt need to use only sqrt
      double var1= sqrt(5.0);
      //instead of Math.tan need to use only tan
      double var2= tan(30);
      //need not to use System in both the below statements
      out.println("Square of 5 is:"+var1);
      out.println("Tan of 30 is:"+var2);
   }
}

输出:

Square of 5 is:2.23606797749979
Tan of 30 is:-6.405331196646276
于 2017-03-25T18:18:40.303 回答
0

为了访问静态成员,有必要使用它们来自的类来限定引用。例如,必须说:

double r = Math.cos(Math.PI * theta);
or
System.out.println("Blah blah blah");

您可能希望避免不必要地使用静态类成员,例如 Math。和系统。为此使用静态导入。例如上面的代码当使用静态导入更改为:

import static java.lang.System.out;
import static java.lang.Math.PI;
import static java.lang.Math.cos;
...
double r = cos(PI * theta);
out.println("Blah blah blah");
...

那么使用上述技术有什么好处呢?我看到的唯一优势是代码的可读性。不用写静态类名,直接写方法名或成员变量名即可。这里还要记住一件事。不允许模棱两可的静态导入。即如果你已经导入了 java.lang.Math.PI 并且你想导入 mypackage.Someclass.PI,编译器会抛出一个错误。因此,您只能导入一个成员 PI。

于 2013-09-16T10:34:15.093 回答
0

伙计们,今天我们遇到了静态导入的一个很大的缺点。下面简单分享一下。

  1. XXXConsts.java 有 EVENT_ID (EVENT_ID = "EVENT_ID"),它被静态导入到从 AbstractService.java 扩展的类 XXXComceteImpl.java 中
  2. 从 AbstractService.java 扩展的 XXXZeloImpl.java 需要 EVENT_ID = "eventId"。所以在 AbstractService.java 中声明了 EVENT_ID = "eventId"。
  3. 现在 #1 已损坏,因为 XXXComceteImpl.java 中的 EVENT_ID 指的是 AbstractService.java 中的 EVENT_ID
  4. 可能是 EVENT_ID = "eventId" 的命名应该有所不同。
  5. 注意:- 分类的名称是经过编辑的版本,因此看起来很不寻常。
于 2017-10-25T11:07:43.307 回答