Page 1 of 1
About Question enthuware.ocajp.i.v8.2.1475 :
Posted: Wed Apr 08, 2015 7:33 am
by alkour
The correct answer is C
() -> System.out.println(" running...")
() -> System.out.println(" running...")
The colon is missing.
It must colon at the end of statement or curly brackets.
Am I correct?
Re: About Question enthuware.ocajp.i.v8.2.1475 :
Posted: Wed Apr 08, 2015 11:34 am
by admin
No, it is just a lambda expression. It is not a statement.
Re: About Question enthuware.ocajp.i.v8.2.1475 :
Posted: Mon Jun 29, 2015 11:58 am
by ha12345
I thought that in java 8 the methods in an interface aren't impliciet abstract anymore, due to the possibilities of default and static methods. Is that true? Here public void run() is not expliciet abstract.
Re: About Question enthuware.ocajp.i.v8.2.1475 :
Posted: Mon Jun 29, 2015 2:20 pm
by admin
No, methods in an interface are still implicitly abstract except when they are explicitly defined with the keyword default or static.
Re: About Question enthuware.ocajp.i.v8.2.1475 :
Posted: Fri Dec 04, 2015 11:38 am
by Russtam
Last part of explanation:
Further, since it does not return anything, the body part must be such that it does not return anything either. Thus, you can either use a method call that returns void or some code enclosed within { and } that does not return anything.
Without { and } you can call not only "void" method.
Following code successfully compiles and runs
Code: Select all
public static void main(String[] args) {
run(() -> voidMethod());
run(() -> intMethod());
}
public static void run(Runner x) {
x.run();
}
public static void voidMethod() {
System.out.println("voidMethod");
}
public static int intMethod() {
System.out.println("intMethod");
return 0;
}
Re: About Question enthuware.ocajp.i.v8.2.1475 :
Posted: Fri Dec 04, 2015 9:25 pm
by admin
You are right. There should be no constraint on the return value in this case because there is only one interface and one method call.
However, the return type of the method will become important when there are multiple methods with one returning void and one returning a value. For example,
Code: Select all
interface Runner {
public void run();
}
interface Runner2 {
public int run();
}
public class TestClass {
public static void main(String[] args) {
run(() -> voidMethod());
run(() -> intMethod());
}
public static void run(Runner x) {
System.out.println("In runner");
x.run();
}
public static void run(Runner2 x) {
System.out.println("In runner2");
x.run();
}
public static void voidMethod() {
System.out.println("voidMethod");
}
public static int intMethod() {
System.out.println("intMethod");
return 0;
}
}
Now, in the above code, the return type of the lambda expression is important. The expression () -> intMethod() does not bind to run(Runner x) anymore.
HTH,
Paul.
Re: About Question enthuware.ocajp.i.v8.2.1475 :
Posted: Mon Dec 18, 2017 12:06 pm
by ale8989
I'm sorry, how can
Code: Select all
public static void voidMethod() {
System.out.println("voidMethod");
}
public static int intMethod() {
System.out.println("intMethod");
return 0;
}
the expression () -> intMethod() bind to run(Runner x) in first place? It has a return value...
Re: About Question enthuware.ocajp.i.v8.2.1475 :
Posted: Mon Dec 18, 2017 12:17 pm
by Russtam
ale8989 wrote:I'm sorry, how can
Code: Select all
public static void voidMethod() {
System.out.println("voidMethod");
}
public static int intMethod() {
System.out.println("intMethod");
return 0;
}
the expression () -> intMethod() bind to run(Runner x) in first place? It has a return value...
It is equivalent to:
() -> { intMethod(); }
You do not have to do anything with return value.
Re: About Question enthuware.ocajp.i.v8.2.1475 :
Posted: Tue Dec 19, 2017 7:26 am
by ale8989
I'm sorry, for me it's really confusing.
1)In TestClass there is a run(Runner x) method, which dosn't implement Runner run() method, since class TestClass does not implement any interface. Correct?
2) Inside run(Runner x) there is a call for the Runner run() method. Correct?
3) Runner run() method is void and has a no-parameter list.
Inside TestClass we call Runner run() insiede run(Runner x), so my Big question:
Why is possibile to refere to a "Runner" reference, when calling intMethod() (inside the lambda) which returns an int... and not a "Runner"?
Like: void methodOne(String s) wants a String.
void methodTwo(Superclass s) wants a reference of Superclass and we can pass also a subclass reference and that will
still works.
But how can I pass an integer to a method that wants a reference of an interface?
Many thanks.
Re: About Question enthuware.ocajp.i.v8.2.1475 :
Posted: Tue Dec 19, 2017 10:17 pm
by admin
ale8989 wrote:
Inside TestClass we call Runner run() insiede run(Runner x), so my Big question:
Why is possibile to refere to a "Runner" reference, when calling intMethod() (inside the lambda) which returns an int... and not a "Runner"?
But how can I pass an integer to a method that wants a reference of an interface? [/u]
Good question. You need to think at a completely different level while working with lambdas. The first thing that you should remember is that lambdas are a compile time thing. When you compile the code, the compiler converts lambda expressions into anonymous inner class code. There is no trace of a lambda expression in the generated class file.
Now, about the above code. Whoever calls TestClass's run(Runner x), indeed needs to pass in a reference to an "object of a class that implements Runner interface" (let's call it a "Runner object", for short) interface. This fact doesn't change. Whether you use lambda or not.
When you pass in a lambda expression, you are actually telling the compiler that here is the code that I want to use to create the only method that has to be there in a Runner object, so go write an anonymous class that implements Runner interface and put this code inside that class's method.
So when you pass in (() -> intMethod()) to TestClass's run(Runner ) method, the compiler converts it to:
Code: Select all
new Runner() {
public void run(){
TestClass.intMethod();
}
}
So the lambda expression ()->intMethod() is just a short hand for the big anonymous class code. But you can see that we are indeed passing a Runner object to the run method.
HTH,
Paul.
Re: About Question enthuware.ocajp.i.v8.2.1475 :
Posted: Wed Jan 17, 2018 5:45 am
by ale8989
Hello Paul,
sorry for the delay.
Now this makes absolutely sense!
Thank you very much, perfect explanation!
Re: About Question enthuware.ocajp.i.v8.2.1475 :
Posted: Tue Jan 12, 2021 8:04 am
by Denyo1986
admin wrote: ↑Wed Apr 08, 2015 11:34 am
No, it is just a lambda expression. It is not a statement.
Dear Admin,
I dont understand your response to this question.
An expression would be 5 == 10 or object.isArray() or something like this. But here we print something text on the console, which imho clearly is a statement (therefore we always write a ; after it).
All articles about Lambda expressions say that an expression does not need semicolon, one or more statement do need {} and ;
I dont understand why in this example here the part
is not a statement that needs to accompanied by a ";".
Could you please elaborate on this?
Then, on a second note, I never understood this whole question in the first place. The question says which lambda expression
captures the above interface. Nowhere in mentioned interface is anything printed out to the console. And nowhere in the lambda is any reference done to the runner interface. So, for me, they have hardly anything to do with each other, except for the fact that both dont take parameters and dont return anything (the latter is even not entirely true).
So how are we actually
capturing that interface? Is capture the right word here?
Or are we only looking at similarities / common grounds between a functional interface and a lambda expression that have nothing to do with each other?
Re: About Question enthuware.ocajp.i.v8.2.1475 :
Posted: Tue Jan 12, 2021 9:22 am
by admin
I am not sure I understand your question correctly. But the question is just looking for a valid lambda expression that can be supplied, for example, to a method that expects a Runner object. Something like:
Code: Select all
class X
void someMethod(Runner r){
}
}
To call it, you would do: new X.someMethod(() -> System.out.println("running...")); The part inside the ( ) is the lambda expression that captures Runner interface. As you can see, no semicolon should be present after () -> System.out.println("running...").
System.out.println("running...") is not a statement in this case. It is an expression. You might want to read about the difference between a statement and an expression from Section 6.1.2 of
Deshmukh's OCP Java 11 Part 1 Fundamentals if you have any confusion.
Re: About Question enthuware.ocajp.i.v8.2.1475 :
Posted: Tue Jan 12, 2021 9:51 am
by Denyo1986
admin wrote: ↑Tue Jan 12, 2021 9:22 am
I am not sure I understand your question correctly. But the question is just looking for a valid lambda expression that can be supplied, for example, to a method that expects a Runner object. Something like:
Code: Select all
class X
void someMethod(Runner r){
}
}
To call it, you would do: new X.someMethod(() -> System.out.println("running...")); The part inside the ( ) is the lambda expression that captures Runner interface. As you can see, no semicolon should be present after () -> System.out.println("running...").
System.out.println("running...") is not a statement in this case. It is an expression. You might want to read about the difference between a statement and an expression from Section 6.1.2 of
Deshmukh's OCP Java 11 Part 1 Fundamentals if you have any confusion.
Hey there,
thanks for the explanation but a link to an offline book is really a easy-to-use ressource. My exam is this Friday, therefore no chance to read a whole book just to get one question answered (even though I wish I could).
Do you have any other (easily available) sources that will support your statement?
Cause when I research, I only find results that support my view (an "expression" calculates to a value, which println() certainly doesnt, a statement "does something" which println() clearly does. Furthermore, every article about lambdas says that an expression can be without ";" but a statement must have the semicolon.
How can it be explained that here, in this case, a statement does not need a semicolon (or that the definition of a statement changes compared to te rest of the java world).
I am quite confused. Hope you can help me to get my head around this. Thanks for your time and effort.
Re: About Question enthuware.ocajp.i.v8.2.1475 :
Posted: Tue Jan 12, 2021 11:31 am
by admin
Ok, I think I understand your question now. You are looking at System.out.println("running...") in isolation. But the question is about the "lambda expression". So, yes, if you just look at System.out.println("running..."), then it is not an expression because it doesn't return a value. But "() -> System.out.println("running...")" (without the quotes) is a valid lambda expression and it doesn't need semicolon.
You can actually try out the following code, which proves that it doesn't need semicolon:
Code: Select all
interface Runner {
public void run();
}
class X{
void someMethod(Runner r){
r.run();
}
}
public class TestClass{
public static void main(String[] args) {
new X().someMethod(() -> System.out.println("running..."));
}
}
Re: About Question enthuware.ocajp.i.v8.2.1475 :
Posted: Tue Jan 12, 2021 1:09 pm
by Denyo1986
Thanks a lot again.
Got it now.
This is the rule that I was missing:
A return statement is not an expression; in a lambda expression, you must enclose statements in braces ({}). However, you do not have to enclose a void method invocation in braces. For example, the following is a valid lambda expression:
email -> System.out.println(email)
https://docs.oracle.com/javase/tutorial ... sions.html
Because I read everywhere that the body of the lambda expression must consist of one expression (without ";") or one or several statements that need to have a ";" each. However, the exception from that rule that is cited above explains why for this statement (i.e. a call of the void method println() ) does not need the ";". When I was assessing the options of the question I was looking mostly for correct syntax, that is why I stumbled upon that.
Maybe you could add this info in the explanation that void method calls dont need ";" since I was not the first one to got confused by this.
Re: About Question enthuware.ocajp.i.v8.2.1475 :
Posted: Tue Jan 12, 2021 11:49 pm
by admin
Good point. Added.
thanks for the feedback!