Local variable objectCheck defined in an enclosing scope must be final or effectively final

youza

Erfahrenes Mitglied
Hab mir mal des Tutorial von Oracle durchgelesen da steht des eigentlich ganz schön und fast mit deinem Beispiel drin:

http://www.oracle.com/technetwork/articles/java/lambda-1984522.html
Bei "figure 5" ist dein Fehler beschrieben:

A variable used in a lambda expression is required to be final or effectively final. To demonstrate this, declare a local variable and initialize the local variable:
int i=5;

Assign the variable in the lambda expression body. A compiler error—Variable i is required to be final or effectively final—gets generated, as shown in Figure 5.

Warum gibst du nicht direkt den Wert zurück?

Java:
public boolean checkForObject(int distance, SWGObject value ){

        SWGObject object = core.objectService.getObject(((SWGObject) value).getObjectID());
        core.simulationService.get(object.getPlanet(), object.getWorldPosition().x, object.getWorldPosition().z, distance).stream().forEach((objecta) -> {
          if (object instanceof BuildingObject)
            return true;
          }
        );
        return false;
      }

Viele Grüße
Youza

@Edit ich seh grad des machst du in der aktuellen Version welcher Fehler tritt denn jetzt auf?

Hab das ganze mal so simple wie möglich nachgebaut da funktioniert alles, also mit eigenen Objekten.
Wahrscheinlich is aber das interface von simulationService void ist, dann kannst du keinen return machen.
 

Anhänge

  • lambda_tut.zip
    4,6 KB · Aufrufe: 8
Zuletzt bearbeitet:

nchristoph

Erfahrenes Mitglied
Aktuelle Fehlermeldung ist: Void methods cannot return a value.

Mit meiner abgeändterten Variante hab ich wieder:

- Local variable checkObject defined in an enclosing scope must be final or
effectively final

Wie könnte man das sonst noch machen?
 

ComFreek

Mod | @comfreek
Moderator
Wie wäre es mit anyMatch()?

Java:
public boolean checkForObject(int distance, SWGObject value ){
  SWGObject object = core.objectService.getObject(((SWGObject) value).getObjectID());
  core.simulationService.get(object.getPlanet(), object.getWorldPosition().x, object.getWorldPosition().z, distance).stream().anyMatch((objecta) -> {
    return objecta instanceof BuildingObject;
  });
}

Bitte wähle
a) bessere Variablennamen!
b) und versuche die Zeile zu verkürzen, indem du die Rückgabewerte der ganzen Funktionen temporär in lokalen Variablen speicherst.

So schaut es doch gleich viel schöner aus:
Java:
SWGObject object = core.objectService.getObject(((SWGObject) value).getObjectID());
    core.simulationService
        .get(
            object.getPlanet(),
            object.getWorldPosition().x,
            object.getWorldPosition().z,
            distance
        ).stream().anyMatch((objecta) -> {
          return objecta instanceof BuildingObject;
        });
Jetzt nur noch objecta umbenennen (z. B. zu "curObject").
 

nchristoph

Erfahrenes Mitglied
Ich habs jetzt hingekriegt: AtomicBoolean ist das Zauberwort.

Java:
  public boolean checkForObject(int distance, SWGObject value ){
     AtomicBoolean checkObject = new AtomicBoolean();
     core.simulationService.get(value.getPlanet(), value.getWorldPosition().x, value.getWorldPosition().z, distance).stream().forEach((objecta) -> {
       if (objecta instanceof BuildingObject)
         checkObject.set(true);
       }
     );
     return checkObject.get();
   }

Sollte es Jemanden Interessieren:

Bei Normalen boolean wird in so einem Fall verlangt, dass Sie final bzw. Effectively Final gemacht werden.

Dadurch lässt sich die Variable danach leider nicht mehr mit Bedingungen auf True oder False setzen. Für diesen Fall kann/soll man Atomicboolean verwenden. Atomicboolean ist automatisch false und wird nicht als Final oder Effectively Final benötigt.

Einfach mal nach Atomicboolean suchen auf der Oracleseite.
 
Zuletzt bearbeitet: