2013-04-12 15 views
20

Gibt es eine Möglichkeit, eine Java-Ternäroperation auszuführen, ohne eine Aufgabe oder einen Weg zu tun, die Assimilation zu fälschen?Java Ternary ohne Zuordnung

Ich mag, wie prägnanter ternärer Code aussieht, wenn man eine Reihe von if/then/elns macht.

Ich hoffe, in der Lage zu sein, eine von zwei void-Funktionen basierend auf einer booleschen Algebra-Anweisung aufzurufen.

Etwas wie:

(bool1 && bool2) ? voidFunc1() : voidFunc2();

Meine Funktionen sind von Rückgabetyp void, also wenn es eine Möglichkeit, zu fälschen diese in einer Zuweisung ist, damit es funktioniert, dann ich "m in Ordnung mit, dass .. obwohl würde. ich mag, um zu sehen, wie es zu tun :)

+0

@VenomFangs Sie können Ihre Funktionen so ändern, dass immer ein konstanter Wert zurückgegeben wird, und diesen Rückgabewert einer Dummy-Variablen zuweisen. Aber es lohnt sich nicht - der Code wird dumm aussehen, fürchte ich. Besser, es zu tun, wie Sie bereits wissen, dass Sie tun sollten. –

Antwort

17

Nein, das geht nicht. Die spec says so.

Der Bedingungsoperator hat drei Operandenausdrücke. ? erscheint zwischen dem ersten und zweiten Ausdruck und: erscheint zwischen dem zweiten und dritten Ausdruck .

Der erste Ausdruck muss vom Typ boolean oder Boolean sein, oder es tritt ein Fehler bei der Kompilierung auf.

Es ist ein Fehler bei der Kompilierung für entweder den zweiten oder dritten Operanden Ausdruck ein Aufruf einer Hohlraum Methode.

[EDIT]

Da Sie über Reflexion gefragt, hier ist eine Lösung. Ich empfehle das nicht. Ich poste es nur, weil du gefragt hast.

public class MyCall 
{ 

    public void a(){System.out.println("a");} 
    public void b(){System.out.println("b");} 

    public static void main(String... args) 
    { 
     new MyCall().go(); 
    } 

    public void go() 
    { 
     Class<? extends MyCall> class1 = this.getClass(); 
     Method aMethod = class1.getMethod("b", null); 
     Method bMethod = class1.getMethod("a", null); 
     Object fake = false ? aMethod.invoke(this, null) : bMethod.invoke(this, null); 
     Object fake2 = true ? aMethod.invoke(this, null) : bMethod.invoke(this, null); 
    } 
} 

Am Ende des Tages Sie haben sich zu fragen, ob succint sein Ihres Codes Lesbarkeit verbessert (man denke foreach-Schleife). Keine dieser Lösungen verbessert die Lesbarkeit des Codes IMHO. Wenn ich du wäre, würde ich lieber mitgehen.

if(condition) 
    a(); 
else 
    b(); 

Ich bin eigentlich für einschließlich Klammern, auch wenn Schleifen nur eine einzige Zeile enthalten, aber da Sie nach klarem Code fahren, sollte das Snippet oben tun.

+0

Irgendwelche Gedanken zur Reflexion kommentieren in: http://stackoverflow.com/questions/4830843/in-java-is-it-possible-to-cast-to-void -nicht-void –

+0

Gibt es eine Möglichkeit, die Leere auf null zurückzusetzen und dann einem Objekt null zuzuordnen? –

+2

Bearbeitete meine Antwort mit einer reflektierenden Lösung. Für akademische Zwecke natürlich :) –

8

Nein, Sie können dies wie dies nicht.

Sie können diesen Stil bevorzugen, wenn nicht mag es mehr Aussagen machen.

if(bool1 && bool2) voidFunc1(); else voidFunc2(); 

Im ternären Operator müssen Operanden nicht-void Ausdrücke sein; d.h. sie müssen einen tatsächlichen Wert erzeugen.

+0

Ich mag diese Präsentation ... Ich werde diese Antwort akzeptieren, wenn niemand mir einen Weg zeigen kann, dies zu tun. Z.B. Durch die Reflektion von void zu null ... etc. –

1

Wenn Sie wirklich wirklich terny Operation verwenden möchten, dann gibt es einen Hack. ABER das ist sehr schlechter Code, der nur dazu gedacht ist, Sprachfähigkeiten zu zeigen. Ich würde es nie empfehlen, diesen Code in Produktion zu bringen oder sogar Ihren Freunden zu zeigen.

int dummy = (bool1 && bool2) ? new Object(){ 
     public int hashCode() { 
      yourFunction1(); 
      // ... 
      yourFunctionN(); 
      return 0; 
     }; 
    }.hashCode() : new Object(){ 
     public int hashCode() { 
      yourAnotherFunction1(); 
      // ... 
      yourAnotherFunctionN(); 
      return 0; 
     }; 
    }.hashCode(); 
1

Gibt es eine Möglichkeit, eine Java-ternäre Operation zu tun, ohne einen Auftrag oder Art und Weise zu fälschen die Zuordnung zu tun?

OK, also, wenn Sie schreiben eine Erklärung wie folgt aus:

(bool1 && bool2) ? voidFunc1() : voidFunc2(); 

gibt es zwei verschiedene Probleme mit dem Code:

  1. Die 2. und 3. Operanden eines bedingten Ausdrucks können keine Aufrufe von void-Methoden sein. Referenz: JLS 15.25.

  2. Ein Ausdruck ist keine Anweisung, es sei denn, es ist entweder ein Zuweisungsausdruck oder ein Methodenaufruf oder eine Objekterzeugung. Referenz: JLS 14.8.

In der Tat, die zweite dieser Probleme ist ein Syntax Fehler und ich würde alle Mainstream-Java-Compiler erwarten, dass es zu berichten, anstatt das erste Problem. Das erste Problem würde sich nur offenbaren, wenn Sie so etwas wie dies tat:

SomeType dummy = (bool1 && bool2) ? voidFunc1() : voidFunc2(); 

oder

gobble((bool1 && bool2) ? voidFunc1() : voidFunc2()); 

wo gobble ist eine Methode, die nichts tut ... außer „verbrauchen“, um den Wert ihres Arguments.

AFAIK, gibt es keinen Kontext, in dem der ursprüngliche Ausdruck akzeptabel ist.


1 - "Die Bedingung" ist der primäre Begriff für dieses Konstrukt in der Java Language Specification verwendet. Es wird im Oracle Java Tutorial als "ternärer Bedingungsoperator" bezeichnet.