Back to Blog
Java

Accessing Hidden Fields with the super Keyword in Java

Learn how the super keyword accesses hidden superclass fields in Java, the difference between field hiding and method overriding, and when to use super.field.

Java inheritancesuper keywordfield hidingconstructor chainingJava object-oriented programming
Java code showing a subclass using the super keyword to access a parent class field

When a subclass declares a field with the same name as a field in its superclass, the subclass field hides the superclass field. Using the super keyword as super.field lets you reference that hidden field when you need the superclass version. This article explains how field hiding works, how super accesses the hidden field, and where this pattern can cause problems.

How Field Hiding Works

Field hiding occurs when a subclass declares a field with the same name as a field in its superclass. The two fields are independent storage locations; the subclass field does not override the superclass field, it merely hides it. Consider this example:

class Parent { String name = "Parent"; } class Child extends Parent { String name = "Child"; }

Here, Child has its own name field. The Parent field still exists, but any unqualified reference to name inside Child resolves to the subclass field. To access the hidden superclass field, you use super.name.

Using super to Access a Hidden Field

Inside an instance method of the subclass, super.fieldName refers to the field declared in the immediate superclass. For example:

class Parent { String name = "Parent"; } class Child extends Parent { String name = "Child"; void printNames() { System.out.println(name); // Child System.out.println(super.name); // Parent } }

Calling new Child().printNames() outputs:

Child Parent

The super keyword does not change Java's access rules. It can reach a hidden field only when the subclass can normally access that field—for example, a protected field, or a package-private field when the subclass is in the same package. A private field is not visible to subclasses, so super cannot bypass encapsulation; trying to access it causes a compile-time error.

When super.field Can Be Useful

Accessing a hidden field with super can be useful when a subclass needs to incorporate the superclass's state into its own logic. For instance, a subclass might extend a configuration object and need to refer to the original value during initialization or in a method that combines both fields.

class BaseConfig { int timeout = 1000; } class AdvancedConfig extends BaseConfig { int timeout = 5000; int getEffectiveTimeout() { // Use the subclass value if set, else fall back to the superclass value return this.timeout > 0 ? this.timeout : super.timeout; } }

But this pattern is rare. In well-designed code, fields are usually private and accessed through methods, so field hiding is less common. The primary use of super in Java is for constructor chaining and calling overridden methods, not field access.

Constructor Chaining and the super Keyword

The most frequent use of super is in constructors. A subclass constructor must call one of the superclass constructors, either implicitly or explicitly. The call must be the first statement in the constructor.

class Parent { private String name; Parent(String name) { this.name = name; } } class Child extends Parent { private int age; Child(String name, int age) { super(name); // must be the first statement this.age = age; } }

If you do not explicitly call super(...), the compiler inserts a call to the no-argument constructor of the superclass. If the superclass has no accessible no-argument constructor, the code will not compile.

super() is not the same as super.field; the former is a constructor invocation, while the latter is a field access. Both use the super keyword but serve different purposes.

Method Overriding vs. Field Hiding

It is important to distinguish method overriding from field hiding. Methods are polymorphic; fields are not. When you call an overridden method, the JVM resolves the method call at runtime based on the object's actual type. Field access, however, is resolved at compile time based on the declared type of the reference.

Consider:

class Parent { String name = "Parent"; void printName() { System.out.println(name); } } class Child extends Parent { String name = "Child"; @Override void printName() { System.out.println(super.name); // explicitly uses the Parent field } }

If you have a Parent reference pointing to a Child object and call printName(), the overridden method runs. If that method had not used super, it would reference the field based on the enclosing class, not the runtime type. This subtlety leads to bugs when developers expect fields to behave like methods.

Common Pitfalls and Misconceptions

One common mistake is expecting super to work outside an instance context, such as in a static method. Static methods do not have a this reference, so super is not allowed; it results in a compile-time error.

Another pitfall is assuming that super can access a field of a grandparent class directly. super always refers to the immediate superclass. If the immediate superclass also hides a field from a higher ancestor, you cannot use super.super.field—Java does not support such syntax. To reach a field two levels up, you need accessor methods or a different design.

Also note that super does not bypass encapsulation. If the superclass field is private, it is not accessible at all, even with super. The same access rules apply as for normal member access.

Performance and Maintainability Considerations

Field access with super has no meaningful runtime performance cost; the JVM resolves field accesses efficiently. The real cost is in maintainability. Overusing field hiding and super can make code confusing because the same field name refers to different variables depending on context. Debugging becomes harder when reading code because it is not immediately obvious which field is being referenced.

A better approach is to avoid field hiding altogether by:

  • Giving subclass fields distinct names
  • Using private fields and protected accessor methods (getters/setters) in the superclass
  • Using constructors or methods to pass the superclass state to the subclass when needed

That said, there are legitimate uses, such as when you are extending a third-party class where you cannot modify the superclass to add getters. In such cases, super.field provides a direct way to access the hidden field, but you must be careful about the access level and the immediate-superclass limitation.

Choosing Between super.field and Getters

When you need the superclass's field value, you have two options: direct access with super.field or calling a getter method. The choice depends on the situation:

  • If the superclass exposes a public getter, use the getter. It respects encapsulation and allows the superclass to change its internal representation later.
  • If no getter exists and the field is accessible to the subclass (protected, package-private when the subclass is in the same package, or public), super.field is usually the most direct way to access the superclass version without modifying the superclass.

Consider the trade-offs:

ApproachEncapsulationDependency on field nameRuntime costBest used when
super.fieldWeakHighNoneNo getter available; field is protected/package
Getter methodStrongLowMinimalAccessor exists; want to preserve flexibility
Distinct field nameStrongNoneNoneYou control both classes and can rename

For most new code, prefer getters or renaming fields. Reserve super.field for cases where you are extending external or legacy code and cannot alter the superclass.

When Field Hiding Is Unavoidable

Sometimes field hiding arises in constrained code. You might be working with generated code or a framework where field names are prescribed and you cannot rename the superclass field. In those situations, super.field is the tool that lets you access the superclass's version of the hidden field.

Even then, you can mitigate confusion by:

  • Documenting why the field is hidden
  • Adding comments near the super.field usage
  • Keeping the logic that accesses the hidden field minimal and localized

This reduces the chance of a future maintainer misreading the code. The cost is mostly cognitive, not runtime.

Accessing Hidden Superclass Fields with super in Java | RYUSLOG DEV