前面已经对java一些基础概念进行了理解:
Java 包(package)详解
java中文件名、类名之间的关系
java中类的main方法总结
public class HelloWorld {
public static void main(String[] args) {
int employee;
String isSave;
boolean hhh;
final double PI = 3.14;
final int y = 10;
MyClass myclass = new MyClass();
myclass.sayHello();
System.out.println("Hello World");
}
}
class MyClass {
int a;
byte b;
char c;
String s;
public static void main(String[] args) {
System.out.println("Hello World");
}
void sayHello() {
System.out.println("say hello");
}
}
从下面的图可以看出HelloWorld.java中包含两个class,HelloWorld和MyClass。
在test目录下新建一个class文件,自动会出现下面的内容
注意此时的 package test是自动出现的。
此时如果我们在HelloWorld的main函数中使用Mytest类,我们需要在前面引入这个类
//import test.MyTest1;
public class HelloWorld {
public static void main(String[] args) {
int employee;
String isSave;
boolean hhh;
final double PI = 3.14;
final int y = 10;
MyClass myclass = new MyClass();
myclass.sayHello();
MyTest1 mytest1 = new MyTest1();
System.out.println("Hello World");
}
}
class MyClass {
int a;
byte b;
char c;
String s;
public static void main(String[] args) {
System.out.println("Hello World");
}
void sayHello() {
System.out.println("say hello");
}
}
如果去掉import test.MyTest1,运行程序则会报错:
加上import test.MyTest1,程序可以正常运行:
我们先新建一个package
此时,我们到项目的实际目录下去看看
发现虽然我们是新建了一个package,实际上也是新建了一个目录。
我们继续在新建的package中,新建一个class,
发现自动会出现package test.Mypackage;
此时在我们的HelloWorld的main函数中,如果想使用package中的MyP1类,我们需要在HelloWorld.java中前面加上import test.Mypackage.MyP1;
import test.MyTest1;
import test.Mypackage.MyP1;
public class HelloWorld {
public static void main(String[] args) {
int employee;
String isSave;
boolean hhh;
final double PI = 3.14;
final int y = 10;
MyClass myclass = new MyClass();
myclass.sayHello();
MyTest1 mytest1 = new MyTest1();
MyP1 myp1 = new MyP1();
System.out.println("Hello World");
}
}
class MyClass {
int a;
byte b;
char c;
String s;
public static void main(String[] args) {
System.out.println("Hello World");
}
void sayHello() {
System.out.println("say hello");
}
}
如果不加,则会报下面的错误,加上之后则可以正常运行。
通过上面我们其实可以知道package和目录实际上是一个意思,只是在不同的语境下的不同解释。
现在我们可以这样理解了,有一个package/目录叫test,该package/目录下有一个package/目录叫Mypackage,Mypackage这个package/目录下有一个类文件,该类文件中只包含一个类MyP1。test这个ackage/目录下还有两个类文件,分别叫HelloWorld和MyTest1,HelloWorld文件下有HelloWorld和MyClass两个类,MyTest1文件下只有一个类MyTest1。
从这张图片中我们可以知道每个类只要有main函数,都可以执行。
如果我们把类MyClass中的main函数删掉,则会发现这个类的绿色小三角形不存在了,也就不可以执行了。
即使这个源文件不在子目录com/mycompany下,也可以进行编译。如果它不依赖于其他包,就不会出现编译错误。但是,最终的程序将无法运行,这是因为虚拟机找不到类文件。(对于这部分我不是很懂,class文件不是就在那里吗,怎么就不能执行了,我自己试了一下的确如此。一定要目录结构对准,和用java来加载类的时候,必须用完整包名,即com.mycompany.xx来执行。)
Java允许使用包将类组织起来。借助于包可以方便地组织自己的代码,并将自己的代码与别人提供的代码库分开管理。使用包的主要原因是确保类名的唯一性。同名的类放置在不同的包中,就不会产生冲突。如同硬盘的目录嵌套一样,也可以使用嵌套层次组织包。
为了保证包名的绝对唯一性,Sun公司建议将公司的因特网域名以逆序的形式作为包名,并且对于不同的项目使用不同的子包。所以,我们经常在类库中看到一堆包名像这样的:com.sun和org.apache等等。
这里我要说明一下的就是不要认为import与C/C++中的#include是相同作用的。其实,java编译器可以查看其他文件的内部,所以根本不需要把文件的内容include进来,因此java不需要include机制,而只要告诉类文件在哪里就可以了。
其实,import语句唯一的好处是简捷。这说明我们完全可以不用import语句来写出所有程序,只不过这样会很麻烦而已。其实,Java的包机制与C++的命名空间(namespace)非常类似,都是用来防止重名冲突的。在Java中,package和import语句类似于C++中的namespace和using 指令。
注意,从编译器的角度来看,嵌套的包之间没有任何关系、例如,java.util包和java.util.jar包毫无关系。每一个都拥有独立的类集合。
还有,只要使用星号(*)来导入一个包,而不能使用import java.*来导入以java为前缀的所有包。而且,如果要同时使用两个类名相同的类,只能在使用的时候给出类的完整包名。
在包中定位类是编译器的工作。因此,class文件中的字节码是使用完整的包名来引用其他的类。这样JVM就会直接根据这个包名来找到对应的class文件。
import语句不仅可以导入类,还可以导入静态方法和静态域。例如通过import static java.lang.System.*;就可以使用System类的静态方法和静态域,而不必加类名前缀。
接着说下包作用域。标记为public的部分可以被任意的类使用。而如果没什么修饰符都没写,这个部分(类、方法和变量)就只可以被同一个包的所有方法访问。所以说,对于一个包,只有public的类才可以被其他包的类访问,其他的非公有类,你import了也没用!
JAR文件使用ZIP格式组织class文件和目录。
类路径就是Java编译器和JVM寻找class文件的默认路径。通常有:基目录/home/user/classdir、当前目录(.)和JAR文件目录/home/user/archives/archive.jar等等。
包的概念
包是Java语言提供的一种确保类名唯一性的机制,是类的一种组织和管理方式、是一组功能相似或相关的类或接口的集合。
一个完整的类名是包名+类名,在没有import导入的情况下,使用一个类需要给出完整的类名,如java.util.Date。为了方便,Java自动导入两个包:java.lang包和默认包。
无包的类可以访问有包的类, 直接导入即可;有包的类无法访问无包的类, 直接访问是访问同一个包中的, 而有包的类与无包的类不在一个包里。由于使用不同包中的类需要导入, 而无包的类因无包名无法导入;
Java的包表面上看(从路径上看)是有等级的,但实际上并没有,比如java.awt,java.awt.color是两个地位相同的包。java.awt.color并不属于java.awt。
在采用类名方式使用一个类的时候, 先在当前包中查找是否有这个类, 如果没有才去导入的包中找。
包的作用
方便组织自己的代码,并将自己的代码与别人提供的代码库分开管理。
将相关联的接口和类集合到一块。比如,package graphics; 就把图形处理相关的模块放到了一起。便于使用。
如同文件夹一样,包也采用了树形目录的存储方式。同一个包中的类名字是不同的,不同包中的类的名字是可以相同的,当同时调用两个不同包中相同类名的类时,应该加上包名加以区别。因此,包可以避免名字冲突。
实现了外界对包的访问控制。 需要先进行导入。
定义包
要想将一个类放入一个包中,必须在源文件中除注释以外的第一行使用package+包名语句。同时将属于包的文件放在与完整的包名匹配的子目录中。当需要调用此包中的类时,就可以使用关键字import进行导入。如果源文件中没有使用package语句,这个源文件中的类就会被放置在一个默认包(default package)中。默认包是一个没有名字的包。
一、在定义包的时候,应该注意几点:
为了尽量使包名保持唯一性,包名通常采用小写、按倒写因特网域名的形式进行定义。
在进行命名包时,应该避免使用与系统发生冲突的名字。
一个源文件只能有一个package语句,放在源文件第一行,import语句前。
自定义包可以以java开头。
编译和运行
一、编译带包的类:
javac -d 目录 源文件名.java
注:在使用命令javac –d 之前,必须先创建好包路径,因为该命令不会自动创建文件夹。
1
2
二、运行带包的类:
java 包名.类名
1
使用包
同个包的类之间访问比较简单,在代码中直接使用类名;而不同包之间的访问则必须满足一个条件:一个类如果希望被其他包中的类访问, 那么必须加上public修饰(注意:用public修饰的类必须和源文件名同名)。
一、不同包之间的使用通常有以下3种方法:只能导入public修饰的类
使用全名访问类;
import 该类;
import 包含该类的整个包;
常用的包
Java.lang包:java的核心类库,包含了运行java程序必不可少的系统类,如基本数据类型、基本数学函数、字符串处理、线程、异常处理类等,系统缺省(默认)加载这个包。
java.util包:Java的实用工具类库。在这个包中,Java提供了一些实用的方法和数据结构。例如,Java提供日期(Data)类、日历(Calendar)类来产生和获取日期及时间,提供随机数(Random)类产生各种类型的随机数,还提供了堆栈(Stack)、向量(Vector) 、位集合(Bitset)以及哈希表(Hashtable)等类来表示相应的数据结构。
java.io包:java语言的标准输入/输出类库,如基本输入/输出流、文件输入/输出、过滤输入/输出流等。
java.util.zip包:实现文件压缩功能。
java.lang.reflect包:提供用于反射对象的工具。
java.mah:如提供用于执行任意精度整数算法 (BigInteger) 和任意精度小数算法 (BigDecimal) 的类。
java.net包:用来实现网络功能的类库。如Socket类、ServerSocket类。
java.awt包:构建图形用户界面(GUI)的类库。提供的类如:低级绘图操作Graphics类,图形界面组件和布局管理如 Checkbox类、Container类、LayoutManager接口等,以及用户界面交互控制和事件响应,如Event类。
java.awt.event包:GUI事件处理包。
java.awt.image包:处理和操纵来自于网上的图片的java工具类库。
java.sql包:实现JDBC的类库。
java.applet包:编写java applet程序用的。