Value of "this" in an anonymous class vs a lambda expression - java

I am little bit confused with the different behavior of an anonymous class and a lambda expression.
When I'm using a lambda expression:
//Test.java
Runnable r1 = () -> System.out.println(this);
Runnable r2 = () -> System.out.println(toString());
#Override
public String toString() {
return "Hello World!";
}
// in main method
new Test().r1.run();
new Test().r2.run();
Output : Hello World!
Hello World!
When using an anonymous class:
Runnable r1 = new Runnable() {
#Override
public void run() {
System.out.println(this);
}
};
Runnable r2 = new Runnable() {
#Override
public void run() {
System.out.println(toString());
}
};
#Override
public String toString() {
return "Hello World!";
}
// in main method
new Test().r1.run();
new Test().r2.run();
Output : Package_Name.Test$1#1db9742
Package_Name.Test$2#106d69c
Can someone please explain the different behavior?

In a lambda expression, this is lexically bound to the surrounding class, while in the anonymous class this is lexically bound to the anonymous class.
The Java Language Specification describes this behavior at 15.27.2:
Unlike code appearing in anonymous class declarations, the meaning of names and the this and super keywords appearing in a lambda body, along with the accessibility of referenced declarations, are the same as in the surrounding context (except that lambda parameters introduce new names).
The transparency of this (both explicit and implicit) in the body of a lambda expression - that is, treating it the same as in the surrounding context - allows more flexibility for implementations, and prevents the meaning of unqualified names in the body from being dependent on overload resolution.
Practically speaking, it is unusual for a lambda expression to need to talk about itself (either to call itself recursively or to invoke its other methods), while it is more common to want to use names to refer to things in the enclosing class that would otherwise be shadowed (this, toString()). If it is necessary for a lambda expression to refer to itself (as if via this), a method reference or an anonymous inner class should be used instead.
In order to reference this of the surrounding class from inside an anonymous class, you will have to use a qualified this.
Runnable r1 = new Runnable() {
#Override
public void run() {
System.out.println(Test.this); // or Test.this.toString()
}
};

Related

Calling a method in ExecuterService using double colon (::) [duplicate]

This question already has answers here:
:: (double colon) operator in Java 8
(17 answers)
Closed 2 years ago.
I have a class constitues 2 methods static and non static respectively, as per my limited knowledge submit method accepts runnable,callable instance directly or through lamba expression.
Today I came to know that we can even call or trigger static as well as non static method directly by using double colon which has been added in java 8.
I was just wondering how this works, there is no run method in my class and it doesn't implements runnable and even I'm not using lamba?
Is it a good practice to use :: or one should pass the runnable or callable instance.
Is there any other way to call a method inside submit() rather passing an instance?
Class A {
public static void printSomething(){
System.out.println("Staitc Method");
}
public void print()
{
System.out.println("Non-Staitc Method");
}
}
psvm()
{
A a = new A():
ExecutorService es = Executors.newFixedThreadPool(2);
es.submit(A::printSomething); //Expected is runnable or callable task
es.submit(a::print);
}
A::printSomething is called a method reference. When you use a method reference in a place that expects an interface like Runnable or Callable, Java automatically creates an implementation of that interface that calls the method.
That is,
es.submit(A::printSomething);
behaves the same as
es.submit(new Runnable() {
public void run() {
A.printSomething();
}
});
but is easier to read and does not create a new class everywhere you use it, or a new object instance every time it's called.
You can read more about method references in
The tutorial from Oracle
This write-up on Baeldung
Another way of achieving the same is using lambda expressions such as:
es.submit(() -> A.printSomething());
Since Runnable is a functional interface, you can use lambda expressions or method references that fit it even if the method name doesn't match. Therefore any no-arg void method can be used as a Runnable.
Runnable r1 = () -> a.printSomething();
Runnable r2 = A::printSomething(); // Method reference, short-hand
Runnable r3 = () -> A.printSomething(); // Same as r2, but as explicit lambda expression
The reason why the method reference works even though the class does not implement a void run() method is because what matters for Functional Interface assignment is the method signature and not the method names.
The method signature of A's printSomething matches Runnable's run and for that reason it works. Notice this only works with Functional Interfaces (i.e. those with only one method, said method method not having a default implementation).
Is it good practice? It's a matter of style but it is definitely not bad practice to use method references, and they're also more concise than left -> right lambdas.
I suggest you try this out yourself so you're clear on the rules.
public class FunctionalInterfaceDemo {
public static class SimpleClass {
public static void doItStatic() {
}
public void doItNonStatic() {
}
}
interface MyOwnFunctionalInterface {
void methodA();
}
interface NotAFunctionalInterface {
void methodA();
void methodB();
}
interface AlsoNotAFunctionalInterface {
default void methodA() {
}
}
public static void main(String[] args) {
MyOwnFunctionalInterface compiles = SimpleClass::doItStatic;
MyOwnFunctionalInterface alsoCompiles = new SimpleClass()::doItNonStatic;
NotAFunctionalInterface doesNotCompile = SimpleClass::doItStatic;
AlsoNotAFunctionalInterface alsoDoesNotCompile = SimpleClass::doItStatic;
}
}

Inner lambda reference Outer lambda variable

There is a Outer lambda that contains inner lambda whis tries to reference var in Outer lambda, how does it possible?
Im try to understand what this expression will look like when its compiled to make this possible.
public static void main(String[] args) {
ExecutorService service = Executors.newScheduledThreadPool(10);
DoubleStream.of(3.14159, 2.71828)
.forEach(c -> service.submit(
() -> System.out.println(c)));
I'm guess is will compiled to something like this:
new Consumer<Double>() {
#Override
public void accept(Double aDouble) {
new Runnable() {
#Override
public void run() {
System.out.println(aDouble);
}
};
}
};
Am i right?
The compiled code is closer to
class MyClass {
public static void main(String[] args) {
ExecutorService service = Executors.newScheduledThreadPool(10);
DoubleStream.of(3.14159, 2.71828)
.forEach(new DoubleConsumer() {
#Override public void accept(double value) {
lambda1(service, value);
}
});
}
private static void lambda1(ExecutorService service, double c) {
service.submit(new Runnable() {
#Override public void run() {
lambda2(c);
}
});
}
private static void lambda2(double c) {
System.out.println(c);
}
}
not having any nesting anymore. Actually, the compiled code doesn’t contain anonymous inner classes. There will be generate classes at runtime fulfilling the interfaces DoubleConsumer and Runnable though, which will invoke these synthetic methods holding the bodies of your lambda expression.
But this sketch is already sufficient to demonstrate that there is no real technical difference between “outer lambda” and “inner lambda”. The nesting exists on the source code level, allowing you to express your intent concisely.
See also “How will Java lambda functions be compiled?”
The innermost lambda can access c from its enclosing lambda because c is effectively final, because nothing ever assigns to it. From the linked portion of the spec:
A method, constructor, lambda, or exception parameter (§8.4.1, §8.8.1, §9.4, §15.27.1, §14.20) is treated, for the purpose of determining whether it is effectively final, as a local variable whose declarator has an initializer.
and then above that
A local variable whose declarator has an initializer (§14.4.2) is effectively final if all of the following are true:
It is not declared final.
It never occurs as the left hand side in an assignment expression (§15.26). (Note that the local variable declarator containing the initializer is not an assignment expression.)
It never occurs as the operand of a prefix or postfix increment or decrement operator (§15.14, §15.15).
So even though c isn't explicitly final, it's effectively final.
I'm guess is will compiled to something like this:
...
Am i right?
I think that's about it in effect; the compiler doesn't actually do that, lambdas are their own thing. If we wanted to underscore the fact that c is effectively final, we might add final to its parameter declaration there.

Java 8 Lambda Can't Call Default Interface Methods [duplicate]

I have created a simple interface using java8. In that it contains one method and one default method.
interface Lambda{
default void dummy(){
System.out.println("Call this..");
}
void yummy();
}
I'm trying to us these two methods using the historical way like
public class DefaultCheck {
public static void main(String[] args) {
DefaultCheck check = new DefaultCheck();
check.activate(new Lambda() {
#Override
public void yummy() {
dummy();
}
});
}
void activate(Lambda lambda){
lambda.yummy();
}
}
Now i'm trying to implement the same thing using lambda expression, getting error like `dummy is undefined`
check.activate(() -> {
dummy();
});
Can any one please suggest, how to implement this scenario using Lambda expression ??
It can't be done.
JLS 15.27.2 addresses this:
Unlike code appearing in anonymous class declarations, the meaning of
names and the this and super keywords appearing in a lambda body,
along with the accessibility of referenced declarations, are the same
as in the surrounding context (except that lambda parameters introduce
new names).
The transparency of this (both explicit and implicit) in the body of a
lambda expression - that is, treating it the same as in the
surrounding context - allows more flexibility for implementations, and
prevents the meaning of unqualified names in the body from being
dependent on overload resolution.
Practically speaking, it is unusual for a lambda expression to need to
talk about itself (either to call itself recursively or to invoke its
other methods), while it is more common to want to use names to refer
to things in the enclosing class that would otherwise be shadowed
(this, toString()). If it is necessary for a lambda expression to
refer to itself (as if via this), a method reference or an anonymous
inner class should be used instead.
The inner class implementation works since the code is called as if you coded:
check.activate(new Lambda() {
#Override
public void yummy() {
this.dummy();
}
});
Our problem now is that lambdas do not introduce a new scope. So, if you want your lambda to be able to reference itself, you may refine your #FunctionalInterface so that its functional method accepts itself and its required parameters:
check.activate(this_ -> this_.dummy());
where Lambda is defined as:
#FunctionalInterface
public interface Lambda {
void yummy(Lambda this_);
default void yummy() {
yummy(this);
}
default void dummy(){
System.out.println("Call this..");
}
}
If I understand it correctly. You are trying to call a default method in an interface through lambda implementation. I think it can be done.
#FunctionalInterface
interface Value
{
String init(Value a);
default String add(String b)
{
return "added content "+b;
}
default String getResult()
{
String c = init(this);
return c;
}
}
public class Main
{
public static void main(String[] args)
{
Value v = a -> a.add("inpout"); // here I am calling add method in Value interface.
String c = v.getResult();
System.out.println(c);
}
}

Can a lambda access members of its target functional interface?

I have created a simple interface using java8. In that it contains one method and one default method.
interface Lambda{
default void dummy(){
System.out.println("Call this..");
}
void yummy();
}
I'm trying to us these two methods using the historical way like
public class DefaultCheck {
public static void main(String[] args) {
DefaultCheck check = new DefaultCheck();
check.activate(new Lambda() {
#Override
public void yummy() {
dummy();
}
});
}
void activate(Lambda lambda){
lambda.yummy();
}
}
Now i'm trying to implement the same thing using lambda expression, getting error like `dummy is undefined`
check.activate(() -> {
dummy();
});
Can any one please suggest, how to implement this scenario using Lambda expression ??
It can't be done.
JLS 15.27.2 addresses this:
Unlike code appearing in anonymous class declarations, the meaning of
names and the this and super keywords appearing in a lambda body,
along with the accessibility of referenced declarations, are the same
as in the surrounding context (except that lambda parameters introduce
new names).
The transparency of this (both explicit and implicit) in the body of a
lambda expression - that is, treating it the same as in the
surrounding context - allows more flexibility for implementations, and
prevents the meaning of unqualified names in the body from being
dependent on overload resolution.
Practically speaking, it is unusual for a lambda expression to need to
talk about itself (either to call itself recursively or to invoke its
other methods), while it is more common to want to use names to refer
to things in the enclosing class that would otherwise be shadowed
(this, toString()). If it is necessary for a lambda expression to
refer to itself (as if via this), a method reference or an anonymous
inner class should be used instead.
The inner class implementation works since the code is called as if you coded:
check.activate(new Lambda() {
#Override
public void yummy() {
this.dummy();
}
});
Our problem now is that lambdas do not introduce a new scope. So, if you want your lambda to be able to reference itself, you may refine your #FunctionalInterface so that its functional method accepts itself and its required parameters:
check.activate(this_ -> this_.dummy());
where Lambda is defined as:
#FunctionalInterface
public interface Lambda {
void yummy(Lambda this_);
default void yummy() {
yummy(this);
}
default void dummy(){
System.out.println("Call this..");
}
}
If I understand it correctly. You are trying to call a default method in an interface through lambda implementation. I think it can be done.
#FunctionalInterface
interface Value
{
String init(Value a);
default String add(String b)
{
return "added content "+b;
}
default String getResult()
{
String c = init(this);
return c;
}
}
public class Main
{
public static void main(String[] args)
{
Value v = a -> a.add("inpout"); // here I am calling add method in Value interface.
String c = v.getResult();
System.out.println(c);
}
}

Declaring Anonymous Inner class

rb.addActionListener(new ActionEvent(ae) {
public void actionPerformed(ActionEvent ae) {
nowCall(ae);
}
});
Another way
Thread th=new Thread(Runnable r) {
public void run() {
// do something
}
};
// notice the ending of above 2 snippets
I am really confused seeing these two.It seems there is no exact pattern to declare an anonymous inner class.
please explain the syntax for anonymous inner class.
The second isn't valid, as far as I can see and test.
What would be more common would be to create a new Runnable implementation:
Thread th=new Thread(new Runnable() {
#Override
public void run() {
// This implements Runnable.run
}
});
Now you could just override the run method of a normal thread:
Thread th=new Thread() {
#Override
public void run() {
// This overrides Thread.run
}
};
... but personally I prefer specifying the Runnable separately when creating a thread.
Now the difference that you noticed at the end is simply whether the expression is used as an argument (e.g. to the addActionListener method or the Thread(Runnable) constructor, or whether it's just assigned directly to the variable. Think of the whole new TypeName() { ... } as a single expression, and it's just the difference between:
Thread th = expression;
and
Thread th = new Runnable(expression);
There is the difference that in the first case your passing it as an parameter to a method and in the second example you're storing it in a local variable.
So you can't really compare both examples against each other.
[...] notice the ending of above 2 snippets
The trailing ) in your first example is simply a termination of
rb.addActionListener(
(i.e., your two examples have different endings because one is a right hand side of an assignment
Thread th = ... ;
and the other is an argument to a method call
...addActionListener( ... );
The syntax of creating an anonymous class is simply:
new SomeClassOrInterface() {
// implementation goes here
}
Which as you can see is the pattern for both of your examples.
From Anonymous Classes (Java in a Nutshell):
3.12.3. New Syntax for Anonymous Classes
We've already seen examples of the syntax for defining and instantiating an anonymous class. We can express that syntax more formally as:
new class-name ( [ argument-list ] ) { class-body }
or:
new interface-name () { class-body }
Also, you have a typo in your second example. It should probably read new Thread() { ... or new Thread(r) { ... (though in the latter case the overridden method will not be called).
Instanciating new anonymous class and passing the object to addActionListener method.
Instanciating new anonymous class and assigning the object to local variable th
They are both the same. You put the anonymous class right after the declaration, before the semicolons:
new ActionEvent(ae) {class details, methods etc} ;
and
Thread(Runnable r) { public void run() { // do something }} ;
in both cases you create a new instance of the class, in the first example you use it as a parameter to method, and in the second you assign it to a variable.
The difference is that you can either implement an interface as an anonymous inner class or extend a class. In you example both are extending a class

Categories