Java - tutorial - 11/13 Java packages

revision:


Java Packages/API

A package in Java is used to group related classes. Think of it as a folder in a file directory. We use packages to avoid name conflicts, and to write a better maintainable code.

Packages are used for:

Preventing naming conflicts;
Making searching/locating and usage of classes, interfaces, enumerations and annotations easier;
Providing controlled access: protected and default have package level access control. A protected member is accessible by classes in the same package and its subclasses. A default member (without any access specifier) is accessible by classes in the same package only;
Packages can be considered as data encapsulation (or data-hiding).

How packages work?

Package names and directory structure are closely related.

Package naming conventions: packages are named in reverse order of domain names. For example, in a college, the recommended convention is college.tech.cse, college.tech.ee, college.art.history, etc.

Adding a class to a Package : we can add more classes to a created package by using package name at the top of the program and saving it in the package directory. We need a new java file to define a public class, otherwise we can add the new class to an existing .java file and recompile it.

Subpackages: Packages that are inside another package are the subpackages. These are not imported by default, they have to imported explicitly. Also, members of a subpackage have no access privileges, i.e., they are considered as different package for protected and default access specifiers.

example:

import java.util.*;

explanation: util is a subpackage created inside java package.

Accessing classes inside a package

Consider following two statements :

    // import the Vector class from util package.
    import java.util.vector; 
    
    // import all the classes from util package
    import java.util.*; 
    

explanation: the first statement is used to import "Vector" class from "util" package which is contained inside java. The second statement imports all the classes from "util" package.


Types of packages

Packages are divided into two categories: built-in packages (packages from the Java API) and user-defined packages (create your own packages)

Built-in packages

The Java API is a library of pre-written classes, that are free to use, included in the Java Development Environment.
The library contains components for managing input, database programming, and much much more. The complete list can be found at Oracles website: https://docs.oracle.com/javase/8/docs/api/.
The library is divided into packages and classes. You can either import a single class (along with its methods and attributes), or a whole package that contain all the classes that belong to the specified package.
To use a class or a package from the library, you need to use the import keyword.

syntax:

import package.name.Class; // Import a single class
import package.name.*; // Import the whole package

import a class: example: import java.util.Scanner;

import a package: example: import java.util.*;

Some of the commonly used built-in packages are:

1) java.lang: Contains language support classes(e.g classed which defines primitive data types, math operations). This package is automatically imported.
2) java.io: Contains classed for supporting input / output operations.
3) java.util: Contains utility classes which implement data structures like Linked List, Dictionary and support ; for Date / Time operations;
4) java.applet: Contains classes for creating Applets;
5) java.awt: Contain classes for implementing the components for graphical user interfaces (like button , ;menus etc).
6) java.net: Contain classes for supporting networking operations.

User-defined packages

These are the packages that are defined by the user: first create a directory "myPackage" (name should be same as the name of the package); then create the "MyClass" inside the directory with the first statement being the package names.

To create your own package, you need to understand that Java uses a file system directory to store them. Just like folders on your computer.
To create a package, use the package keyword.

        // Name of the package must be same as the directory
        // under which this file is saved
        package myPackage;

        public class MyClass
        {
            public void getNames(String s)
            {        
                System.out.println(s);        
            }
        }
        

Now we can use the MyClass class in our program.

    /* import 'MyClass' class from 'names' myPackage */
    import myPackage.MyClass;

    public class PrintName 
    {
    public static void main(String args[]) 
    {       
        // Initializing the String variable 
        // with a value 
        String name = "GeeksforGeeks";
        
        // Creating an instance of class MyClass in 
        // the package.
        MyClass obj = new MyClass();
        
        obj.getNames(name);
    }
    }

Note : MyClass.java must be saved inside the "myPackage" directory since it is a part of the package.


Using Static Import

Static import is a feature introduced in Java programming language ( versions 5 and above ) that allows members ( fields and methods ) defined in a class as "public static" to be used in Java code without specifying the class in which the field is defined. Following program demonstrates static import :

    // Note static keyword after import.
    import static java.lang.System.*;
    
    class StaticImportDemo
    {
    public static void main(String args[])
    {      
            // We don't need to use 'System.out' 
            // as imported using static.
            out.println("MyFirstTrial");
    }
    }

Output: MyFirstTrial


Handling name conflicts

The only time we need to pay attention to packages is when we have a name conflict . For example both, "java.util' and "java.sql" packages have a class named "Date". So if we import both packages in program as follows:

    import java.util.*;
    import java.sql.*;

    //And then use Date class, then we will get a compile-time error :

    Date today ; //ERROR-- java.util.Date or java.sql.Date?

The compiler will not be able to figure out which Date class do we want. This problem can be solved by using a specific import statement:

    import java.util.Date;
    import java.sql.*;

If we need both Date classes then, we need to use a full package name every time we declare a new object of that class.For Example:

    java.util.Date deadLine = new java.util.Date();
    java.sql.Date today = new java.sql.Date();

Directory structure

The package name is closely associated with the directory structure used to store the classes. The classes (and other entities) belonging to a specific package are stored together in the same directory. Furthermore, they are stored in a sub-directory structure specified by its package name.

For example, the class Circle of package com.zzz.project1.subproject2 is stored as “$BASE_DIR\com\zzz\project1\subproject2\Circle.class”, where $BASE_DIR denotes the base directory of the package.
Clearly, the “dot” in the package name corresponds to a sub-directory of the file system.
The base directory ($BASE_DIR) could be located anywhere in the file system. Hence, the Java compiler and runtime must be informed about the location of the $BASE_DIR so as to locate the classes. This is accomplished by an environment variable called CLASSPATH.
CLASSPATH is similar to another environment variable PATH, which is used by the command shell to search for the executable programs.