Frage Können Sie eine Variable in einer if-Klausel speichern?


Ich warte auf eine "Nein" Antwort auf diese Frage.

Ich war interessiert, ob Sie eine Variable gleichzeitig speichern können, wenn Sie sie in einer if-Klausel überprüfen.

Sagen wir, ich habe diesen Code.

if(foo!=null){
  if(foo.getBar()!=null){
    Bar bar = foo.getBar();
    System.out.println("Success: " + bar);
  } else {
    System.out.println("Failure.");
  }
} else {
  System.out.println("Failure.");
}

Ich handle jetzt auf "Ausfall" -Status unabhängig, auch wenn das Ergebnis gleich ist. Ich könnte sie so zusammenbekommen:

if(foo!=null && foo.getBar()!=null){
  Bar bar = foo.getBar();
  System.out.println("Success: " + bar);
} else {
  System.out.println("Failure.");
} 

Viel besserer Code schon. Wenn foo null ist, wird es dort aufhören und foo.getBar nicht versuchen (im if), damit ich keine NPE bekomme. Die letzte Sache, die ich verbessern möchte, und die Hauptfrage: Gebe ich wirklich an, foo.getBar () zweimal aufzurufen? Es wäre schön, von dem zweiten identischen Aufruf wegzukommen, wenn getBar () eine sehr schwere Operation wäre. Ich frage mich, ob es irgendwie möglich ist, etwas Ähnliches zu tun:

if(foo!=null && (Bar bar = foo.getBar())!=null){
  Bar bar = foo.getBar();
  System.out.println("Success: " + bar);
} else {
  System.out.println("Failure.");
}

Ich würde es auf zwei verschiedene brechen müssen, wenn ich es wieder tun möchte

Bar bar = foo.getBar();
if (bar!=null) ...

14
2018-02-19 07:47


Ursprung


Antworten:


Dies ist der nächste, den Sie bekommen können:

Bar bar;
if(foo!=null && (bar = foo.getBar())!=null){
  System.out.println("Success: " + bar);
} else {
  System.out.println("Failiure.");
}

28
2018-02-19 07:53



Ich habe diese Technik beim Iterieren von Zeilen aus einem BufferedReader verwendet:

BufferedReader br = // create reader
String line
while ((line = br.readLine()) != null) {
    // process the line
}

Also ja, Sie können eine Zuweisung machen, und das Ergebnis davon wird die Variable auf der linken Seite sein, die Sie dann überprüfen können. Es ist jedoch nicht zulässig, Variablen innerhalb eines Tests zu deklarieren, da sie nur auf diesen Ausdruck beschränkt sind.


11
2018-02-19 07:52



Wenn Sie den Umfang der Bar begrenzen möchten, füge ich {und} den Code hinzu, den Michael gepostet hat.

void foo ()
{
    // irgendein Code ...

    // Dieser Block begrenzt den Bereich von "Bar bar", so dass der Rest der Methode nicht sehen kann
    // es.
    {
        Bar-Bar;
        if (foo! = null && (bar = foo.getBar ())! = null) {
            System.out.println ("Erfolg:" + bar);
        } sonst {
            System.out.println ("Failiure.");
        }
    }
}

Sie können auch in das Null-Objektmuster einchecken, wenn es Sinn macht. Ich persönlich versuche zu vermeiden, dass Dinge null sind, wenn ich ... wirklich darüber nachdenken kann, ob Sie wollen, dass null erlaubt wird oder nicht.


7
2018-02-19 08:07



Aus der Abteilung "Meine Programmiersprache ist besser als Ihre Programmiersprache": Groovig, du kannst den ... benutzen "?." Operator:

Bar bar = foo?.bar
if (bar != null) {
}

In Java ist dies ein gutes Muster (*):

Bar bar = foo == null ? null : foo.getBar();
if (bar != null) {
}

*: Etwas, das du in deinen Fingerspitzen speichern kannst.


2
2018-02-19 10:34



Drei Punkte, die die Frage nicht vollständig beantworten:

null ist böse. Schreiben Sie keine Methoden, die es zurückgeben. Ihr Beispielproblem würde dann verschwinden.

Ich denke, Sie könnten die Kapselung verpassen. Anstatt von foo.getBar() könnte die Schnittstelle von foo so gemacht werden, dass Sie eine "Tell do not ask" -Operation durchführen?

Nebenwirkungen im Ausdruck neigen dazu, schlechten Code zu verursachen. Lieber mehr, einfachere Zeilen zu weniger, fehlerhaften Zeilen. Die übliche Ausnahme bei Verwendung ++ um einen Index zu erhöhen, wenn auf einen Puffer oder ähnliche Iterator-Stilalgorithmen zugegriffen wird.


1
2018-02-19 13:06



Eigentlich denke ich, dass dies eine Möglichkeit ist, dies mit Java Optional zu tun, hier ein Beispiel:

Optional.ofNullable("text").ifPresent( $0 -> {
  System.out.println($0.toUpperCase());
});

Oder in deinem Fall:

  if(foo != null){
      Optional.ofNullable(foo.getBar()).ifPresent(bar -> {
          System.out.println("Success: " + bar);
      });
  }

0
2018-03-22 14:02