Java 包(package)
一、包的概述:(什么是包?)
开始之前还是得说个例子!
假如有很多Person类,有的有名字有性别,有的又只有名字,那我是不是代码删了写,写了又删?有没有办法这个同样的Person类都存在呢?那有人一激灵说这还不好说,多建几个类不就好了?而File already exists?什么意思?文件已经存在!
我们发现电脑上两个相同的文件放在一起是不是会提示是否要覆盖?那你如果不覆盖,只能改名字了。还有个方法,就是放在不同文件夹中,是不是?
同理java项目中也是可以分不同文件夹的。只不过java中类的文件夹不叫文件夹,叫“包名”
英文单词:package,那package还有个意思就是打包的意思,所以你可以理解为这个文件夹,就是打了一个包裹,就跟快递包裹似的,你买了好多东西,不同商家是不同的包裹,每个包裹放的东西是不同类别的。
java中也是这个意思,包中放的基本上都是同一类的东西。比如放汽车类,有Car,有Bus,有MiniBus,有Taxi是不是
好了,说这么多,其实就是一个文件夹而已!记住在Java中叫做包。
为了更好地组织类,Java 提供了包机制,用于区别类名的命名空间。
包的作用(对类进行分类管理)
- 1 把功能相似或相关的类或接口组织在同一个包中,方便类的查找和使用。
- 2 如同文件夹一样,包也采用了树形目录的存储方式。同一个包中的类名字是不同的,不同的包中的类的名字是可以相同的,当同时调用两个不同包中相同类名的类时,应该加上包名加以区别。因此,包可以避免名字冲突。
- 3 包也限定了访问权限,拥有包访问权限的类才能访问某个包中的类。
二、创建包(如何创建包?)
在Java项目中,每一个包中的文件,都要有相应的包声明;
在Java文件中,声明一个包需要注意:
1、声明一个包使用关键字:package;
2、一个类中,包的声明必须放在类中第一行;
3、包名也是标识符全部都是小写,多级之间使用.隔开;一般为了避免包名重复,都是公司域名反转加项目名加模块名
首先命名规范:
1、不同路径通过点 (.) 来分割,比如这个目录/cn/craaaaazy,包名的话就是cn.craaaaazy了
2、由字母、数字下划线组成,不能以数字开头
3、全部小写
4、一般使用域名反写来命名包,为了保证包名唯一性,一般是用域名反写来做包名的。cn.craaaaazy其实是两个文件夹,一个是cn,另外一个文件加是craaaaazy,那你去这个项目目录看,其实是两个文件夹。
例如,一个Something.java 文件它的内容
package net.java.util
public class Something{
...
}
那么它的路径应该是 net/java/util/Something.java 这样保存的。 package(包)的作用是把不同的java程序分类保存,更方便的被其他java程序调用。
那说了这么半天,怎么用呢?(如何带包编译和运行?)
带包的编译和运行:
手动式(麻烦)
a:编写一个带包的java文件。
b:通过javac命令编译该java文件。
c:手动创建包名。(注意路径)
d:把b步骤的class文件放到c步骤的最底层包(即文件)
e:回到和包根目录在同一目录的地方,然后运行
带包运行
如果按照以前的方法直接编译和运行,如下显示会报错:
所以通过手动,按照上面方法步骤进行,如下:
手动式添加包名路径(相当文件夹路径),路径如a/b/c/d/e/f/.......等等,比较麻烦,所以就有第二种方法。
自动式
a:编写一个带包的java文件。
b:javac编译的时候带上-d即可
javac -d . HelloWorld.java (注意:点 . 前后之间有空格符)
c:回到和包根目录在同一目录的地方,然后运行
带包运行
三、不同包中的类之间的访问
1、通过带包名的完整路径访问。
这里以两个简单的带不同包的类为例,.java文件源代码如下:
//Test.java文件
package cn.itcast;
class Test {
public static void main(String[] args) {
Demo d = new Demo();
System.out.println(d.sum(10,20));
}
}
/Demo.java文件
package com.wen;
public class Demo {
public int sum(int a,int b) {
return a + b;
}
}
如果在当前的test路径下直接运行Test.java文件,则会报错。原因是在Test.java中找不到符合Demo
Test.java:7: 错误: 找不到符号
Demo d = new Demo();
^
符号: 类 Demo
位置: 类 Test
Test.java:7: 错误: 找不到符号
Demo d = new Demo();
^
符号: 类 Demo
位置: 类 Test
2 个错误
修改Test.java中代码如下:
//Test.java文件
package cn.itcast;
class Test {
public static void main(String[] args) {
//Demo d = new Demo();
com.wen.Demo d = new com.wen.Demo();
System.out.println(d.sum(10,20));
}
}
显示报错如下,发现没有包,所以呢安装上面的方法分别创建包。(选择自动式创建:javac -d . XXXXX.java)
Test.java:8: 错误: 程序包com.wen不存在
com.wen.Demo d = new com.wen.Demo();
^
Test.java:8: 错误: 程序包com.wen不存在
com.wen.Demo d = new com.wen.Demo();
^
2 个错误
之后运行时,注意要带包路径运行(这里是:java cn.itcast.java) 。过程大致如下:
然而,上面的方法虽然可以,如果其中的代码调用很多呢?那岂不是很麻烦,得重复操作。例如:
package cn.itcast;
class Test {
public static void main(String[] args) {
//Demo d = new Demo();
com.wen.Demo d = new com.wen.Demo();
System.out.println(d.sum(10,20));
com.wen.Demo d = new com.wen.Demo();
System.out.println(d.sum(10,20));
com.wen.Demo d = new com.wen.Demo();
System.out.println(d.sum(10,20));
com.wen.Demo d = new com.wen.Demo();
System.out.println(d.sum(10,20));
//...
}
}
所以引入第二种方法。
2、通过导包来访问(通过import 导入完整的类路径)<到类>
如果一个类中要使用其它包中的类,而且不止使用一次,通过上面的方式就比较麻烦,应该通过导包的方式来解决问题;
- 导包需要使用关键字:import
- 导包的位置:在包声明(package)下面,类(class)上面
- 导包的格式:import 完整包名.类名;
3、通过import 导入包路径(到包)(通用符)
比如你使用了某个包的所有类,你可以这样写
import cn.craaaaazy.fruit.*;
那cn.craaaaazy.fruit是一个包名,这个包中存放了所有的水果类,如果我都要用,那我得一个一个把类导入进来(在以前没有自动导入这么强大的编辑工具的时候,工作是相当乏味的!)
那如果不一个一个导入进来就需要使用通配符了,这个通配符就是星号(*)。这样一个是省去了很多麻烦,另外也降低了代码量。
注意:一般不推荐使用通用符,我们用什么就导入什么。
小知识点:
package,import,class有没有顺序关系? 有
package > import > class
Package:只能有一个
import:可以有多个
class:可以有多个,以后建议是一个