4

When using an anonymous class below , the variable x us called without problem

interface Age { 
    int x = 21; 
    void getAge(); 
} 

class AnonymousDemo  { 
    public static void main(String[] args) { 
        Age oj1 = new Age() { 
            @Override
            public void getAge() { 
                // printing age 
                System.out.print("Age is "+x); 
            } 
        }; 
        oj1.getAge(); 
    } 
} 

But when I use the same code with lambda expression below, an exception occured:

interface Age { 
    int x = 21; 
    void getAge(); 
} 

class AnonymousDemo { 
    public static void main(String[] args) { 
        Age oj1 = () -> { System.out.print("Age is "+x); };
        oj1.getAge(); 
    } 
} 

What would be the problem here? Knowing that lambda expression are just an abbreviation to implement anonymous classes.

4
  • 1
    What is this exception? Commented May 20, 2020 at 19:47
  • @mattfreake error: the exception was -> error:cannot find symbol Commented May 20, 2020 at 20:21
  • 1
    Note that "every field declaration in the body of an interface is implicitly public, static, and final", see JLS § 9.3. Commented May 20, 2020 at 22:04
  • 1
    That means that it is a constant, so according to the Java Naming Conventions, it should be written in UPPER_SNAKE_CASE. Commented May 20, 2020 at 22:06

2 Answers 2

5

Actually lambda expressions aren't "just an abbreviation to implement anonymous classes". The benefit of using lambda expression is that it has direct access to instance of this class (the class from which it was called), while anonymous class don't (it has its own this instance).

In other words, anonymous classes introduce a new scope. so that names are resolved from their superclasses and interfaces and can shadow names that occur in the lexically enclosing environment. For lambdas, all names are resolved lexically.

https://stackoverflow.com/a/22640484 And also

Lambda performance with Anonymous classes

When application is launched each class file must be loaded and verified.

Anonymous classes are processed by compiler as a new subtype for the given class or interface, so there will be generated a new class file for each.

Lambdas are different at bytecode generation, they are more efficient, used invokedynamic instruction that comes with JDK7.

For Lambdas this instruction is used to delay translate lambda expression in bytecode untill runtime. (instruction will be invoked for the first time only)

As result Lambda expression will becomes a static method(created at runtime). (There is a small difference with stateles and statefull cases, they are resolved via generated method arguments)

https://stackoverflow.com/a/33874965

For instance:

interface Supplier {
   void foo();
}

class A {

   private String name;

   public void doSome() {
      baz(() -> System.out.println(this.name));
   }

   private void baz(Supplier sup){
     sup.foo();
   }
}

or

class A {

   private String name;

   public void doSome() {
      baz(new Supplier() {
         void foo() {
            System.out.println(A.this.name);
         }
      });
   }

   private void baz(Supplier sup){
     sup.foo();
   }
}

I recommend to read this: Java8 Lambdas vs Anonymous classes.

Sign up to request clarification or add additional context in comments.

Comments

3

The x is not recognized as a field from the Age interface. You have to either do a static import (import static Age.x) or specify where the x comes from:

Age oj1 = () -> System.out.print("Age is "+ Age.x);

2 Comments

Thank you for the answer. By doing the static import approach, does it mean to declare the x variable inside the main class as static ? if so do I have to maintain Age.X approach you mentioned ?
@CheBoss no. he means import static Age.x along with your other import statement.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.