Quick Java Anonymous function/class question - java

I know how anonymous functions work in JS and all but a bit confused on parts of it in Java.
So below I have an anonymous class (I'm just using the Thread class as an example to what I've seen), where I override the run() function and then call .start() on that class.
new Thread() {
#Override
public void run() {
System.out.println("Hello from the anonymous class thread");
}
}.start();
So this works, but IntelliJ wants to me re-write it as this:
new Thread(() -> System.out.println("Hello from the anonymous class thread")).start();
I get most of this syntax, but just a bit confused as to how the run() function is being overridden. From my understanding, there is no parameter being passed into the Thread class (so nothing being passed into the constructor I'm assuming). Now where I'm confused is here. It doesn't state anywhere that it is overriding the run() function. Is this a special case for the Thread class or is there something I am missing?
Hope that I explained this clearly and thanks in advance!

The syntax that IntelliJ proposes to you is not more of an "oblique" translation of your original code, and does not actually override Thread.run like your original code does.
Your original code creates an anonymous subclass of Thread with run overridden, whereas the proposed syntax by IntelliJ calls this constructor of Thread that accepts a Runnable. The lambda expression represents the Runnable. If we "expand" the lambda expression into an anonymous class, we will be actually doing this:
new Thread(new Runnable() {
#Override
public void run() {
System.out.println("Hello from the anonymous class thread");
}
}).start();
So we are creating an anonymous implementation of Runnable, and implementing Runnable.run instead.
It doesn't state anywhere that it is overriding the run() function.
True, but run is the only abstract method in the Runnable interface, so Java is able to figure out that you are overriding that method.

The run() function is being overridden implicitly because it's the only method of the Runnable interface, which makes it a functional interface. A functional interface has exactly one abstract method. This special property of an interface allows you to implement it implicitly using a lambda expression. The compiler knows you're providing an implementation of the Runnable.run() method, because it's the only method inside the interface.
If you take a look at the Runnable interface, you'll see that it is decorated with the #FunctionalInterface annotation. This annotation ensures that the decorated interface can never have more than one abstract method (or else the compiler will fail). Note that this annotation is not required in order for the implicit lambda feature to work.

Related

Is it necessary to define run() method when extending Thread class?

When I searched on the internet about extending the Thread class, all the examples I came across had overridden the run() method. I have also extended the Thread class in my program but I haven't defined the run() method. It's just another class (I'll refer to it as MyClass), which extends Thread class, with a constructor and a few methods defined by me. However, I'm puzzled because I have created an object of MyClass in the Main class and have called the start() method using that object in main() method. And it still works.
My question is whether the run() method is implicitly defined by the Java compiler, like the default constructor, or is it simply not required to be overridden when extending the Thread class?
No, the run() method is not implicitly defined by the Java compiler. It is explicitly defined by the Thread class.
If this thread was constructed using a separate Runnable run object, then that Runnable object's run method is called; otherwise, this method does nothing and returns.
It is not abstract, so it does not need to be overridden. There is nothing special about the run method here.
Because you're extending Thread and not supplying a separate Runnable, your class inherits the run method; run runs and does nothing.
Because it does nothing, it's not very useful. Usually you want to do something in your Thread, so normally when creating a Thread this way, run is overridden to do something useful.

Why is Thread not an abstract class and start() not final?

Why was the Thread class implemented as a regular class and not an abstract class with run() method being abstract.
Will it possibly introduce any problems? Or does it have any use in being this way?
Also, the Thread.start() method is supposed to be a very specific method whose functionality cannot be implemented by any other class (If I am not wrong). And hence I guess the final keyword would be apt for this more than any other method.
But I am able to override this method and use it as I like,
public class Test extends Thread {
public static void main (String... args) {
Thread test = new Test();
test.start();
}
#Override
public void run() {
System.out.println("New thread started...");
}
#Override
public void start() {
System.out.println("Did anyone tell you I will spawn a new thread??");
}
}
It obviously only printed,
Did anyone tell you I will spawn a new thread??
Is there any use in overriding other than confusing the engineer replacing you?
If not, why was the method not declared final in Thread class?
You can of course choose to shoot yourself in the foot, but that doesn't mean you must.
Why was the Thread class implemented as a regular class and not an abstract class with run() method being abstract.
Because the recommended way to create a start a thread is not to subclass Thread. The recommended way is to define a Runnable, and pass it as argument to the Thread constructor:
Runnable r = new Runnable() {
#Override
public void run() {
...
}
};
Thread t = new Thread(r);
t.start();
And hence I guess the final keyword would be apt for this more than any other method.
Yes and no. You can't replace the implementation of start() by your own implementation, but you can do additional things in start() if you want:
#Override
public void start() {
System.out.println("Did anyone tell you I will spawn a new thread??");
super.start();
}
That said, if Java was redesigned from scratch today, there is a good chance the design would be different. Remember that this class dates from Java 1.0, and is still backward-compatible.
Why was the Thread class implemented as a regular class and not an
abstract class with run() method being abstract.
This question actually boils down to the fact that you should always prefer composition over inheritance.
If the Thread class was declared as abstract, the language would have to provide another class that extended from it which programmers could use to create a Thread. Your question would then be about why this class that extends from Thread is not abstract. If the language did not provide another class that extends from Thread, programmers would have to create their own class that extends from Thread and override the run() method.
If not, why was the method not declared final in Thread class??
The only possible explanation I can give is that the developers of the language saw some use-cases for overriding start when the class was introduced to the JDK. The first version of Java that I used was 1.5 and I personally have not come across a use-case where I found the need to override start. As JB Nizet stated in his answer
if Java was redesigned from scratch today, there is a good chance the design would be different
Why is Thread.start() not final?
Are you sure you would never want to override it?
Class MyThreadFactory implements ThreadFactory {
#Override
public Thread newThread(Runnable r) {
return new Thread(r) {
#Override
public void start() {
LOGGER.info("Starting thread " + this);
super.start();
}
};
}
}
I feel a few calirifcations should be posted for the answers :
"Are you sure you would never want to override it?"
No ! I would not. Thats like saying, "Are you sure , you want to declare this variable private?" Because if I could declare any variable I use as public without fearing that other developers may mess my design logic, coding would be a breeze. One of the most important purpose of OOPS concepts of Scope, abstraction, polymorphism, Error handling etc is to communicate to other developers the design and intentions behind your code.As pointed out in the question, when you override start method, nobody is forcing you to use super.start(). #Codebender wrote a start method for a thread without using super.start() and compiler never complained. So he is free to break the whole mechanism of Threading and compiler is suppose to just let it pass? Thread's start method ensures that run method is called and execute at the right time ! It is critical to the very concept of Threading. I would be more than happy to be corrected, if I missed something here.
2.
Because the recommended way to create a start a thread is not to
subclass Thread.
OK, if codebender is allowed by design, to sublass Thread and mess up the start method, By that logic, it is the design shooting itself in the foot.
By another statement made,(which I agree with completely) , Runnable is the recommended way. Then why do we allow Thread class at all to instantiate the thread at all with no restrictions? This is followed by :
You can't replace the implementation of start() by your own
implementation,
That actually supports codebender's claim that start method should be final when you say that.. ^
The one point, that's valid, is mentioned already as a side note, but is the actual answer to this question
"Backward compatibility".
In fact, improvements were even going on as late as JDK 5.0 , when they incorporated many major additions and clarifications to the Java concurrency model. We want backward compatibility to be supported all the way and thats why Thread class is still exactly as it was before, even though Runnable interface is the recommended way nowadays.
Again, I would be more than happy to be corrected, if I missed something.

how just by implementing an interface subclass acquires the behaviour

I always wonder how just by implementing an interface , sub class acquires the behavior. For example if I implement Runnable interface my subclass start behaving as thread, but what if I implement all the methods defined in interface Runnable but not write "implementing Runnable", subclass doesn't behave as Thread. Same with EventListeners . Please help me understanding this behavior.
By implementing an interface I, you're declaring that the Object "is a" I and that it'll contain all the methods defined by this interface. If you just implement the methods of the interface I, but don't declare it by an implement statement, compiler won't be able to determine that your class "is a" I and you won't be able to use it as a I-type.
No, Runnable has nothing to do with behaving like a thread. It just contains a plain, simple, void nullary method called "run".
Not specifying implements Runnable will just make your object not an instance of the Runnable type, which means you won't be able to pass it to a method requiring a Runnable. This is just an issue of type safety. The method you call could also accept an Object and invoke run using reflection, with the exact same behavior.
When you are implementing Runnable your class does not become thread and does not start behavior as thread. However if your class implements Runnable you can run it in context of thread:
class MyClass1 implements Runnable {
public void run() {
// this stuff will run in thread when thread's start() method is called
}
}
new Thread(new MyClass1()).start();
But java is strongly typed language. You can just create class like this:
class MyClass2 {
public void run() {
// this stuff will run in thread when thread's start() method is called
}
}
But it will not be Runnable. Therefore you cannot just send it to thread:
new Thread(new MyClass2()).start();
In this case you will get compilation error. Compiler cannot know that your class indeed implements method that looks like one that is declared in Runnable. You must declare this (as in first case).
A Runnable only allows your class to be run in a Thread. You still need e.g. a java.util.concurrent.Executor to actually run it in an actual Thread.
However, you can extend Thread which would allow you to call Thread.start().
To actually get out behavior from just implementing an interface, you would need a second object inspecting the classpath for classes implementing your interface using reflection, and then do something with that class.
Your question has two aspect:
Interface as a contract: Interfaces imposes a behavioral contract on a class implementing it. For example, If Car is an interface with some methods abstractly defining a car, any class implementing Car interface will have to define the methods of the car. You are free to actually implement the behavior.
Analogy of Runnable acting as thread is incorrect. What makes Runnable class act as thread is the the Thread class. Runnable just specifies the contract for a class to act as thread. Check this post.
This is not a subclassing behavior. In order to use subclass behavior you need to extend the class.
W.r.t interfaces these are just templates/contracts that are implemented by class. In order for runnable to work calling program need to instantiate a thread and when thread will start it will call run method implemented by your class.
I always wonder how just by implementing an interface , sub class acquires the behavior.
It doesn't 'acquire' any 'behaviour'. The subclass provides the behaviour. What implementing the interface does is provide the compile-time type signatures such that you can use the subclass where the interface is specified.

questions on implementing Runnable [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Java: “implements Runnable” vs. “extends Thread”
I have two questions about multithreaded programming. I read a few answers on the internet, but still I can't find a satisfying answer.
Implementing the Runnable is preferred over extending the thread class. Why?
How is it that we are able to get away with overriding just the run() method?
According to 'The Complete Reference to Java' by Herbert Schildt, If we are not overriding any methods of Thread class other than run(), it's better we implement Runnable.
My 2nd question might sound a bit silly, but I seem to be missing something and I'm not sure about how the whole thing works.
1: Implementing the Runnable is preferred over extending the thread class. why?
Because it allows your class to extend another class if it wants to instead of being forced to extend Thread.
2: How is it that we are able to get away with over-ridding just the run() method?
You can certainly override other methods but the Thread object will call the run() method when the thread is started. That's how it works. The default Thread.run() method is:
public void run() {
if (target != null) {
target.run();
}
}
If you call the Thread constructor with a Runnable then that is what the target is set to. If you instead extend Thread and #Override the run() method then that is the method that will be called when the thread object is started.
That's how the Thread class works.
2: How is it that we are able to get away with over-ridding just the run() method?
You may have misspoke here and were instead asking why we only need to implement the run() method in Runnable().
Runnable is an interface with a single run() method that you must implement.
Thread is a concrete class that you are extending. You can override any methods in a concrete class unless the class is final or the method is final.
Make sure you use proper Java terminology and don't mixup implement and override.
Three fundamentals before you delve deeper.
A class can only extend one class.
A class can implement any number of interfaces.
An interface can extend any number of interfaces.
Additionally, an abstract class is a class. So it behaves like a class and you can't implement it. You only extend it.
There are a number of traps which can occur if you extend Thread which you don't get with implementing Runnable.
public static String getName() {
return "My Test Application";
}
public static void stop() {
System.out.println("Shutting down");
}
public static void main(String... args) {
new Thread() {
#Override
public void run() {
System.out.println(getName());
stop();
}
}.run();
System.out.println("Bye now.");
}
prints
Thread-0
Bye now.
See how many bugs you can spot.
Unnecessary inheritance is generally a bad idea. You might hear "prefer composition over inheritance" often enough. I'm sure google can pull up enough links for you. The general issue is that inheritance bring tight, unnecessary coupling between classes.
Same goes for GUI components, btw.

Anonymous class definition based on interface... maybe?

I saw this Java snippet in the book Spring in Action, but I'm not familiar with the language construct.
new RowMapper() {
public Object mapRow() throws SQLException, DataAccessException {
Motorist motorist = new Motorist();
motorist.setId(rs.getInt(1));
motorist.setEmail(rs.getString(2));
motorist.setPassword(rs.getString(3));
motorist.setFirstName(rs.getString(4));
motorist.setLastName(rs.getString(5));
return motorist;
}
}
According the Spring documentation, RowMapper is an interface. It looks to me like an anonymous class definition based on the RowMapper interface. The new keyword is a little confusing, making me wonder if this also creates one instance of the anonymous class. I would guess yes, because if the class has no name, how will you ever create an instance after the line that defines it?
Can anyone confirm my guesses that:
this is an anonymous class definition based on the RowMapper interface, and
it creates a single instance of that class?
This is an anonymous class definition based on the RowMapper interface
That's precisely what it is.
It creates a single instance of that class?
Yep. That's correct.
That code is implementing the interface in an anonymous way.
The syntax would be similar to:
Runnable runnable = new Runnable() {
public void run() {
}
};
Note the semicolon at the end of the declaration. Here the runnable object, though holds the reference to the Runnable interface actually contains the implemented object. That's runtime polymorphism for you!
Your guesses are entirely correct. An anonymous class definition may be based on either a non-final class or on an interface, and you must implement all abstract (or interface) methods. The only available syntax for declaring anonymous classes is new, which also has the effect of instantiating exactly one instance of the anonymous class (in the course of the program, though, many instances of the same anonymous class could be created, if this code is executed several times).
Interface tells what methods the built class instance should have or if thy are label interfaces, then what kind of behavior to associate with it.
Anonymous classes are classes that basically while instantiating a class instance thy are also extending it with custom code. So if you are instantiating a interface, then you must write all the methods described with that interface, and as long as you do at least that much, then compiler will be happy. This is what is done here.
IS this is an anonymous class definition based on the RowMapper interface?
Yes. As you can see mapRow() function has been written. And if you debug the code you can see, that is not a class of an instance of interface, but class that extends interface. In case of abstract class or just class, it would be same - extended. So if class is final you cant write anonymous class for it.
Does it create a single instance of that class?
Well, it extends it and makes an instance of it. It will be single instance and any sequent call to it would result in a different class. If you debug the code, then you can even see different class names dynamically associated with it.
Solely from the code above and without knowing about RowMapper, all you can assume is that a new anonymous class based on RowMapper (which may be an interface or a class) is instantiated.
Declaring Anonymous class and in below example it creates two instances .
public class Multithread {
void test(){
new Runnable() {
#Override
public void run() {
System.out.println("1");
}
}.run();
new Runnable() {
#Override
public void run() {
System.out.println("11");
}
}.run();}
public static void main(String[] args) {
new Multithread().test();
}
}

Categories