我的编程空间,编程开发者的网络收藏夹
学习永远不晚

详解java中import的作用

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

详解java中import的作用

一、package

C/C++ 的 #include会把所包含的内容在编译时添加到程序文件中,而java的import则不同。

这里我们先了解一下Java 的 package 到底有何用处。

package名称就像是我们的姓,而class名称就像是我们的名字 。package和package的附属关系用"."来连接,这就像是复姓。比如说 java.lang.String就是复姓 java.lang,名字為 String 的类别;java.io.InputStream 则是复姓 java.io,名字為 InputStream的类别。

Java 会使用 package 这种机制的原因也非常明显,就像我们取姓名一样 ,光是一间学校的同一届同学中,就有可能会出现不少同名的同学,如果不取姓的话,那学校在处理学生资料,或是同学彼此之间的称呼,就会发生很大的困扰。相同的,全世界的 Java 类数量,恐怕比日本人还多,如果类别不使用package名称,那在用到相同名称的不同类时, 就会产生极大的困扰。所以package这种方式让极大降低了类之间的命名冲突。

Java 的package名称我们可以自己取,不像人的姓没有太大的选择 ( 所以出现很多同名同姓的情况 ),如果依照 Sun 的规范来取套件名称,那理论上不同人所取的套件名称不会相同 ( 需要的话请参阅 “命名惯例” 的相关文章 ),也就不会发生名称冲突的情况。

可是现在问题来了,因為很多package的名称非常的长,在编程时,要使用一个类要将多个包名.类名完全写出,会让代码变得冗长,减低了简洁度。例如


java.io.InputStream is = java.lang.System.in;
java.io.InputStreamReader isr= new java.io.InputStreamReader(is);
java.io.BufferedReader br = new java.io.BufferedReader(isr);

显得非常麻烦,于是Sun公司就引入了import。

二、import

import就是在java文件开头的地方,先说明会用到那些类别。
接着我们就能在代码中只用类名指定某个类,也就是只称呼名字,不称呼他的姓。

首先,在程序开头写:


import java.lang.System;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;

于是我们就可以在程序中这样写到:


InputStream = System.in;
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);

一个java文件就像一个大房间,我们在门口写着在房间里面的class的姓和名字,所以在房间里面提到某个class就直接用他的名字就可以。例如:

System 就是指 java.lang.System,而 InputStream 就是指 java.io.InputStream。

但是如果一个java文件里面有多个同个“姓”,即包名相同的类(例如上面的InputStream,InputStreamReader,BufferedReader都是java.io中的类),我们一一写出显得比较繁杂,所以Sun就让我们可以使用


import java.lang.*;
import java.io.*;

表示文件里面说到的类不是java.lang包的就是java.io包的。编译器会帮我们选择与类名对应的包。

那我们可不可以再懒一点直接写成下面声明呢?


import java.*;

历史告诉我们,这样是不行的。因為那些类别是姓 java.io 而不是姓 java。就像姓『诸葛』的人应该不会喜欢你称他為『诸』 先生吧。这样写的话只会将java包下的类声明,而不不会声明子包的任何类。

这里注意,java.lang包里面的类实在是太常太常太常用到了,几乎没有类不用它的, 所以不管你有没有写 import java.lang,编译器都会自动帮你补上,也就是说编译器只要看到没有姓的类别,它就会自动去lang包里面查找。所以我们就不用特别去 import java.lang了。

一开始说 import 跟 #include 不同,是因为import 的功能到此為止,它不像#include 一样,会将其他java文件的内容载入进来。import 只是让编译器编译这个java文件时把没有姓的类别加上姓,并不会把别的文件程序写进来。你开心的话可以不使用import,只要在用到类别的时候,用它的全部姓名来称呼它就行了(就像例子一开始那样),这样跟使用import功能完全一样。

三、import的两种导入声明

  • 单类型导入(single-type-import)(例:import java.util.ArrayList; )
  • 按需类型导入(type-import-on-demand)(例:import java.util.*;)

有如下属性:

  1. java以这样两种方式导入包中的任何一个public的类和接口(只有public类和接口才能被导入)
  2. 上面说到导入声明仅导入声明目录下面的类而不导入子包,这也是为什么称它们为类型导入声明的原因。
  3. 导入的类或接口的简名(simple name)具有编译单元作用域。这表示该类型简名可以在导入语句所在的编译单元的任何地方使用.这并不意味着你可以使用该类型所有成员的简名,而只能使用类型自身的简名。例如: java.lang包中的public类都是自动导入的,包括Math和System类.但是,你不能使用它们的成员的简名PI()和gc(),而必须使用Math.PI()和System.gc().你不需要键入的是java.lang.Math.PI()和java.lang.System.gc()。
  4. 程序员有时会导入当前包或java.lang包,这是不需要的,因为当前包的成员本身就在作用域内,而java.lang包是自动导入的。java编译器会忽略这些冗余导入声明(redundant import declarations)。即使像这样import java.util.ArrayList;import java.util.*;多次导入,也可编译通过。编译器会将冗余导入声明忽略.

四、static import静态导入

在Java程序中,是不允许定义独立的函数和常量的。即什么属性或者方法的使用必须依附于什么东西,例如使用类或接口作为挂靠单位才行(在类里可以挂靠各种成员,而接口里则只能挂靠常量)。

如果想要直接在程序里面不写出其他类或接口的成员的挂靠单元,有一种变通的做法 :
将所有的常量都定义到一个接口里面,然后让需要这些常量的类实现这个接口(这样的接口有一个专门的名称,叫(“Constant Interface”)。这个方法可以工作。但是,因为这样一来,就可以从“一个类实现了哪个接口”推断出“这个类需要使用哪些常量”,有“会暴露实现细节”的问题。

于是J2SE 1.5里引入了“Static Import”机制,借助这一机制,可以用略掉所在的类或接口名的方式,来使用静态成员。static import和import其中一个不一致的地方就是static import导入的是静态成员,而import导入的是类或接口类型

如下是一个有静态变量和静态方法的类


package com.assignment.test;
public class staticFieldsClass {
	static int staticNoPublicField = 0; 
	public static int staticField = 1;
    public static void staticFunction(){}
}

平时我们使用这些静态成员是用类名.静态成员的形式使用,即staticFieldsClass.staticField或者staticFieldsClass.staticFunction()。

现在用static import的方式:


//**精准导入**
//直接导入具体的静态变量、常量、方法方法,注意导入方法直接写方法名不需要括号。
import static com.assignment.test.StaticFieldsClass.staticField;
import static com.assignment.test.StaticFieldsClass.staticFunction;

//或者使用如下形式:
//**按需导入**不必逐一指出静态成员名称的导入方式
//import static com.assignment.test.StaticFieldsClass.*;

public class StaticTest {
    public static void main(String[] args) {
	    //这里直接写静态成员而不需要通过类名调用
        System.out.println(staticField);
        staticFunction();
    }
}

这里有几个问题需要弄清楚:

  1. Static Import无权改变无法使用本来就不能使用的静态成员的约束,上面例子的StaticTest和staticFieldsClass不是在同一个包下,所以StaticTest只能访问到staticFieldsClass中public的变量。使用了Static Import也同样如此。
  2. 导入的静态成员和本地的静态成员名字相同起了冲突,这种情况下的处理规则,是“本地优先。
  3. 不同的类(接口)可以包括名称相同的静态成员。例如在进行Static Import的时候,出现了“两个导入语句导入同名的静态成员”的情况。在这种时候,J2SE 1.5会这样来加以处理:
  4. 如果两个语句都是精确导入的形式,或者都是按需导入的形式,那么会造成编译错误。
  5. 如果一个语句采用精确导入的形式,一个采用按需导入的形式,那么采用精确导入的形式的一个有效。

大家都这么聪明上面的几个特性我就不写例子了。

static import这么叼那它有什么负面影响吗?

答案是肯定的,去掉静态成员前面的类型名,固然有助于在频繁调用时显得简洁,但是同时也失去了关于“这个东西在哪里定义”的提示信息,理解或维护代码就呵呵了。
但是如果导入的来源很著名(比如java.lang.Math),这个问题就不那么严重了。


五、按需导入机制

使用按需导入声明是否会降低Java代码的执行效率?

**绝对不会! **

1.import的按需导入


import java.util.*;
public class NeedImportTest {
    public static void main(String[] args) {
        ArrayList tList = new ArrayList();
    }
}

编译之后的class文件 :


//import java.util.*被替换成import java.util.ArrayList
//即按需导入编译过程会替换成单类型导入。
import java.util.ArrayList;

public class NeedImportTest {
    public static void main(String[] args) {
        new ArrayList();
    }
}

2.static import的按需导入


import static com.assignment.test.StaticFieldsClass.*;
public class StaticNeedImportTest {
    public static void main(String[] args) {
        System.out.println(staticField);
        staticFunction();
    }
}

上面StaticNeedImportTest 类编译之后 :


//可以看出 : 
//1、static import的精准导入以及按需导入编译之后都会变成import的单类型导入
import com.assignment.test.StaticFieldsClass;

public class StaticNeedImportTest {
    public static void main(String[] args) {
    //2、编译之后“打回原形”,使用原来的方法调用静态成员
        System.out.println(StaticFieldsClass.staticField);
        StaticFieldsClass.staticFunction();
    }
}

六、附加

这是否意味着你总是可以使用按需导入声明?
**是,也不是! **

在类似Demo的非正式开发中使用按需导入声明显得很有用。

然而,有这四个理由让你可以放弃这种声明:

  1. 编译速度:在一个很大的项目中,它们会极大的影响编译速度.但在小型项目中使用在编译时间上可以忽略不计。
  2. 命名冲突:解决避免命名冲突问题的答案就是使用全名。而按需导入恰恰就是使用导入声明初衷的否定。
  3. 说明问题:毕竟高级语言的代码是给人看的,按需导入看不出使用到的具体类型。
  4. 无名包问题:如果在编译单元的顶部没有包声明,Java编译器首选会从无名包中搜索一个类型,然后才是按需类型声明。如果有命名冲突就会产生问题。

Sun的工程师一般不使用按需类型导入声明.这你可以在他们的代码中找到:
在java.util.Properties类中的导入声明:


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;

可以看到他们用单类型导入详细的列出了需要的java.io包中的具体类型。

以上就是java中import作用的详细内容,更多关于java中import的资料请关注编程网其它相关文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

详解java中import的作用

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

java中import的作用是什么

在Java中,import语句用于导入其他类或包中的类,以便在当前源文件中可以直接使用这些类而不需要使用完全限定的类名。具体来说,import语句的作用有以下几个方面:1. 简化类的引用:使用import语句可以省略类的完全限定名,只需要使
2023-09-15

import与export在node.js中的使用详解

简述 import与export是es6中模块化的导入与导出,node.js现阶段不支持,需要通过babel进行编译,使其变成node.js的模块化代码。(关于node.js模块,可参考其他node.js模块化的文章) export 曝露
2022-06-04

Python中import机制详解

Python语言中import的使用很简单,直接使用 import module_name 语句导入即可。这里我主要写一下"import"的本质。 Python官方 定义:Python code in one module gains ac
2022-06-04

java中import怎么使用

在Java中,可以使用import语句来导入其他类或包。import语句用于告诉编译器需要使用某个类或包中的内容。导入类的语法如下:```import package.name.ClassName;```或者可以使用通配符(*)来导入整个包
2023-09-08

java中Serializable接口作用详解

本文为大家解析java中Serializable接口的作用,具体内容如下 1.(serializable)主要支持对象的回复,所以可以用来保存当前的程序系统状态,远程方法调用RMI(远程机器必须含有必要的.class文件,否则将掷出clas
2023-05-31

SpringBoot@Import与@Conditional注解使用详解

在了解springboot自动配置原理前,再来了解下两个注解@Import注解和@Conditional注解,@Conditional是Spring4新提供的注解,它的作用是按照一定的条件进行判断,满足条件给容器注册bean
2022-11-13

java中的import语句有什么用

在Java中,import语句用于导入其他包中的类、接口或静态成员。它有以下作用:1. 方便使用:通过import语句,可以直接使用其他包中的类、接口或静态成员,而无需使用完整的包名进行调用。2. 避免命名冲突:当不同包中存在同名的类或接口
2023-08-16

python中import和from-import的区别解析

这篇文章主要介绍了python中import和from-import的区别解析,本文通过实例代码给大家讲解的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
2022-12-08

Python中import是如何工作的

这篇“Python中import是如何工作的”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Python中import是如何工
2023-07-06

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录