package com.java8;
public class MethodReferenceExample {
public MethodReferenceExample() {
System.out.println("MethodReferenceExample.....");
}
public int display() {
System.out.println("in display");
return 1;
}
public static int read() {
System.out.println("in read");
return 10;
}
public static void main(String[] args) {
//point 1
MyInterface myIn = MethodReferenceExample::new;
myIn.show();
//point 2
MyInterface objectReference = new MethodReferenceExample()::display;
objectReference.show();
int value = objectReference.show(); //you can't assign this because show is void///
MyInterface staticReference = MethodReferenceExample::read;
staticReference.show();
}
}
interface MyInterface{
public void show();
default public int getvalue() {
return 10;
}
}
In this at point 1 we can assign constructor reference using ::new but that interface is not implementing that
In point 2, we can call display method which has return value as int using show method which has return value as void and still it calls that method. How weird is this? There's no connection between 2 methods still it can call that because it has same number of arguments. Why has java people made this change? I mean, this method reference is really confusing and really makes no sense, no valid justification then why have they introduced this confusing change?
Again in point 2 we can call that but can't assign return value to int because calling method is void so it can't convert void to int, seriously why all this confusion? Can someone explain me this? It's pretty hard for my brain to accept all this method reference thing.
Thanks in advance.
In point 2, we can call display method which has return value as int using show method which has return value as void and still it calls that method. How weird is this?
Just as weird as being able to call, for example, someList.add(something) and ignore the returned value, just as if the return type of List.add() was void. It's not void: it's boolean, but you don't care about the return value, so you call it as if it was returning void and just ignore the result. Same here. The interface defines a method that you can call without any argument. display() is such a method. As simple as that.
Why has java people made this change?
Because it's a good change that often makes code clearer, and more efficient too.
this method reference is really confusing and really makes no sense
It does make a lot of sense, and has plenty of justifications. The fact that you don't yet understand them doesn't make them less useful.
Related
I have been working with java 8 functional interfaces and I noticed something unusual when I started executing below code.
interface Carnivore{
default int calories( List<String> food)
{
System.out.println("=======line ABC ");
return food.size() * 100;
}
int eat(List<String> foods);
}
class Tiger implements Carnivore{
public int eat(List<String> foods)
{
System.out.println("eating "+ foods);
return foods.size();
}
}
public class TestClass {
public static int size(List<String> names){
System.out.println("======line XYZ ");
return names.size()*2;
}
public static void process(List<String> names, Carnivore c){
c.eat(names);
}
public static void main(String[] args) {
List<String> fnames = Arrays.asList("a", "b", "c");
Tiger t = new Tiger();
process(fnames, t::eat);
process(fnames, t::calories);
process(fnames, TestClass::size ); // ----> this is where I am confused.
}
}
As you can see that static method process(List<String> names, Carnivore c) takes object type Carnivore. The method call process(fnames, TestClass::size ) works, and there's no compile time error, how is this possible? I'm not able to comprehend how internally this method call works. I was expecting an error because TestClass is not Carnivore.
The best answer I found: "You can either pass a Carnivore instance explicitly or pass a reference to a method that matches the parameter list of Carnivore's abstract method eat(List<String> foods)"
The part pass a reference to a method that matches the parameter list of abstract method is confusing to me.
Appreciated if experts help me understand what happens when process(fnames, TestClass::size ); is called.
Carnivore is a functional interface having a single abstract method int eat(List<String> foods);.
Therefore, any method that fits the signature of the eat method can be used to implement the interface.
public static int size(List<String> names) is such a method, since it takes a List<String> argument and returns an int. Therefore TestClass::size can be passed as an argument of type Carnivore, which is why process(fnames, TestClass::size); passes compilation.
BTW, Tiger does not have to implement the Carnivore interface for process(fnames, t::eat); to pass compilation, since the public int eat(List<String> foods) method also matches the signature of the functional interface's single abstract method.
I am trying to get IZO-809 certification I was reading the OCA/OCP SE8 test book and a code really caught my attention.
The code gets me to this question.
I know consumer get a parameter and not return nothing and Supplier has not parameters and returns a value.
But this code is almost the same after the ->.
public class Pregunta24{
private final Object obj;
public Pregunta24(final Object obj){
this.obj = obj;
}
}
//Returns a Supplier
private final Supplier<Pregunta24>supplier = ()->new Pregunta24("HI");
//Returns a Consumer.
private final Consumer<Pregunta24>consumer = a->new Pregunta24(a);
Both codes work.
But if this code not work i know that consumer doesn't return nothing.
private final Consumer<String>consumerString = String::length
I know this not work because consumer doesn't return a value my question is in the supplier code and the consumer code the code is right after the -> mark but this time is considered return in fact a instance of the class.
My question is why sometimes Java complaints that is a return value and something not?
I mean this code.
private final Supplier<Pregunta24>supplier = ()->new Pregunta24("HI");
// I would think is returning a instance of the Pregunta24 class.
private final Consumer<Pregunts24>consumer = a->new Pregunta24(a);
Is returning the same after the -> but why in the consumer don't say the error.
incompatible types: bad return type in lambda expression
But if do this I do
final Consumer<String>consumerString = a->1;
I think the code after the -> is context inferred.
According to javadoc Consumer:
Represents an operation that accepts a single input argument and
returns no result.
Consumer<Pregunts24>consumer = a->new Pregunta24(a);
doesn't actually return anything. This basically is implementation of Consumer#accept method, which accepts an object of type T and has void as return type.
public void accept(Pregunta24 a) {
new Pregunta24(a);
}
You are not returning anything. Same thing with
Consumer<String>consumerString = String::length
public void accept(String a) {
a.length();
}
However
Consumer<String>consumerString = a->1;
is an invalid expression which is translated to something like this:
public void accept(String a) {
1;
}
I am creating functional interfaces and want to reuse default methods with anonymous implementation.
public class JavaInterfaceTest {
public static void main(String[] args) {
FunctionalIntf fi = () -> {
System.out.println("In ananymus impl, trying to call default method");
// doInternal()
return "Hello";
};
fi.doFunction(); // How this line valid ?
fi.doInternal();
FunctionalIntf.doSomething();
}
}
#FunctionalInterface
interface FunctionalIntf {
String doFunction();
default void doInternal(){
System.out.println("In doInternal");
}
static void doSomething(){
System.out.println("In doSomething");
}
}
How fi.doFunction(); is valid, if I go thru anonymous implementation.
How can I re-sue default method or static method if I want from implementation?
3. Is returning something valid/best practice in my case as I can not handle the returned value.
When you are creating the anonymous class, you actually provide an implementation for your abstract method doFunction() from FunctionalIntf interface. So when you are using this line of code:
fi.doFunction();
It means that you are calling doFunction() method from the anonymous class. This is another example on how functional interfaces work:
Runnable r = new Runnable() {
#Override
public void run() {
System.out.println("I'm Runnable!");
}
};
r.run();
In this case we override run() method from Runnable interface, which is also a functional interface.
You cannot provide another implementation for the static method because you cannot override a static method. Static methods are not inherited in Java at all. You can instead provide another implementation for the default method by overriding as mentioned in my above example.
Regarding the returned value, you need to define your method to return the exact value you need. There is no best practice in that.
When you implement a functional interface, you have 2 options:
Use lambdas, as you have
Use inner classes.
If you use lambdas, like you have, you have the default implementation of the static/default methods along with the implementation of the abstract method.
If you use an inner class, the normal rules of overriding applies.
Hey this is a very simple question. Can I call a variable, in this case an array, from a void method? I have declared my arrays at the class level and initialized them in a void method. Not sure it I am doing this correctly but I am trying to call the array from another class. I am a beginner. Thank you for the help.
ex:
public class HeyThere{
public double me[];
public void yeahYou(int you){
me = new me[69]
}
}
Here you declarate a public variable (array)
public double me[ ];
and here you instantiate it in a method
me = new me[69]
Yes, since your class level array me is scoped as Public, you will be able to access it from another class after you instantiate the HeyThere class.
Ex:
public class HeyThereCaller
{
..
....
public void SomeMethod()
{
...
....
HeyThere heyThereInstance = new HeyThere();
double[] meArray = heyThereInstance.me;
}
}
HeyThere obj1; double a = obj1.me[0]; This is going to give an error in Java though, because me is not instantiated
Yes, you certainly can! Because me is public, you can access it from outside of the class in which it is stored.
Also, you spoke of accessing it from a void method. The return type of a method has no effect on the data it can access; void only means that the method doesn't return a value when called.
If you want to study how variables can be accessed in Java, there is some useful info on this page.
if i have a static method Only advantage is that we have single copy.Need not have a object to call the Method. The same can be done be creating an object i.e we can call method with object. Why should we have static method. Can someone provide a example to explain?
Static methods can be useful when you have private constructors, because you want to abstract the instantiation process.
For example in C++:
class Foo {
Foo() {}
public:
static Foo *create() {
return new Foo;
}
};
In that example the abstraction just called an otherwise in accessible constructor, but in practice you might want to have a pool of objects which is shared and so the create() method would be managing this for you.
Sometimes when you have const members which need to be initalised at construction time it can be cleaner to move the logic for this into a private static method, e.g.:
struct Foo;
struct Bar {
Bar() : f(make()) {
}
private:
const Foo f;
static Foo make() {
// Create it here
}
};
The static method is used when developer is really sure the method is only have one instance in the class. There are no other instance that can change that.
eg :
public class People
{
private
public static Int32 GetValue(Int x)
{
return x + 3;
}
}
So even you are make instances of object people, the return from getvalue static method only produce x + 3.
It is usually used when you are really sure to make a functional method like math or physics method.
You can refer to functional programming that using static point of view.
Some of the old school guys are overusing the static method instead of doing OOP approach.
eg:
public class People
{
public static DataSet GetPeopleById(String personId)
{ .... implementation that using SQL query or stored procedure and return dataset ... }
public static DataSet GetXXXXXXX(String name, DateTime datex)
{ .... implementation ... }
}
The implementation above can be thousands of lines
This style happens everywhere to make it like OOP style (because it happen in the class) but thinking like procedural approach.
This is a help since not all people understand OOP style rather than like OOP style.
The other advantage using static are saving memory footprints and faster.
You can see in the blogs : http://www.dotnetperls.com/callvirt