xdevel2000
xdevel2000

Reputation: 21364

Lambda conversion of method reference

If I have:

class B
{
    public static boolean test1(File f)
    {
        return true;
    }

    public boolean test2(File f)
    {
        return true;
    }    
}

are the following conversions to a full lambda expressions correct?

File dir = new File("C:\\TEST");

// here UNBOUND instance method reference
// converted as?  dir.listFiles((File f) -> f.isFile());
dir.listFiles(File::isFile);        

// here static method reference
// converted as? dir.listFiles((File f) -> B.test1(f));
dir.listFiles(B::test1);  

// here BOUND instance method reference
// converted as?  dir.listFiles((File f) -> b.test2(f));
B b = new B();
dir.listFiles(b::test2);  

then, still, one question: if I write: dir.listFiles(B::test2); I have from the compiler:

non-static method test2(File) cannot be referenced from a static context

but why is that error not throws for: dir.listFiles(File::isFile);

Upvotes: 1

Views: 2077

Answers (2)

Toby
Toby

Reputation: 9803

Short answer: Yes, your conversions are correct.

public void question() {
    File dir = new File("C:\\TEST");

    // here UNBOUND instance method reference
    dir.listFiles((File f) -> f.isFile());
    dir.listFiles(File::isFile);

    // here static method reference
    dir.listFiles((File f) -> B.test1(f));
    dir.listFiles(B::test1);

    // here BOUND instance method reference
    B b = new B();
    dir.listFiles((File f) -> b.test2(f));
    dir.listFiles(b::test2);
}

The compilation problem is because the reference;

dir.listFiles(B::test2);

or (expanded as a lambda);

dir.listFiles((pathname) -> B.test2(pathname));

is trying to access test2 as a static method. It's a static method reference. Whereas

dir.listFiles(File::isFile);        

or as a lambda;

dir.listFiles((f) -> f.isFile())

is an instance method reference, it's referring to a (non-static) method on the File class.

So although the File::isFile looks like a static reference, the use of the type in this context is actually referring to an object! Weird huh?

Upvotes: 2

Maurice Naftalin
Maurice Naftalin

Reputation: 10533

I think you've got confused: B::test2 must be an unbound instance method reference to a method in the class B, so the lambda argument must be a B not a File. So you should have got a different compile error telling you that the argument is of the wrong type.

Upvotes: 1

Related Questions