Ehrlich gesagt hatte ich nicht selbst ausprobiert, ob sich das Verhalten in diesem Fall “spürbar” ändert (hab’ hier gerade kein JDK8), aber es gab einen Grund zu der Annahme. Zumindest die Spezifikation hat sich geändert, dewswegen sollte der Hinweis auf JDK <=7 sicherstellen, dass nicht jemand sich auf etwas falsches bezieht.
Wie auch immer: Die Lösung ist
5. Compilerfehler beim Aufruf von methodA (aber nicht bei methodB)
Der Grund dafür liegt darin, wie Java die “passende” Methode für einen bestimmten Aufruf mit bestimmten Parametern herausfindet. Das läuft grob in mehreren Phasen ab:
Phase 1: Identify Matching Arity Methods Applicable by Subtyping
Phase 2: Identify Matching Arity Methods Applicable by Method Invocation Conversion
Phase 3: Identify Applicable Variable Arity Methods
In Phase 1 wird geschaut, ob es eine Methode gibt, die so viele formale Parameter hat, wie beim Aufruf Argumente angegeben wurden, und die Typen der Argumente zu den Parametern passen, wenn man davon ausgeht dass man auch Subtypen übergeben kann. Wenn man eine Methode hat, die eine Number
erwartet, und man die so eine Methode mit einem Byte
aufruft, dann passt das.
In Phase 2 wird geschaut, ob es eine Methode gibt, die so viele formale Parameter hat, wie beim Aufruf Argumente angegeben wurden, und die Typen der Argumente zu den Parametern passen, wenn man davon ausgeht dass, dass es weitere Konvertierungen geben kann. Wenn man eine Methode hat, die einen int
erwartet, und man die so eine Methode mit einem Integer
aufruft, dann passt das, weil dafür eine Unboxing-Conversion von Integer
nach int
durchgeführt werden kann.
Diese beiden Phasen spielen für die methodA
aber keine Rolle: Dort wird direkt bei Phase 3 gestartet, weil es eine “varargs”-Methode ist. Dann wird allerdings nicht mehr zwischen den Methoden unterschieden, die “per Subtyping” passen, und denen, die “per Method Invocation Conversion” passen, sondern nur letzteres. Das heißt, dort gibt es auf einen Schlag zwei passende Methoden - und da es dort keine “spezifischere” gibt, wird der Aufruf uneindeutig.