I was reading through one of Oracle's lambda expression tutorials, and came across the following code:
http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/Lambda-QuickStart/index.html
public class RunnableTest {
public static void main(String[] args) {
System.out.println("=== RunnableTest ===");
// Anonymous Runnable
Runnable r1 = new Runnable(){
#Override
public void run(){
System.out.println("Hello world one!");
}
};
// Lambda Runnable
Runnable r2 = () -> System.out.println("Hello world two!");
// Run em!
r1.run();
r2.run();
}
}
My question is why didn't they implement Runnable when creating the class? Since they overrode the run method when initializing r1, did that take care of the implementation?
Yes, this is called an anonymous class in Java.
https://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html
You can implement an interface or extend a class when using the new operator, which will create a new instance of the unnamed subclass you define at the time. It's mostly used when you're writing code to be used in another thread or as a callback, since you only get the one instance.
The new lambda syntax in Java 8 replaces anonymous classes for interfaces with a single method, such as Runnable or the interfaces in java.util.function. This is what they're demonstrating in the example.
Related
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;
}
}
This question already has answers here:
How are Anonymous inner classes used in Java?
(18 answers)
Closed 3 years ago.
While creating threads I see code like:-
Runnable watdaheck = new Runnable()
{
System.out.println("java with time contradicts itself");
}
From what I know an interface cannot be instantiated so I fail to understand how we can write Runnable() for creating anonymous class. An interface can be given a reference but cannot be instantiated is what we are taught in polymorphism.
Runnable is interface, you are creating an anonymous class which implements the Runnable interface.
I just modify a bit your code.
Runnable watdaheck = new Runnable()
{
public void run(){
System.out.println("java with time contradicts itself");
}
}
The right part
new Runnable()
{
public void run(){
System.out.println("java with time contradicts itself");
}
}
is an instance of an anonymous class that implements interface Runnable
The left part Runnable watdaheck, watdaheck is a reference that refers to above object.
Your code is same with below code:
class SubRunnable implements Runnable{
public void run(){
//do something
}
}
Runnable r = new SubRunnable();
You should read more about anonymous class in Java. https://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html
Runnable is an interface. We use it with the "new" operator in order to create an anonymous class object whICH
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()
}
};
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I run into some code which contains anonymous classes. I haven't met with anonymous classes before, so I did some research on them.
My main area of interest is java, so I checked Oracle's tutorial of anonymous classes. I understand the mechanism and I see the point of the examples but in my opinion using anonymous classes makes the code hard to read and can cause a lot of headache.
Are there any cases when it is unavoidable to use anonymous classes or it is advised to use them instead of named classes?
Are there any cases when it is unavoidable to use anonymous classes
No, you can always just use a private inner class instead of an Anonymous class.
using anonymous classes makes the code hard to read and can cause a lot of headache
This very much depends on how you use anonymous classes. Consider the following example:
new Thread(new Runnable() {
#Override
public void run() {
// do something
}
}).start();
In this example you create a Runnable which is run by a thread. If you wouldn't use an anonymous class you'd have to write it as follows:
private class SomeClass implements Runnable {
#Override
public void run() {
// TODO Auto-generated method stub
}
}
and use it as:
new Thread(new SomeClass()).start();
With the first possibility you can directly see what that thread is doing, in the second possibility you'll first have to find the class that is used here.
Another advantage of anonymous classes. You can do the following:
// define some constant which can be used in the anonymous class:
final String someStr = "whatever";
new Thread(new Runnable() {
#Override
public void run() {
// use the String someStr directly
System.out.println(someStr);
}
}).start();
You can use the constant which is declared in the code where the anonymous class is defined. If you'd use a private inner class you'd have to give these constants to the constructor of the class in order to use them!
You can always avoid using of anonymous classes by defining new class implicitly. However in some cases it's better to use anonymous classes. Consider following example:
void main() {
new Thread(new Runnable(){
public void run() {
System.out.println("Hello world");
}
}).start();
}
Code snippet above is more readable and shorter then defining new class.
public class MyRunnable implements Runnable {
public void run() {
System.out.println("Hello world");
}
}
void main() {
new Thread(new MyRunnable()).start();
}
In Java 8 labmda can be used instead of anonymous class in some cases
Runnable task = () -> { System.out.println("hello world"); };
new Thread(task).start();
Are there any cases when it is unavoidable to use anonymous classes...
No. You could always define a named class for that. The point of annonymous classes is to make the code more concise and compact in situations in which you only need to use a class once.
it is advised to use them instead of named classes?
It depends on the context of the class being created.
if you are implementing interfaces having only one function (i.e Runnable) then using lambda expression instead of anonymous classes is not a bad choice.
lamba expression
Am new to multi threading programming, when I declare the run() method as static its giving the compiler error as
"This static method cannot hide the instance method from Thread".
I didn't understand what that means, so please help me.
public class hello extends Thread {
public static synchronized void run() {
for(int i=0;i<1000;i++)
System.out.println(i);
}
public static void main(String[] args) {
hello t1 = new hello();
hello t2 = new hello();
t1.start();
t2.start();
}
}
It is not necessarily relevent to multi-threaded programming, it is true of Java in general. If you have a class:
public class MySuperclass {
public void myMethod() {
//do stuff
}
}
You cannot then over-ride it to make it static:
public class MySubclass extends MySuperclass {
public static void myMethod() {
//do other stuff
}
}
This is not allowed.
That's what the error message means.
public void run();
is a Method declared in class Thread. As it's not static in Thread you cannot "change" it into a static method in your subclass. And given your example, you don't even need to do that.
If you need to have the code executed inside the Thread public and static and synchronized, I'd advise to refactor that part out:
#Override
public void run() {
staticRun();
}
public static synchronized void staticRun() {
for(int i=0;i<1000;i++)
System.out.println(i);
}
In the main() method you create two instances of Thread - t1 and t2 and then you call start() on them and that is correct you cannot run/start the class but an instance. That is why run() method is not supposed to be static. It needs an object (a Thread object) to be executed. Just remove static from your declaration and it shall be almost fine. Other thing is that you dont need to make your run method synchronized (it is counter productive - you use thread to execute in paralel and ynchronize only on specific parts never whole run method).
The instance method run() is already available in hello class due to inheritance. You are trying to create another method (static) with same name which is run().
If the method is not static, it will automatically override the implementation and hide the method instance of parent class..
So, is the Error.. Simple!
Because java is Object Oriented language and anything is java is object.
And task which you are trying to perform in multiple threads is object too and you should create this object. When object is created you should call start() method which is defined on Thread class. So to implement your own logic, you should override this behavior by implementing run() method in Hello subclass.
Run method defines logic which should be performed in other thread (note, that run method doesn't create new thread)
Start method tells java to create new native thread and perform your run method in this new thread
Try:
public class Hello extends Thread{
public void run()
{
for(int i=0;i<1000;i++)
System.out.println(i);
}
}
public class Main
{
public static void main(String[] args)
{
Hello hello t1 = new hello();
Hello hello t2 = new hello();
t1.start();
t2.start();
}
}
The thread Class has a run method, therefore if you define it again in the hello class then you are overriding it, (direct inheritance since Hello extends Thread) now, it makes no sense to turn a Object method into a Class method, (run method belongs to an object and not to the class) that is the reason why your compiler is complaining with the message:
"...you can not This static method cannot hide the instance method
from Thread".
in other words, you are violating inheritance rules with it.