Method Reference. Cannot make a static reference to the non-static method

后端 未结 3 500
难免孤独
难免孤独 2020-12-14 22:11

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 met

相关标签:
3条回答
  • 2020-12-14 22:42

    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);
    }
    
    0 讨论(0)
  • 2020-12-14 22:46

    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.

    0 讨论(0)
  • 2020-12-14 22:49

    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.

    0 讨论(0)
提交回复
热议问题