使用静态导入优于导入是否有任何优势?

时间:2013-09-16 10:20:55

标签: java import static-import

考虑以下课程

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")){

   }
 }
}

我的问题是,在这种情况下,静态导入的正常导入是否存在差异或优势?

8 个答案:

答案 0 :(得分:29)

普通importimport static之间的唯一区别是后者用于移动某些其他类或接口的static成员 - 尤其是常量 - 进入范围。你是否使用它取决于你;我喜欢它,因为它让班级的身体更短,但是YMMV。

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

答案 1 :(得分:20)

主要区别是可读性,与Constant.USER_NAME相比,USER_NAME的可读性较差。

来自Documentation

  

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

但无论如何,尽量避免做

import static B.Constant.*;

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

答案 2 :(得分:9)

我很少使用静态导入,只是在实际使代码更容易理解的地方。

根据oracle:

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

  

那么什么时候应该使用静态导入?非常谨慎!只在使用时才使用它   否则你会想要声明常量的本地副本,或者   滥用继承(Constant Interface Antipattern)。其他   单词,当您需要频繁访问静态成员时使用它   一两节课。如果过度使用静态导入功能,则可以   使你的程序不可读和不可维护,污染它   包含您导入的所有静态成员的命名空间。您的代码的读者   (包括你,在你写完几个月后)将不知道哪个   class一个静态成员来自。导入所有静态成员   从一个班级可以特别有害于可读性;如果你需要   只有一两个成员,单独导入它们。适当使用,   通过删除,静态导入可以使您的程序更具可读性   重复类名的样板。

这里要注意的重点:

  • 当您需要经常访问来自一个或两个班级的静态成员时使用它
  • 使用得当,静态导入可以使您的程序更具可读性

评论员@Donal Fellows恰当地说,使用IDE管理静态导入风险较小。我同意现代IDE已经走过了漫长的道路,并将消除管理依赖性和追踪方法调用回到父母的许多痛苦。

答案 3 :(得分:4)

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

答案 4 :(得分: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;
}

答案 5 :(得分:1)

静态导入用于节省您的时间和输入内容。如果你不喜欢一次又一次地输入同样的东西,那么你可能会发现这些导入很有趣。

import 允许java程序员在没有包认证的情况下访问包的类。

s tatic import 功能允许访问类的静态成员,而无需通过类限定。

让我们在以下示例的帮助下理解这一点:

示例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

答案 6 :(得分: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成员。

答案 7 :(得分:-1)

今天我们遇到静态导入的一大缺点。只需在下面分享即可。

  1. XXXConsts.java有EVENT_ID(EVENT_ID =" EVENT_ID"),它是从AbstractService.java扩展的类XXXComceteImpl.java中静态导入的。
  2. 从AbstractService.java扩展的XXXZeloImpl.java想要EVENT_ID =" eventId"。所以EVENT_ID =" eventId"在AbstractService.java中声明。
  3. 现在#1已被破坏,因为XXXComceteImpl.java中的EVENT_ID指的是AbstractService.java中的EVENT_ID
  4. 可能是EVENT_ID =" eventId"的命名应该是不同的。
  5. 注意: - 分类的命名是编辑版本所以它看起来很不寻常。