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.
Related
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.
I've recently started working on a Java Project that was done many years ago and I'm trying to understand the code as much as I can (considering I'm somewhat of a beginner trying to evolve).
Here's my doubt:
I have two classes, let's say it's ClassA and ClassB that don't extend one another.
In ClassA there's a main method that runs the following code:
Thread object = new Thread(ClassB);
object.start();
From my understanding of threads, this should call a run() method on ClassB.
However the most important method on ClassB is a doMain() method and there is no run().
How do I know if doMain() is actually the method being called?
Thanks for the help :)
P.S. This is an example code, the real code is 1000x more complex and maybe there are nuances that I'm not getting, but any clues on what to do would be great.
There is two constructors for Thread you must be using here
Thread object = new Thread(classB);
Either classB is a String or Runnable. There is no other options which will compile. Assuming it is not a String, and it is a Runnable it must have a run() method or it won't compile (or if its an abstract class you can't create an instance)
In short, you have a run() method.
This is an example code, the real code is 1000x more complex and maybe there are nuances that I'm not getting, but any clues on what to do would be great.
The simplest way to prove this is to check the call hierarchy of doMain() in your IDE or add a breakpoint on this line and run your code in your debugger.
The method Thread.start always calls the run method, it's stated explicitly in the documentation: Thread#start().
Perhaps that your class with the doMain method inherits some other class, where the doMain method is abstract and the run method, defined in the same parent class, calls it?
Let say I have:
class Superclass {
//fields...
methodA() {...}
methodB() {...}
...
}
class Subclass extends Superclass {
//fields...
methodA() {
// Here I need to call methods A and B from superclass:
// For this, I can use supper
super.methodA();
super.methodB();
// Or I have to instantiate the superclass and use the instance
Superclass superclass = new Superclass();
superclass.methodA();
superclass.methodB();
}
It works both ways, but I want to know which is better to use. Any of these ways is a bad programming technique? I hope you give me answer and arguments.
super.methodA();
Superclass superclass = new Superclass();
superclass.methodA();
These two calls of methodA work on different instances, so they are completely different. super.methodA() executes methodA on the current instance. superclass.methodA() executes methodA on a new instance of Superclass which is not related to the current instance.
You would almost always use the first option. As for the second option, It doesn't make sense to create a new instance, call a method on that instance and then never do anything with that instance again.
It works both ways, but I want to know which is better to use.
Well that entirely depends on what you're trying to achieve. If you want to create a new, entirely independent instance, do so. But it's more common that you want to use the superclass implementation of a method you're overriding on the same instance that the overridden method is currently executing on in which case you would use super.methodA().
In my experience, super is most commonly used when overriding a method to do some subclass-specific work, call the superclass implementation, then do some more superclass-specific work. For example:
#Override public void add(Foo foo) {
doSomeSubclassSpecificValidation(foo);
super.add(foo);
doSomeSubclassSpecificBookKeeping();
}
In other words, even though you're overriding the method, you still want the "normal" behaviour - you just want some extra code to run as well. Or sometimes you want to run the superclass code conditionally, e.g. only if the input meets a certain criterion.
It's totally different.
super.methodA() will call methodA() in the left circle, while creating a new superclass and calling that methodA() will first create the right circle, and then call methods from it.
With above answers, you must have understood that basically you are calling same method of same class but on two different objects so it all depends as what you are trying to achieve ( On which object you plan to call those methods ). As you know, call to same methods of same class but on different instances are not the same. "super" object is parent of "this" object and that super object was created implicitly when you instantiated Subclass so as per your example code, both are NOT SAME but for simple cases,output might be same. Go one more level up and see if it looks different to you from client code ( try writing calling code of Subclass ).
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.
I am going through Hello Android (Android PDF/tutorial) and have now seen this syntax a couple of times. Can someone please explain to me what Java syntax is used when run Runnable is defined?
private class AndroidBridge {
public void callAndroid(final String arg) { // must be final
handler.post(new Runnable() {
public void run() {
Log.d(TAG, "callAndroid(" + arg + ")" );
textView.setText(arg);
}
...
Is the code defining a Runnable object and overriding it's run method?
As Dave Newton indicated, this is an anonymous inner class implementing the Runnable interface.
As to why one would want to use this, it could be thought of as syntactic sugar of sorts. You'll notice that in your example, the code in run() has access to the same scope as where the anonymous inner class itself is defined.
This simplifies access to those members, as if you defined the class externally, you'd have to pass in a reference to any object whose members you wanted to invoke/use.
In fact, IIRC, this is actually what happens when Java compiles the anonymous inner class; if there are references to the outer containing class, the compiler will create a constructor that passes in a reference to the outer containing class.
The .post method expects a Runnable object, which in your code sample is declared anonymously and passed as the argument.
That will start a new thread for some long-running process.
The thread constructor needs a Runnable object, which has a run method that's called when the thread is ready.
When many Java apps start, all of the operations pile up on one thread, including the UI. I mainly use threads to avoid freezing up the UI if I'm doing something "heavy".
You've seen this happen when you click "execute" or something, and the UI suddenly is less than responsive. This is because the current thread doesn't have enough resources to build the UI and do whatever "execute" is asking.
So, sometimes that's done elsewhere, on a different thread, which needs a Runnable object.
It's worth noting that multithreading (where you make more than one thread on purpose) is notoriously difficult to work with, for debugging reasons mostly, IMO. But it is a useful tool, of course.
The code is defining an anonymous inner class that implements the Runnable interface, and implementing the run method to perform the appropriate actions.