Skip to content

Instantly share code, notes, and snippets.

@AppLoidx
Last active November 16, 2019 22:11
Show Gist options
  • Save AppLoidx/a69d481ee97681059155025e803358d8 to your computer and use it in GitHub Desktop.
Save AppLoidx/a69d481ee97681059155025e803358d8 to your computer and use it in GitHub Desktop.
java.lang.IllegalAccessError in runtime
package tasks;
/**
* @author Arthur Kupriyanov
*/
class C {
private boolean getBoolean() {
return false;
}
// but it works when we declare getBoolean method as public
}
interface I {
default boolean getBoolean() {
return true;
}
}
class D extends C implements I {}
public class IllegalAccessError {
public static void main(String[] a) {
foo(new D()); // java.lang.IllegalAccessError in Runtime
}
public static void foo(I i) {
System.out.println(i.getBoolean());
}
}
@AppLoidx
Copy link
Author

Такое поведение JVM объясняется тем, как происходит поиск целевого метода для инструкции invokeinterface. Согласно спецификации, в первую очередь просматриваются instance-методы класса и всех супер-классов, и только затем ищется подходящий default метод среди супер-интерфейсов, при этом приватность найденного метода проверяется только после завершения всего процесса.

Поэтому, если вы измените метод getBoolean в классе C на public, то получите false. А при приватном, у вас выбросится IllegalAccessError

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment