1

I am learning method references in Java 8. I learnt that we can define functional interface method with either lambda or method reference. Method reference is a way of telling "there exist a similar method with same signature of functional interface method, you can call it". Further if that similar looking method exists as a static method, we call it using its class name. Or if it exists as non static way, then we will call it with object.

I am confused with below code.. EatSomething class has non-static similarToEat method, then why it is being called like a static method?

import java.util.function.*;

public class Test {
    public static void main(String[] args) {
        Test test = new Test();
        EatSomething es = new EatSomething();
        
        Function <EatSomething,String> ff1 = EatSomething::similarToEat; //here.. similarToEat is a non-static method, then why do I need to call it using class name?
        Function <EatSomething,String> ff2 = (EatSomething eat)->eat.similarToEat();
        Function <EatSomething,String> ff3 = es::eatOverloaded;
        
        
        System.out.println(test.process(ff1));
        
    }

    private String process(Function<EatSomething,String> func) {
        EatSomething es = new EatSomething();
        return func.apply(es);
    }
}


class EatSomething{
    public String similarToEat() {
        return "eat lightning, and crap thunder ";
    }
    
    public String eatOverloaded(EatSomething es) {
        return es.similarToEat();
    }

}

I am totally confused with this. Why should't I call similarToEat using object. Why do I have to use class name here? I can easily relate ff2 and ff3 objects in above code. Really confused with ff1.

One more piece of code..

interface MyCustomFunction{  
    String test(String abc);  
}  
public class MethodReference {  
     
    public static void main(String[] args) {  
        MethodReference mr = new MethodReference();
        MyCustomFunction func = String::toUpperCase; //here again. Why are we calling toUpperCase with its class name when its a non-static method
        System.out.println(mr.processs(func));
    }  
    public String processs(MyCustomFunction obj) {
        
        return obj.test("abc");
    }
}  
5
  • It's not getting called. The method declaration is being referenced on the EatSomething class. It only runs when explicitly invoked on an instance of EatSomething inside the process method. Also this is horrible code, never write something like this =D Commented Jul 12, 2023 at 23:18
  • MyCustomFunction func = String::toUpperCase; here MyCustomFunction has a method lets say String test(String abc); but toUpperCase is a non static method. Then why are we calling toUpperCase with its class name i.e. String. Commented Jul 12, 2023 at 23:40
  • 1
    Remember that terminology matters: we're not calling anything. Calling a method/function means executing ("running") that method/function. We're referencing a method here, using the method reference operator, ::. The docs for which have already been linked to in the answer you accepted. Commented Jul 13, 2023 at 0:43
  • Yes. Actually this whole confusion arise due to this code : public String extractUsername(String token) { // TODO Auto-generated method stub Function<Claims,String> func = (Claims c)->c.getSubject(); // or Claims::getSubject return extractClaim(token,func); } here a implemented method of Claims interface getSubject is called as if it is a static method. Commented Jul 13, 2023 at 5:21
  • So I treid to mimick that in my exercise session here. Understood now. If something is like (Object o)->o.someMethod() can be further shortened to Object::someMethod will remember that. Commented Jul 13, 2023 at 5:25

1 Answer 1

3

You can call similarToEat using object, you will just get not a Function <EatSomething,String> but functional interface with zero-arg method like Callable/Runnable/Supplier since an instance of EatSomething is already defined by that object.

Here is Oracle documentation with types of method references:

Kind Syntax
Reference to a static method ContainingClass::staticMethodName.
Reference to an instance method of a particular object containingObject::instanceMethodName
Reference to an instance method of an arbitrary object of a particular type ContainingType::methodName

Look at examples:

    // denotes a method of any EatSomething instance that is not defined yet
    Function<EatSomething, String> ff1 = EatSomething::similarToEat; // thus we get a function from EatSomething to String
    // denotes a method of already specified EatSomething object
    Supplier<String> ff2 = es::similarToEat; // here we get a function without any argument
    Callable<String> ff3 = es::similarToEat; // it could be another FunctionalInterface with no-arg method
    
    ff1.apply(new EatSomething()); // we could provide any EatSomething object
    ff2.get(); // will execute similarToEat exactly against the es object
    ff3.call(); // will execute similarToEat exactly against the es object

What if EatSomething have a static method?

class EatSomething {
    public static String eatSomethingStaticMethod() {
        return "";
    }
}

Then taking method reference with a class name would return no-arg functional interface:

    Supplier<String> ff4 = EatSomething::eatSomethingStaticMethod;
    Callable<String> ff5 = EatSomething::eatSomethingStaticMethod;
Sign up to request clarification or add additional context in comments.

2 Comments

One more scenario, MyCustomFunction func = String::toUpperCase; here MyCustomFunction functional interface has a method lets say String test(String abc); but toUpperCase is a non static method. Then why are we calling toUpperCase with its class name i.e. String.
Again, we can call it both ways and it would denote different things: String::toUpperCase; would return Function<String, String> or MyCustomFunction and "a"::toUpperCase would return Supplier<String> or another no-arg functional interface like String test() since target (string "a") is previously defined

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.