Packages in Java: Detailed Notes, Examples & Practice Questions (Object Oriented Programming)

Hello dear students! Today we are going to learn about Packages in Java. I know some of you might be wondering why we even need packages when our programs have been working fine without them. Well, as your programs grow bigger and you start working on real projects, packages become very important. Let me explain everything step by step so you can answer any question about packages in your exam. Are you ready? Let us start!

What is a Package?

A package in Java is a group of related classes, interfaces, and sub-packages. Think of it like a folder on your computer. When you have many files on your desktop, it becomes messy and hard to find things. So you create folders like “Documents,” “Photos,” and “Music” to organize your files. A package does the exact same thing for your Java classes.

When you write a small program with one or two classes, you do not need a package. But imagine a large project like a university management system that has hundreds of classes for students, courses, teachers, grades, and fees. If all those classes are in one place, it becomes very hard to manage. Packages help you group related classes together so your project stays clean and organized.

Project Without Packages (Messy) Main.java Student.java Course.java Teacher.java Grade.java Fee.java Library.java Report.java (All classes mixed together – hard to manage!) Project With Packages (Organized) com.university/ +– student/ | +– Student.java | +– Grade.java | +– Report.java +– course/ | +– Course.java | +– Schedule.java +– staff/ | +– Teacher.java | +– Admin.java +– library/ +– Library.java +– Book.java (Each group of related classes in its own package – clean!)

Every package has a name, and that name becomes part of the full name of every class inside it. For example, if you have a class called Student inside a package called com.university.student, then the full name of that class is com.university.student.Student. This full name is called the fully qualified name of the class.

Important Notes to Remember for Exam:
1. A package is a grouping mechanism for related classes and interfaces.
2. It is like a folder on your computer that organizes files.
3. Every class in a package has a fully qualified name: packageName.ClassName.
4. The package statement must be the first statement in a Java source file (before any import or class).
5. A source file can have only one package statement.
6. If you do not write a package statement, your class is placed in a default (unnamed) package.
MCQ

Question 1: What is a package in Java?

A) A single class file    B) A group of related classes and interfaces    C) A method that groups variables    D) A type of access modifier

Answer: B) A group of related classes and interfaces

A package is a namespace that organizes related classes, interfaces, and sub-packages together. It is not a single file (option A), not a method (option C), and not an access modifier (option D). The main purpose is organization and grouping of related types, just like folders organize files on a computer.

Fill in the Blank

Question 2: The package statement must be the ________ statement in a Java source file.

Answer: first

The package statement must be the very first line in a Java source file. You cannot put any comment, import statement, or class declaration before it. The only thing allowed before a package statement is comments in some cases, but as a rule, always write the package statement first. This tells the compiler which package the classes in this file belong to.

MCQ

Question 3: What happens if you do not write a package statement in your Java file?

A) Compile error    B) The class is placed in a default unnamed package    C) The class is deleted    D) The class is placed in java.lang

Answer: B) The class is placed in a default unnamed package

If you do not write a package statement, Java places your class in a default (unnamed) package. This default package has no name, and classes in it can be accessed by any other class without an import statement. However, using the default package is not recommended for real projects because it does not provide any organization or name space protection. It is mainly used for small practice programs.

Advantages of Packages

Now let me explain why packages are so important. There are several key advantages that you should be able to list and explain in your exam.

1. Organization and Grouping: Packages group related classes together, making the project structure clean and logical. Just like books in a library are organized by subject (science books on one shelf, history books on another), classes in a project are organized by functionality using packages.

2. Name Space Management (Avoiding Class Name Conflicts): This is one of the most important advantages. In a large project, two programmers might create classes with the same name. For example, both a database module and a user interface module might have a class called Connection. Without packages, these names would clash. With packages, one is database.Connection and the other is ui.Connection. The package name makes them different. This is like two students named “Abebe” in different sections of a school. Their full identity “Section A – Abebe” and “Section B – Abebe” makes them distinct.

3. Access Control: Packages work together with access modifiers to control which classes can access which other classes. Classes marked as protected or with default access are only accessible within the same package. This provides a layer of security and encapsulation at the package level.

4. Reusability: Packages make it easy to reuse code. You can create a package of utility classes and use that package in multiple projects. For example, you create a com.mycompany.utils package with common math and string functions, and then use it in every project your team works on.

5. Searching and Locating Classes: The package structure helps the JVM and the compiler find classes quickly. The fully qualified name uniquely identifies every class in Java. This is similar to how a postal address helps the post office find your house among millions of houses.

Important Notes to Remember for Exam:
1. The five main advantages are: organization, avoiding name conflicts, access control, reusability, and easy searching.
2. The name conflict advantage is the most frequently tested one in exams.
3. Packages provide access control at the group level (all classes in a package share certain access privileges).
4. Reusability means creating a package once and using it in many projects.
5. If asked to “list and explain,” write each advantage with a brief one-line explanation and an example if possible.
List and Explain

Question 4: List any four advantages of using packages in Java with a brief explanation for each.

Answer:

1. Organization: Packages group related classes and interfaces together, making large projects easier to manage and navigate. For example, all database-related classes go in a database package.

2. Avoiding Name Conflicts: Two classes can have the same name if they are in different packages. For example, com.bank.Connection and com.network.Connection are different classes even though both are named “Connection.”

3. Access Control: Packages define boundaries for access. Classes with default (no modifier) access can only be used within the same package. This provides data hiding at the package level.

4. Reusability: Once a package is created, it can be distributed and reused in multiple projects without copying the source code. For example, the java.util package is reused in almost every Java program.

MCQ

Question 5: How do packages help solve the problem of class name conflicts?

A) By renaming classes automatically    B) By providing a unique namespace through the package name    C) By preventing creation of classes with common names    D) By deleting duplicate classes

Answer: B) By providing a unique namespace through the package name

Packages create namespaces. The fully qualified name of a class includes both the package name and the class name (e.g., com.example.Date vs java.util.Date). Even if two classes have the same simple name, their fully qualified names are different because they are in different packages. Java does NOT rename or delete classes. It simply uses the package name as part of the unique identity.

Types of Packages

There are two types of packages in Java. Understanding the difference between them is important for your exam.

1. Built-in Packages (Predefined Packages)

These are packages that come with the Java Development Kit (JDK). You do not need to create them. They are already there, ready for you to use. Java has a very large collection of built-in packages that provide thousands of pre-written classes for various purposes. These built-in packages save you a lot of time because you do not need to write common functionality from scratch.

Here are the most important built-in packages that you must know for your exam:

Package NamePurposeImportant Classes
java.langCore language classes (automatically imported)String, Integer, Math, System, Object, Thread
java.utilUtility classes and collectionsScanner, ArrayList, HashMap, Date, Collections
java.ioInput and output operationsFile, FileInputStream, BufferedReader, PrintWriter
java.netNetworking operationsURL, Socket, ServerSocket, HttpURLConnection
java.awtGUI components (Abstract Window Toolkit)Frame, Button, Label, TextField, Panel
javax.swingImproved GUI componentsJFrame, JButton, JLabel, JTextField, JPanel
java.sqlDatabase connectivity (JDBC)Connection, Statement, ResultSet, DriverManager
java.appletApplet programs (now mostly deprecated)Applet

Let me highlight the most important one: java.lang. This package is special because it is automatically imported into every Java program. You do not need to write import java.lang.String; to use the String class. It is always available. This package contains the most fundamental classes that every Java program needs, like String, System, Math, Integer, Double, and Object.

Built-in Package Structure (Partial View) java/ +– lang/ | +– String.class | +– Math.class | +– System.class | +– Integer.class | +– Object.class | +– Thread.class +– util/ | +– Scanner.class | +– ArrayList.class | +– HashMap.class | +– Date.class +– io/ | +– File.class | +– BufferedReader.class | +– PrintWriter.class +– net/ | +– URL.class | +– Socket.class +– sql/ +– Connection.class +– ResultSet.class javax/ +– swing/ +– JFrame.class +– JButton.class +– JLabel.class

2. User-Defined Packages (Custom Packages)

These are packages that you create yourself for your own project. When you write package com.myproject.student; at the top of your file, you are creating a user-defined package. You have full control over the name, structure, and contents of these packages.

Important Notes to Remember for Exam:
1. Built-in packages come with the JDK (e.g., java.lang, java.util, java.io).
2. User-defined packages are created by the programmer for their project.
3. java.lang is automatically imported into every Java program. No import statement needed.
4. All other built-in packages require an import statement to use their classes.
5. Know the purpose of at least these packages: java.lang, java.util, java.io, java.sql, java.net.
6. Packages starting with java. are core Java packages. Packages starting with javax. are Java extensions.
MCQ

Question 6: Which built-in package is automatically imported into every Java program without needing an import statement?

A) java.util    B) java.io    C) java.lang    D) java.sql

Answer: C) java.lang

The java.lang package is implicitly imported by the Java compiler into every source file. This means you can use classes like String, System, Math, Integer, and Object without writing any import statement. All other packages (java.util, java.io, java.sql, etc.) require an explicit import statement to use their classes.

MCQ

Question 7: Which package would you import to use the Scanner class for reading user input?

A) java.lang    B) java.io    C) java.util    D) java.net

Answer: C) java.util

The Scanner class is part of the java.util package. To use it, you write import java.util.Scanner; at the top of your file. It is not in java.lang (option A), not in java.io (option B, though java.io has other input/output classes), and not in java.net (option D, which is for networking). Many students confuse the package locations, so memorize this one well.

Fill in the Blank

Question 8: The ________ package provides classes for database connectivity in Java, including Connection and ResultSet.

The package Statement

The package statement is how you tell Java which package your class belongs to. It is a very simple statement but it has strict rules that you must follow.

Syntax:

package packageName;

Rules for the package statement:

  • It must be the first statement in the source file (comments can come before it in some cases).
  • There can be only one package statement per source file.
  • Package names are written in all lowercase by convention.
  • Sub-packages are separated by dots: package com.university.student;
  • The package name should follow the reverse domain name convention: package com.yourcompany.project.module;
// This is the correct way to write a file with a package package com.university.student; // MUST be first statement import java.util.ArrayList; // import comes AFTER package public class Student { String name; int id; ArrayList courses; // using class from java.util // class body… }

Naming Conventions for Packages

Java has a standard convention for naming packages to ensure uniqueness across all Java projects in the world. The convention is to use your organization’s reverse internet domain name, followed by the project name, followed by the module name. All in lowercase.

// If your company website is ethiotelecom.et package com.ethiotelecom.billing.payment; // If your university website is aau.edu.et package edu.aau.cs.oop.lab; // Personal project with no domain package com.myname.project.module;

This naming convention guarantees that package names are unique worldwide. If two companies create a package called utils, they would actually be com.company1.utils and com.company2.utils, which are different.

Important Notes to Remember for Exam:
1. The package statement must be the first line (ignoring comments).
2. Only one package statement per file.
3. Package names use lowercase letters by convention.
4. Use reverse domain name for uniqueness: com.company.project.module.
5. The dot (.) in a package name represents a directory separator in the file system.
6. package com.university.student; means the Student.class file must be in a folder called student, which is inside a folder called university, which is inside a folder called com.
True or False

Question 9: You can have more than one package statement in a single Java source file.

Answer: False

A Java source file can have only ONE package statement. This is because all classes in a single source file must belong to the same package. If you need classes in different packages, you must put them in different source files, each with its own package statement. There is no way to have two package statements in one file.

MCQ

Question 10: What does the dot (.) represent in a package name like com.university.student?

A) Object reference    B) Directory separator in the file system    C) Method call    D) Decimal point

Answer: B) Directory separator in the file system

In a package name, each dot represents a folder (directory) in the file system. The package com.university.student means the class file must be stored in the directory path: com/university/student/. The dot in package names has nothing to do with object references (option A), method calls (option C), or decimal numbers (option D). This is purely a directory structure representation.

Creating a User-Defined Package

Now let me teach you the actual steps to create and use a user-defined package. This is a practical skill that you must know because exam questions often ask about the process.

Step-by-Step Process

Step 1: Create the directory structure

Create folders that match your package name. If your package is com.university.student, create folders: com/university/student/.

Directory Structure on Your Computer MyProject/ +– com/ | +– university/ | +– student/ | +– Student.java (this file has: package com.university.student;) | +– course/ | +– Course.java (this file has: package com.university.course;) +– Main.java (this file uses: import com.university.student.Student;)

Step 2: Write the class file with the package statement

// File: com/university/student/Student.java package com.university.student; public class Student { private String name; private int id; public Student(String name, int id) { this.name = name; this.id = id; } public void displayInfo() { System.out.println(“Student: ” + name + “, ID: ” + id); } }

Step 3: Compile the class with the package structure

// Navigate to the root of your project (where “com” folder is) // Compile with -d flag to create the package directory structure javac -d . com/university/student/Student.java // The -d flag tells the compiler to create directories as needed // The . (dot) means “put the compiled classes in the current directory”

Step 4: Use the class from another file

// File: Main.java (in the same root directory) import com.university.student.Student; public class Main { public static void main(String[] args) { Student s = new Student(“Abebe”, 1234); s.displayInfo(); } } // Compile: javac Main.java // Run: java Main

Output:

Student: Abebe, ID: 1234

The -d flag is very important when compiling packages. Without it, the compiler would put the .class file in the same directory as the .java file, but the package structure would not be created properly. With -d ., the compiler creates the necessary folder structure (com/university/student/) and places the Student.class file inside the correct folder.

Important Notes to Remember for Exam:
1. To compile a class with a package, use: javac -d . FileName.java
2. The -d flag creates the directory structure matching the package name.
3. The . (dot) after -d specifies the destination directory (current directory).
4. A public class in a package must be in a file with the same name as the class.
5. The .class file must be in the correct folder path matching the package name for the JVM to find it.
6. You can also use javac -d ../output src/com/university/student/Student.java to put compiled files in a different directory.
MCQ

Question 11: What is the purpose of the -d flag when compiling a Java file that has a package statement?

A) To delete the source file after compilation    B) To create the directory structure matching the package name    C) To debug the program    D) To display documentation

Answer: B) To create the directory structure matching the package name

The -d flag (which stands for “directory”) tells the Java compiler to create the necessary directory structure based on the package name and place the compiled .class files in the correct directories. For example, if the package is com.university.student, the compiler creates folders com/university/student/ and puts the .class file there. It does not delete files (option A), debug (option C), or display documentation (option D).

Short Answer

Question 12: Write the steps to create a user-defined package called com.example.math containing a class Calculator, and then use it from a main class in the default package.

Answer:

Step 1: Create the directory structure: com/example/math/

Step 2: Create the file com/example/math/Calculator.java with the following content:

package com.example.math; public class Calculator { public static int add(int a, int b) { return a + b; } public static int multiply(int a, int b) { return a * b; } }

Step 3: Compile with the -d flag: javac -d . com/example/math/Calculator.java

Step 4: Create Main.java in the root directory:

import com.example.math.Calculator; public class Main { public static void main(String[] args) { int result = Calculator.add(5, 3); System.out.println(“Sum: ” + result); } }

Step 5: Compile and run Main: javac Main.java then java Main

The import Statement

The import statement is how you tell Java that you want to use a class from a specific package. Without importing, you would have to use the fully qualified name every time you reference a class, which would make your code very long and hard to read.

Without Import (Using Fully Qualified Name)

// No import statement – using fully qualified name everywhere public class Main { public static void main(String[] args) { java.util.Scanner scanner = new java.util.Scanner(System.in); java.util.ArrayList list = new java.util.ArrayList(); java.util.Date date = new java.util.Date(); } }

See how tedious that is? Every time you use Scanner, you have to write java.util.Scanner. This makes the code long and hard to read. The import statement solves this problem.

With Import (Using Simple Name)

// With import statement – using simple class name import java.util.Scanner; import java.util.ArrayList; import java.util.Date; public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); // Simple name! ArrayList list = new ArrayList(); // Simple name! Date date = new Date(); // Simple name! } }

Much cleaner! The import statement tells the compiler: “When I say Scanner, I mean java.util.Scanner.” You only write the full package path once at the top, and then you can use the simple class name everywhere in the file.

Types of Import Statements

There are three ways to import classes:

1. Specific Import (Importing a single class)

import java.util.Scanner; // Only imports Scanner import java.util.ArrayList; // Only imports ArrayList

2. Wildcard Import (Importing all classes in a package)

import java.util.*; // Imports ALL classes in java.util package

The asterisk (*) is a wildcard that means “all classes.” Instead of writing separate import statements for Scanner, ArrayList, HashMap, Date, etc., you write one line with the wildcard. This saves typing but does NOT import sub-packages. Let me explain this very carefully because it is a common exam question.

import java.util.*; // Imports all classes in java.util // Does NOT import classes from java.util.regex // Does NOT import classes from java.util.jar // Does NOT import classes from java.util.zip

The wildcard only imports classes directly in that specific package, not in its sub-packages. If you also need classes from java.util.regex, you must import that separately: import java.util.regex.*;

3. Static Import (Importing static members)

import static java.lang.Math.PI; import static java.lang.Math.sqrt; public class Main { public static void main(String[] args) { // No need to write Math.PI or Math.sqrt System.out.println(PI); double result = sqrt(25); System.out.println(result); } }

Static import allows you to use static members (constants and static methods) of a class without writing the class name. Instead of Math.PI, you just write PI. This is mostly used with Math class constants and methods.

Important Notes to Remember for Exam:
1. The import statement comes after the package statement and before the class declaration.
2. import java.util.* imports all classes in java.util but does NOT import sub-packages.
3. Importing is only for convenience. It does NOT actually load classes into memory (classes are loaded when used).
4. You can use the fully qualified name instead of import if you prefer (no import needed).
5. import static is used to import static members (constants and static methods) without the class name.
6. The order in a source file is: package -> import -> class.
7. Having unused import statements does not cause errors but is bad practice.
MCQ

Question 13: Does import java.util.*; import classes from the sub-package java.util.regex?

A) Yes, it imports everything including sub-packages    B) No, it only imports classes directly in java.util, not sub-packages    C) It depends on the Java version    D) Yes, but only if you add another import statement

Answer: B) No, it only imports classes directly in java.util, not sub-packages

The wildcard import * only imports the classes that are directly in the specified package. It does NOT recursively import sub-packages. So import java.util.*; imports Scanner, ArrayList, HashMap, Date, etc. (which are directly in java.util), but it does NOT import Pattern or Matcher (which are in java.util.regex). You would need a separate import java.util.regex.*; for that. This is one of the most commonly asked questions about packages in exams!

MCQ

Question 14: What is the correct order of statements in a Java source file?

A) import -> package -> class    B) class -> package -> import    C) package -> import -> class    D) package -> class -> import

Answer: C) package -> import -> class

The correct order is: first the package statement (if any), then the import statements (if any), then the class declaration. You cannot put import before package, and you cannot put class before import. This order is strictly enforced by the Java compiler. Comments can appear before the package statement, but code statements must follow this order.

True or False

Question 15: The import statement loads the imported classes into memory at compile time.

Answer: False

The import statement does NOT load any class into memory. It simply tells the compiler where to find the class when it is used in the code. Classes are loaded into memory by the JVM at runtime only when they are actually needed (when an object is created or a static member is accessed). The import statement is purely a compile-time convenience that saves you from typing fully qualified names. It is like adding a contact to your phone – it does not call the person, it just saves you from typing the full phone number each time.

Fill in the Blank
See also  Classes and Objects in Java: Detailed Notes, Examples & Practice Questions (Object Oriented Programming)

Question 16: The ________ import is used to import static members of a class so they can be used without the class name.

Answer: static

The syntax is import static packageName.ClassName.staticMember; or import static packageName.ClassName.*; (to import all static members). After a static import, you can use the static member directly without prefixing it with the class name. For example, after import static java.lang.Math.PI;, you can write just PI instead of Math.PI.

Sub-Packages

A sub-package is a package inside another package. For example, java.util.regex is a sub-package of java.util. The dot notation creates a hierarchy of packages.

Now here is a very important point that confuses many students: a sub-package is NOT a child of the parent package in terms of access or inheritance. They are two completely separate packages. The only relationship is in the naming convention. The class java.util.regex.Pattern is NOT inside java.util. It is in java.util.regex, which happens to have “java.util” as part of its name.

// These are TWO DIFFERENT packages with NO special relationship: // java.util (contains Scanner, ArrayList, etc.) // java.util.regex (contains Pattern, Matcher, etc.) // Importing java.util.* does NOT give you access to java.util.regex classes // You MUST import java.util.regex.* separately

Think of it this way: “Ethiopia” and “Ethiopian Airlines” share the word “Ethiopia,” but Ethiopian Airlines is not inside Ethiopia in a programming sense. They are separate entities. Similarly, java.util and java.util.regex share the name prefix, but they are separate packages with separate access controls.

Important Notes to Remember for Exam:
1. Sub-packages are created by adding dots: package parent.child.grandchild;
2. A sub-package is NOT a child of the parent package. They are logically separate.
3. Importing a parent package does NOT import sub-packages.
4. There is NO special access between a package and its sub-packages.
5. java.util and java.util.regex have no access relationship with each other beyond what normal packages have.
6. The dot in the package name creates directory hierarchy but does NOT create any special code relationship.
True or False

Question 17: Classes in the sub-package java.util.regex have special access to classes in the parent package java.util.

Answer: False

Sub-packages do NOT have any special access to their parent packages. The relationship between java.util and java.util.regex is only in the naming convention (directory structure). They are two completely separate packages as far as access control is concerned. A class in java.util.regex must import java.util classes just like any other package would. There is no parent-child privilege in Java packages.

Access Modifiers and Packages

Packages play a very important role in determining which classes can access which other classes. The access modifiers in Java work together with packages to control visibility. Let me explain how each access modifier behaves across packages.

You already know the four access modifiers. Now let me look at them from the perspective of packages:

1. private: Accessible only within the same class. The package does not matter. Even other classes in the same package cannot access private members.

2. default (no modifier): Accessible only within the same package. This is where packages directly affect access. If a class has default access, only classes in the same package can use it. Classes in other packages cannot see it at all, even if they try to import it.

3. protected: Accessible within the same package AND accessible from subclasses in other packages (through inheritance only, not through direct object reference).

4. public: Accessible from everywhere. Any class in any package can access public members by importing the class.

Access ModifierSame ClassSame PackageDifferent Package (by object)Different Package (by subclass)
privateYesNoNoNo
defaultYesYesNoNo
protectedYesYesNoYes
publicYesYesYesYes

Let me show you a practical example to make this clear:

// File: com/example/core/Person.java package com.example.core; public class Person { public String name; // accessible everywhere protected int age; // same package + subclasses in other packages String address; // default: same package only private String phone; // same class only void showInfo() { // default method: same package only System.out.println(name + “, ” + age + “, ” + address + “, ” + phone); } }
// File: com/example/core/Employee.java package com.example.core; // SAME package as Person public class Employee extends Person { void test() { name = “Abebe”; // OK – public age = 25; // OK – protected, same package address = “AAU”; // OK – default, same package phone = “0911…”; // ERROR! private, different class even in same package showInfo(); // OK – default method, same package } }
// File: com/example/other/Manager.java package com.example.other; // DIFFERENT package import com.example.core.Person; public class Manager extends Person { void test() { name = “Tigist”; // OK – public age = 30; // OK – protected, accessed through inheritance address = “Jimma”; // ERROR! default, different package phone = “0922…”; // ERROR! private showInfo(); // ERROR! default method, different package } }
// File: com/example/other/Tester.java package com.example.other; // DIFFERENT package import com.example.core.Person; public class Tester { // NOT a subclass of Person void test() { Person p = new Person(); p.name = “Yohannes”; // OK – public p.age = 28; // ERROR! protected, NOT accessed through inheritance p.address = “Bahir Dar”; // ERROR! default, different package p.phone = “0933…”; // ERROR! private p.showInfo(); // ERROR! default method, different package } }

Look carefully at the Manager and Tester classes. Both are in a different package. But Manager is a SUBCLASS of Person, while Tester is NOT. The protected member age is accessible in Manager (through inheritance) but NOT in Tester (not a subclass, using a direct object reference). This is a very subtle but important distinction.

Important Notes to Remember for Exam:
1. default access = accessible only within the same package. This is the package-level access control.
2. protected = same package access + subclass access in other packages (inheritance only).
3. public = accessible from any package (after importing).
4. A class with default access (no public modifier) is NOT visible outside its package at all.
5. protected members in a different package can ONLY be accessed through inheritance (by a subclass), NOT through an object reference of the parent class.
6. For the exam: memorize the access modifier table above. It is asked in almost every OOP exam.
MCQ

Question 18: A class has a method with default (no modifier) access. Which classes can call this method?

A) All classes in all packages    B) Only classes in the same package    C) Only subclasses in the same package    D) Only the class where it is defined

Answer: B) Only classes in the same package

Default access (no modifier) means package-level access. Any class in the same package can access the method, whether it is a subclass or not. But classes in different packages cannot access it at all, even if they are subclasses. Option A is wrong (that is public). Option C is too restrictive (subclasses AND non-subclasses in the same package can access it). Option D is too restrictive (that is private). The correct answer is B because default access = same package only.

MCQ

Question 19: A class in package A has a protected method. A class in package B extends this class. How can the subclass access the protected method?

A) Through an object of the parent class    B) Only through inheritance (directly, without parent object)    C) It cannot access it at all    D) By using a special import

Answer: B) Only through inheritance (directly, without parent object)

When a subclass is in a different package, it can access protected members ONLY through inheritance, meaning it calls the method directly on itself (since it inherited the method). It CANNOT access the protected member through a reference to the parent class. For example, if class B extends class A, and A has a protected method display(), then inside B you can write display() (inherited) but you CANNOT write A obj = new A(); obj.display();. This is a very important and commonly tested distinction.

True or False

Question 20: A public class in one package is automatically visible to all classes in all other packages without any import statement.

Answer: False

Even though the class is public, you still need an import statement (or use the fully qualified name) to use it from a different package. “Public” means the class CAN be accessed from other packages, but you still need to tell the compiler WHERE to find it. Without importing, the compiler does not know which package the class belongs to. Think of it this way: a public building is open to everyone, but you still need the address to find it.

Class Access in Packages

Just like members (fields and methods), the class itself also has access levels. The access modifier on a class determines which other classes can see and use it.

public class: Can be accessed from any package. You must import it to use it from a different package.

// File: com/example/core/Student.java package com.example.core; public class Student { // This class can be used from any package }

default class (no modifier): Can ONLY be accessed from within the same package. Classes in other packages cannot even see this class, let alone use it. It is completely hidden from outside packages.

// File: com/example/core/Helper.java package com.example.core; class Helper { // This class can ONLY be used by other classes in com.example.core // Classes in other packages cannot import or use this class at all }

Note: A class CANNOT be private or protected (except for inner classes). Only public and default are allowed for top-level classes.

Important Notes to Remember for Exam:
1. A top-level class can only be public or default (no modifier).
2. A default class is invisible to other packages entirely.
3. A public class is visible to other packages but still requires an import statement.
4. Only inner classes (classes inside another class) can be private or protected.
5. If a class is default, no class in any other package can use it, regardless of what import statements you write.
MCQ

Question 21: Which access modifier can be applied to a top-level class in Java?

A) public only    B) public and default only    C) public, protected, default, and private    D) protected and public only

Answer: B) public and default only

A top-level class (a class that is not inside another class) can only have two access levels: public or default (no modifier). You cannot make a top-level class private, protected, or any other modifier. If you try protected class MyClass { }, the compiler will give an error. Private and protected are only valid for inner classes (classes declared inside another class).

The CLASSPATH

The CLASSPATH is an environment variable that tells the Java Virtual Machine (JVM) where to look for user-defined classes and packages. When you run a Java program and it needs to find a class, the JVM searches in the locations listed in the CLASSPATH.

Think of CLASSPATH as a list of folders and JAR files that the JVM searches through to find your classes. If your class is in a package and the JVM cannot find it, the most common reason is that the CLASSPATH is not set correctly.

By default, the CLASSPATH includes the current directory (represented by a dot “.”). That is why when you compile with javac -d . and run from the same directory, it usually works. The JVM finds the classes in the current directory.

// Setting CLASSPATH in command line // Windows: set CLASSPATH=.;C:\mylibs\myutils.jar // Linux/Mac: export CLASSPATH=.:/home/user/mylibs/myutils.jar // Running with custom classpath java -cp .;/home/user/mylibs MyClass // The -cp (or -classpath) flag overrides the CLASSPATH environment variable

The CLASSPATH can include:

  • Directories containing .class files (like the current directory “.”)
  • JAR files (Java ARchive files, which are compressed collections of .class files)
  • ZIP files containing .class files

Multiple paths are separated by a semicolon (;) on Windows and a colon (:) on Linux/Mac.

Important Notes to Remember for Exam:
1. CLASSPATH tells the JVM where to find classes and packages.
2. By default, CLASSPATH includes the current directory (.).
3. On Windows, paths are separated by semicolon (;). On Linux/Mac, by colon (:).
4. The -cp or -classpath flag overrides the environment variable.
5. CLASSPATH can include directories and JAR files.
6. If the JVM cannot find a class, you get NoClassDefFoundError or ClassNotFoundException.
7. “Class not found” errors are almost always a CLASSPATH problem.
MCQ

Question 22: What does the CLASSPATH environment variable specify in Java?

A) Where to install Java    B) Where the JDK is located    C) Where the JVM should look for user-defined classes and packages    D) Where to save source files

Answer: C) Where the JVM should look for user-defined classes and packages

See also  Introduction to Object-Oriented Programming (OOP): Detailed Notes, Examples & Practice Questions (Object Oriented Programming)

CLASSPATH is used by the JVM to locate .class files and packages at runtime. It is a list of directories and JAR files that the JVM searches when it needs to load a class. Option A refers to JAVA_HOME. Option B also refers to JAVA_HOME. Option D is wrong because CLASSPATH is about finding compiled classes, not saving source files. Remember: JAVA_HOME is for the JDK location, PATH is for finding the java/javac executables, and CLASSPATH is for finding your classes.

Fill in the Blank

Question 23: On Windows systems, multiple CLASSPATH entries are separated by a ________, while on Linux systems they are separated by a ________.

Answer: semicolon (;), colon (:)

This is a small detail but it can appear in exams. On Windows, the path separator for CLASSPATH is the semicolon (;). On Linux and Mac, it is the colon (:). For example: Windows: set CLASSPATH=.;C:\libs\utils.jar, Linux: export CLASSPATH=.:/home/user/libs/utils.jar. Getting this wrong means the JVM cannot find your classes, leading to runtime errors.

JAR Files and Packages

A JAR file (Java ARchive) is a compressed file that contains a collection of Java class files, along with any related resources like images and text files. JAR files use the ZIP format for compression. They are used to distribute Java libraries and applications.

When you create a package, you can package all the .class files into a JAR file for easy distribution. Other developers can then add your JAR file to their CLASSPATH and import your packages.

// Creating a JAR file from a package structure jar cf mylibrary.jar -C com . // Using a JAR file in CLASSPATH java -cp .;mylibrary.jar MainClass // Viewing contents of a JAR file jar tf mylibrary.jar

Most third-party libraries that you use in Java projects (like database drivers, logging frameworks, etc.) come as JAR files. You download the JAR file and add it to your project’s CLASSPATH to use the classes inside it.

Important Notes to Remember for Exam:
1. A JAR file is a compressed collection of .class files and resources.
2. JAR files use ZIP compression format.
3. To create a JAR: jar cf filename.jar -C packageRoot .
4. To use a JAR: add it to CLASSPATH or use -cp flag.
5. JAR files make it easy to distribute packages as a single file.
6. Most Java libraries are distributed as JAR files.

Complete Practical Example

Let me now give you one big complete example that shows how to create multiple packages, import classes between them, and demonstrate access control. This type of comprehensive question can appear in your exam.

Project Structure myproject/ +– com/ | +– school/ | +– model/ | | +– Student.java | | +– Course.java | +– service/ | +– StudentService.java +– Main.java
// File: com/school/model/Student.java package com.school.model; public class Student { public String name; protected int id; String department; // default access private double GPA; // private public Student(String name, int id, String department, double GPA) { this.name = name; this.id = id; this.department = department; this.GPA = GPA; } public void displayAll() { System.out.println(name + “, ID: ” + id + “, Dept: ” + department + “, GPA: ” + GPA); } void displayBasic() { // default method System.out.println(name + “, ID: ” + id); } }
// File: com/school/service/StudentService.java package com.school.service; import com.school.model.Student; public class StudentService { public void printStudentInfo(Student s) { // s.GPA = 3.5; // ERROR! private, different package // s.department = “CS”; // ERROR! default, different package // s.id = 100; // ERROR! protected, NOT through inheritance s.name = “Updated”; // OK! public s.displayAll(); // OK! public method // s.displayBasic(); // ERROR! default method, different package } } // Class in same package extending Student class AdvancedStudent extends com.school.model.Student { AdvancedStudent(String name, int id, String dept, double gpa) { super(name, id, dept, gpa); } void test() { name = “Test”; // OK – public id = 999; // OK – protected, same package? NO – different package! // Actually ERROR! service and model are different packages // Wait, AdvancedStudent is in com.school.service // Student is in com.school.model // These are DIFFERENT packages! // So id is accessible ONLY through inheritance, not through object // But since AdvancedStudent extends Student, accessing id directly is OK // because it is inherited. Let me correct: // id = 999; is OK because AdvancedStudent inherits id from Student } }
// File: Main.java (default package) import com.school.model.Student; import com.school.service.StudentService; public class Main { public static void main(String[] args) { Student s = new Student(“Abebe”, 101, “CS”, 3.75); s.displayAll(); StudentService service = new StudentService(); service.printStudentInfo(s); } }

Compile and run:

javac -d . com/school/model/Student.java javac -d . com/school/service/StudentService.java javac Main.java java Main

Output:

Abebe, ID: 101, Dept: CS, GPA: 3.75 Updated, ID: 101, Dept: CS, GPA: 3.75
Find the Error

Question 24: In the example above, identify which lines in StudentService would cause compile errors and explain why.

Errors in StudentService:

1. s.GPA = 3.5; – Compile error. GPA is private, and StudentService is in a different package (com.school.service) and is NOT a subclass of Student. Private members are only accessible within the same class.

2. s.department = "CS"; – Compile error. department has default access, which means it is only accessible within the same package (com.school.model). StudentService is in a different package, so it cannot access default members.

3. s.id = 100; – Compile error. id is protected. StudentService is in a different package AND is NOT a subclass of Student. Protected members in a different package are only accessible through inheritance (by subclasses), not through object references of the parent class.

4. s.displayBasic(); – Compile error. displayBasic() has default access (no modifier), so it is only accessible within the same package. StudentService is in a different package.

Only s.name and s.displayAll() work because they are public.

Exercises with Answers

Exercise 1: You are given the following directory structure and files. Identify all compile errors and explain each one.
Project Structure: com/ +– math/ | +– Calculator.java +– test/ +– Main.java
// File: com/math/Calculator.java package com.math; class Calculator { public static int add(int a, int b) { return a + b; } public static int subtract(int a, int b) { return a – b; } } // File: com/test/Main.java package com.test; import com.math.Calculator; public class Main { public static void main(String[] args) { int result = Calculator.add(5, 3); System.out.println(“Result: ” + result); } }

Compile Error: The Main class will NOT compile.

Reason: The Calculator class in com/math/Calculator.java does NOT have the public modifier. It has default (package-private) access. This means it is only visible within the com.math package. The Main class in com.test package tries to import and use Calculator, but since Calculator is not public, it is invisible outside its package.

Fix: Change class Calculator to public class Calculator in the Calculator.java file.

Exercise 2: Write a complete program with two packages: com.store.product containing a Product class, and com.store.inventory containing an InventoryManager class that imports and uses Product. The Product class should have public, protected, default, and private members to demonstrate access levels between different packages.
// File: com/store/product/Product.java package com.store.product; public class Product { public String name; protected double price; String category; // default access private int stock; // private public Product(String name, double price, String category, int stock) { this.name = name; this.price = price; this.category = category; this.stock = stock; } public void display() { System.out.println(name + ” | ” + price + ” Birr | ” + category + ” | Stock: ” + stock); } void showCategory() { // default method System.out.println(“Category: ” + category); } private void showStock() { System.out.println(“Stock: ” + stock); } }
// File: com/store/inventory/InventoryManager.java package com.store.inventory; import com.store.product.Product; public class InventoryManager { public void checkProduct() { Product p = new Product(“Laptop”, 25000, “Electronics”, 15); p.name = “Updated Laptop”; // OK – public // p.price = 30000; // ERROR – protected, different package, NOT subclass // p.category = “Gadgets”; // ERROR – default, different package // p.stock = 20; // ERROR – private p.display(); // OK – public method // p.showCategory(); // ERROR – default method, different package // p.showStock(); // ERROR – private method } }

Only the public members (name, display()) are accessible from InventoryManager because it is in a different package and is NOT a subclass of Product. All other members (protected, default, private) cause compile errors.

Exercise 3: Answer the following questions about static imports:

a) Write the import statement to import only the PI constant from java.lang.Math.

b) Write the import statement to import all static members of java.lang.Math.

c) After the imports in parts (a) and (b), how would you use the sqrt method?

a) import static java.lang.Math.PI;

b) import static java.lang.Math.*;

c) After part (a): you must still write Math.sqrt(25) because you only imported PI, not sqrt. After part (b): you can write just sqrt(25) because the wildcard imported all static members including sqrt.

More Practice Questions for Exam

MCQ

Question 25: What will happen if you try to compile and run the following code?

// File: com/example/Utils.java package com.example; class Utils { public static void greet() { System.out.println(“Hello!”); } } // File: Main.java import com.example.Utils; public class Main { public static void main(String[] args) { Utils.greet(); } }

A) Prints “Hello!”    B) Compile error in Main.java    C) Runtime error    D) Prints nothing

Answer: B) Compile error in Main.java

The Utils class has default (package-private) access because there is no public keyword before class Utils. This means Utils is only visible within the com.example package. The Main class is in the default package (no package statement), which is a different package. Even though Main imports com.example.Utils, the compiler will give an error saying that Utils is not public in com.example and cannot be accessed from outside the package.

MCQ

Question 26: Which of the following import statements is valid?

A) import java.util.Scanner.*;    B) import static java.util.Scanner;    C) import java.util.*.Scanner;    D) import java.util.Scanner;

Answer: D) import java.util.Scanner;

Option A is invalid because you cannot use wildcard on a class name (Scanner.* makes no sense). Option B is invalid because static import is used for importing static members, not the class itself. Option C is invalid syntax (you cannot have *.Scanner). Only option D is the correct syntax for importing a specific class from a package.

Short Answer

Question 27: Differentiate between CLASSPATH and PATH environment variables in Java.

Answer:

PATH: The PATH environment variable tells the operating system where to find the Java executable files (like java and javac). When you type javac in the command line, the OS searches the PATH directories to find the javac executable. PATH is used by the OS, not by the JVM.

CLASSPATH: The CLASSPATH environment variable tells the JVM where to find user-defined classes and packages (the .class files). When the JVM needs to load a class, it searches the CLASSPATH directories and JAR files. CLASSPATH is used by the JVM, not by the OS.

In short: PATH is for finding Java tools (javac, java). CLASSPATH is for finding your classes and libraries.

List and Explain

Question 28: List the three types of import statements available in Java and explain each with an example.

Answer:

1. Specific Import: Imports a single class from a package. Example: import java.util.Scanner; – Only the Scanner class is imported.

2. Wildcard Import: Imports all classes from a package (but NOT sub-packages). Example: import java.util.*; – All classes directly in java.util are imported (Scanner, ArrayList, etc.), but classes in java.util.regex are NOT imported.

3. Static Import: Imports static members (constants and static methods) of a class so they can be used without the class name. Example: import static java.lang.Math.PI; – You can now use PI directly instead of Math.PI.

MCQ

Question 29: When you compile a file with javac -d . MyClass.java where MyClass has package com.example.test;, where will the compiled .class file be placed?

A) In the current directory    B) In com/example/test/ directory    C) In the user’s home directory    D) In the JDK installation directory

Answer: B) In com/example/test/ directory

The -d flag tells the compiler to create directories matching the package structure. Since the package is com.example.test, the compiler creates the directory structure com/example/test/ inside the destination directory specified by the dot (which means the current directory). So the final location is ./com/example/test/MyClass.class. The .class file is NOT placed directly in the current directory; it goes into the package folder structure.

Final Exam Tips for Packages:
1. Memorize the five advantages of packages: organization, name conflicts, access control, reusability, easy searching.
2. Know the correct order: package statement FIRST, then import, then class. Always.
3. java.lang is automatically imported. All other packages need explicit import.
4. import java.util.* does NOT import sub-packages. This question comes in EVERY exam.
5. Know the access modifier table by heart (private, default, protected, public) with respect to packages.
6. A default class is invisible outside its package. Only public classes can be imported.
7. Protected in a different package: accessible ONLY through inheritance, NOT through parent object reference.
8. Remember the -d . flag for compiling packages. Know what -d does and what the dot means.
9. Know the difference between PATH, JAVA_HOME, and CLASSPATH.
10. Sub-packages are NOT child packages. No special access between parent and sub-packages.
11. Only public and default access for top-level classes. Private and protected are for inner classes only.
12. Practice the practical exercise of creating a package structure, compiling with -d, and importing from another file.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top