考虑以下类
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")){
}
}
}
我的问题是在这种情况下,正常导入与静态导入有什么区别或优势吗?
普通import
和import static
之间的唯一区别是后者用于将其他类或接口的static
成员(尤其是常量)移动到作用域中。是否使用它取决于您;我喜欢它,因为它使班级的主体更短,但是 YMMV。
使用它们没有任何性能优势或惩罚(除了可能在编译时,好像你关心这一点),因为它们编译成相同的字节码。
主要区别在于可追溯性,Constant.USER_NAME
与USER_NAME
相比,可读性较差。
从文档:
如果使用得当,静态导入可以通过删除重复类名的样板文件使程序更具可读性。
但无论如何,尽量避免这样做
import static B.Constant.*;
因为它会用您导入的所有静态成员污染其命名空间。
我很少使用静态导入,只在它们实际上使代码更容易理解的地方使用。
根据甲骨文:
http://docs.oracle.com/javase/1.5.0/docs/guide/language/static-import.html
那么什么时候应该使用静态导入呢?非常谨慎!仅在以下情况下使用 否则,您会很想声明常量的本地副本,或者 滥用继承(常量接口反模式)。在其他 单词,当您需要频繁访问静态成员时使用它 一两个班级。如果过度使用静态导入功能,它可以 使您的程序不可读和不可维护,污染其 包含导入的所有静态成员的命名空间。代码的读取器 (包括你,在你写几个月后)不会知道哪个 类 A 静态成员来自。导入所有静态成员 从类中可能对可读性特别有害;如果你需要 只有一个或两个成员,单独导入它们。使用得当, 静态导入可以通过删除 重复类名的样板。
这里要注意的要点:
- 当您需要频繁访问一个或两个类中的静态成员时,请使用它
- 如果使用得当,静态导入可以使程序更具可读性
评论者@Donal Fellows恰当地表示,使用IDE来管理静态导入的风险较小。我同意,因为现代 IDE 已经走了很长一段路,并且将消除管理依赖项和跟踪方法调用回父级的许多痛苦。
类中的所有方法都是静态的,我们称它们为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);
}
}
静态导入允许您避免使用类名限定静态成员。
导入静态成员后,可以在代码中使用它,而无需类名前缀。
好例子:
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;
}
静态导入用于节省您的时间和键入。如果您讨厌一次又一次地键入相同的东西,那么您可能会发现此类导入很有趣。
导入允许 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
伙计们,今天我们遇到了静态导入的一大缺点。就在下面分享。
- XXXConsts.java有EVENT_ID(EVENT_ID="EVENT_ID"),它是静态导入到从AbstractService扩展的XXXComceteImpl类中.java.java
- XXXZeloImpl.java从AbstractService延伸而来.java想要EVENT_ID = "eventId"。所以EVENT_ID = "eventId" 是在 AbstractService.java 中声明的。
- 现在#1被打破了,因为XXXComceteImpl.java中的EVENT_ID指的是AbstractService中的EVENT_ID.java
- 可能是EVENT_ID="eventId"的命名应该有所不同。
- 注意:- 类的名称是编辑版本,因此看起来不寻常。
为了访问静态成员,必须使用引用来自的类来限定引用。例如,必须说:
double r = Math.cos(Math.PI * theta);
or
System.out.println("Blah blah blah");
您可能希望避免不必要地使用静态类成员,如 Math. 和 System。为此,请使用静态导入。例如,使用静态导入更改时,上面的代码将更改为:
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。