mockito: Wie passen Varargs in Java 8?

8

Ich arbeite daran, ein Projekt von Java 7 auf 8 zu migrieren, und habe einen Kompilierungsfehler in einem Mockito-Fall bekommen, wenn es mir schwer fällt, es aufzuspüren:

%Vor%

gibt mir einen Kompilierungsfehler von:

%Vor%

Dieser Fehler tritt in Build 1.8.0-b128 auf, aber nicht in 1.7.0_45. Ich benutze Mockito 1.9.5.

Was ist der richtige Weg, anyVarArg() argument matching in Java 8 zu verwenden?

    
Paul Sanwald 24.03.2014, 21:10
quelle

1 Antwort

7

Das Problem besteht darin, dass die Typinferenz verbessert wurde. anyVararg() ist eine generische Methode, die Sie jedoch in einem geschachtelten Methodenaufruf verwenden. Vor Java 8 mussten die Einschränkungen der Typinterferenz die Methode <T> T anyVararg() like <Object> Object anyVararg() erzwingen, wenn sie als Argument für einen anderen Methodenaufruf verwendet wurde, ohne explizite Typargumente einzufügen.

Also nur query(String, ResultSetHandler, Object...) übereinstimmend, da das dritte Argument als vom Typ Object behandelt wurde.

Aber jetzt mit Java 8 Typ Inferenz arbeitet mit verschachtelten Methodenaufrufen. Da für <T> T anyVararg() der Typparameter <T> nur irgendetwas sein kann, kann er auch ResultSetHandler sein. Also query(String,Object,ResultSetHandler) ist jetzt auch ein Matchkandidat.

(Ich habe den Typparameter <T> aus dem äußeren Aufruf in beiden Fällen weggelassen, um es weniger verwirrend zu machen)

Da wir jetzt zwei mögliche Übereinstimmungen haben, gilt hier das normale Verfahren der Methodenauswahl. Und ja, es ist mehrdeutig. Der erste Parameter ist derselbe, String , aber für die anderen beiden ist ResultSetHandler spezifischer als Object , aber während ein Kandidat einen spezifischeren Typ für den zweiten Parameter akzeptiert, tut der andere für den dritten (und folgt ups).

Es ist klar, dass Typparameter, die den Rückgabetyp einer Methode zu etwas einfachem machen, eine Quelle der Mehrdeutigkeit sind, aber APIs wie Mockito, die solche Methoden enthalten, sind ein Eckfall der Java-Programmierung. Sie müssen einen Typ entweder über den generischen Weg Matchers.<Desired>anyVararg() oder über den Typ Cast (Desired)anyVararg() erzwingen.

    
Holger 14.05.2014, 10:03
quelle

Tags und Links