Aguid
Aguid

Reputation: 1043

Java 8: Why Effectively Final variable doesn't work for switch block?

Why Effectively Final variable works for functions and not for switch block ?

The following example gives a compilation error

    String comparing = " ";
    String effectivelyFinal = "Hello ";
    switch(comparing){
        case effectivelyFinal :
            System.out.println("Are equal");
            break ;
        default :
            System.out.println("Are not equal");
    }
    Predicate<String> areEqual = s -> s.equals(effectivelyFinal);

Upvotes: 1

Views: 654

Answers (3)

Ousmane D.
Ousmane D.

Reputation: 56473

The code doesn't compile simply because only constant expressions can be compared against when using a switch case. whereas with lambdas (anonymous functions) , we are not restricted to this extent.

just to clarify any more confusions, effectively final simply means a variable or a parameter whose value is never changed after it is initialized but doesn't necessarily make it a constant expression as you can change it; in which case it's no longer effectively final hence why it's disallowed as a switch case expression.

Upvotes: 3

JRG
JRG

Reputation: 4187

That is because effectivelyFinal is not really a final as you can reassign it to any other string.

Compiler is assured about compile-time constants and not effectively constants.

More on this in Java Language Specification: https://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.11

If you update your code by adding final keyword to the variable then it would become a compile-time constant and code would compile as now effectivelyFinal variable is really a final as you cannot change its value anymore.

String comparing = " ";
final String effectivelyFinal = "Hello ";
switch(comparing){
    case effectivelyFinal :
        System.out.println("Are equal");
        break ;
    default :
        System.out.println("Are not equal");
}
Predicate<String> areEqual = s -> s.equals(effectivelyFinal);

For lambda or regular functions, there is no such restriction.

Upvotes: 1

Joe C
Joe C

Reputation: 15714

A switch label must be one of three types, as per Section 14.11 of the JLS:

SwitchLabel:
    case ConstantExpression : 
    case EnumConstantName : 
    default :

By Section 15.28, a constant expression can be, among other things,

Simple names (§6.5.6.1) that refer to constant variables (§4.12.4).

Your simple name does not refer to a constant variable, and so is not allowed.

For lambdas, on the other hand, the JLS makes no such restriction.

Upvotes: 2

Related Questions