2015-06-20 4 views
5

Ich habe dies in der Mitte einer Entwicklung festgestellt.Warum arbeitet der Ternary-Operator nicht innerhalb eines Methodenarguments in Java

Warum arbeitet der Ternary-Operator nicht innerhalb eines Methodenarguments? Hier ist es eindeutig oder (sonst) String.

class A{ 

    public static boolean opAlpha(InputStream inputStream) { 

     // Do something 

     return true; 

    } 

    public static boolean opAlpha(String arg) { 

     // Do something else 

     return true; 
    } 

    public static void main(String[] args) throws Exception { 

     boolean useIsr = true; 

     InputStream inputStream = null; 
     String arg = null; 

//  boolean isTrue = useIsr ? A.opAlpha(inputStream): A.opAlpha(arg); // This is OK. 
     boolean isTrue = A.opAlpha(useIsr ? inputStream : arg); // This is not. (Error : The method opAlpha(InputStream) in the type A is not applicable for the arguments (Object)) 

    } 

} 
+1

Hier wird kein Bediener überlastet. – EJP

+2

Und meine übliche pedantische Bemerkung: Es ist nicht der ternäre Operator, es ist der [* bedingte Operator *] (https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls- 15,25). Es ist wahr, dass es ein ternärer Operator ist (ein Operator, der drei Operanden akzeptiert), und es ist wahr, dass es das einzige Java ist, aber theoretisch könnte es irgendwann andere geben ... :-) –

+0

Danke T.J. Hab deinen Punkt! – namalfernandolk

Antwort

6

Der Ausdruck useIsr ? inputStream : arg ist vom Typ Object, denn das ist die übliche Art von inputStream (InputStream) und arg (String) ist.

Sie haben keine opAlpha Methode, die eine Object akzeptiert. Daher der Kompilierungsfehler.

+0

@Namalak 'Das bedeutet, dass es die Methoden abhängig vom Klassentyp aufruft. Nicht der Objekttyp'. Ich weiß nicht, was du damit meinst. Wenn Sie gemeint haben, dass es die Methoden abhängig vom Kompilierzeittyp der Argumente und nicht vom Laufzeittyp aufruft, dann sind Sie richtig. Der Compiler entscheidet zur Kompilierzeit, welche überladene Version der Methode aufgerufen wird. – Eran

+0

Das ist wahr Eran. Habe die generellen Methoden, die Prinzipien überladen, für eine Weile vergessen. Ich habe meinen Kommentar gelöscht, nachdem ich das notiert habe. Ich habe Ihren Kommentar nicht notiert, wenn Sie ihn löschen. Ich werde versuchen, es wieder ablaufen zu lassen, da du das geantwortet hast. Danke trotzdem für die Antwort. Es hat mich durchgereicht! – namalfernandolk

7

Der Compiler muss entscheiden, welche Methode überlastet es in Ihrem main Methode aufrufen sollte. Der Methodenaufruf muss in den kompilierten Bytecode main gestellt und zur Laufzeit nicht entschieden werden.

In der Tat, obwohl Sie wissen, dass die Art des bedingten Ausdrucks ist entweder InputStream oder String, sieht der Compiler den Typ als Object. Von Section 15.25.3 of the Java Language Specification:

Ein Referenzbedingungsausdruck ist eine Poly-Expression, wenn es in einer Zuweisungskontext oder einen Aufrufkontext erscheint (§5.2 §5.3.). Ansonsten ist es ein eigenständiger Ausdruck.

Wo ein Poly Referenzbedingungsausdruck mit Zielart T in einem Zusammenhang mit einer bestimmten Art erscheint, der zweiten und der dritten Operanden Ausdrücke erscheinen in ähnlicher Weise in einem Rahmen von der gleichen Art mit Zielart T.

Die Art der Ein bedingter PolyReferenzausdruck ist derselbe wie sein Zieltyp.

Der Typ einer eigenständigen Referenzbedingungsausdruck wird wie folgt bestimmt:

  • Wenn die zweiten und dritten Operanden denselben Typ haben (der die Null Typ sein kann), so dass der Typ der ist bedingter Ausdruck.

  • Wenn der Typ eines der zweiten und dritten Operanden der Null-Typ ist und der Typ des anderen Operanden ein Referenztyp ist, dann ist der Typ des bedingten Ausdrucks dieser Referenztyp.

  • Ansonsten sind der zweite und der dritte Operand vom Typ S1 bzw. S2. Sei T1 der Typ, der sich aus der Anwendung der Box-Konvertierung auf S1 ergibt, und sei T2 der Typ, der sich aus der Anwendung der Box-Konvertierung auf S2 ergibt. Der Typ des bedingten Ausdrucks ist das Ergebnis der Anwendung der Capture-Konvertierung (§5.1.10) auf lub (T1, T2).

wo lub(T1, T2) steht für "Least Upper Bound" von Typen T1 und T2. Der am wenigsten obere Typ von InputStream und String ist Object.

+0

Danke Manuti. Ihre Antwort ist sehr informativ und ich bin der festen Überzeugung, dass SOF eine Option haben muss, um mehr als eine Antwort zu akzeptieren. – namalfernandolk

Verwandte Themen