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;
}
}
Related
Say I'm using a Runnable interface,
Runnable runnable = new Runnable() {
#Override
public void run() {
// some code
}
};
If the run () method in Runnable interface is empty , why should we use #Override and same name for the method in our code instead of just using a random name for our implementation like ,
Runnable runnable = new Runnable() {
public void myRun() {
// some code
}
};
The question might seem dumb but I'm a newbie to programming!
Runnable has only one method, thus, you may be tempted to think the method name is irrelevant. But most interfaces have more than one method. For example, java.util.Iterator which has 2 (well, 4, but 2 of those have default impls so you don't need to implement those. Point is, 2 that you must implement).
So, let's say that instead of naming your two methods next and hasNext, you name them jill and jane instead.
How is the compiler or any caller supposed to figure out which one performs the hasNext job and which one performs the next job? Look at the signatures? What if your interface has 2 different methods with the exact same signature?
Not possible. That's why the names need to match: They are used to look this up.
Yes, if the interface has just the one name you'd think the compiler/caller can just go: Yeah, well, the one and only method it has, that's the one. But that's not how it works - language design is simpler if you avoid making exceptions just for simplified cases.
Note that java has lambda syntax, which only works when an interface has one method, and which omit the method name entirely, as well as the argument types. Instead of your myRun method you could write this too:
Runnable r = () -> /* some code */;
No new Runnable() { public void myRun, and no }} required. If myRun had arguments, you don't even need to add their types, just their names. For example, Comparator, which has arguments:
long form:
Comparator<String> lengthComparator = new Comparator<String>() {
#Override public int compare(String a, String b) {
return a.length() - b.length();
}
};
can be written much shorter:
Comparator<String> lengthComparator = (a, b) -> a.length() - b.length();
Think about what it means to "implement an interface". If I have a variable of an interface type, I can call any method defined in the interface on that variable. For example, for the Runnable interface:
interface Runnable {
void run();
}
If I have a variable of type Runnable, I know I can call run on it:
Runnable r = ...;
r.run(); // I can guarantee this will work, because whatever "..." evaluates to, implements Runnable
So when you implement Runnable, you are really just saying that "this class has a run method". The Java compiler also checks that what you are saying is true, that the class actually has a run method. Saying false things about your class, intuitively, should not be allowed, right?
We can also think about what would happen if you were allowed to implement Runnable, but not provide a run method, then you would not be 100% sure that any variable of type Runnable has a run method.
class TrueRunnable implements Runnable {
#Override public void run() {}
}
class FakeRunnable implements Runnable { // suppose this is allowed
public void myRun() {}
}
...
Runnable r;
if (new Random().nextBoolean()) {
r = new TrueRunnable()
} else {
r = new FakeRunnable();
}
// does r have a run method? Maybe.
Then interfaces would not be very useful, because you are not 100% sure whether any Object has any method anyway.
Object r;
if (new Random().nextBoolean()) {
r = new TrueRunnable()
} else {
r = new FakeRunnable();
}
// does r have a run method? Maybe.
So in that case we would lose the whole point of using interfaces.
As to why an interface implementation method has to have the same name as the declaration method name in the interface , i think it boils down to allowing Java compiler to understand which method actually implements the interface. Otherwise its impossible for the Java compiler to know.
Another solution could have been to use a qualifier name in an annotation to signal which is the implementation method something like this.
public interface MyInterface {
void sayHello();
}
and
public class Hello implements MyInterface {
#Implements("MyInterface.sayHello")
public void someOtherName() {
print("Hello World);
}
}
This approach is not valid , but could have been an alternative if Java creators wanted to allow users to declare different names for interface implementation methods. I think this approach is uglier and prone to errors though.
Also this problem does not exist when using lambda expressions where the compiler can understand whats happening without the code writer having to specify the name of the interface method. Note that this only applies to functional interfaces.
I am learning about Java Lambdas and I asked myself is it always required to call a abstract method of functional interface if I want to use the lambda here?
#FunctionalInterface
public interface A {
public void somefunction();
}
#FunctionalInterface
public interface B extends A {
}
public class testing {
public static void main(String[] args) {
B b = () -> System.out.println("MyText");
b.somefunction(); //Why do I need to call somefunction()
}
}
If I don't write b.somefunction(); I don't get any output even though the compiler does not give an error.
I don't pass any value to the method so why do I need to call the abstract method?
Is there anyway to skip the abstract method call? If my case was to add or perform some calculations, then I can understand that I need to pass some values in method, but in the above scenario I am just printing the value.
If you want the output to print when your program runs, write:
public class testing {
public static void main(String[] args) {
System.out.println("MyText");
}
}
If you want the output to print when some other function runs, then you might use a lambda:
class Testing {
public static void main(String[] args) {
runn(() -> System.out.println("MyText"), 10);
}
static runn(Runnable task, int times) {
for (int i = 0; i < times; ++i) {
task.run();
}
}
}
Lambdas exist to make it easy to specify a function whose execution you want to delegate to another entity. When the lambda is invoked, its arguments, and the treatment of its result are up to someone else.
A functional interface serves to provide a way
to define what is to be performed on a given call and
to define when it is to be called.
Normally, you'd define a "lambda object" as you did and then pass it to somewhere else to tell what to do under a certain circumstance. If you want to see it this way, it is a kind of callback.
The entity where you pass this object calls/uses it when it sees time to do so, or you do it yourself, as you do it in your example.
I'm trying to write a method that takes a constructor of a Runnable class and runs it in a certain way, according to the constructor that was input.
So I want to be able to do something like this:
executeInParallel(someRunnable::new)
executeInParallel(someOtherRunnable::new)
My question is how do I define the executeInParallel method in order to be able to pass any of the Runnable constructors I've defined in the parameters? Essentially my question is in order to do that what how do I define this method?
void executeInParallel(??){ ... }
It seems that I can only have methods that adhere to a Functional Interface as parameters though, so I can't define executeInParallel with a single parameter that accepts more than one xRunnable::new constructors Is there a way for me to do this without using some sort of a Factory pattern?
I want to make clear that the reason I want to do this is that I want to pass in constructors and not instances. I can't generate the instance outside executeInParallel, it has to be generated inside that method. I also want to pass in different constructors that take different parameters
Thank you in advance
EDIT
Sorry, I made the question a little more clear hopefully.
Your executeInParallel() method accepts something that will generate a Runnable, so its signature should be executeInParallel(Supplier<? extends Runnable> runnableFactory)
Then, you can call it with any lambda or method reference that can return an instance of any class that implements Runnable.
Possible usages :
// Ex 1 :
class MyJob implements Runnable {
public void run() {...}
}
executeInParallel(() -> new MyJob());
executeInParallel(MyJob::new);
// Ex 2 :
class MyJobWithParams implements Runnable {
public MyJobWithParams(String param1, int param2) { ... }
public void run() {...}
}
executeInParallel( () -> new MyJobWithParams("Hello",42) );
// You cannot use method references here
// Ex 3 :
class RunnableFactory {
public static Runnable makeRunnable() {
return new MyJob(); // which is a Runnable, see above
}
}
executeInParallel( () -> RunnableFactory.makeRunnable() );
executeInParallel( RunnableFactory::makeRunnable );
Also, you state that you only want Runnable constructors to be passed to the method. This can be done via a method reference (but only for a no-arg constructor), or via a lambda expression (like in example #1 and #2 above).
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.
This question already has answers here:
What's wrong with overridable method calls in constructors?
(8 answers)
Closed 5 years ago.
Let's suppose I have an abstract Base class that implements Runnable interface.
public abstract class Base implements Runnable {
protected int param;
public Base(final int param) {
System.out.println("Base constructor");
this.param = param;
// I'm using this param here
new Thread(this).start();
System.out.println("Derivative thread created with param " + param);
}
#Override
abstract public void run();
}
And here is one of a few derivative classes.
public class Derivative extends Base {
public Derivative(final int param) {
super(param);
}
#Override
public void run() {
System.out.println("Derivative is running with param " + param);
}
public static void main(String[] args) {
Derivative thread = new Derivative(1);
}
}
The point is that I want my Base class do some general stuff instead of copying it every time.
Actually, it's running fine, the output is always the same:
Base constructor
Derivative thread created with param 1
Derivative is running with param 1
But is it safe IN JAVA to start a thread calling the abstract method in constructor? Because, in C++ and C# it is unsafe in most cases, so far as I know.
Thank you!
This code demonstrates why you should never call an abstract method, or any other overridable method, from a constructor:
abstract class Super {
Super() {
doSubStuff();
}
abstract void doSubStuff();
}
class Sub extends Super {
String s = "Hello world";
void doSubStuff() {
System.out.println(s);
}
}
public static void main(String[] args) {
new Sub();
}
When run, this prints null. This means the only "safe" methods to have in a constructor are private and/or final ones.
On the other hand, your code doesn't actually call an abstract method from a constructor. Instead, you pass an uninitialized object to another thread for processing, which is worse, since the thread you're starting may be given priority and execute before your Base finishes its initialization.
Not a good idea since when run() is invoked, the Derivative object may not have been initialized. If run() depends on any state in Derivative, it can fail.
In your simple case it works. But then there's no point for the subclass. You can simply
public Base(final int param, Runnable action) {
new Thread(action).start();
It's a very bad practice to call an abstract method from a constructor. Methods called from constructors should always be private or final, to prevent overriding.
See this link to a question here
Passing this out of the constructor is called "letting this escape from the constructor", and can lead to some particularly nasty and weird bugs, because the object may be in an inconsistent state.
This is especially the case when this is passed to another thread, as in this example. Due to the JVMs right to reorder statements within a thread, you can get undefined behaviour/state occurring.