Define method with object instantiation in java - java

I'm slowly transitioning from C++ to java and I do not understand the following piece of code:
public class TestThread
{
public static void main (String [] args)
{
Thread t = new MyThreads()
{
public void run()
{
System.out.println(" foo");
}
};
t.start();
System.out.println("out of run");
}
}
An object type "MyThreads" is being instantiated, but what does the function "void run" mean?
Why is it written using that syntax right after the object instantiation?
Is that function being overriden?
When is this kind of syntax (where I define a function with an object instantiation) necessary/required? and where is it preferred/useful?

It means that the class MyThreads either require you to first write a method with name run or the way you are doing provides the ability to change the existing run method behaviour where you are declaring.
It is like overriding if run method is already there or creating the method when you want to create object.
This provides the ability to create objects of MyThreads without having to change the original class or creating multiple classes.
public class TestThread
{
public static void main (String [] args)
{
Thread t = new MyThreads()
{
public void run()
{
System.out.println(" foo");
}
};
t.start();
Thread t1 = new MyThreads()
{
public void run()
{
System.out.println(" this time it is somethidn else");
}
};
t1.start();
System.out.println("out of run");
}
}
Little modification to your code shows the advantage of having this feature. If you observe run method of t1 is doing something different than what is in t. So it is now completely new thread.

This code is equivalent to
public class TestThread
{
static class MyThreadSubclass extends MyClass {
public void run() {
System.out.println("foo");
}
}
public static void main (String [] args)
{
Thread t = new MyThreadSubclass();
t.start();
System.out.println("out of run");
}
}
It's just a convenient way of defining a subclass inline, without having to give it a name; it's just syntactic sugar. It's creating an object of a subclass that overrides the method run() from MyThreads.

Related

Adding a method to a class using anonymous class [duplicate]

Is there any Java syntax to access new methods defined within anonymous inner classes from outer class? I know there can be various workarounds, but I wonder if a special syntax exist?
For example
class Outer {
ActionListener listener = new ActionListener() {
#Override
void actionPerformed(ActionEvent e) {
// do something
}
// method is public so can be accessible
public void MyGloriousMethod() {
// viva!
}
};
public void Caller() {
listener.MyGloriousMethod(); // does not work!
}
}
MY OWN SOLUTION
I just moved all methods and members up to outer class.
Once the anonymous class instance has been implicitly cast into the named type it can't be cast back because there is no name for the anonymous type. You can access the additional members of the anonymous inner class through this within the class, in the expression immediate after the expression and the type can be inferred and returned through a method call.
Object obj = new Object() {
void fn() {
System.err.println("fn");
}
#Override public String toString() {
fn();
return "";
}
};
obj.toString();
new Object() {
void fn() {
System.err.println("fn");
}
}.fn();
identity(new Object() {
void fn() {
System.err.println("fn");
}
}).fn();
...
private static <T> T identity(T value) {
return value;
}
A student in my class asked our professor if this could be done the other day. Here is what I wrote as a cool proof of concept that it CAN be done, although not worth it, it is actually possible and here is how:
public static void main(String[] args){
//anonymous inner class with method defined inside which
//does not override anything
Object o = new Object()
{
public int test = 5;
public void sayHello()
{
System.out.println("Hello World");
}
};
//o.sayHello();//Does not work
try
{
Method m = o.getClass().getMethod("sayHello");
Field f = o.getClass().getField("test");
System.out.println(f.getInt(o));
m.invoke(o);
} catch (Exception e)
{
e.printStackTrace();
}
}
By making use of Java's Method class we can invoke a method by passing in the string value and parameters of the method. Same thing can be done with fields.
Just thought it would be cool to share this!
Your caller knows listener as an ActionListener and therefore it doesn't know anything about that new method. I think the only way to do this (other than doing reflection gymnastics, which really would defeat the purpose of using an anonymous class, i.e. shortcut/simplicity) is to simply subclass ActionListener and not use an anonymous class.
Funny enough, this is now allowed with var construct (Java 10 or newer). Example:
var calculator = new Object() {
BigDecimal intermediateSum = BigDecimal.ZERO;
void calculate(Item item) {
intermediateSum = Numbers.add(intermediateSum, item.value);
item.sum= intermediateSum;
}
};
items.forEach(calculator::calculate);
Here with method reference, but works with dot method call as well, of course. It works with fields as well. Enjoy new Java. :-)
I found more tricks with var and anonymous classes here: https://blog.codefx.org/java/tricks-var-anonymous-classes/
No, it's imposible. You would need to cast the ActionListener to its real subclass name, but since it's anonymous, it doesn't have a name.
The right way to do it is using reflection:
import java.lang.reflect.InvocationTargetException;
public class MethodByReflectionTest {
public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
Object obj = new Object(){
public void print(){
System.out.println("Print executed.");
}
};
obj.getClass().getMethod("print", null).invoke(obj, null);
}
}
You can check here: How do I invoke a Java method when given the method name as a string?
Yes you can access the method see the example below if any doubt please comment
package com;
interface A
{
public void display();
}
public class Outer {
public static void main(String []args)
{
A a=new A() {
#Override
public void display() {
System.out.println("Hello");
}
};
a.display();
}
}

Is it possible to call a method in the same line you create an instance in java

class BooleanWrap{
boolean b = new Boolean("true").booleanValue();
}
When I try to do the same with the code below, it doesn't work:
class TestCode {
public static void main(String[] ar) {
TestCode tc = new TestCode().go();
}
void go() {
//some code
}
}
Compile error:
TestBox.java:6: error: incompatible types
TestBox t = new TestBox().go();
When I change the return type of method go() from void to class type, then I do not get the error anymore.
class TestCode2 {
public static void main(String[] ar) {
TestCode2 tc2 = new TestCode2().go();
}
TestCode2 go() {
//some code
}
}
What happens to the object I just created in above code (referenced by tc2)? Will it get abandoned?
TestCode tc = new TestCode().go() would only work if the go() method returns a TestCode, since you are assigning it to a variable of TestCode type.
In the case of TestCode2 tc2 = new TestCode2().go();, if the go() method returns a reference to a different instance of TestCode2 (i.e. not the one for which you called go()), the original instance won't be referenced anywhere and would be eligible for garbage collection. In other words, tc2 would refer to the instance returned by go(), which doesn't have to be the same instance as the one created in the main method with new TestCode2().
This should work just fine:
class TestCode{
public static void main(String[] ar){
new TestCode().go();
}
void go() {
System.out.println("Hello World");
}
}
Edit: Additional info
This way you can't save the created instance. It will get destroyed right away in the next garbage collection. So normally, to avoid this unneccessary creation and destruction a static method would be used if the instance itself is not needed.
class TestCode{
public static void main(String[] ar){
TestCode.go();
}
static void go() {
System.out.println("Hello World");
}
}
As Eran said, the method go() returns nothing, and you're trying to assing that nothing to a variable, your method needs to return something, a TestCode object in this case

implementing thread using runnable interface in java

Why we have to create an instance of a class and attach it to the newly created thread object even if both are in the same class?
import java.io.*;
class thread1 implements Runnable{
public void run(){
System.out.println("thread started");
}
public static void main(String args[]) throws Exception{
Thread t1=new Thread(new thread1());
t1.start();
}
}
You don't have to create a Runnable to perform custom code within a new Thread. It's also possible to create a subclass of thread directly.
public class WorkerThread extends Thread{
#Override
public void run() {
// TODO Auto-generated method stub
super.run();
// DO SOMETHING
}
}
public class MainClass {
public static void main(String[] args){
new WorkerThread().start();
MainClass mc = new MainClass();
mc.startThread();
}
private void startThread(){
Thread t = new WorkerThread();
t.start();
}
}
I think you have two questions in one:
1.) How to work with a Thread in Java? The answer of Fizer Khan is an example of this.
2.) How do static methods work in java? If you have a static method you are, in a maner of speaking, on a "static layer". You have no "this" reference because there is not object on this layer. Only if you create an instance you can access instance fields and non static methods on this object.
If you add a second static method, you can do the same stuff as in your main method, because both are static. This is rudementary look at this question: https://stackoverflow.com/questions/18402564/how-do-static-methods-work
pulblic class Thread1 implements Runnable{ //name should be upper case
public void run(){
System.out.println("thread started");
}
public static void main(String args[]) throws Exception{ //static method
Thread t1=new Thread(new Thread1()); //t1 is a local reference to an object on the heap - no specil magic here
t1.start(); //call to an "instance" method, can only be performed on an object.
}
There are two ways to write threads.
public class ThreadX implements Runnable {
public void run() {
//Code
}
}
/* with a "new Thread(new ThreadX()).start()" call */
public class ThreadY extends Thread {
public ThreadY() {
super("ThreadY");
}
public void run() {
//Code
}
}
/* with a "new ThreadY().start()" call */
public class MainClass {
private Thread threadX = new Thread(new ThreadX());
private Thread threadY = new ThreadY();
public static void main(String[] args){
// Call threads
threadX.start();
threadY.start();
// some more threads
new Thread(new ThreadX()).start();
new ThreadY().start();
}
}
When you extends Threads, You usually extend a class to add or modify functionality. So, if you don't want to overwrite any Thread behavior, then use Runnable.

Why is the constructor of a class which implements Runnable Interface not called?

I tried using the constructor of a class which implements Runnable Interface. But I was surprised to see it was never called. The run() method was called, however, the constructor was never called. I have written a simple sample code to show the phenomenon. Can anyone explain why this is happening?
public class MyRunner implements Runnable {
public void MyRunner() {
System.out.print("Hi I am in the constructor of MyRunner");
}
#Override
public void run() {
System.out.println("I am in the Run method of MyRunner");
}
public static void main(String[] args){
System.out.println("The main thread has started");
Thread t = new Thread(new MyRunner());
t.start();
}
}
Change public void MyRunner() to public MyRunner() (no return type). public void MyRunner() is not a constructor, it's a method. Constructor declarations don't have a return type.
You have a default Constructor there, since you don't define any constructor. And, the default Constructor was called internally.
A Constructor can't have return type. In your case, public void MyRunner() {} is a method. remove void from you Constructor signature.
Constructor is a special method which does not have return type and its name is same as Class name so remove void from method name to make it constructor.
public class MyRunner implements Runnable {
public MyRunner() {
System.out.print("Hi I am in the constructor of MyRunner");
}
#Override
public void run() {
System.out.println("I am in the Run method of MyRunner");
}
public static void main(String[] args) {
System.out.println("The main thread has started");
Thread t = new Thread(new MyRunner());
t.start();
}
}
This will work and your constructor will be called.

Callback from new thread to class from which thread was initiated

I have a class from which I am calling a new thread.
public class MainClass{
private void cleardata() {
// do something on a separate thread
new Thread(new Runnable() {
#Override
public void run() {
//Do Something
//After this I would like to notify my MainClass that some thing has been done and pass a value.
}
}
}
private void callbackFunc(int a){
// Do something based on value of a
}
}
I have a function in my MainClass. But how do i call this function from my new thread, so as to receive a callback.
Thanks.
You should just be able to call the method in MainClass by its name just as if you were calling from directly inside MainClass itself (as opposed to from the inner class).
If a method name you want to call happens to conflict with one that your inner class has inherited from Object then you can prefix the call with MainClass.this, e.g. MainClass.this.toString() calls toString on MainClass, whereas just toString() calls it on the inner class instance.
In such a case pass the instance of MainClass to the thread class ((during creation)) so that it can call method on it. Having inner class as suggested by others is also a good option.
Something similar-
class MainClass {
private void cleardata() {
new Thread(new MyThread(this)).start();
}
}
class MyThread implements Runnable {
private MainClass mc;
MyThread(MainClass mc) {
this.mc = mc;
}
public void run() {
// do something
// mc.someMethod();
}
}
public class MainClass{
private void cleardata() {
// do something on a separate thread
new Thread(new Runnable() {
#Override
public void run() {
callBackFunc(result);
}
}
}
private void callBackFunc(int a) {
}
}
Just do it:
public class MainClass{
private void cleardata() {
// do something on a separate thread
new Thread(new Runnable() {
#Override
public void run() {
//Do Something
notifyTheClass("a parameter");
}
}
private void notifyTheClass(String aParam) {
//..do something else
}
}
}
But it is not related to threads, this is about inner classes. If you want the main thread to wait until the new thread is finishes, use Futures for a result. Or use some other multithreading primitives.

Categories