想要将一个类放入包中,就必须将包的名字放在源文件的开头,包中定义类的代码之前。例如,例4-7中的文件Employee.java开头是这样的:

 
  
  1. package com.horstmann.corejava; 
  2.  
  3. public class Employee 
  4.     .... 

    如果没有在源文件中放置package语句,这个源文件中的类就被放置在一个默认包(default package)中。默认包是一个没有名字的包。在此之前,我们定义的所有类都在默认包中。

    将包中的文件放到与完整的包名匹配的子目录中。例如,com.horstmann.corejava包中的所有源文件应该被放置在子目录com\horstmann\corejava(Windows中com\horstmann\corejava)中。编译器将类文件也放在相同的目录结构中。

    例4-6和例4-7中的程序分放在两个包中:PackageTest类放置在默认包中;Employee类放置在com.horstmann.corejava包中。因此,Employee.class文件必须包含在子目录com\horstmann\corejava中。换句话说,目录结构如下所示:

 
  
  1. 基目录 
  2.     PackageTest.java 
  3.     PackageTest.class 
  4.     com\ 
  5.       horstmann\ 
  6.         corejava\ 
  7.           Employee.java 
  8.           Employee.class 

    想要编译这个程序,只需改变基目录,并运行命令

 
  
  1. javac PackageTest.java 

编译器就会自动地查找文件com/horstmann/corejava/Employee.java并进行编译。

    下面看一个更加实际的例子。在这里不使用默认包,而是将类分别放在不同的包中(com.horst-mann.corejava和com.mycompany)。

 
  
  1. 基目录 
  2.     com/ 
  3.       horstmann/ 
  4.         corejava/ 
  5.           Employee.java 
  6.           Employee.class 
  7.       mycompany 
  8.         PayrollApp.java 
  9.         PayrollApp.class 

    需要注意,编译器对文件(带有文件分隔符和扩展名.java的文件)进行操作。而java解释器加载类(带有.分隔符)。

    警告:编译器在编译源文件的时候不检查目录结构。例如,假定有一个源文件开头有下列语句:

    package com.mycompany;

即使这个源文件没有在子目录com/mycompany下,也可以进行编译。如果它不依赖于其他包,就不会出现编译错误。但是,最终的程序将无法运行,这是因为虚拟机找不到类文件。

例4-6  PackageTest.java

 
  
  1. import com.horstmann.corejava.*; 
  2. // the Employee class is defind in that package 
  3.  
  4. import static java.lang.System.*; 
  5.  
  6. /** 
  7.  * This program demonstrates the use of packages. 
  8.  * @ author Wcg 
  9.  * @ version 1.01 2012-11-19 
  10.  */ 
  11. public class PackageTest 
  12.     public static void main(String[] args) 
  13.     { 
  14.         // because of the import statement, we don't have to use com.horstmann.corejava.Employee here 
  15.         Employee harry = new Employee("Harry Hacker"500001989101); 
  16.         harry.raiseSalary(5); 
  17.         // because of the static import statement, we don't have to use System.out here 
  18.         out.println("name = " + harry.getName() + ", salary = " + harry.getSalary()); 
  19.     } 

例4-7  Employee.java

 
  
  1. package com.horstmann.corejava; 
  2.  
  3. // the classes in this file are part of this package 
  4.  
  5. import java.util.*; 
  6.  
  7. //import statements come after the package statement 
  8.  
  9. /** 
  10.  * @version 1.01 2012-11-19 
  11.  * @author Wcg 
  12.  */ 
  13. public class Employee 
  14.     public Employee(String aName, double aSalary, int aYear, int aMonth, int aDay) 
  15.     { 
  16.         name = aName; 
  17.         salary = aSalary; 
  18.         GregorianCalendar calendar = new GregorianCalendar(aYear, aMonth - 1, aDay); 
  19.         // GregorianCalendar uses 0 for January 
  20.         hireDay = calendar.getTime(); 
  21.     } 
  22.  
  23.     public String getName() 
  24.     { 
  25.         return name; 
  26.     } 
  27.  
  28.     public double getSalary() 
  29.     { 
  30.         return salary; 
  31.     } 
  32.  
  33.     public Date getHireDay() 
  34.     { 
  35.         return hireDay.clone(); 
  36.     } 
  37.  
  38.     public void raiseSalary(double byPercent) 
  39.     { 
  40.         double raise = salary * byPercent / 100
  41.         salary = salary + raise; 
  42.     } 
  43.  
  44.     private String name; 
  45.     private double salary; 
  46.     private Date hireDay;