Packages

In this part of the Java tutorial, we will talk about Java packages.

A package is a grouping of related types providing access protection and name space management. Packages in Java is a similar concept to namespaces in C#.

A package is declared with the package keyword. This statement must be placed at the top of every source file. There can be only one such statement in each source file. The Java source files must be placed in directories that match the package name.

package com.zetcode;

All types defined in the file with the above package are part of the com.zetcode package. A class Being has a fully qualified name com.zetcode.Being. There are millions of Java programmers worldwide. To avoid potential name conflicts, there is a naming convention in Java. The package names reversed Internet domain names. The letters are written in lowercase. There can be only one zetcode.com domain name so using a reversed name com.zetcode for the packages will make them unique. A Java source file with a com.zetcode package must be located in the com/zetcode subdirectory.

The import keyword is used at the beginning of a source file to specify types (classes, interfaces, enumerations, annotations) or entire Java packages to be referred to later without including their package names in the reference. Since Java SE 5.0, import statements can import static members of a class (methods and variables).

import java.awt.*;

Using the * wildcard character, we can import the whole package at a time. After this import, we can refer to all types of the java.awt package without their fully qualified names.

import java.awt.event.*;

The java.awt.event subpackage is not imported with the java.awt.* import. Subpackages must be imported independently.

package com.zetcode;

import java.util.Random;

public class Packages {

    public static void main(String[] args) {
        
        Random r = new Random();
        
        int x = r.nextInt();
        System.out.println(x);
        
        java.util.Calendar c = java.util.Calendar.getInstance();
        System.out.println(c.getTime());    
    }
}

The example uses two types. The Random class and the Calendar class. The first class is imported and the second is referred by its fully qualified name.

package com.zetcode;

We declare a package with the package keyword. The Packages.java file must be located in the com/zetcode subdirectory.

import java.util.Random;

This code line enables us to use the Random class without the package name.

Random r = new Random();

Here we use the Random without using its full name.

java.util.Calendar c = java.util.Calendar.getInstance();

If we did not use the import keyword on a type, we can refer to it only by its full name - java.util.Calendar in our case. The import keyword saves a lot of typing.

$ ls com/zetcode/
Packages.java

The Packages.java source file is placed in the com/zetcode subdirectory. The package name must reflect the directory structure.

$ javac com/zetcode/Packages.java 

We compile the source file with the javac tool. The tool is called from the parent directory of the com/zetcode directory.

$ java com.zetcode.Packages 
928256084
Sun Jul 21 15:01:14 CEST 2013

This is the output of the com.zetcode.Packages program.

Package-private visibility

If we do not specify any access modifier (e.g. private, protected, or public), we have a package-private visibility. In such a case, variables and methods are accessible within the same package. Classes in other packages cannot access classes and members declared with package-private access.

Default package

If no package is declared, all types defined in that file are part of a default unnamed package. It is recommended to always place your types in a package. Even for small programs.

public class DefaultPackage {

    public static void main(String[] args) {
        
        System.out.println("A class in a default package");   
    }    
}

The DefaultPackage class is part of the default package.

$ ls
DefaultPackage.java

If we do not specify a package, we do not place the source file in a specific subdirectory.

$ javac DefaultPackage.java 
$ java DefaultPackage 
A class in a default package

We compile the code and run the application. The source file and the bytecode is located in the current working directory.

Automatic imports

Java compiler automatically imports two packages. The java.lang package and the current package.

Constants.java
package com.zetcode;

public class Constants {
    
    public static final String version = "1.0";
}

The Constants class is located in the same package as the AutomaticImports which is referring to its version member.

AutomaticImports.java
package com.zetcode;

public class AutomaticImports {

    public static void main(String[] args) {
        
        String os = System.getProperty("os.name");
        
        System.out.println(os);
        System.out.println(Constants.version);    
    }
}

In this example, we refer to some classes that are automatically imported by Java compiler.

String os = System.getProperty("os.name");

The String and System classes are part of the java.lang package.

System.out.println(Constants.version);    

The Constants class is located in the same package as the AutomaticImports class. Therefore, we can access the class and its member without using the fully qualified name or utilizing the import keyword.

$ ls com/zetcode/
AutomaticImports.java  Constants.java

Both AutomaticImports.java and Constants.java files are located in the same subdirectory.

$ javac com/zetcode/AutomaticImports.java com/zetcode/Constants.java

Both files are compiled.

$ java com.zetcode.AutomaticImports 
Linux
1.0

This is a sample output of the com.zetcode.AutomaticImports program.

Static imports

If we often use some static members, we can use import static statement to refer to them later without a full class name. Static imports should be used with caution.

package com.zetcode;

import static java.lang.Math.E;
import static java.lang.Math.PI;
import static java.lang.Math.abs;

public class StaticImport {

    public static void main(String[] args) {
        
        System.out.println(E);
        System.out.println(PI);
        
        System.out.println(abs(-5));    
    }
}

In this example, we refer to two constants and one static method.

import static java.lang.Math.E;
import static java.lang.Math.PI;
import static java.lang.Math.abs;

We use the import static statement to enable referring to them without their full names.

System.out.println(E);
System.out.println(PI);

System.out.println(abs(-5));  

We refer to these three members without their class name.

$ java com.zetcode.StaticImport 
2.718281828459045
3.141592653589793
5

This is the output of the com.zetcode.StaticImport program.

This chapter covered packages in Java.