Description
It appears that there is no way to override Java methods which have "incorrectly" typed (from Scala's perspective) overrides in the superclass even though the superclass's override is allowed by the Java compiler. Specifically javax.swing.DefaultListCellRenderer.getListCellRendererComponent
's first argument is JList<? extends E>
in ListCellRenderer<E>
, but JList<?>
in DefaultListCellRenderer
which implements ListCellRenderer<Object>
. I suspect that the Java type system allows this, since for Java ? extends Object
is equivalent to ?
.
This is actually a very old issue from the Scala 2.9 days. The Java code is questionable, but it is accepted by the Java compiler and is still present in OpenJDK 14. Scala 2.11 also rejects this code with a similar error.
minimized code
import javax.swing._
import java.awt._
class DuplicateSymbolError_DirectSuperclass extends DefaultListCellRenderer() {
override def getListCellRendererComponent(list: JList[_ <: Object], value: Object, index: Int, isSelected: Boolean, cellHasFocus: Boolean): Component = ???
}
class DuplicateSymbolError_IndirectInterface extends DefaultListCellRenderer() {
override def getListCellRendererComponent(list: JList[_], value: Object, index: Int, isSelected: Boolean, cellHasFocus: Boolean): Component = ???
}
expectation
I would expect some class declaration overriding this method to be accepted by the Scala compiler. I would select DuplicateSymbolError_IndirectInterface
myself, but I'm not picky. Currently (and in Scala 2.11) both are rejected.
Or failing that Scala could produce an error message hinting that the Java classes may have inconsistent types to simplify the debugging process for programmers who encounter this.
PS: In this specific case, the work around is to use composition instead of inheritance. But, if some of the superclass called the problem method, there would be no work around (other than a hacky class written in Java to forward the virtual call to the wrapper).