Saltar al contenido

La variable utilizada en la expresión lambda debe ser final o efectivamente final

Solución:

Aunque otras respuestas prueban el requisito, no explican por qué el requisito existe.

La JLS menciona por qué en §15.27.2:

La restricción a las variables finales efectivamente prohíbe el acceso a variables locales que cambian dinámicamente, cuya captura probablemente introduciría problemas de concurrencia.

Para reducir el riesgo de errores, decidieron asegurarse de que las variables capturadas nunca mutaran.

A final variable significa que solo se puede crear una instancia. en Java, no puede usar variables no finales en lambda ni en clases internas anónimas.

Puede refactorizar su código con el antiguo bucle for-each:

private TimeZone extractCalendarTimeZoneComponent(Calendar cal,TimeZone calTz) {
    try {
        for(Component component : cal.getComponents().getComponents("VTIMEZONE")) {
        VTimeZone v = (VTimeZone) component;
           v.getTimeZoneId();
           if(calTz==null) {
               calTz = TimeZone.getTimeZone(v.getTimeZoneId().getValue());
           }
        }
    } catch (Exception e) {
        log.warn("Unable to determine ical timezone", e);
    }
    return null;
}

Incluso si no entiendo algunas partes de este código:

  • llamas a un v.getTimeZoneId(); sin usar su valor de retorno
  • con la tarea calTz = TimeZone.getTimeZone(v.getTimeZoneId().getValue()); no modificas el originalmente pasado calTz y no lo usas en este método
  • Tu siempre vuelves null, por qué no te pones void como tipo de retorno?

Espero que también estos consejos te ayuden a mejorar.

A partir de una lambda, no puede obtener una referencia a nada que no sea definitivo. Debe declarar una envoltura final desde fuera de lamda para contener su variable.

Agregué el objeto de ‘referencia’ final como este contenedor.

private TimeZone extractCalendarTimeZoneComponent(Calendar cal,TimeZone calTz) {
    final AtomicReference<TimeZone> reference = new AtomicReference<>();

    try {
       cal.getComponents().getComponents("VTIMEZONE").forEach(component->{
        VTimeZone v = (VTimeZone) component;
           v.getTimeZoneId();
           if(reference.get()==null) {
               reference.set(TimeZone.getTimeZone(v.getTimeZoneId().getValue()));
           }
           });
    } catch (Exception e) {
        //log.warn("Unable to determine ical timezone", e);
    }
    return reference.get();
}   
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *