Back to Predict the Output
Q2Question 2 of 10

Predict the output: parent reference calling static method

Key Concepts
  • Static methods are resolved by REFERENCE type (compile time), not object type (runtime)
  • Parent p = new Child(); p.staticMethod() calls Parent's version, not Child's
  • This is method hiding, not overriding – no polymorphism for statics
  • Understanding this concept is essential for Java interviews at senior level
  • This concept directly affects how banking applications manage resources

Definition

The parent's static method is called because static methods are resolved by reference type at compile time, not by object type at runtime.

Static method hiding:

DIAGRAM
- `Parent p = new Child();` – reference type is Parent.
- `p.greet()` (static) → resolved by reference type → Parent.greet().
- Instance methods would call Child's version (polymorphism). Static methods do not participate in polymorphism.

See Q12 (Keywords: static) and Q37 (Can main be overridden) for full explanation.

Understanding the Concepts

The code

JAVA
class Parent {
    static void greet() { System.out.println("Parent"); }
}
class Child extends Parent {
    static void greet() { System.out.println("Child"); }
}

Parent p = new Child();
p.greet();

Output

TEXT
Parent

Why?

Static methods are resolved at compile time by the reference type. p is declared as Parent, so Parent.greet() is called regardless of the actual object type (Child).

If greet() were an instance method with @Override, the output would be "Child" (polymorphism).

What are common mistakes?

A common mistake is assuming the output without tracing through the code step by step.

Wrong approach:

JAVA
package com.bank.quiz;

public class OutputQuiz {
    public static void main(String[] args) {
        // Developers often guess the wrong output
        // because they skip the step-by-step evaluation
        String result = "Balance: " + 100 + 50;
        System.out.println(result);
        // Many guess: "Balance: 150"
        // Actual: "Balance: 10050" (left-to-right string concat)
    }
}

Correct reasoning:

JAVA
package com.bank.quiz;

public class OutputQuiz {
    public static void main(String[] args) {
        // Step 1: "Balance: " + 100 = "Balance: 100" (String + int = String)
        // Step 2: "Balance: 100" + 50 = "Balance: 10050" (String + int = String)
        String result = "Balance: " + 100 + 50;
        System.out.println(result);  // Balance: 10050

        // To get arithmetic: use parentheses
        String correct = "Balance: " + (100 + 50);
        System.out.println(correct);  // Balance: 150
    }
}

Always trace left to right and remember that once a String is involved in concatenation, everything after it becomes string concatenation too.

What should a senior engineer know?

A senior engineer working on banking systems should understand the production implications of this concept.

  • Performance impact. Measure with JMH before making assumptions about which approach is faster.
  • Thread safety. In a multi-threaded banking service processing concurrent transactions, always consider whether the approach is thread-safe.
  • Memory footprint. Use JFR and VisualVM to measure actual memory usage under realistic banking workloads.
  • Monitoring. Set up JMX metrics and alerts for production banking applications.
JAVA
package com.bank.monitoring;

import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;

public class MemoryMonitor {
    public static void printMemoryUsage() {
        MemoryMXBean mem = ManagementFactory.getMemoryMXBean();
        System.out.println("Heap: " + mem.getHeapMemoryUsage());
        System.out.println("Non-Heap: " + mem.getNonHeapMemoryUsage());
    }
}

What are the edge cases?

Edge cases can cause unexpected behavior in banking applications. Here are some to watch for.

JAVA
package com.bank.edge;

public class EdgeCaseDemo {
    public static void main(String[] args) {
        // Edge case 1: null handling
        String accountId = null;
        try {
            System.out.println(accountId.length());
        } catch (NullPointerException e) {
            System.out.println("Null account ID");
        }

        // Edge case 2: empty vs null
        String emptyId = "";
        System.out.println(emptyId.isEmpty());  // true
        System.out.println(emptyId == null);     // false

        // Edge case 3: boundary values
        java.math.BigDecimal zero = java.math.BigDecimal.ZERO;
        java.math.BigDecimal negativeBalance = new java.math.BigDecimal("-0.01");
        System.out.println(zero.compareTo(negativeBalance) > 0);  // true
    }
}
TEXT
Null account ID
true
false
true

Always test with null values, empty strings, boundary values, and negative amounts in banking applications.

What are common interview follow-up questions?

Interviewers often follow up with these related questions:

  • How does this concept apply to a high-throughput banking transaction system?
  • What are the performance implications in a production environment?
  • How would you debug issues related to this concept?
  • What tools would you use to monitor this in production?
  • How does this behave differently in Java 8 vs Java 17+?

When answering follow-up questions, always relate your answer back to practical experience. For example, at National Bank of India, Rajesh debugged a production issue related to this concept by using JFR recordings and heap dumps. Providing concrete examples from banking systems shows the interviewer that you understand both the theory and the practice.

Visual Overview

DIAGRAM
  Parent p = new Child();
  p.greet();  (static)
    → compile time: reference type = Parent
    → calls Parent.greet()
    → output: "Parent"

  If instance method:
    p.greet();  (instance, overridden)
    → runtime: object type = Child
    → calls Child.greet()
    → output: "Child"

Key Takeaway

Static methods are resolved by reference type at compile time. Parent p = new Child(); p.staticMethod() calls the Parent's version. This is hiding, not overriding.

One sentence to remember: static = reference type wins (compile time), instance = object type wins (runtime).

---

Share
Use ← → arrow keys to navigate