Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/389.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我们如何通过“getClass().getName()”找到源文件中的lambda位置?_Java_Jvm - Fatal编程技术网

Java 我们如何通过“getClass().getName()”找到源文件中的lambda位置?

Java 我们如何通过“getClass().getName()”找到源文件中的lambda位置?,java,jvm,Java,Jvm,我们有一些在线日志,它们看起来像com.xxx.yyy.SomeClass$$Lambda$12345/7654321@qwert. 这些日志指向一些lambda函数函数接口,比如Runnable Runnable=->{},但是SomeClass有很多lambda函数,因此需要在源文件中找到它们的特定行,以便找到错误的 顺便说一下,我们发现这些lambda函数的所有日志看起来都是$package.$ClassName$$lambda$index/$number@hashCode,并且相同的la

我们有一些在线日志,它们看起来像com.xxx.yyy.SomeClass$$Lambda$12345/7654321@qwert. 这些日志指向一些lambda函数函数接口,比如Runnable Runnable=->{},但是SomeClass有很多lambda函数,因此需要在源文件中找到它们的特定行,以便找到错误的


顺便说一下,我们发现这些lambda函数的所有日志看起来都是$package.$ClassName$$lambda$index/$number@hashCode,并且相同的lambda在重新编译类之前具有相同的$index/$number。

这是不可能的。类是在运行时生成的,不反映触发类生成的代码位置。观察到的索引号反映了类生成的顺序,而不是lambda表达式在代码中的外观

只要程序的行为没有改变,看起来这个数字和代码位置之间有一个稳定的映射,但是我们可以通过创建一个故意改变其行为的程序来很容易地反驳这一点:

导入java.io.IOException; 导入java.lang.invoke.MethodHandles; 导入java.nio.file.path; 公共类LambdaClassGeneration{ 公共静态无效字符串[]args{ ifargs.length==0{ 我自己; 回来 } 布尔偶数=args[0]。相等偶数; forint i=0;i<2;i++,偶数=!偶数{ 可运行r; StackTraceElement; 即使{ r=->System.out.println偶; e=新异常。getStackTrace[0]; } 否则{ r=->System.out.printlnodd; e=新异常。getStackTrace[0]; } r、 运行; 在+e处创建System.out.PrintLn; System.out.printlnr.getClass; } } 私有静态无效运行{ 字符串[]cmd={ Path.getSystem.getPropertyjava.home、bin、java.toString、, -cp,System.getPropertyjava.class.path, MethodHandles.lookup.lookupClass.getName, arg }; ProcessBuilder p=新的ProcessBuilder.Inheritario; forint i=0;i<2;i++尝试{ System.out.printlnRun+i; cmd[cmd.length-1]=i%2==0?偶数:奇数; p、 commandcmd.start.waitFor; System.out.println; } catchIOException | InterruptedException ex{ 例如,打印跟踪; 回来 } } } 此程序使用不同的参数(偶数和奇数)运行两次,以显示不同的行为,从而影响lambda表达式在运行时对可运行实现的对象求值的顺序

它打印出如下内容:

运行0 即使 创建于LambdaClassGeneration.mainLambdaClassGeneration.java:20 类LambdaClassGeneration$$Lambda$1/0x0000000800b90840 古怪的 创建于LambdaClassGeneration.mainLambdaClassGeneration.java:24 类LambdaClassGeneration$$Lambda$2/0x0000000800b91440 运行1 古怪的 创建于LambdaClassGeneration.mainLambdaClassGeneration.java:24 类LambdaClassGeneration$$Lambda$1/0x0000000800b90840 即使 创建于LambdaClassGeneration.mainLambdaClassGeneration.java:20 类LambdaClassGeneration$$Lambda$2/0x0000000800b91440
清楚地显示第一个生成的类得到索引1,第二个生成的类得到索引2,并且类名中没有任何东西暗示我们是在看“偶数”还是“奇数”可运行。

这是不可能的。类是在运行时生成的,不反映触发类生成的代码位置。观察到的索引号反映了类生成的顺序,而不是lambda表达式在代码中的外观

只要程序的行为没有改变,看起来这个数字和代码位置之间有一个稳定的映射,但是我们可以通过创建一个故意改变其行为的程序来很容易地反驳这一点:

导入java.io.IOException; 导入java.lang.invoke.MethodHandles; 导入java.nio.file.path; 公共类LambdaClassGeneration{ 公共静态无效字符串[]args{ ifargs.length==0{ 我自己; 回来 } 布尔偶数=args[0]。相等偶数; forint i=0;i<2;i++,偶数=!偶数{ 可运行r; StackTraceElement; 即使{ r=->System.out.println偶; e=新异常。getStackTrace[0]; } 否则{ r=->System.out.printlnodd; e=新异常。getStackTrace[0]; } r、 运行; 在+e处创建System.out.PrintLn; System.out.printlnr.getClass; } } 私有静态无效运行{ 字符串[]cmd={ P aths.getSystem.getPropertyjava.home、bin、java.toString、, -cp,System.getPropertyjava.class.path, MethodHandles.lookup.lookupClass.getName, arg }; ProcessBuilder p=新的ProcessBuilder.Inheritario; forint i=0;i<2;我试试看{ System.out.printlnRun+i; cmd[cmd.length-1]=i%2==0?偶数:奇数; p、 commandcmd.start.waitFor; System.out.println; } catchIOException | InterruptedException ex{ 例如,打印跟踪; 回来 } } } 此程序使用不同的参数(偶数和奇数)运行两次,以显示不同的行为,从而影响lambda表达式在运行时对可运行实现的对象求值的顺序

它打印出如下内容:

运行0 即使 创建于LambdaClassGeneration.mainLambdaClassGeneration.java:20 类LambdaClassGeneration$$Lambda$1/0x0000000800b90840 古怪的 创建于LambdaClassGeneration.mainLambdaClassGeneration.java:24 类LambdaClassGeneration$$Lambda$2/0x0000000800b91440 运行1 古怪的 创建于LambdaClassGeneration.mainLambdaClassGeneration.java:24 类LambdaClassGeneration$$Lambda$1/0x0000000800b90840 即使 创建于LambdaClassGeneration.mainLambdaClassGeneration.java:20 类LambdaClassGeneration$$Lambda$2/0x0000000800b91440 清楚地显示第一个生成的类得到索引1,第二个生成的类得到索引2,并且类名中没有任何东西暗示我们是在看“偶数”还是“奇数”可运行