Study guide
3.4 Abstract Classes, Static Members, and Object Methods (`equals`, `hashCode`, `toString`)
Oracle Java SE 17 Developer Certified Professional 1Z0-829
Track your progress as you read
Finished sections get a check mark.
1 Introduction: The 1Z0-829 Exam
About the Java SE 17 Developer (1Z0-829) Exam
2 Chapter 1: Java Fundamentals & Language Basics
1.1 Primitive Types, Literals, Wrapper Classes, and Type Promotion/Casting 1.2 Local Variable Type Inference (`var`) Rules and Scoping 1.3 Operators, Precedence, Evaluation Order, and Short-Circuit Evaluation 1.4 Text Blocks, String Immutability, and StringBuilder APIs
3 Chapter 2: Program Flow & Decision Constructs
2.1 Conditional Branching with if/else and the Ternary Operator 2.2 Switch Statements and Switch Expressions 2.3 Iteration Constructs, Loop Control, and Branching Labels
4 Chapter 3: Object-Oriented Design & Class Mechanics
3.1 Class Declarations, Field/Method Signatures, and Access Modifiers 3.2 Constructors, Overloading, Initialization Order, and Garbage Collection 3.3 Inheritance, Method Overriding, Polymorphism, and `super`/`this` 3.4 Abstract Classes, Static Members, and Object Methods (`equals`, `hashCode`, `toString`)
5 Chapter 4: Advanced OOP: Interfaces, Records & Sealed Types
4.1 Interface Architecture: Default, Static, and Private Methods 4.2 Enumerations: Constants, Constructors, Methods, and Custom Bodies 4.3 Records: Canonical/Compact Constructors, Components, and Immutability 4.4 Sealed Classes and Interfaces: `permits`, Hierarchy Constraints, and Modifiers
6 Chapter 5: Pattern Matching & Nested Types
5.1 Pattern Matching for `instanceof` and Flow Scoping Mechanics 5.2 Nested Types: Member Inner, Static Nested, Local, and Anonymous Classes 5.3 Defensive Programming, Immutability Patterns, and Validation
7 Chapter 6: Generics, Collections & Arrays
6.1 Generic Classes, Interfaces, Methods, and Type Erasure 6.2 Bounded Type Parameters and Wildcards (PECS Rule) 6.3 Collections Framework: List, Set, Queue, and Deque APIs 6.4 The Map Interface, Sorting, Comparable, and Comparator 6.5 Arrays: Declaration, Initialization, Multidimensional Arrays, and the Arrays Utility Class
8 Chapter 7: Functional Programming & Lambda Expressions
7.1 Functional Interfaces and Lambda Syntax Rules 7.2 Standard Functional Interfaces in `java.util.function` 7.3 Method References: Static, Bound, Unbound, and Constructor References
9 Chapter 8: The Stream API
8.1 Stream Lifecycle: Creation, Pipeline Architecture, and Lazy Evaluation 8.2 Intermediate Stream Operations: Filtering, Mapping, Sorting, and Slicing 8.3 Terminal Stream Operations: Reduction, Matching, Finding, and Collecting 8.4 Primitive Streams (`IntStream`, `LongStream`, `DoubleStream`) and Numeric Statistics
10 Chapter 9: Advanced Streams & Collectors
9.1 The Optional Class: Safe Null Handling, Transformation, and Chaining 9.2 The Collectors API: Downstream Reductions, Grouping, and Partitioning 9.3 Parallel Streams: Fork/Join Pool, Spliterators, and Concurrency Pitfalls
11 Chapter 10: Exception Handling
10.1 The Java Exception Hierarchy: Checked vs. Unchecked Exceptions and Errors 10.2 Exception Constructs: `try-catch-finally`, Multi-Catch, and Rethrowing 10.3 Try-With-Resources, `AutoCloseable`, Suppressed Exceptions, and Custom Exceptions
12 Chapter 11: Date/Time API & Localization
11.1 Date and Time Core Types: `LocalDate`, `LocalTime`, `LocalDateTime` 11.2 Timestamps, Intervals, and Durations: `Instant`, `Period`, and `Duration` 11.3 Time Zones, Daylight Saving Time (DST) Offsets, and `ZonedDateTime` 11.4 Internationalization and Localization: `Locale`, `ResourceBundle`, and Formatters 11.5 Formatting and Parsing Messages, Numbers, Percentages, and Localized Dates
13 Chapter 12: Java Platform Module System (JPMS)
12.1 Module Architecture, `module-info.java`, and Module Paths 12.2 Module Directives: `requires`, `requires transitive`, `exports`, and Qualified Exports 12.3 Reflection, Deep Encapsulation, `opens`, and Open Modules 12.4 Services in JPMS (`uses`, `provides...with`), Migration Paths, and Tooling (`jlink`, `jdeps`) 12.5 Compiling and Packaging Code: Non-Modular JARs, Modular JARs, and Migration Strategies
14 Chapter 13: Concurrency & Multithreading
13.1 Thread Fundamentals, `Runnable`, `Callable`, and Thread Lifecycle 13.2 Memory Visibility, `volatile`, Intrinsic Locks, and Synchronization 13.3 The Concurrency Framework: `ExecutorService`, Thread Pools, and `Future` 13.4 Concurrent Collections, Atomic Variables, Explicit Locks, and `CompletableFuture`
15 Chapter 14: Java I/O and NIO.2
14.1 Classical I/O: Byte and Character Streams, Readers, Writers, and Buffering 14.2 Object Serialization, `Serializable`, `transient`, and `serialVersionUID` 14.3 NIO.2 Architecture: `Path`, `Paths`, and Basic `Files` Operations 14.4 Advanced NIO.2: Directory Walking, Streams (`Files.lines`, `walk`), and `WatchService`
16 Chapter 15: Accessing Databases with JDBC
15.1 JDBC Architecture, Drivers, `DriverManager`, and `DataSource` Connections 15.2 SQL Execution: `Statement`, `PreparedStatement`, and `CallableStatement` 15.3 `ResultSet` Navigation, Data Types, and Transaction Management (Commit, Rollback, Savepoints)
17 Chapter 16: Annotations & the Java Logging API
16.1 Standard Annotations: @Override, @FunctionalInterface, @Deprecated, @SuppressWarnings, and @SafeVarargs 16.2 Java Logging API Basics: Logger, Levels, Handlers, and Configuration
3.4 Abstract Classes, Static Members, and Object Methods (`equals`, `hashCode`, `toString`)
Key Takeaways Explain This Topic AI
Abstract classes cannot be instantiated directly and may contain abstract methods; the first concrete subclass in the inheritance hierarchy must implement all inherited abstract methods.
Abstract methods cannot be declared final, private, static, or synchronized.
Static members belong to the class and are resolved at compile time; accessing static members through a null reference variable succeeds without throwing NullPointerException.
The equals(Object) contract mandates reflexivity, symmetry, transitivity, consistency, and non-nullity; overloading equals with a domain-specific parameter type fails to override Object.equals.
Overriding equals requires overriding hashCode so that equal objects consistently produce identical integer hash codes, preserving hash table functionality.
Last updated: October 2026
Abstract Classes, Static Members, and Object Methods
Abstract classes and common Object methods define the contract and behavior of Java types. Mastering abstract class constraints, static member scoping, and the contracts of equals , hashCode , and toString is essential for developing correct enterprise applications and excelling on the 1Z0-829 examination.
1. Abstract Classes and Method Mechanics
An abstract class is declared with the abstract keyword. It represents an incomplete conceptual model that cannot be instantiated directly using new .
Key Abstract Class Rules
Direct Instantiation Forbidden : Attempting new AbstractClass() causes a compile-time error: AbstractClass is abstract; cannot be instantiated .
Abstract Method Presence : If a class defines even one abstract method (or inherits an abstract method without implementing it), the class must be declared abstract .
Zero Abstract Methods Allowed : An abstract class is not required to contain abstract methods. Declaring a class abstract without any abstract methods is valid and frequently used to prevent instantiation.
Constructors and State : Abstract classes can declare constructors, instance fields, static fields, concrete instance methods, and static methods. Constructors are executed via super(...) when concrete subclasses are instantiated.
Concrete Implementation Requirement : The first concrete (non-abstract) subclass in the inheritance chain must implement all inherited abstract methods.
Abstract Method Constraints
An abstract method declares a signature followed by a semicolon, without a method body ( abstract void process(); ).
Warning
The following modifiers are illegal on abstract methods and cause compile-time errors:
final : Contradiction. abstract requires an override; final forbids it.
private : Contradiction. Subclasses cannot access private methods to provide an implementation.
static : Contradiction. static methods belong to the class and are resolved at compile time; they cannot participate in dynamic dispatch.
synchronized : Contradiction. Synchronization is an implementation detail of a method body, which an abstract method lacks. abstract class PaymentGateway {
protected String merchantId;
- public PaymentGateway(String merchantId) { // Legal constructor
- this.merchantId = merchantId;
- }
public abstract boolean processPayment(double amount); // Abstract method
- public void logTransaction(String txId) { // Concrete method
- System.out.println("Merchant " + merchantId + " tx: " + txId);
- }
- }
- 2. Static Variables and Methods
Static members belong to the class itself rather than any specific instance. They are loaded into memory when the class is initialized and shared across all instances.
Static Member Access Rules
Static members can be accessed directly using the class name: Math.max(10, 20) .
Static methods and initializers run in a class-level context without a this reference. They cannot access instance fields, invoke instance methods, or use super without creating or receiving an explicit instance.
The Null Reference Static Trap
Java permits accessing static members through an object reference variable ( instance.staticMethod() ). The compiler resolves this access using the declared type of the reference , completely ignoring the runtime object on the heap. public class Device {
- public static int deviceCount = 100;
- public static void reset() {
- System.out.print("Reset ");
- }
- public static void main(String[] args) {
- Device dev = null;
- dev.reset(); // Outputs: Reset (No NullPointerException!)
- System.out.println(dev.deviceCount); // Outputs: 100 (No NullPointerException!)
- }
- }
Even though dev is null , no NullPointerException is thrown. The compiler translates dev.reset() directly into Device.reset() and dev.deviceCount into Device.deviceCount .
3. The java.lang.Object Method Contracts
java.lang.Object is the root of the Java class hierarchy. Three of its methods are central to collection behavior and object equality: equals , hashCode , and toString .
The equals(Object obj) Contract
The default implementation in Object evaluates reference equality ( this == obj ). To compare objects based on their internal state, classes must override equals(Object) .
The general contract of equals specifies five mandatory properties for any non-null references x , y , and z :
Reflexive : x.equals(x) must return true .
Symmetric : x.equals(y) must return true if and only if y.equals(x) returns true .
Transitive : If x.equals(y) returns true and y.equals(z) returns true , then x.equals(z) must return true .
Consistent : Multiple invocations of x.equals(y) consistently return true or consistently return false , provided no fields used in the comparison are modified.
Non-nullity : For any non-null reference x , x.equals(null) must return false without throwing an exception.
Warning
Overloading vs. Overriding equals : A common exam trap involves declaring public boolean equals(Employee e) . This is an overload , not an override of public boolean equals(Object obj) . Standard collections like HashSet and ArrayList call equals(Object) ; if equals(Object) is not overridden, the collection defaults to reference equality ( == ), leading to missed matches.
The hashCode() Contract
The hashCode() method returns an integer hash code used by hash-based collections ( HashMap , HashSet , Hashtable ).
The contract specifies:
Consistency : Multiple invocations on the same object during an application run must return the same integer, provided equality-determining fields remain unmodified.
Equal Objects Must Have Equal Hash Codes : If x.equals(y) returns true , then x.hashCode() == y.hashCode() must be true .
Unequal Objects May Share Hash Codes : If x.equals(y) returns false , x.hashCode() and y.hashCode() are not required to be distinct (a hash collision). However, distinct hash codes improve hash table performance.
Important
The Golden Rule : Whenever you override equals(Object) , you must override hashCode() . If two objects are considered equal by equals , but produce different hash codes, hash-based collections will place them into different buckets, breaking lookups like set.contains(item) .
- The toString() Method
- The default implementation in Object returns: getClass().getName() + "@" + Integer.toHexString(hashCode())
Overriding toString() provides human-readable diagnostic text representing the object's state. It is invoked automatically during string concatenation ( "User: " + user ) and printing ( System.out.println(user) ).
Proper Implementation Pattern import java.util.Objects;
- public class Employee {
- private int id;
- private String department;
- public Employee(int id, String department) {
- this.id = id;
- this.department = department;
- }
- @Override
- public boolean equals(Object obj) {
- if (this == obj) return true; // Reflexive check
- if (obj == null || getClass() != obj.getClass()) return false; // Null and exact type check
- Employee other = (Employee) obj;
- return this.id == other.id && Objects.equals(this.department, other.department);
- }
- @Override
- public int hashCode() {
- return Objects.hash(id, department); // Consistent with equals
- }
- @Override
- public String toString() {
- return "Employee[id=" + id + ", department=" + department + "]";
- }
- }