Hello, I am watching the mountains.
The reason for this article is a disagreement with my colleagues about the import statement during the code review.
Those who have used IDEA know that by default, when importing classes through import, when the number reaches the set number (5 classes, 3 static variables), it will be changed to the on-demand import method, that is, use the * sign to fold the import .
Colleagues suggest not to use on-demand import, but to use single-type-import. And I think that since IDEA is a universe-level IDE, there will be no mistakes in this kind of place, so I want to continue to follow the IDEA default configuration.
So sum up the differences between these two methods. If you are not familiar with java import, from here take a look.
Two import declarations of import
In java, there are two ways to import classes through import:
- Single-type-import (single-type-import), for example
import java.io.File
: This method is easier to understand, and most of the time we use this method. Import them in by clearly specifying the class and interface path. - Type-import-on-demand (type-import-on-demand), for example
import java.io.*
,*
defines the import method through wildcards , but not all classes in this package are directly imported, but all classes can be imported. In other words, if you need to import it, you don't need to import it.
Has the following attributes:
- Java imports
public
the classes and interfaces of any one of the packages in these two ways (only public classes and interfaces can be imported) - As mentioned above, import declarations only import classes under the declaration directory and not subpackages, which is why they are called type import declarations.
- The simple name of the imported class or interface has the scope of the compilation unit. This means that the short name of the type can be used anywhere in the compilation unit where the import statement is located. This does not mean that you can use the short names of all members of the type, but only the short names of the type itself. For example: the public classes in the java.lang package are automatically imported, including
Math
andSystem
classes. However, you cannot use thePI()
sum of the short names of their membersgc()
, but must use theMath.PI()
sumSystem.gc()
. You do not need to type thejava.lang.Math.PI()
sumjava.lang.System.gc()
. - Programmers sometimes import the current package or
java.lang
package, which is unnecessary, because the members of the current package themselves are in scope, and thejava.lang
package is automatically imported. The java compiler ignores these redundant import declarations.
Import mechanism on demand
On-demand type import is more convenient in most cases. A wildcard can import all classes under the package, so you don't have to write a lot of imports.
However, according to the conservation of energy, the energy saved when typing codes will inevitably be consumed elsewhere.
For example, a Date
class can be written if it is completely imported using the on-demand type import java.util.*
. When this class happens to be needed, an import PrepareStatement
needs to be added import java.sql.*
. At this time, the compiler does not know whether the Date
class is to be used in the java.util
package or java.sql
inside, it will report an Reference to 'Date' is ambiguous, both 'java.util.Date' and 'java.sql.Date' match
exception, which is the so-called naming conflict .
The solution is to specify Date
the full path to the class, that is, using a single type of import: import java.util.Date
.
In addition to naming conflicts, there are some less obvious disadvantages:
- Compilation speed: Because of the characteristics of the on-demand import mechanism, you need to find all classes that match the package name under the CLASSPATH, which will consume performance during compilation. In small projects, this speed can be ignored. If in a large project, there will be detailed differences.
- Readability: In the development process using IDE, we rarely look at
import
the path of the class. But if we need to edit files in other environments, such as vim,import
it is very convenient to view the path of the class.
What happens when importing unnecessary classes
From a rational point of view, the java compiler will definitely optimize here, and will not add unnecessary import declarations to the class file, but I haven't seen any instructions before, so let's do some experiments:
First define the java class:
package cn.howardliu;
// 需要用到的单类型导入
import java.util.Date;
// 需要用到的按需类型导入
import java.math.*;
// 不需要用到的单类型导入
import java.sql.PreparedStatement;
// 不需要用到的按需类型导入
import java.awt.*;
public class Main {
private Date date1;
private BigDecimal num1;
public void test(){
Date date2 = new Date();
BigDecimal num2 = new BigDecimal(0);
}
}
javac Main.java
Compile by command , and then javap -verbose Main.class
view the results of the compilation:
Classfile /path/to/Main.class
Last modified 2021-1-31; size 439 bytes
MD5 checksum 81e13559f738197b4875c2c2afd6fc41
Compiled from "Main.java"
public class cn.howardliu.Main
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #7.#19 // java/lang/Object."<init>":()V
#2 = Class #20 // java/util/Date
#3 = Methodref #2.#19 // java/util/Date."<init>":()V
#4 = Class #21 // java/math/BigDecimal
#5 = Methodref #4.#22 // java/math/BigDecimal."<init>":(I)V
#6 = Class #23 // cn/howardliu/Main
#7 = Class #24 // java/lang/Object
#8 = Utf8 date1
#9 = Utf8 Ljava/util/Date;
#10 = Utf8 num1
#11 = Utf8 Ljava/math/BigDecimal;
#12 = Utf8 <init>
#13 = Utf8 ()V
#14 = Utf8 Code
#15 = Utf8 LineNumberTable
#16 = Utf8 test
#17 = Utf8 SourceFile
#18 = Utf8 Main.java
#19 = NameAndType #12:#13 // "<init>":()V
#20 = Utf8 java/util/Date
#21 = Utf8 java/math/BigDecimal
#22 = NameAndType #12:#25 // "<init>":(I)V
#23 = Utf8 cn/howardliu/Main
#24 = Utf8 java/lang/Object
#25 = Utf8 (I)V
{
public cn.howardliu.Main();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 12: 0
public void test();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=3, locals=3, args_size=1
0: new #2 // class java/util/Date
3: dup
4: invokespecial #3 // Method java/util/Date."<init>":()V
7: astore_1
8: new #4 // class java/math/BigDecimal
11: dup
12: iconst_0
13: invokespecial #5 // Method java/math/BigDecimal."<init>":(I)V
16: astore_2
17: return
LineNumberTable:
line 17: 0
line 18: 8
line 19: 17
}
SourceFile: "Main.java"
It can be seen from the content of the class file:
- The presentation of the on-demand type import method in the class file is the same as the import by type. The required class import will be found, and all the classes in the package will not be imported.
- Unnecessary class import declarations will eventually be optimized away and will not appear in the class file.
import
Unlike the C language, Javainclude
does not write the imported declared classes into the class file, and each is an independent class file.
JDK recommends which way
JDK is definitely the benchmark for java programming. Many of us can learn from JDK:
import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.io.BufferedWriter;
import java.security.AccessController;
import java.security.PrivilegedAction;
import sun.util.spi.XmlPropertiesProvider;
This is java.util.Properties
the import statement in. It can be seen that a single-type import statement is used. Therefore, if there are no other requirements, we try to use single-type import as much as possible.
End-of-sentence thinking
- Java
import
is a class import declaration, and will not write the file to the compiled class file import
There are two import methods for java : single type import and on-demand type import- On-demand type import will only have performance loss during the compilation process, and there is no difference between single-type import at runtime
- Most of the JDK source code uses single-type imports.
Hello, I’m Kanshan, public account: Kanshan’s Lodge, a 10-year-old backend, open source contributors to Apache Storm, WxJava, and Cynomys. Main job: programmer, part-time job: architect. Swim in the code world, enjoy life in drama.
Personal homepage: https://www.howardliu.cn
Personal blog post: java import import package
CSDN homepage: http://blog.csdn.net/liuxinghao
CSDN blog post: java import import package