我正在研究lambda表达式,这本书演示了一个使用toString()
lambda表达式方法的例子。
Supplier<ArrayList<String>> s1 = ArrayList<String>::new;
ArrayList<String> a1 = s1.get();
System.out.println(s1);
//Output: functionalinterface.BuiltIns$$Lambda$1/791452441@1fb3ebeb
它解释了输出的含义,
这实际上意味着什么。我们的测试类名为BuiltIns, 它位于我们创建的名为functionalinterface的包中。 然后是
$$
,这意味着类在类中不存在 文件系统上的文件。它只存在于内存中。
我不明白最后句子的意思。你能表达一下吗?
答案 0 :(得分:3)
这本书略微误导。声明它确实是正确的,但有一个小的修正。 假定如果您在类名中有$
,则会自动创建(不是您);这可能不是事实。
例如假设这个例子:
public class TestSO {
public static void main(String[] args) {
Test t = new Test() {
};
}
static class Test {}
}
您创建了一个匿名内部类,它实际上是编译器创建的普通类。如果您编译TestSO
,您将看到一个名为TestSO\$1.class
的类,它是为您创建的。如果您使用javap -c -p TestSO\$1.class
检查它的外观,您会看到如下内容:
final class TestSO$1 extends TestSO$Test { ...
但是同时声明包含$
符号的类/方法是完全合法的:
static class $$Test2$$ {}
因此$$
的存在并不强烈表明该类是由编译器/运行时生成的。这也是一个可能在某一天改变的实施细节......
现在同时这本书是正确的the class doesn’t exist in a class file on the file system. It exists only in memory
。
Supplier
是一个接口,你没有提供实现它的类,对吗?接下来发生的事情很有趣。
我不打算详细介绍,但这里有一个简单的解释。
如果您对示例(javap -p -c -v TestSO.class
)进行反编译,您将看到如下所示的行:
invokedynamic #2, 0 // InvokeDynamic #0:get:()Ljava/util/function/Supplier;
invokedynamic
做了什么让runtime
决定如何提供Supplier
的实际实例。并且在运行时创建了一个实际的类来实现所使用的Supplier
。
您可以通过运行它时使用的命令查看该类的外观:
-Djdk.internal.lambda.dumpProxyClasses=/Your/Path/Here
在该路径中,您将看到一个名为:
的类TestSO$$Lambda$1.class
如果你用javap -c -p TestSO\$\$Lambda\$1.class
反编译它,那么又一次:
final class TestSO$$Lambda$1
implements java.util.function.Supplier {....
作者试图说的是,在运行时会为您生成class
来实现供应商界面,但不是您创建了它的人。
答案 1 :(得分:2)
这个引用试图用更简单或更通俗的术语来解释某些东西,避免过于正式,但结果可能被称为灾难性的。
这个名字实际上没有任何意义。实例的类为lambda表达式或方法引用is intentionally unspecified提供,因此它的名称也是如此。甚至未指定在执行toString()
时隐式调用的System.out.println(s1);
方法是否会产生“classname @ hashcode”输出。
是否涉及文件系统,无关紧要。正确和实际的一点是,在编译应用程序时,该实例的类不属于Java编译器创建的类。相反,它由JRE在运行时以特定于实现的方式提供。 OpenJDK确实提供了一个生成的类,其恰好具有包含lambda表达式和$$
的类的名称,但是,如上所述,这是一个实现细节。而且,as explained by Eugene,美元符号是Java标识符的合法部分,因此两个美元符号的存在并不是特定属性。
答案 2 :(得分:1)
创建类时,键入
# AppBundle/Admin/ShapeAdmin.php protected function configureFormFields(FormMapper $formMapper) /** @var Shape $shape */ $shape = $this->getSubject(); // add form fields for both types $formMapper ->add('service', null, ['disabled' => true]); // add specific form fields if ($shape instanceof Rectangle) { // custom rectangle form fields } elseif ($shape instanceof Circle { // custom circle form fields } }
文件并将其编译为.java
个文件。两者都是存在于您的某个地方的实际文件 文件系统。.class
表明它不同。没有$$
文件系统。 相反,Java为我们创建了类。就是这样 不必输入类,只能提供lambda 表达
其作者Ms.Boyarsky
回答