Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling default method in interface when having conflict with private method

Consider below class hierarchy.

class ClassA {
    private void hello() {
        System.out.println("Hello from A");
    }
}

interface Myinterface {
    default void hello() {
        System.out.println("Hello from Interface");
    }
}

class ClassB extends ClassA implements Myinterface {

}

public class Test {
    public static void main(String[] args) {
        ClassB b = new ClassB();
        b.hello();
    }
}

Running the program will give following error :

Exception in thread "main" java.lang.IllegalAccessError: tried to access method com.testing.ClassA.hello()V from class com.testing.Test
at com.testing.Test.main(Test.java:23)
  1. This is all because I marked ClassA.hello as private.
  2. If I mark ClassA.hello as protected or remove the visibility modifier(i.e. making it default scope), then it shows a compiler error as : The inherited method ClassA.hello() cannot hide the public abstract method in Myinterface

However, as per exception stacktrace above, I get a runtime IllegalAccessError.

I couldn't get why this is not detected at compile time. Any clues ?

like image 868
CourseTriangle Avatar asked Apr 02 '18 11:04

CourseTriangle


People also ask

How do you resolve default method conflicts in interface?

Rules for Default Method Conflict Resolution Classes will always win. If a class extends a parent class and implements one or more interfaces, the default method in the class or a superclass will take priority. Otherwise the subinterfaces will take the next level of precedence.

Can we call default method of interface?

Interfaces can have default methods with implementation in Java 8 on later. Interfaces can have static methods as well, similar to static methods in classes. Default methods were introduced to provide backward compatibility for old interfaces so that they can have new methods without affecting existing code.

Can we override default method in interface?

If you have default method in an interface, it is not mandatory to override (provide body) it in the classes that are already implementing this interface. In short, you can access the default methods of an interface using the objects of the implementing classes.

What is the actual use of default method in interface?

Default methods allow an interface to define an implementation for a method so that when a class implements the interface, it does not need to provide its own version of the method, helping APIs and libraries move forward without always needing to make breaking changes when interfaces require additional methods.


1 Answers

Update: Seems like it's really a bug.

A class or super-class method declaration always takes priority over a default method!

default hello(...) method from the Myinterface allows you to write without errors:

ClassB b = new ClassB(); b.hello(); 

Until runtime, because at runtime hello(...) method from the ClassA takes the highest priority (but the method is private). Therefore, IllegalAccessError occurs.

If you remove the default hello(...) method from the interface, you get the same illegal access error, but now at compile time.

like image 59
Oleksandr Pyrohov Avatar answered Oct 13 '22 10:10

Oleksandr Pyrohov