Is it incorrect for Elements.hides to report that static methods in interfaces hide static methods in super-interfaces?
https://docs.oracle.com/javase/specs/jls/se11/html/jls-9.html#jls-9.4.1 discusses that it's a compile time error for static methods in interfaces to hide instance methods in super-interaces. It also mentions that interfaces don't inherit static methods, which suggests static methods in interfaces can't hide static methods in super-interfaces.
i.e. the following doesn't compile because static methods aren't inherited into interfaces, so it seems impossible for a declaration of 'f' in B to hide the one in A:
interface A {
static void f() {}
}
interface B extends A {
static void g() {
f();
}
}
Consider:
```
interface A {
static void f() {}
}
interface B extends A {
static void f() {}
}
```
```
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.List;
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.ElementScanner8;
import javax.tools.Diagnostic;
@SupportedAnnotationTypes("*")
public class P extends AbstractProcessor {
@Override
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latestSupported();
}
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
List<Element> elements = new ArrayList<>();
new ElementScanner8<Void, Void>() {
@Override
public Void scan(Element e, Void unused) {
elements.add(e);
return super.scan(e, null);
}
}.scan(roundEnv.getRootElements(), null);
for (Element a : elements) {
for (Element b : elements) {
boolean hides = processingEnv.getElementUtils().hides(a, b);
String message = String.format("hides(%s, %s) = %s\n", key(a), key(b), hides);
if (hides) {
processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, message);
}
}
}
return false;
}
private Object key(Element e) {
Deque<String> bits = new ArrayDeque<>();
do {
if (e.getSimpleName().length() > 0) {
bits.add(e.getSimpleName().toString());
}
e = e.getEnclosingElement();
} while (e != null);
return String.join(".", bits);
}
}
```
$ javac -processor P T.java
Note: hides(f.B, f.A) = true
https://docs.oracle.com/javase/specs/jls/se11/html/jls-9.html#jls-9.4.1 discusses that it's a compile time error for static methods in interfaces to hide instance methods in super-interaces. It also mentions that interfaces don't inherit static methods, which suggests static methods in interfaces can't hide static methods in super-interfaces.
i.e. the following doesn't compile because static methods aren't inherited into interfaces, so it seems impossible for a declaration of 'f' in B to hide the one in A:
interface A {
static void f() {}
}
interface B extends A {
static void g() {
f();
}
}
Consider:
```
interface A {
static void f() {}
}
interface B extends A {
static void f() {}
}
```
```
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.List;
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.ElementScanner8;
import javax.tools.Diagnostic;
@SupportedAnnotationTypes("*")
public class P extends AbstractProcessor {
@Override
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latestSupported();
}
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
List<Element> elements = new ArrayList<>();
new ElementScanner8<Void, Void>() {
@Override
public Void scan(Element e, Void unused) {
elements.add(e);
return super.scan(e, null);
}
}.scan(roundEnv.getRootElements(), null);
for (Element a : elements) {
for (Element b : elements) {
boolean hides = processingEnv.getElementUtils().hides(a, b);
String message = String.format("hides(%s, %s) = %s\n", key(a), key(b), hides);
if (hides) {
processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, message);
}
}
}
return false;
}
private Object key(Element e) {
Deque<String> bits = new ArrayDeque<>();
do {
if (e.getSimpleName().length() > 0) {
bits.add(e.getSimpleName().toString());
}
e = e.getEnclosingElement();
} while (e != null);
return String.join(".", bits);
}
}
```
$ javac -processor P T.java
Note: hides(f.B, f.A) = true
- duplicates
-
JDK-8301794 Elements.hides(m1, m2) should return false if m2 is a static method of an interface
-
- Closed
-
- relates to
-
JDK-8301794 Elements.hides(m1, m2) should return false if m2 is a static method of an interface
-
- Closed
-