Java中关于package(包)的总结介绍

2019年4月8日16:25:42 发表评论 4 浏览

Java里的包,可以理解成文件夹因为它是一种树形结构的路径,当我们用package把包声明到某个package下面时,我们也要把它的.class放到以该package为名字的目录下,否则将找不到类。

要把类放到某个包需要用package语句,事实上,当我们没有使用package语句时,我们的类都被放到了一个默认缺省包,这也是为什么我们运行Java程序时,在运行目录下面不能有同名的.class文件。

此外,一个完整类名是包名+类名,在没有import导入的情况下,使用一个类需要给出完整的类名,如java.util.Date。为了方便,Java自动导入两个包java.lang和现在文件的缺省包,也就是说:(1)Java规定,其他包使用java.lang包中的类时无需给出完整类名;(2)缺省包中的类之间(或者说同一个包下面)互相使用也不需要给出完整类名。

有包的类和无包的类互相访问有以下规则:(1)无包的类可以访问有包的类, 直接导入即可;(2)有包的类无法访问无包的类, 直接访问是找同一个包中的, 由于不同包需要导入, 而无包的类无法导入;(3)在定义类的时候, 为了让别人都能使用到, 所以一定要定义一个包。

Java的包表面上看(从路径上看)是有等级的,但实际上并没有,比如java.awt,java.awt.color是两个地位相同的包。java.awt.color并不属于java.awt。

在采用类名方式使用一个类的时候, 先在当前包中查找是否有这个类, 如果没有才去导入的包中找。

包的成员

一些相关联的类、接口、枚举、注释类型、包中的类所用到的资源文件如图片等

包的作用

(1)将相关联的接口和类集合到一块

比如,package graphics; 就把图形处理相关的模块放到一起

(2)避免了类型之间命名冲突:包作为一种封装,给类提供多层命名空间。

(3)实现了外界对包的访问控制

包的使用(包的声明、导入)

总的来说,包的使用可以总结为三个步骤:如何将类和接口捆绑到包中、如何使用包中的类、以及如何安排文件系统以便编译器找到源文件。

一、定义包

1、带包类的声明

在源代码的第一行使用package关键字定义包. 包名通常全部小写, 用"."分隔。

包的命名规范见链接:https://segmentfault.com/a/1190000008711718

https://docs.oracle.com/javase/tutorial/java/package/namingpkgs.html

包的声明有以下原则:(1)package语句必须放在源文件开头;(2)一个源文件只能有一个package语句;(3)包名字全部小写,避免与类、接口的名字冲突。

2、编译带包的类

javac -d 目录 源文件名.java

3、运行带包的类

java 包名.类名

二、使用包

同个包的类之间访问比较简单,在代码中直接以类名使用;而不同包之间的访问则必须满足一个条件:一个类如果希望被其他包中的类访问, 那么必须加上public修饰(注意:用public修饰的类必须和文件名同名)。不同包之间的使用通常有以下3种方法:(1)使用全名访问类;(2)import 该类;(3)import 包含该类的整个包

1、使用全名

假设有个graphics包,其中有个Circle类(public修饰),那么外包访问它时如下所示:

graphics.Circle cir = new graphics.Circle();

2、导入该类

上面使用全名的方法有些繁琐,如果要略写或者经常使用这个类时可以这样:

import graphics.Circle;

public class PackageTest {
    public static void main(String[] args) {
        Circle cir = new Circle();
    }
}

3、导入整个包

当我们想要使用该包的更多类,比如Line类时,可以把该包的所有类都导入:

import graphics.*;

public class PackageTest {
    public static void main(String[] args) {
        Circle cir = new Circle();
        Line line = new Line();
    }
}

三、管理文件系统

许多Java平台的实现依赖于文件系统的等级制度 来管理源文件和class文件。我们一般把类、接口、枚举、注释类型放在可以反映包名的目录中,比如,Rectangle.java属于graphics类,我们就放在...../graphics/Rectangle.java的路径上。同样,我们对其进行编译产生的class文件也要放在类似的目录上(这个目录最好不要和源文件放在一起),这样的好处是当我们要复用某个类时,就知道到哪去找了,JVM在运行程序时也知道去哪里找类。

比如,源文件放在:<path_one>/sources/com/example/graphics/Rectangle.java

class文件放在:<path_two>/classes/com/example/graphics/Rectangle.class,其中,<path_two>/classes是类路径(class path),由CLASSPATH系统变量进行设置,而包名是com.example.graphics。编译器、JVM通过将包名称添加到类路径来构造.class文件的路径。

所以编译器、JVM在路径<path_two>/classes/com/example/graphics中查找类文件。class path可以有好几条,由分号(Windows)或冒号(UNIX)分隔。 默认情况下,编译器、JVM搜索当前目录和包含Java平台类的JAR文件,所以这些目录自动位于类路径中。

CLASSPATH是JVM或Java编译器中的一个参数,它指定用户定义的类和包的位置。 可以在命令行上或通过环境变量设置。默认情况下,我们访问JDK标准API和扩展包时,无需设置查找位置。 而用户自定义的包和库,则必须设置。由于JVM会在当前目录下搜索,所以当我们的文件都在运行目录下时,也可以不设置CLASSPATH。

有关CLASSPATH可以参考:

https://en.wikipedia.org/wiki/Classpath_%28Java%29

https://en.wikipedia.org/wiki/Java_Classloader

关于Import

关于import,有三个注意的地方。

1、

首先是,Java的包表面上的等级问题。从路径上看,包似乎是分层的,但它们不是。 例如,Java API包括java.awt包,java.awt.color包,java.awt.font包等等。但是,java.awt.color包、java.awt.font包和其他java.awt.xxxx包并不属于java.awt。 前缀java.awt(The Java abstract window toolkit)的作用只是告诉开发者——和窗口有关的包都在这里面。但是包和包之间并不是包含关系。

当你导入java.awt.*时,会导入java.awt包中的所有类型,但它不会导入java.awt.color,java.awt.font或任何其他java.awt.xxxx包的所有类型。 如果你要使用java.awt.color中的类以及java.awt中的类,则必须同时导入导入这两个包:

import java.awt.*;
import java.awt.color.*;

2、

其次是名字含糊不清的问题。当你导入的两个包中有一个类名字相同时,如果你继续采用缩写,就会出现一些问题。这时,你就要使用这个类的全名。比如,java.util、java.sql包中都有Date类,程序又同时导入了这两个包中的Date类。

import java.sql.*;
import java.date.*;

3、static import

当我们需要频繁访问某个类的常量和静态方法,反复写它们的前缀(全名)可能不利于代码阅读。 静态import语句就提供了一种导入要使用的常量和静态方法的方法,这样您就不需要为其名称添加前缀。比如java.lang.Math类定义PI常量和许多静态方法,包括计算正弦,余弦,切线,平方根,最大值,最小值,指数等。

import static java.lang.Math.PI;
import static java.lang.Math.cos;

public class ImportTest {
    public static void main(String[] args) {
        double r = Math.cos(Math.PI * 2);
		double r1 = Math.cos(PI * 2);
		double r2 = cos(PI * 2);
		System.out.println(r+" "+r1+" "+r2);    
    }
}

当然,你也可以直接全部导入:

import static java.lang.Math.*;

应该注意的是,使用静态导入时要非常谨慎。 过度使用静态导入会导致代码难以阅读和维护,因为阅读者不知道某个特定的静态对象是哪个类的。 不过,当我们恰当地使用静态导入时,代码可以因为不用繁琐地写全名而更具可读性。

【推荐课程:Java视频教程】

以上就是Java中关于package(包)的总结介绍的详细内容,更多请关注洋洋博客其它相关文章!

Java中关于package(包)的总结介绍

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: