Java Programming
Packages, Classpath, Arrays and Program Structure
PGCP-BDA
Java packages
A package creates a namespace and access boundary and should match a stable directory and module organization.
imports and classpath
An import shortens source type names; the classpath or module path tells tools where compiled classes and resources can be found.
source and class files
A .java file contains source code; compilation produces .class files containing JVM bytecode and class metadata.
one-dimensional arrays
A Java array is a fixed-length indexed object whose elements share one declared component type and receive default values at allocation.
multidimensional arrays
Java multidimensional arrays are arrays of array references, so rows can have different lengths and are allocated independently.
ragged array
A multidimensional Java array whose component arrays may have different lengths because each row is a separate object.
command-line arguments
Strings supplied after the program name and received by the main method through its String array parameter.
The main parameter is a String array. Arguments need parsing and validation:
public static void main(String[] args) {
if (args.length != 2) {
System.err.println("Usage: java Sum <left> <right>");
return;
}
try {
int left = Integer.parseInt(args[0]);
int right = Integer.parseInt(args[1]);
System.out.println(Math.addExact(left, right));
} catch (NumberFormatException ex) {
System.err.println("Both arguments must be integers");
} catch (ArithmeticException ex) {
System.err.println("Sum is outside the int range");
}
}
The shell separates arguments before Java receives them. Quoting rules belong to the shell. Parsing success does not establish domain validity, so ranges and relationships still need checks.
main method
The conventional Java application entry point declared public static void main(String[] args).
program structure
The arrangement of package declaration, imports, type declarations, members, statements and expressions in valid Java source.
Multidimensional and jagged arrays
Java represents a multidimensional array as an array whose components are array references.
int[][] matrix = new int[3][];
matrix[0] = new int[2];
matrix[1] = new int[5];
matrix[2] = new int[1];
Rows may have different lengths or be null. Always use matrix[row].length for that row rather than assuming a rectangular shape. Cloning matrix copies only the outer array and shares row arrays; a deep copy must clone each non-null row.
Package access and source-file rules
A top-level type is either public or package-private. It cannot be declared private or protected. A source file may contain several top-level types, but at most one can be public and its name must match the file name.
Package-private access is created by omitting a modifier:
package com.acme.billing;
class TaxCalculator { // visible inside this package
static double tax(double amount) {
return amount * 0.18;
}
}
Package structure should follow responsibility, not merely technical kind. A feature package that keeps its controller, service and repository near one another can be easier to understand than global packages containing every controller or every service.
Arrays and boundaries
An array has a fixed length after creation and uses zero-based indexing. A new primitive array contains default primitive values; a new reference array contains null references until elements are assigned. Java multidimensional arrays are arrays of arrays, so rows can have different lengths. An enhanced for loop reads elements conveniently, but reassigning its loop variable does not replace an array entry.
int[] values = {3, 5, 7};
int sum = 0;
for (int i = 0; i < values.length; i++) sum += values[i];
System.out.println(sum); // 15
Index bounds are checked at runtime. The valid range is zero through length minus one. Array covariance permits a String array reference to be stored in an Object-array variable, but inserting an incompatible object then fails with ArrayStoreException. Prefer types that express intended operations without relying on a runtime failure to enforce them.
Array creation and initialization
Arrays are objects with a fixed length and a component type.
int[] first = new int[3]; // {0, 0, 0}
String[] names = new String[2]; // {null, null}
int[] values = {3, 5, 7};
The declaration int[] values is generally preferred over placing brackets after the variable because the type is easier to read. Length is a final array field accessed as values.length, not a method.
Valid indexes run from zero through length minus one. The JVM checks each access and throws ArrayIndexOutOfBoundsException for an invalid index. A zero-length array is valid but has no valid index.
Promotion and array identity
byte small = 10;
// small = small + 1; // int result cannot be assigned without narrowing
small += 1; // compound assignment includes its conversion
int[][] rows = { {1, 2}, {3} };
System.out.println(rows.length); // 2
System.out.println(rows[1].length); // 1
An array object has its own identity. Copying the variable copies its reference, not its elements. Cloning a two-dimensional array duplicates the outer array but keeps references to the existing rows unless those rows are copied separately. Short-circuit expressions can guard both null references and index bounds. Evaluate the guard before the operation it protects; writing the same conditions in reverse order can throw before the guard is reached.
Array covariance
Reference arrays are covariant:
String[] strings = new String[2];
Object[] objects = strings;
objects[0] = "valid";
// objects[1] = Integer.valueOf(10); // ArrayStoreException
The variable type permits Object, but the runtime array object still has component type String. The JVM performs the store check and rejects the incompatible value. Generic collections instead reject many analogous type mismatches at compile time and are often a better API choice.
Primitive arrays do not participate in reference-array covariance: int[] is an Object, but it is not an Object[].
Copying and equality
int[] a = {1, 2, 3};
int[] alias = a;
int[] copy = a.clone();
System.out.println(a == alias); // true
System.out.println(a == copy); // false
System.out.println(Arrays.equals(a, copy)); // true
Assignment copies the array reference. Clone creates a new array with copied component values. For reference components, those copied values are references, so element objects remain shared. System.arraycopy, Arrays.copyOf and copyOfRange support other copy requirements.
Array equals inherits identity behavior from Object. Use Arrays.equals for one-dimensional content and Arrays.deepEquals for nested array content when its recursive semantics match the domain.
Cycles and collection timing
Tracing collectors do not rely only on reference counts. Therefore, an unreachable cycle can be reclaimed:
class Node { Node next; }
Node a = new Node();
Node b = new Node();
a.next = b;
b.next = a;
a = null;
b = null;
The two nodes reference each other, but no root reaches either of them. They are eligible for collection. Eligibility does not mean immediate destruction. The JVM decides when and whether to collect based on memory pressure and collector policy.
System.gc() and Runtime.getRuntime().gc() are requests, not guarantees. Programs must never depend on prompt collection for correctness.
The historical finalize() mechanism is deprecated and unreliable. The JVM never promised prompt finalization, finalizer queues could delay reclamation, exceptions could be ignored and resurrection could make object lifetime unpredictable. Do not use finalization to close files, sockets, database connections or other resources. Use try-with-resources and AutoCloseable; specialized cleanup facilities such as Cleaner are fallback mechanisms rather than substitutes for explicit ownership.
Traversal and search
Use an index loop when the position is needed or entries must be replaced:
for (int index = 0; index < values.length; index++) {
values[index] *= 2;
}
Use enhanced for when reading each value is sufficient. Common off-by-one defects use <= values.length or start at one. State the invariant: before each iteration, indexes below index have been processed and index is within zero through length.
Linear search takes O(n) comparisons in the worst case. A sorted array supports binary search, but only if the sort order and comparator agree with the search operation.
if and else
An if condition must be boolean; Java does not implicitly treat integers as conditions.
if (marks < 0 || marks > 100) {
throw new IllegalArgumentException("marks outside range");
} else if (marks >= 75) {
grade = 'A';
} else if (marks >= 60) {
grade = 'B';
} else {
grade = 'C';
}
Conditions are tested in order, so ranges should be arranged without unreachable or overlapping mistakes. Braces prevent the dangling-else and accidental single-statement problems even when a branch presently has one statement.
Continue learning
Related notes
Put this topic into timed practice
Open mock tests when you want full-exam pacing, or keep drilling in practice mode.