你真正的了解过JAVA import 导包吗?

前言

欢迎大家来到院长的博客,记录一下工作中的琐事。本文主要内容白话(说一下)import 导入 应不应该加上static关键字。

时间,今天下午。同事最近在做代码优化,准备将代码合并到Dev分支。我耳朵比较敏锐听到了,也想了解一下他优化了什么内容。于是上gitlab上看了一圈,发现代码中貌似有一些不妥的地方,并针对import static 导入方式做了一下面对面讨论。

下面将我个人想法和建议做一下梳理。希望能帮助到有需要的同学。如果哪里说的不对,欢迎大家指出。

假装是个动图.png

代码展示

下面代码,模拟一下今天下午的真实场景。XXXUtil代码中大约有20多个常量类 都是采用如下静态import导入的形式。

import static com.package.framework.cmd.Constants.LOGINSUCCESS;
import static com.package.framework.cmd.Constants.LOGINFAIL;
import static com.package.framework.cmd.Constants.LOGINCANCEL;
import static com.package.framework.cmd.Constants.N;
import static com.package.framework.cmd.Constants.N;
import static com.package.framework.cmd.Constants.N;
import static com.package.framework.cmd.Constants.N;
import static com.package.framework.cmd.Constants.N;
import static com.package.framework.cmd.Constants.;

public class XXXUtil {//类名
      switch (cmd) {
       case LOGINSUCCESS:
       	//执行具体的逻辑
         break;
      }
}

下列展示的是我认为这样写比较好的代码,不需要大量静态导入,同样达到一样的效果,直观清晰明了。虽然从编译结果、业务逻辑角度来说,上面写的代码你也不能说错或者有问题。但是总感觉很别扭,通过接下来说明和小例子。来阐述我得观点。


public class XXXXXUtil {//类名
      switch (cmd) {
       case  Constants.LOGINSUCCESS:
       	//执行具体的逻辑
         break;
      }
}


JAVA 知识了解

在 Java 中,静态导入的概念在 1.5 版本中引入。借助静态导入,我们可以直接访问类的静态成员,无需类名或任何对象。例如:我们可以通过使用 Math 类即Math.sqrt()来使用 Math 类的 sqrt() 方法,但是通过使用静态导入,我们可以直接访问 sqrt() 方法。

据SUN公司称,静态导入将提高代码可读性并增强编码。但是一些编程大佬们不认可这样的说法,认为它会导致程序混乱并且不利于编程。给到的建议是:如果没有特殊要求,尽量不要使用静态导入。为什么呢?文末会给出答案。

正常improt 导入

class HelloWorld{
	public static void main(String[] args){
		System.out.println(Math.sqrt(4));
		System.out.println(Math.pow(2, 2));
		System.out.println(Math.abs(6.3));
	}
}

输出:

2.0

4.0

6.3


静态导入

静态导入的方式,可以观察到下面的代码省略了Math。输出的结果也是一致的

import static java.lang.Math.*;

public class HelloWorld{
	public static void main(String[] args){
		System.out.println(sqrt(4));
		System.out.println(pow(2, 2));
		System.out.println(abs(6.3));
	}
}

输出:

2.0

4.0

6.3

静态导入升级版

静态导入的方式,可以观察到下面的代码省略了Math和System。输出的结果也是一致的

import static java.lang.Math.*;
import static java.lang.System.*;
public class HelloWorld{
	public static void main(String[] args){
		out.println(sqrt(4));
		out.println(pow(2, 2));
		out.println(abs(6.3));
	}
}

输出:

2.0

4.0

6.3

注意: System 是 java.lang 包中的一个类,out 是 System 类中的静态变量。通过静态导入的方式,我们可以不用类名去调用它。

静态导入带来的歧义点:
如果从多个不同的类中导入两个同名的静态成员,编译器会抛出错误,因为在没有类名限定的情况下,它将无法确定使用哪个成员。 代码和错误截图如下所示。

import static java.lang.Integer.*;
import static java.lang.Byte.*;
public class HelloWorld{
	public static void main(String[] args){
		out.println(MAX_VALUE);
	}
}

错误输出.png

Error:Reference to MAX_VALUE is ambigious //错误:对 MAX_VALUE 的引用不明确

说明:在上面的代码中,我们试图访问 MAX_VALUE 变量,但是每个原始数据类型都包含 MAX_VALUE 变量,该变量在 Wrapper 类中预先声明。这里我们同时导入 Integer 和 Byte 类并尝试访问静态变量 MAX_VALUE。

但编译器会因为看到两个导入语句而感到懵逼,因为 Integer 和 Byte 类都包含一个静态变量 MAX_VALUE。因此这里编译器抛出一个错误,说Reference to MAX_VALUE is ambiguous。

正常import 导入和静态import 导入的区别

在正常import 导包中,我们能够访问任何包中存在的类和接口。但是使用静态导入,我们可以直接访问类的所有静态成员(变量和方法),而无需显式调用类名。

静态导入的优缺点:

  • 静态导入的优点:如果经常访问类的任何静态成员,则需要较少的代码。

  • 静态导入的缺点:过度使用静态导入功能,它会使程序不可读和不可维护。

    • 假如同时导入的两个类中又有重命名的静态成员,会出现报错。例如Integer类和Long类的MAX_VALUE。

总结:两个包中包含两个同名的类/接口是非常少见的。因此,正常导入我们很少会出现问题(歧义)。但是有可能两个类包含相同的变量,所以在静态导入会出现引用不明确报错。这就是为什么上面提到,如果没有这样特殊要求不建议使用静态引用的原因。

结尾

有用的知识又增加了,如果文本对你有帮助,希望给个关注和点赞。你的支持是我继续写作的动力。(疯狂暗示 !!!)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值