
Java 8 Method Reference Evaluation - cnahr
http://news.kynosarges.org/2016/10/23/java-method-reference-evaluation/
======
pdpi
It's much easier to keep track of what's happening if you don't try to write
it as one-liners.

This:

    
    
        final Runnable newRef = new Counter()::show;
    

is the same as this:

    
    
        final Counter counter = new Counter();
        final Runnable newRef = counter::show;
    

Which is roughly equivalent to this:

    
    
        final Counter counter = new Counter();
        final Runnable newRef = () -> { counter.show(); };
    

Which is, of course, not the same thing as

    
    
        final Runnable newLambda = () -> { new Counter().show(); };
    

The rest of the differences follow naturally from this distinction.

~~~
mobiuscog
Absolutely this.

It took me quite a few reads of the article to work out exactly what the issue
was, as the output was what I would have expected intuitively.

------
Leon
Something to add that would help on your examples, would be a non-static
counter to the static inner class. I think that would really help convey when
when multiple objects are created but the reference to the first class
instance is kept. With the static count variable new object instantiation is
tracked, but misses a detail on object references that is interesting.

Specifically for this example:

    
    
            System.out.println("\nVariable in method reference");
            obj = new Counter(); // NPE if after method reference declaration!
            final Runnable varRef = obj::show;
            System.out.println("Running...");
            varRef.run(); obj = new Counter(); varRef.run();
    

obj::show was evaluated, so varRef should be pointing to the original instance
method of show, even when called the second time. Which could potentially
create a memory leak if someone is tracking the method references and
recreating objects underneath unknowingly.

However if I am completely wrong about this please tell me! I have not gone
through and run this code for confirmation, so I would be very happy to know
if I'm mistaken. I'm going by memory without reference checking or testing. In
either case if I am wrong or right - please put a note about this situation!
It would help immensely and make your post even more interesting.

Thanks!

Leon

------
twic
What's correct here is that the target of a method reference is evaluated when
the reference is evaluated.

What's incorrect is that references to static (or other) variables are somehow
treated differently. The author has misinterpreted their own code - see
jwolfe's and my comments on the post.

~~~
Clee681
Hey @twic,

Does the fact that Java is "pass by value" explain why the reassignment of
"obj" does not change the output of re-invoking the method ref?

~~~
twic
Kind of. When i see a method reference like this:

    
    
      someExpression()::methodName
    

I mentally rewrite it into:

    
    
      getMethodReference(someExpression(), "methodName")
    

Where there is some fictional getMethodReference function that takes an object
and a method name, and creates a reference. It works like this even when
someExpression() is just a reference to a variable.

In the rewritten form, someExpression() gets fully evaluated before
getMethodReference is called, producing a value, and it's that value which is
used to create the reference. As you suggested, it works like that because
Java is pass-by-value.

If Java was pass-by-reference, then someExpression() would produce a reference
to a variable instead of a value, and the reference could somehow be based on
that variable. But it doesn't, so it's not.

~~~
Clee681
Awesome, thanks for the clarification!

------
mdadm
Google cache since it seems to be 404'ing:
[http://webcache.googleusercontent.com/search?q=cache:20xO-
ms...](http://webcache.googleusercontent.com/search?q=cache:20xO-ms-
ek8J:news.kynosarges.org/2016/10/23/java-method-reference-
evaluation/+&cd=1&hl=en&ct=clnk&gl=us)

------
therealidiot
404?

~~~
tempodox
Content seems to have disappeared. Spontaneous self-combustion?

~~~
cnahr
Sorry for the downtime, took me a while to correct the post. It's now up
again.

As some commenters have pointed out I had a stupid bug in my sample code where
I misused the static object creation counter as an object instance identifier.
Hence some very strange results I couldn't explain. With that bug fixed,
method references now behave as expected (which is still notably different
from lambda expressions).

