Interview Questions 1 - 10  «Prev Next»

Java SE 25: Equality, Polymorphism, and Annotations

Review value equality, mutable text, abstraction, interface methods, boxing, metadata, and Object references with current Java SE 25 terminology.

  1. What does it mean for two Java objects to be equal?

    Answer: It depends on the type's equality contract. Object.equals uses identity, while String and many value types compare selected state. Equal does not necessarily mean every field is identical. Value equality must obey reflexivity, symmetry, transitivity, consistency, and comparison with null returning false.

    A matching hashCode is also required. Records generate equality and hashing based on their components, but referenced arrays still have their own identity-based equals unless you design a different contract.

  2. How do String and StringBuffer differ?

    Answer: String is immutable; operations do not modify its character sequence. StringBuffer is mutable and synchronizes many operations. StringBuilder is a mutable alternative without that synchronization and is useful for text assembly confined to one thread.

    A series of individually synchronized StringBuffer operations is not automatically atomic. String concatenation with + is supported by the language; Java does not offer general user-defined operator overloading.

  3. What is an example of runtime polymorphism?

    Answer: A reference of an interface or superclass type can refer to different implementations. Calling an overridden instance method selects behavior based on the object's runtime class. Static method hiding and overload selection are different mechanisms.

    public class AnimalDispatch {
        interface Animal { String speak(); }
        static final class Dog implements Animal {
            @Override public String speak() { return "Woof"; }
        }
        static final class Cat implements Animal {
            @Override public String speak() { return "Meow"; }
        }
        public static void main(String[] args) {
            Animal[] animals = {new Dog(), new Cat()};
            for (Animal animal : animals) {
                System.out.println(animal.speak());
            }
        }
    }
    

    An override must follow signature, access, return-type, and exception rules. Reference return types may be covariant; the return type need not always be textually identical to the overridden declaration.

  4. What is encapsulation?

    Answer: It groups state and behavior behind a controlled boundary. Private fields and meaningful methods can protect invariants, such as a quantity never being negative. Merely generating public getters and setters for every field does not guarantee that the design hides representation or protects its rules.

  5. What is an abstract class for?

    Answer: It supplies a base type and optionally shared state or partial implementation. It cannot be directly instantiated. A concrete subclass must provide implementations for any remaining abstract methods. An abstract class can contain constructors and implemented methods, and can be abstract even without abstract methods.

  6. Are all interface methods abstract?

    Answer: No. Java SE 25 interfaces can declare public abstract methods, default instance methods, static methods, and private helper methods. Private interface methods have bodies and support implementation reuse inside the interface; they are not methods that implementing classes must expose.

    Default methods can be inherited, subject to conflict rules. Static interface methods are invoked through the interface type rather than inherited as instance behavior.

  7. What does implements mean on a class declaration?

    Answer: It declares that the class is a subtype of the listed interface and commits it to that contract. A concrete class must have suitable implementations for all required abstract methods, whether declared locally or inherited. An abstract implementing class may defer some methods to concrete subclasses.

  8. What are autoboxing and unboxing in Java SE 25?

    Answer: Autoboxing converts primitive values to corresponding wrapper references when the context permits it; unboxing converts them back. For example, Integer boxed = 100; int value = boxed; performs both. Unboxing null throws NullPointerException.

    Use boxing or valueOf instead of deprecated wrapper constructors. Wrapper identity is not numeric equality, and boxing does not allow every numeric conversion: an int cannot be assigned directly to a Long reference.

  9. How has annotation metadata evolved since early Java releases?

    Answer: Java 5 introduced annotations. Java 8 added repeatable annotations and broader type-use annotations. Later APIs expose metadata for modules, record components, and sealed hierarchies. These are related inspection facilities, not evidence that annotation processing automatically changes all program behavior.

    Retention determines whether annotations are available only in source, in class files, or at runtime. Compilers, processors, and frameworks can interpret them; an annotation without a consumer is not executable logic. Java SE 25 supports reflection APIs such as getRecordComponents and getPermittedSubclasses.

  10. What is special about Object as a reference type?

    Answer: An Object variable can hold a reference to any class instance or array, or null. It is the variable's reference value that changes when assigned another object; the original object does not transform into that new type. Primitive values require boxing to be assigned to Object.

    An Object-typed reference directly exposes Object methods, while overriding still dispatches dynamically. Use a checked cast or pattern matching when more specific operations are required.

References: Java SE 25 Language Specification, Object, StringBuffer, StringBuilder, Retention, Class.