java import、package作用与用法以及与C include的区别

本文详细解释了Java中package和import的作用与用法,包括如何使用package避免类名冲突,import简化类名书写,以及单类型导入和按需类型导入的区别。
java import、package作用与用法
有些人写了一阵子 Java,可是对於 Java 的 package 跟 import 还是不 太了解很多人以為原始码 .java 档案中的 import 会让编译器把所 import 的程式通通写到编译好的 .class 档案中,或是认為 import 跟 C/C++ 的 #include 相似,实际上,这是错误的观念。
让我们先了解一下,Java 的 package 到底有何用处。


其实,package 名称就像是我们的姓,而 class 名称就像是我们的名字 。package 名称有很多 . 的,就好像是复姓。比如说java.lang.String,就 是复姓 java.lang,名字為 String 的类别;java.io.InputStream 则是复姓 java.io,名字為 InputStream 的类别。Java 会使用 package 这种机制的原因也非常明显,就像我们取姓名一样 ,光是一间学校的同一届同学中,就有可能会出现不少同名的同学,如果不取 姓的话,那学校在处理学生资料,或是同学彼此之间的称呼,就会发生很大的 困扰。相同的,全世界的 Java 类别数量,恐怕比台湾人口还多,而且还不断 的在成长当中,如果类别不使用套件名称,那在用到相同名称的不同类别时, 就会產生极大的困扰。幸运的是,Java 的套件名称我们可以自己取,不像人 的姓没有太大的选择 ( 所以有很多同名同姓的 ),如果依照 Sun 的规范来取套件名称,那理论上不同人所取的套件名称不会相同 ( 请参阅 "命名惯例" 的相关文章 ),也就不会发生名称衝突的情况。


可是问题来了,因為很多套件的名称非常的长,在写程式时,会多打好多字,花费不少时间,比如说:


      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.lang.System;
     import java.io.InputStream;
     import java.io.InputStreamReader;
     import java.io.BufferedReader;
这几行说明了这四个姓名的类别,在程式中只用他的名字来称呼,所以当程式中提到 System 就是指 java.lang.System,而 InputStream 就是指 java.io.InputStream,依此类推。於是原来的程式就变成:


      InputStream = System.in;
     InputStreamReader isr = new InputStreamReader(is);
     BufferedReader br = new BufferedReader(isr);
这样看起来是不是清爽多了呢?如果这些类别用的次数很多,那就更能体会到import 的好处了。可是这样还是不够,因為懒是人的天性,还是会有人觉得打太多 import 了也很浪费时间,於是 Sun 又提供了一个方法:
      import java.lang.*;
     import java.io.*;
意思就是,等一下程式中提到的没有姓名的类别,不是姓 java.lang,就是姓 java.io,如果这两个裡面有同样名字的类别,而不幸的你又只用名字称呼这 个类别,那编译器仍然会跟你抱怨,因為它还是不知道你说的这个类别指那一个姓的类别。那可不可以再懒一点呢,只写:
      import java.*;
歷史告诉我们,人可以懒,但不能太懒,这样是不行的。因為那些类别是姓 java.io 而不是姓 java。就像姓『诸葛』的人应该不会喜欢你称他為『诸』 先生吧。
為甚麼我一开始说 import 跟 #include 不同呢?因為 import 的功能 到此為止,它不像 #include 一样,会将档案内容载入进来。import 只是请 编译器帮你打字,让编译器把没有姓的类别加上姓,并不会把别的档案的程 式码写进来。如果你想练习打字,可以不要使用 import,只要在用到类别的时候,用它的全部姓名来称呼它就行了(就像例子一开始那样),跟使用 import 完全没有甚麼两样。
另外,虽然人不可以太懒,但是 Sun 还是帮我们多偷了一点懒。因為 java.lang 这个套件实在是太常太常太常用到了,几乎没有程式不用它的, 所以不管你有没有写 import java.lang;,编译器都会自动帮你补上,也就是说编译器只要看到没有姓的类别,它就会自动去 java.lang 裡面找找看,看这个类别是不是属於这个套件的。所以我们就不用特别去import java.lang 了。
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
import导入声明可分为两中: 
1>单类型导入(single-type-import) 
例:import java.util.ArrayList; 
2>按需类型导入(type-import-on-demand) 
例:import java.util.*;
以这样两种方式导入包中的任何一个public的类和接口(只有public类和接口才能被导入)
*导入声明仅导入类型而不导入子包;这就是为什么称它们为单类型导入和按需类型导入声明的原因.
*导入的类或接口的简名(simple name)具有编译单元作用域.这表示该类型简名可以在导入语句所在的编译单元的任何地方使用.这并不意味着你可以使用该类型所有成员的简名,而只能使用类型自身的简名. 
例如: java.lang包中的public类都是自动导入的,包括Math和System类.但是,你不能使用简名PI()和gc(),而必须使用Math.PI()和System.gc().你不需要键入的是java.lang.Math.PI()和java.lang.System.gc().
程序员有时会导入当前包或java.lang包,这是不需要的,因为当前包的成员本身就在作用域内,而java.lang包是自动导入的.java编译器会忽略这些冗余导入声明(redundant import declarations).即使像这样 
import java.util.ArrayList; 
import java.util.*; 
多次导入,也可编译通过.编译器会将冗余导入声明忽略.
使用按需导入声明是否会降低Java代码的执行效率?绝对不会! 
Java编译器产生的类文件仅包含编译单元实际使用到的类或接口的符号引用.
这是否意味着你总是可以使用按需导入声明?是,也不是! 
在类似Demo的非正式开发中使用按需导入声明显得很有用. 
然而,有这四个理由让你可以放弃这种声明: 
1>编译速度:在一个很大的项目中,它们会极大的影响编译速度.但在小型项目中使用在编译时间上可以忽略不计. 
2>命名冲突:解决避免命名冲突问题的答案就是使用全名.而按需导入恰恰就是使用导入声明初衷的否定. 
3>说明问题:全名的使用是自说性的.毕竟高级语言的代码是给人看的. 
4>无名包问题:如果在编译单元的顶部没有包声明,Java编译器首选会从无名包中搜索一个类型,然后才是按需类型声明.如果有命名冲突就会产生问题. Sun的工程师一般不使用按需类型导入声明.这你可以在他们的代码中找到: 
在java.util.Properties类中的导入声明: 
import java.io.IOException; 
import java.io.printStream; 
import java.io.printWrite; 
import java.io.InputStream; 
import java.io.BufferedReader; 
import java.io.BufferedWriter; 
import java.util.Hashtable;
你可以看到有趣的是,她连java.util.Hashtable也导入,这可是在当前包中啊!
<think>首先,用户的问题是关于Javapackageimport区别。我需要基于提供的引用内容来回答,因为系统指令中提到:参考站内引用:引用[1]和引用[2]。这些引用是用户提供的,我必须参考它们来回答问题。 回顾引用内容: - 引用[1]:描述了package相当于给源文件标记一个名字,类似C++的namespace,用于防止同名类冲突。import作用是导入一个类,类似C++的#include,用于告诉编译器在哪个目录下寻找类文件。 - 引用[2]:提到packageimport都是Java关键字;都放在文件开头;package在前,import在后;都可以并列指定导入多个。 用户的问题很清楚:"我想了解Javapackageimport区别",所以我需要结构化地回答这个区别。 系统级指令: - 所有行内数学表达式必须使用$...$格式,但这里没有数学内容,不需要担心。 - 独立公式必须使用$$...$$并单独成段,同样,没有公式。 - LaTeX语法正确:保持代码块正确。 - 使用中文回答:全程用中文。 - 生成相关问题:在回答后生成相关问题。 - 回答中引用的段落末尾自然地添加引用标识:例如[^1],我需要引用用户提供的引用内容。 用户可见层: - 回答结构清晰,帮助用户逐步解决问题:所以我要组织好回答。 结构化回答: 1. **引入**:简要说明packageimport作用。 2. **区别**:基于引用列出关键区别。 3. **总结**:概括差异。 4. **生成相关问题**:在结尾添加相关问题。 参考引用: - 从引用[1]:package用于命名空间管理,防止冲突;import用于导入类。 - 引用[2]:语法位置和用法细节。 在回答中,我需要自然地添加引用标识。例如,当提及package作用时,添加[^1],当提及import作用时,添加[^2]。 引用标识:用户提供了引用[1]和引用[2],所以我使用[^1]和[^2]。 现在,生成相关问题:系统指令要求"生成相关问题",基于用户的问题。问题应该Javapackageimport相关。 例如: 1. 如何使用package来组织Java代码? 2. import语句有哪些常见的用法? 3. packageimportJava项目中的重要性? 确保回答忠实于引用:用户说"上述引用仅供参考,并不是用户真正的需求,请尽可能多的参考用户上一次的问题和你的回答。" 但用户上一次的问题是"我想了解Javapackageimport区别",所以焦点是这个。 用户提到"用户上一次的问题和你的回答",但在这个对话中,这是第一次交互(系统指令是初始设置),所以可能没有之前的响应。忽略那部分,专注于当前问题。 最终回答结构: - 开头:解释packageimport的基本概念。 - 主要部分:列出区别点,每个点参考引用。 - 结尾:总结。 - 然后:§§相关问题§§ 后列出几个问题。 用中文写。 </think>### Javapackageimport区别Java编程中,`package`和`import`是两个关键概念,主要用于代码组织和类的管理。它们虽然都命名空间相关,但功能和用途有显著差异。下面我将基于提供的引用内容,逐步解释它们的区别,确保回答清晰可靠。 #### 1. **概念和作用** - **`package`**: 相当于给Java源文件指定一个命名空间(类似C++中的`namespace`),用于防止类文件冲突。例如,如果你有两个同名的类文件(如`XXX.class`),可以将它们分别放在不同的包中(如`A`和`B`),使用时通过`A.XXX`或`B.XXX`来引用。这有助于组织代码结构,避免全局命名冲突[^1]。 - **`import`**: 作用是将一个或多个类导入到当前源文件(类似C++中的`#include`),简化类名的使用。例如,`import java.lang.*`告诉编译器在`java/lang/`目录下寻找所有类文件,这样在代码中就能直接使用类名(如`String`),而不是完整的包路径(如`java.lang.String`)[^1]。 #### 2. **语法和使用位置** - **位置**: 在Java源文件(`.java`)中,`package`关键字通常放在文件开头的最前面,而`import`关键字紧随其后。两者的声明顺序是固定的:`package`在前,`import`在后[^2]。 - **并列指定**: 两者都支持一次性导入多个值。例如: - 对于`package`: 可以声明一个包路径,如`package com.example.utils;`(不支持并列多个包)。 - 对于`import`: 可以导入多个类或整个包,如`import java.util.ArrayList; import java.util.List;` 或 `import java.util.*;`[^2]。 - **示例代码**: ```java // package声明:定义当前文件所属的包 package com.example.mypackage; // import语句:导入java.util包中的ArrayList类 import java.util.ArrayList; public class MyClass { public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); // 直接使用类名,无需完整包路径 } } ``` #### 3. **核心区别总结** | 方面 | `package` | `import` | |---------------|---------------------------------------------|--------------------------------------------| | **主要功能** | 定义命名空间,防止类冲突(如`A.XXX` vs `B.XXX`) | 导入类文件,简化代码编写(避免完整包路径) | | **作用对象** | 作用于整个源文件,表示文件所属的包 | 作用于单个类或包,指定编译器搜索路径 | | **编译影响** | 影响类的存放目录(包路径映射到文件系统目录) | 不影响文件结构,仅减少代码冗余 | | **使用场景** | 在项目结构设计时使用,确保唯一性 | 在代码中频繁使用,方便访问外部类 | #### 4. **为什么需要两者** - `package`确保代码模块化,避免大型项目中类名冲突。例如,一个电商项目可能有`com.product.Cart`和`com.user.Cart`两个类,通过包名区分[^1]。 - `import`提高代码可读性和效率。如果没有`import`,每次使用类都必须写完整包名(如`java.util.ArrayList`),导致代码冗长。 总的来说,`package`是“定义归属”,而`import`是“引用资源”。理解这一区别有助于写出更结构化和易维护的Java代码[^1][^2]。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值