13

Can someone explain to me,
why passing a non-static method-reference to method File::isHidden is ok,
but passing method reference to a non-static method MyCass::mymethod - gives me a "Cannot make a static reference to the non-static method" ?

public static void main(String[] args) {
 File[] files = new File("C:").listFiles(File::isHidden); // OK
 test(MyCass::mymethod); // Cannot make a static reference to the non-static method
}
static interface FunctionalInterface{
 boolean function(String file);
}
class MyCass{
 boolean mymethod(String input){
 return true;
 }
}
// HELPER
public static void test(FunctionalInterface functionalInterface){}
asked Sep 16, 2015 at 21:32

3 Answers 3

12

Method references to non-static methods require an instance to operate on.

In the case of the listFiles method, the argument is a FileFilter with accept(File file). As you operate on an instance (the argument), you can refer to its instance methods:

listFiles(File::isHidden)

which is shorthand for

listFiles(f -> f.isHidden())

Now why can't you use test(MyCass::mymethod)? Because you simply don't have an instance of MyCass to operate on.

You can however create an instance, and then pass a method reference to your instance method:

MyCass myCass = new MyCass(); // the instance
test(myCass::mymethod); // pass a non-static method reference

or

test(new MyCass()::mymethod);

Edit: MyCass would need to be declared static (static class MyCass) in order to be accessible from the main method.

answered Sep 16, 2015 at 22:31
Sign up to request clarification or add additional context in comments.

2 Comments

You cannot instantiate MyClass from within a static method (such as main) because is is a non-static inner class. You would have to declare the class as static. I am assuming the code in the original example is wrapped inside a class.
@Peter As per the documentation, Method References is absolutely not a static call. It works on both static and non- static methods. If going by your explanation then who exactly creates the instance in the case of String class private Function<String, String> f1 = String::toUpperCase;
1

As peter-walser pointed out, since MyCass::mymethod is an instance method it requires an instance to be converted to a Function instance.

The static in front of your interface declaration just makes it a static interface, it does not turn each method into a static one.

A possible solution would be to declare the method inside the class as static:

class MyCass{
 static boolean mymethod(String input){
 return true;
 }
}

To understand better how it works, you can consider the code equivalente to the method reference MyCass::mymethod that is (assuming the above modified declaration of MyClass):

new FunctionalInterface{
 boolean function(String file){
 return MyClass.mymethod(file);
 }
}

Your original code would attempt to sort-of translate into:

new FunctionalInterface{
 boolean function(String file){
 return _missing_object_.mymethod(); # mymethod is not static
 }
}

Another possibility is using a BiFunction instead of your FunctionalInterface. In that case the first argument of apply would be the object and the second would be the argument to mymethod.

answered Sep 17, 2015 at 10:17

1 Comment

Your first example has to be MyClass.mymethod(file). The OP's code would also be translated into that. That's where the "Cannot make a static reference ..." error comes from. There is no static reference in your second example.
0

Short answer:

You're trying to access a static method through the class.

test(MyCass::mymethod); // Cannot make a static reference to the non-static method

Is the same as

test(v -> MyCass.mymethod(v)); // static access

Solution

Make the method static

class MyCass {
 static boolean mymethod(String input) {
 return true;
 }
}

Or use an object as reference

public static void main(String[] args) {
 MyCass myCass = new MyCass();
 test(myCass::mymethod);
}
answered May 24, 2019 at 16:21

1 Comment

Incase of String class, even though toUppercase is non-static then why this does not give error Function<String, String> f1 = String::toUpperCase;

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.