Error: Local variable assignedHour defined in an enclosing scope must be final or effectively final

Are you facing “Local variable assignedHour defined in an enclosing scope must be final or effectively final” error while trying to use local variable assignedHour that is not declared as final in the lambda expression or inside an inner class ?

Error: Local variable must be final

private TimeSlot getStartingTimeSlotAssigned(Request req){

  int assignedHour = req.getAssignedHourValue();
		
  if(assignedHour  < 3) {  
    //would like to manipulate/change assignedHourValue if it's less than 3     
    assignedHour  = assignedHour  + 1;
  }

  //Error thrown here: Local variable assignedHourValue defined in an enclosing scope must be final or effectively final
  TimeSlot ts = timeSlotList.stream()
	.filter(timeSlot-> (req.getAssignedDatePlanned().getDayOfYear() == timeSlot.getDay().getDayOfYear()) 
			&& (assignedHour == timeSlot.getStartingHourOfDay()))
	.findAny()
	.orElse(null);

  return ts;
}

In the above code, you would see the error specified while using non-final local variable assignedHour in the lambda expression or inner class. To overcome this you can modify the above code as shown below.

Workaround: Java Lambda Expression and Variable Scope

private TimeSlot getStartingTimeSlotAssigned(Request req){

  int[] assignedHour = {req.getAssignedHourValue()};
		
  if(assignedHour[0]  < 3) {      
    assignedHour[0]  = assignedHour[0]  + 1;
  }
  
  TimeSlot ts = timeSlotList.stream()
	.filter(timeSlot-> (req.getAssignedDatePlanned().getDayOfYear() == timeSlot.getDay().getDayOfYear()) 
			&& (assignedHour[0] == timeSlot.getStartingHourOfDay()))
	.findAny()
	.orElse(null);

  return ts;
}

By changing the code using int array and accessing first element assignedHour[0] in the array, you would be able to access the local variable in the lambda expression without declaring it as final.

Further Learning:

References:

Leave a Reply

avatar
  Subscribe  
Notify of