A package in Java is a mechanism to organize related classes, interfaces, and other types into a single namespace. It helps avoid naming conflicts, provides modularity, and improves code maintainability.
Purpose:
Group related classes and interfaces.
Prevent naming collisions (e.g., two classes with the same name in different packages).
Provide access control (e.g., restricting access to package members).
Facilitate code reuse and organization.
How to Define a Package:
Use the package keyword at the top of a Java source file.
Syntax: package packageName;
Example:
package com.example.myapp;public class MyClass { public void display() { System.out.println("Hello from MyClass!"); }}
The above code declares that MyClass belongs to the com.example.myapp package.
Directory Structure:
The package name must correspond to the directory structure where the source file is stored.
For example, com.example.myapp.MyClass should be in the directory com/example/myapp/.
Compiled .class files must also follow this structure.
Default Package:
If no package statement is specified, the class belongs to the default package (no namespace).
Example:
// No package statementpublic class Test { // Class in default package}
Using the default package is discouraged for large projects due to lack of organization.
Rules:
The package statement must be the first non-comment line in the source file.
Only one package statement is allowed per file.
All classes in the same source file belong to the declared package.
2. CLASSPATH
The CLASSPATH is an environment variable or a parameter that tells the Java Virtual Machine (JVM) and Java compiler where to look for user-defined classes and packages.
Purpose:
Specifies the location of .class files and other resources (e.g., JAR files).
Helps the JVM locate classes during compilation and runtime.
How CLASSPATH Works:
The JVM searches for classes in the directories or JAR files listed in the CLASSPATH.
The search includes:
The standard Java library (automatically included).
Directories or JAR files specified in the CLASSPATH.
The current directory (if included, often denoted by a dot .).
Accessibility in packages refers to how classes, methods, and fields within a package can be accessed by other classes, either within the same package or from outside it. Java uses access modifiers to control accessibility.
Access Modifiers:
public: The member (class, method, field) is accessible from everywhere.
protected: The member is accessible within the same package and also in subclasses (even in different packages).
default (also called package-private): If no modifier is specified, the member is accessible only within the same package.
private: The member is accessible only within the same class.
Package Accessibility Rules:
Classes:
A public class is accessible from any package.
A default (no modifier) class is accessible only within the same package.
Example:
package com.example.myapp;public class PublicClass { // Accessible everywhere}class DefaultClass { // Accessible only in com.example.myapp}
Members (Fields, Methods, Constructors):
public: Accessible from any class.
protected: Accessible within the same package and in subclasses.
default: Accessible only within the same package.
private: Accessible only within the same class.
Example:
package com.example.myapp;public class MyClass { public int publicField = 1; protected int protectedField = 2; int defaultField = 3; // package-private private int privateField = 4;}
Accessing Across Packages:
To access a class or member in another package, you must:
Import the package/class (see Using Package Members below).
Ensure the class/member is public or protected (if accessed via inheritance).
Example:
package com.example.other;import com.example.myapp.MyClass;public class Test { public void testAccess() { MyClass obj = new MyClass(); System.out.println(obj.publicField); // OK // System.out.println(obj.defaultField); // Error: not visible }}
Package-Private Advantage:
Using default access restricts visibility to the package, which is useful for internal implementation details.
Example: Utility classes or helper classes used only within a package.
5. Using Package Members
To use classes, interfaces, or other members from a package, you need to import them or refer to them using their fully qualified name. Here’s how it works:
Fully Qualified Name:
Refers to the complete package path plus the class name.
Example: com.example.myapp.MyClass.
Usage:
public class Test { public static void main(String[] args) { com.example.myapp.MyClass obj = new com.example.myapp.MyClass(); obj.display(); }}
Drawback: Fully qualified names are verbose and make code harder to read.
Importing Packages/Classes:
Use the import keyword to avoid writing fully qualified names.
Syntax:
import packageName.subPackage.ClassName; // Import specific classimport packageName.subPackage.*; // Import all classes in package
Example:
import com.example.myapp.MyClass;public class Test { public static void main(String[] args) { MyClass obj = new MyClass(); obj.display(); }}
Types of Imports:
Single-Type Import:
Imports a specific class or interface.
Example: import java.util.ArrayList;
On-Demand Import (Importing Entire Package):
Imports all classes in a package (but not subpackages).
Example: import java.util.*;
Note: This does not import subpackages like java.util.concurrent.
Static Import:
Imports static members (fields, methods) of a class.
Example:
import static java.lang.Math.PI;import static java.lang.Math.sqrt;public class Test { public static void main(String[] args) { System.out.println(PI); // No need for Math.PI System.out.println(sqrt(16)); // No need for Math.sqrt }}
Automatic Imports:
The java.lang package is automatically imported in every Java program.
Example: You can use String, System, or Math without importing.
Resolving Naming Conflicts:
If two imported packages contain classes with the same name, use the fully qualified name or import only one class.
Example:
import java.util.Date;import java.sql.Date; // Conflict: two Date classes
Solution:
java.util.Date utilDate = new java.util.Date();java.sql.Date sqlDate = new java.sql.Date();
Rules for Imports:
Imports must appear after the package statement and before class declarations.
Importing a package does not import its subpackages.
Unused imports do not affect performance but should be removed for clarity (modern IDEs do this automatically).
Accessing Package Members:
Ensure the member is accessible based on its access modifier (public, protected, default, private).
Example:
package com.example.other;import com.example.myapp.MyClass;public class Test { public static void main(String[] args) { MyClass obj = new MyClass(); System.out.println(obj.publicField); // OK // System.out.println(obj.privateField); // Error: not accessible }}
Summary for Exam Preparation
Defining Package:
Use package keyword to group classes.
Matches directory structure.
Default package if no package statement.
CLASSPATH:
Tells JVM where to find .class files.
Set via environment variable or -cp option.
Default is current directory (.).
Package Naming:
Use reverse domain name (e.g., com.example.myapp).
Lowercase, no hyphens, follow conventions.
Accessibility of Packages:
Controlled by public, protected, default, private.
default restricts to same package.
public allows access from any package.
Using Package Members:
Import with import or use fully qualified names.
Single-type, on-demand, and static imports.
Resolve conflicts with fully qualified names.
Example Program for Practice
File 1: com/example/myapp/MyClass.java
package com.example.myapp;public class MyClass { public int publicField = 1; protected int protectedField = 2; int defaultField = 3; private int privateField = 4; public void display() { System.out.println("Public: " + publicField); System.out.println("Protected: " + protectedField); System.out.println("Default: " + defaultField); System.out.println("Private: " + privateField); }}
File 2: com/example/other/Test.java
package com.example.other;import com.example.myapp.MyClass;public class Test { public static void main(String[] args) { MyClass obj = new MyClass(); obj.display(); System.out.println("Accessing public field: " + obj.publicField); // System.out.println(obj.defaultField); // Error: not visible }}