I'm studying on lambda expressions, the book illustrates an example that uses toString() method of lambda expressions.
Supplier<ArrayList<String>> s1 = ArrayList<String>::new;
ArrayList<String> a1 = s1.get();
System.out.println(s1);
//Output: functionalinterface.BuiltIns$$Lambda$1/791452441@1fb3ebeb
It explains meaning of the output as,
This actually does mean something. Our test class is named BuiltIns , and it is in a package that we created named functionalinterface . Then comes
$$, which means that the class doesn’t exist in a class file on the file system. It exists only in memory.
I don't understand the meaning of the last sentences. Could you express it?
Source: OCP: Oracle Certified Professional Java SE 8 Programmer II Study Guide, Jeanne Boyarsky, Scott Selikoff
Well the book is slightly misleading. The statement it indeed correct, but with a minor correction. It assumes that if you have $ in a class name it is automatically created (not by you); which might not be a fact.
For example suppose this example:
public class TestSO {
public static void main(String[] args) {
Test t = new Test() {
};
}
static class Test {}
}
You have created an anonymous inner class which is actually a plain class created by the compiler. If you compile TestSO you will see a class called TestSO\$1.class that was a created for you. If you inspect how it looks with javap -c -p TestSO\$1.class you will see something like this:
final class TestSO$1 extends TestSO$Test { ...
But at the same time it is perfectly legal for you to declare a class/method that contains the $ symbol:
static class $$Test2$$ {}
So the presence of $$ is not a strong indication that the class is generated by compiler/runtime. Also that's an implementation detail that could change some day...
Now at the same time the book is correct in the fact that the class doesn’t exist in a class file on the file system. It exists only in memory.
Supplier is an interface and you have not provided a class that implements it, have you? Well what happens next is interesting.
I am not going to go in a lot of details, but here is a simplified explanation.
If you de-compile your example (javap -p -c -v TestSO.class) you will see a line like this:
invokedynamic #2, 0 // InvokeDynamic #0:get:()Ljava/util/function/Supplier;
What invokedynamic does is letting the runtime decide how to provide an actual instance of that Supplier. And at runtime there is an actual class created that implements that Supplier that is used.
You can see how that class looks like with a command used when running it:
-Djdk.internal.lambda.dumpProxyClasses=/Your/Path/Here
As a result in that path you will see a class called:
TestSO$$Lambda$1.class
And again if you decompile it with javap -c -p TestSO\$\$Lambda\$1.class:
final class TestSO$$Lambda$1
implements java.util.function.Supplier {....
What the author is trying to say is that there will be a class generated for you at runtime that implements the Supplier interface, but its not you who have created it.
This cite is an attempt to explain something in easier or more colloquial terms, avoiding to be too formal, however, the result can be called disastrous.
The name actually means nothing. The class of the instance provided for a lambda expression or method reference is intentionally unspecified and so is its name. It is even unspecified whether the toString() method which is implicitly invoked when executing System.out.println(s1); will produce the “classname@hashcode” output.
Whether file systems are involved or not, is irrelevant. The correct and the actual point is that the class of that instance is not among the classes created by the Java compiler when your application is compiled. Instead, it is provided by the JRE at runtime in an implementation specific way. OpenJDK does provide a generated class that happen to have a name that contains the class containing the lambda expression and a $$, but, as said, that’s an implementation detail. And, as explained by Eugene, the dollar sign is a legal part of Java identifiers, so the presence of two dollar signs doesn’t prove a particular property.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With