How does method reference casting work?

后端 未结 3 1726
走了就别回头了
走了就别回头了 2021-01-06 10:57
public class Main {
    interface Capitalizer {
        public String capitalize(String name);
    }

    public String toUpperCase() {
        return \"ALLCAPS\";
          


        
相关标签:
3条回答
  • 2021-01-06 11:34

    You have a method which

    public String capitalize(String name);
    

    Takes a String and returns a String. Such a method can have a number of patterns.

    A constructor

    c = String::new; // calls new String(String)
    // or
    c = s -> new String(s);
    

    A function on String which takes no arguments

    c = String::toLowerCase; // instance method String::toLowerCase()
    // or
    c = s -> s.toLowerCase();
    

    of a method which takes a String as the only argument

    // method which takes a String, but not a Main
    public static String toUpperCase(String str) { 
    
    c = Main::toUpperCase;
    // or
    c = s -> toUpperCase(s);
    

    In every case, the method referenced has to take the String.

    If not you can do this instead.

    c = s -> capitalize(); // assuming Main.capitalize() is static
    

    This tells the compiler to ignore the input.

    0 讨论(0)
  • 2021-01-06 11:48

    There are 3 constructs to reference a method:

    1. object::instanceMethod
    2. Class::staticMethod
    3. Class::instanceMethod

    The line:

    Capitalizer c = String::toUpperCase; //This works
    

    use 3'rd construct - Class::instanceMethod. In this case first parameter becomes the target of the method. This construct is equivalent (translates) to following Lambda:

    Capitalizer = (String x) -> x.toUpperCase();
    

    This Lambda expression works because Lambda gets String as parameter and returns String result - as required by Capitalizer interface.

    The line:

    c = Main::toUpperCase; //Compile error
    

    Translates to:

    (Main m) ->  m.toUpperCase();
    

    Which does not work with the Capitalizer interface. You could verify this by changing Capitalizer to:

    interface Capitalizer {
        public String capitalize(Main name);
    }
    

    After this change Main::toUpperCase will compile.

    0 讨论(0)
  • 2021-01-06 11:53

    You should change:

    public String toUpperCase()
    

    to

    public static String toUpperCase(String text)
    

    You should read the java tutorial on method references. The different kind of method references and there is a similar example with String::compareToIgnoreCase (Reference to an Instance Method of an Arbitrary Object of a Particular Type).

    The equivalent lambda expression for the method reference String::compareToIgnoreCase would have the formal parameter list (String a, String b), where a and b are arbitrary names used to better describe this example. The method reference would invoke the method a.compareToIgnoreCase(b).

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