Java: Local Variable Mi Defined in an Enclosing Scope Must Be Final or Effectively Final

Java: Local variable mi defined in an enclosing scope must be final or effectively final

The error means you cannot use the local variable mi inside an inner class.


To use a variable inside an inner class you must declare it final. As long as mi is the counter of the loop and final variables cannot be assigned, you must create a workaround to get mi value in a final variable that can be accessed inside inner class:

final Integer innerMi = new Integer(mi);

So your code will be like this:

for (int mi=0; mi<colors.length; mi++){

String pos = Character.toUpperCase(colors[mi].charAt(0)) + colors[mi].substring(1);
JMenuItem Jmi =new JMenuItem(pos);
Jmi.setIcon(new IconA(colors[mi]));

// workaround:
final Integer innerMi = new Integer(mi);

Jmi.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JMenuItem item = (JMenuItem) e.getSource();
IconA icon = (IconA) item.getIcon();
// HERE YOU USE THE FINAL innerMi variable and no errors!!!
Color kolorIkony = getColour(colors[innerMi]);
textArea.setForeground(kolorIkony);
}
});

mnForeground.add(Jmi);
}
}

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

You can't use a local variable inside a nested class since the JVM requires it to be final or at least "effectively final" (which means the value of x cannot be modified down the road).

You can by-pass it by declaring x outside of main as a static variable:

static volatile BigInteger x = new BigInteger("0");
public static void main(String[] args) {
....

Pay attention that it is also declared to be volatile since the main thread modified it and you want the Timer to see the updated value of x (if you don't declare it volatile the Timer might see stale values).

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

Can you give me some advice how I can fix this issue, please?

Why does this happen? You can read about it here: Lambdas: local variables need final, instance variables don't

Minimal changes to solve your problem: Don't use the i variable itself. Create a copy of it and make it final.

final int iCopy = i;
Optional<RiskFilters> filter_payload = filterList.stream().filter(f -> newFiltersPositionsList.get(iCopy).getId() == f.getId()).findAny();

For example can I skip the for cycle and use maybe stream into stream?

You could give it a try:

// replace the for-loop

// or just.... `newFiltersPositionsList.forEach(/* ... */)`
newFiltersPositionsList.stream().forEach(filterPosition -> {
Optional<RiskFilters> filter_payload = filterList.stream()
.filter(f -> filterPosition.getId() == f.getId())
.findAny();
RiskFilters filter = filter_payload.get();

filter.setPosition(filterPosition.getPosition());
riskFilterService.save(filter);
});

Also, you could use a for-each instead of a for-loop:

for (ChangeOrderRiskFiltersDTO filterPosition : newFiltersPositionsList) {
Optional<RiskFilters> filter_payload = filterList.stream()
.filter(f -> filterPosition.getId() == f.getId())
.findAny();
RiskFilters filter = filter_payload.get();
filter.setPosition(filterPosition.getPosition());
riskFilterService.save(filter);
}

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

Your question itself has the answer to what you have asked.

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

If anonymous class is created inside any method then all the local variables defined in the method but outside the body of the anonymous class should be made final in case they are needed to be used in anonymous class.

public class OuterClass{
int x,y;
public void someMethod(){

final int neededByAnonymousClass = x + y + 30;

Runnable runnable = new Runnable(){
// This is like we are creating a class which simply implements Runnable interface.
// Scope of this class is inside the method someMethod()
// run() method may be executed sometime later after the execution of someMethod() has completed.
// all the local variables needs to be final in order they can be used later in time when run() gets executed.

public void run(){
System.out.println(neededByAnonymousClass+ 40);
}
}
Thread thread = new Thread(runnable); // passing the object of anonymous class, created above
thread.start();
}
}

So just make your all the local variables (defiend inside the scope of a method) as final which you wish to use inside the run() method of your local anonymous class (class without name). In case you wish to modify the value of a variable then do modifications first and then create the anonymous class. Create another final variable and initialize it with the modified value and use the same in the anonymous class.

I quote below from answer of another related question : Local variable needs to be declared final

It's a promise to yourself (and to the compiler) that the value of box
won't change in the enclosing scope. The compiler will tell you if you
break that promise.

The variable value will be used some time later after the execution of the method is completed. Hence local variables must be declared as final. The methods in the anonymous object are not executed in order they are written (sequentially)

Suppose below lines of code where we have a method : methodA() and it contains definition of an anonymous class.

[ line-1 : method A, line-2 method A, line-3 : anonymous class , Line
4 method of anonymous class, line 5 method A ] ==> Order of execution

Line 1, Line 2, Line 3 (just the object creation of the anonymous class), Line 5. Line 4 will be executed later when method on the object created of anonymous class is invoked.

Getting local variable defined in the enclosing scope must be final or effective final

Try replacing this:

Package entitlePackage = new Package();
if(null != entitleProduct && null != entitleProduct.getPackages() && !entitleProduct.getPackages().isEmpty()) {
entitlePackage = entitleProduct.getPackages().stream().filter(
entitlePack ->
entitlePack.getName().equalsIgnoreCase(productPack.getPack().getPackageName()))
.findAny().orElse(null);
}

by this:

Package entitlePackage =
Optional.ofNullable(entitleProduct)
.map(Product::getPackages)
.map(Collection::stream)
.orElse(Stream.empty())
.filter(e -> productPack.getPack()
.getPackageName()
.equalsIgnoreCase(e.getName()))
.findAny()
.orElseGet(Package::new);

The entitlePackage will be effectively final. Also your code will be much easier to read and maintain.

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

Inside lambda function all variable have to be final.

you can create your collect variable as Atomic and then you can assign on it your list:

 AtomicReference<List<FinalAssessment>> collect = null;

Java 8 shows this error. Local variable itemList defined in an enclosing scope must be final or effectively final

You are using itemList within a lambda expression. Therefore it has to be final.

Java 8 introduces the new concept of effectivly final, which means, the compiler checks, if a used variable is final in usage and does not force the developer to explicitly declare it as final.

So if you change your code to

final List<RestaurantOrderBook> itemList = new ArrayList<RestaurantOrderBook>();

you will see, that the compiler gives you an error at:

itemList = mongoTemplate.find(query, RestaurantOrderBook.class);

because you are reasigning itemList. That is why itemList is not effectivly final as well. If you squash these two lines to

List<RestaurantOrderBook> itemList = mongoTemplate.find(query, RestaurantOrderBook.class);

it should work.



Related Topics



Leave a reply



Submit