user3479249
user3479249

Reputation:

Java 8 method references - dereferenced only once?

I'm confused with method references. Consider the following script.

public class Main {

    static interface I {
        void m();
    }

    static class A implements I {
        @Override
        public void m() {
            System.out.println("A");
        }
    }

    static class B implements I {
        @Override
        public void m() {
            System.out.println("B");
        }
    }

    public static void main(String[] args) {
        A a = new A(); B b = new B();
        I i; Runnable r;
        i = a;
        r = i::m;  // static reference? might infere class
        r.run(); // prints "A"
        run(i); // also prints "A"
        i = b;
        r.run(); // prints "A" instead of "B"!
        run(i); // prints "B"
        r = i::m;
        r.run(); // now prints "B"
        run(i); // also prints "B"
    }

    public static void run(I i) {
        Runnable r = i::m; // dynamic reference, cannot infere class
        r.run();
    }
}

So it seems that:

So my questions are:

Are method references using reflection? And why they do only once?

Upvotes: 0

Views: 203

Answers (1)

JB Nizet
JB Nizet

Reputation: 692023

If you think about how this code would be written without method references, but with classes and objects, it all makes sense:

r = i::m;

is basically equivalent to

private class IRunnable implements Runnable {
    private I i;

    public IRunnable(I i) {
        this.i = i;
    }

    @Override
    public void run() {
        i.m();
    }
}

Runnable r = new IRunnable(i);

So, if you assign another value to i after the IRunnable has been constructed, the IRunnable continues referencing the previous value, and calling its run() method again will still call the previous i's method.

Upvotes: 2

Related Questions