Difference between final and effectively final

后端 未结 14 2806
孤独总比滥情好
孤独总比滥情好 2020-11-22 00:38

I\'m playing with lambdas in Java 8 and I came across warning local variables referenced from a lambda expression must be final or effectively final. I know tha

相关标签:
14条回答
  • 2020-11-22 01:03

    ... starting in Java SE 8, a local class can access local variables and parameters of the enclosing block that are final or effectively final. A variable or parameter whose value is never changed after it is initialized is effectively final.

    For example, suppose that the variable numberLength is not declared final, and you add the marked assignment statement in the PhoneNumber constructor:

    public class OutterClass {  
    
      int numberLength; // <== not *final*
    
      class PhoneNumber {
    
        PhoneNumber(String phoneNumber) {
            numberLength = 7;   // <== assignment to numberLength
            String currentNumber = phoneNumber.replaceAll(
                regularExpression, "");
            if (currentNumber.length() == numberLength)
                formattedPhoneNumber = currentNumber;
            else
                formattedPhoneNumber = null;
         }
    
      ...
    
      }
    
    ...
    
    }
    

    Because of this assignment statement, the variable numberLength is not effectively final anymore. As a result, the Java compiler generates an error message similar to "local variables referenced from an inner class must be final or effectively final" where the inner class PhoneNumber tries to access the numberLength variable:

    http://codeinventions.blogspot.in/2014/07/difference-between-final-and.html

    http://docs.oracle.com/javase/tutorial/java/javaOO/localclasses.html

    0 讨论(0)
  • 2020-11-22 01:06

    According to the docs:

    A variable or parameter whose value is never changed after it is initialized is effectively final.

    Basically, if the compiler finds a variable does not appear in assignments outside of its initialization, then the variable is considered effectively final.

    For example, consider some class:

    public class Foo {
    
        public void baz(int bar) {
            // While the next line is commented, bar is effectively final
            // and while it is uncommented, the assignment means it is not
            // effectively final.
    
            // bar = 2;
        }
    }
    
    0 讨论(0)
  • 2020-11-22 01:08

    If you could add the final modifier to a local variable, it was effectively final.

    Lambda expressions can access

    • static variables,

    • instance variables,

    • effectively final method parameters, and

    • effectively final local variables.

    Source: OCP: Oracle Certified Professional Java SE 8 Programmer II Study Guide, Jeanne Boyarsky, Scott Selikoff

    Additionally,

    An effectively final variable is a variable whose value is never changed, but it isn’t declared with the final keyword.

    Source: Starting Out with Java: From Control Structures through Objects (6th Edition), Tony Gaddis

    Furthermore, don't forget the meaning of final that it is initialized exactly once before it is used for the first time.

    0 讨论(0)
  • 2020-11-22 01:11

    'Effectively final' is a variable which would not give compiler error if it were to be appended by 'final'

    From a article by 'Brian Goetz',

    Informally, a local variable is effectively final if its initial value is never changed -- in other words, declaring it final would not cause a compilation failure.

    lambda-state-final- Brian Goetz

    0 讨论(0)
  • 2020-11-22 01:11

    However, starting in Java SE 8, a local class can access local variables and parameters of the >enclosing block that are final or effectively final.

    This didn't start on Java 8, I use this since long time. This code used (before java 8) to be legal:

    String str = ""; //<-- not accesible from anonymous classes implementation
    final String strFin = ""; //<-- accesible 
    button.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
             String ann = str; // <---- error, must be final (IDE's gives the hint);
             String ann = strFin; // <---- legal;
             String str = "legal statement on java 7,"
                    +"Java 8 doesn't allow this, it thinks that I'm trying to use the str declared before the anonymous impl."; 
             //we are forced to use another name than str
        }
    );
    
    0 讨论(0)
  • 2020-11-22 01:12

    final is a variable declare with key word final , example:

    final double pi = 3.14 ;
    

    it remains final through out the program.

    effectively final : any local variable or parameter that is assigned a value only once right now(or updated only once). It may not remain effectively final through out the program. so this means that effectively final variable might loose its effectively final property after immediately the time it gets assigned/updated at least one more assignment. example:

    class EffectivelyFinal {
    
        public static void main(String[] args) {
            calculate(124,53);
        }
    
        public static void calculate( int operand1, int operand2){   
         int rem = 0;  //   operand1, operand2 and rem are effectively final here
         rem = operand1%2  // rem lost its effectively final property here because it gets its second assignment 
                           // operand1, operand2 are still effectively final here 
            class operators{
    
                void setNum(){
                    operand1 =   operand2%2;  // operand1 lost its effectively final property here because it gets its second assignment
                }
    
                int add(){
                    return rem + operand2;  // does not compile because rem is not effectively final
                }
                int multiply(){
                    return rem * operand1;  // does not compile because both rem and operand1 are not effectively final
                }
            }   
       }    
    }
    
    0 讨论(0)
提交回复
热议问题