- 浏览: 3052483 次
- 性别:
- 来自: 海外
文章分类
- 全部博客 (430)
- Programming Languages (23)
- Compiler (20)
- Virtual Machine (57)
- Garbage Collection (4)
- HotSpot VM (26)
- Mono (2)
- SSCLI Rotor (1)
- Harmony (0)
- DLR (19)
- Ruby (28)
- C# (38)
- F# (3)
- Haskell (0)
- Scheme (1)
- Regular Expression (5)
- Python (4)
- ECMAScript (2)
- JavaScript (18)
- ActionScript (7)
- Squirrel (2)
- C (6)
- C++ (10)
- D (2)
- .NET (13)
- Java (86)
- Scala (1)
- Groovy (3)
- Optimization (6)
- Data Structure and Algorithm (3)
- Books (4)
- WPF (1)
- Game Engines (7)
- 吉里吉里 (12)
- UML (1)
- Reverse Engineering (11)
- NSIS (4)
- Utilities (3)
- Design Patterns (1)
- Visual Studio (9)
- Windows 7 (3)
- x86 Assembler (1)
- Android (2)
- School Assignment / Test (6)
- Anti-virus (1)
- REST (1)
- Profiling (1)
- misc (39)
- NetOA (12)
- rant (6)
- anime (5)
- Links (12)
- CLR (7)
- GC (1)
- OpenJDK (2)
- JVM (4)
- KVM (0)
- Rhino (1)
- LINQ (2)
- JScript (0)
- Nashorn (0)
- Dalvik (1)
- DTrace (0)
- LLVM (0)
- MSIL (0)
最新评论
-
mldxs:
虽然很多还是看不懂,写的很好!
虚拟机随谈(一):解释器,树遍历解释器,基于栈与基于寄存器,大杂烩 -
HanyuKing:
Java的多维数组 -
funnyone:
Java 8的default method与method resolution -
ljs_nogard:
Xamarin workbook - .Net Core 中不 ...
LINQ的恶搞…… -
txm119161336:
allocatestlye1 顺序为 // Fields o ...
最近做的两次Java/JVM分享的概要
原帖地址:http://www.iteye.com/topic/477934?page=3#1186622
再顺手转回来免得以后找起来麻烦
你的思路被局限在Java“语言”里了。JSR 292的主要服务对象是JVM上的动态语言,而不是Java。如果你了解JVM的spec而不只是Java的spec,你应该能理解Java字节码不是只能通过Java编译器来生成的。你可以把我之前回帖的那段完整引用一次:
对,说得一点也没错,所以MethodHandles的API就是这样的:
如果只是要做Java的method overload resolution,当然只要参数类型不要返回值类型就够了,但了解class文件及JVM内部数据组织方式的话就会知道,方法的签名(signature)在class文件里是以方法描述符(method descriptor)的形式存在,而该描述符上是有返回值类型的。MethodHandles的API这么设计就是为了快,能更直接的访问VM里的信息,以最快的方式找到目标方法。
如果那段文字仍然不能让你明白,那请看下面的例子。
首先要明确的是,在Java语言里,method overload只依赖于方法名和参数类型,不考虑返回值类型;仅在返回值类型不同的方法无法通过Java编译器的编译。
但生成Java字节码的方式有很多:JVM上有非常多其它语言,它们的编译器都可以生成Java字节码;动态代理要生成字节码;再不行,手工生成字节码也是可以的。从JVM的角度看,无论字节码的来源是什么,只要符合class文件规范、只要加载成功,JVM就可以执行那些字节码。
这里我用bitescript来生成一个class文件,类名为TestMethodSameName,包括两个foo方法,它们只在返回值类型上不同:
得到的class文件,内容如下:
如果用Java语法来写,就是:
再次注意到这段代码用Java编译器确实编译不了。但上面生成的字节码对JVM来说却是完全没问题的。执行结果输出如下:
这很好的说明了在深入到底层去挖掘MethodHandle时,指定返回值类型的必要性。
JDK原本包含的普通反射API之所以不需要指定返回值类型是因为它只是为Java语言服务的。如今的JSR 292则是为JVM上所有语言服务,主要目标是各种动态语言,但也不拒绝Java去使用它。
关于bitescript的用法,请参考这一帖的例子。上面生成的class文件我也放在附件里了,不相信例子的输出结果的话请自己执行一下,眼见为实。
《Inside the Java Virtual Machine》第二版的6.3.3讲解了描述符,6.6讲解了方法。在6.6的第一段就提到了仅靠返回值也可以区分方法的情况。
再顺手转回来免得以后找起来麻烦
star022 写道
Java代码
findStatic(
TestMethodHandle1.class, // 方法所属类型(Class)
"hello", // 方法名
type // 由参数和返回值类型组成的“方法类型”
);
type// 由参数和返回值类型组成的“方法类型”
“方法类型”这个参数设计得很失败,
一个类中的方法,如果方法名和参数个数及类型一样,这个类能正确编译吗?
其实MethodHandle最终只需要暴露类似这样一个静态方法即可:
//方法如果没有返回值,为void
MethodHandle.<T>invoke(
Class clazz, // 方法所属类型(Class)
String methodName, // 方法名
Object... params//方法参数,可以运行时确定参数个数及类型,定位到具体方法
)
findStatic(
TestMethodHandle1.class, // 方法所属类型(Class)
"hello", // 方法名
type // 由参数和返回值类型组成的“方法类型”
);
type// 由参数和返回值类型组成的“方法类型”
“方法类型”这个参数设计得很失败,
一个类中的方法,如果方法名和参数个数及类型一样,这个类能正确编译吗?
其实MethodHandle最终只需要暴露类似这样一个静态方法即可:
//方法如果没有返回值,为void
MethodHandle.<T>invoke(
Class clazz, // 方法所属类型(Class)
String methodName, // 方法名
Object... params//方法参数,可以运行时确定参数个数及类型,定位到具体方法
)
你的思路被局限在Java“语言”里了。JSR 292的主要服务对象是JVM上的动态语言,而不是Java。如果你了解JVM的spec而不只是Java的spec,你应该能理解Java字节码不是只能通过Java编译器来生成的。你可以把我之前回帖的那段完整引用一次:
RednaxelaFX 写道
star022 写道
定位到一个java方法,其实只需要类型(Class),方法名及参数即可。
对,说得一点也没错,所以MethodHandles的API就是这样的:
引用
findStatic( TestMethodHandle1.class, // 方法所属类型(Class) "hello", // 方法名 type // 由参数和返回值类型组成的“方法类型” );
如果只是要做Java的method overload resolution,当然只要参数类型不要返回值类型就够了,但了解class文件及JVM内部数据组织方式的话就会知道,方法的签名(signature)在class文件里是以方法描述符(method descriptor)的形式存在,而该描述符上是有返回值类型的。MethodHandles的API这么设计就是为了快,能更直接的访问VM里的信息,以最快的方式找到目标方法。
如果那段文字仍然不能让你明白,那请看下面的例子。
首先要明确的是,在Java语言里,method overload只依赖于方法名和参数类型,不考虑返回值类型;仅在返回值类型不同的方法无法通过Java编译器的编译。
但生成Java字节码的方式有很多:JVM上有非常多其它语言,它们的编译器都可以生成Java字节码;动态代理要生成字节码;再不行,手工生成字节码也是可以的。从JVM的角度看,无论字节码的来源是什么,只要符合class文件规范、只要加载成功,JVM就可以执行那些字节码。
这里我用bitescript来生成一个class文件,类名为TestMethodSameName,包括两个foo方法,它们只在返回值类型上不同:
require 'rubygems' require 'bitescript' include BiteScript fb = FileBuilder.build(__FILE__) do public_class 'TestMethodSameName' do public_static_method 'foo', void, int do ldc 'TestMethodSameName.foo:(I)V' aprintln returnvoid end public_static_method 'foo', int, int do ldc 'TestMethodSameName.foo:(I)I' aprintln iload 0 ireturn end public_static_method 'main', void, string[] do push_int 123 invokestatic this, 'foo', [void, int] push_int 456 invokestatic this, 'foo', [int, int] pop returnvoid end end end fb.generate do |filename, class_builder| File.open(filename, 'w') do |file| file.write(class_builder.generate) end end
得到的class文件,内容如下:
Compiled from "test5.rb" public class TestMethodSameName extends java.lang.Object{ public static void foo(int); Code: 0: ldc #9; //String TestMethodSameName.foo:(I)V 2: getstatic #15; //Field java/lang/System.out:Ljava/io/PrintStream; 5: swap 6: invokevirtual #21; //Method java/io/PrintStream.println:(Ljava/lang/Object;)V 9: return public static int foo(int); Code: 0: ldc #24; //String TestMethodSameName.foo:(I)I 2: getstatic #15; //Field java/lang/System.out:Ljava/io/PrintStream; 5: swap 6: invokevirtual #21; //Method java/io/PrintStream.println:(Ljava/lang/Object;)V 9: iload_0 10: ireturn public static void main(java.lang.String[]); Code: 0: bipush 123 2: invokestatic #28; //Method foo:(I)V 5: sipush 456 8: invokestatic #30; //Method foo:(I)I 11: pop 12: return }
如果用Java语法来写,就是:
public class TestMethodSameName { public static void foo(int i) { System.out.println("TestMethodSameName.foo:(I)V"); } public static int foo(int i) { System.out.println("TestMethodSameName.foo:(I)I"); return i; } public static void main(String[] args) { foo(123); // foo:(I)V foo(456); // foo:(I)I } }
再次注意到这段代码用Java编译器确实编译不了。但上面生成的字节码对JVM来说却是完全没问题的。执行结果输出如下:
引用
TestMethodSameName.foo:(I)V
TestMethodSameName.foo:(I)I
TestMethodSameName.foo:(I)I
这很好的说明了在深入到底层去挖掘MethodHandle时,指定返回值类型的必要性。
JDK原本包含的普通反射API之所以不需要指定返回值类型是因为它只是为Java语言服务的。如今的JSR 292则是为JVM上所有语言服务,主要目标是各种动态语言,但也不拒绝Java去使用它。
关于bitescript的用法,请参考这一帖的例子。上面生成的class文件我也放在附件里了,不相信例子的输出结果的话请自己执行一下,眼见为实。
- TestMethodSameName.zip (455 Bytes)
- 下载次数: 6
评论
3 楼
phyeas
2009-10-01
原来是第6章。。
2 楼
RednaxelaFX
2009-10-01
phyeas 写道
好像是inside jvm第3章还是第4章的内容,还好看过,不至于太OUT
《Inside the Java Virtual Machine》第二版的6.3.3讲解了描述符,6.6讲解了方法。在6.6的第一段就提到了仅靠返回值也可以区分方法的情况。
1 楼
phyeas
2009-10-01
好像是inside jvm第3章还是第4章的内容,还好看过,不至于太OUT
发表评论
-
The Prehistory of Java, HotSpot and Train
2014-06-02 08:18 0http://cs.gmu.edu/cne/itcore/vi ... -
MSJVM and Sun 1.0.x/1.1.x
2014-05-20 18:50 0当年的survey paper: http://www.sym ... -
Sun JDK1.4.2_28有TieredCompilation
2014-05-12 08:48 0原来以前Sun的JDK 1.4.2 update 28就已经有 ... -
IBM JVM notes (2014 ver)
2014-05-11 07:16 0Sovereign JIT http://publib.bou ... -
class data sharing by Apple
2014-03-28 05:17 0class data sharing is implement ... -
Java 8与静态工具类
2014-03-19 08:43 16290以前要在Java里实现所谓“静态工具类”(static uti ... -
Java 8的default method与method resolution
2014-03-19 02:23 10465先看看下面这个代码例子, interface IFoo { ... -
HotSpot Server VM与Server Class Machine
2014-02-18 13:21 0HotSpot VM历来有Client VM与Server V ... -
Java 8的lambda表达式在OpenJDK8中的实现
2014-02-04 12:08 0三月份JDK8就要发布首发了,现在JDK8 release c ... -
GC stack map与deopt stack map的异同
2014-01-08 09:56 0两者之间不并存在包含关系。它们有交集,但也各自有特别的地方。 ... -
HotSpot Server Compiler与data-flow analysis
2014-01-07 17:41 0http://en.wikipedia.org/wiki/Da ... -
字符串的一般封装方式的内存布局 (1): 元数据与字符串内容,整体还是分离?
2013-11-07 17:44 22408(Disclaimer:未经许可请 ... -
字符串的一般封装方式的内存布局
2013-11-01 12:55 0(Disclaimer:未经许可请 ... -
关于string,内存布局,C++ std::string,CoW
2013-10-30 20:45 0(Disclaimer:未经许可请 ... -
对C语义的for循环的基本代码生成模式
2013-10-19 23:12 21884之前有同学在做龙书(第二版)题目,做到8.4的练习,跟我对答案 ... -
Java的instanceof是如何实现的
2013-09-22 16:57 0Java语言规范,Java SE 7版 http://docs ... -
oop、klass、handle的关系
2013-07-30 17:34 0oopDesc及其子类的实例 oop : oopDesc* ... -
Nashorn各种笔记
2013-07-15 17:03 0http://bits.netbeans.org/netbea ... -
《深入理解Java虚拟机(第二版)》书评
2013-07-08 19:19 0值得推荐的中文Java虚拟机入门书 感谢作者赠与的样书,以下 ... -
豆列:从表到里学习JVM实现
2013-06-13 14:13 48396刚写了个学习JVM用的豆列跟大家分享。 豆列地址:http: ...
相关推荐
《深入解析JDK7源代码》 JDK7(Java Development Kit 7)是Java编程语言的一个重要版本,它的源代码对于理解Java平台的工作原理、学习面向对象编程以及提升编程技巧具有极大的价值。在这个资源中,包含了 javax、...
Java 7.0 JDK 7 API CHM part02 本资源有五个压缩包,请全部下载后再解压 下载地址如下: Java 7.0 JDK 7 API CHM part05: http://download.csdn.net/source/3487478 Java 7.0 JDK 7 API CHM part04: ...
Java 7.0 JDK 7 API CHM part03 本资源有五个压缩包,请全部下载后再解压 下载地址如下: Java 7.0 JDK 7 API CHM part05: http://download.csdn.net/source/3487478 Java 7.0 JDK 7 API CHM part04: ...
Java 7.0 JDK 7 API CHM part05 本资源有五个压缩包,请全部下载后再解压 下载地址如下: Java 7.0 JDK 7 API CHM part05: http://download.csdn.net/source/3487478 Java 7.0 JDK 7 API CHM part04: ...
Java 7.0 JDK 7 API CHM part01 本资源有五个压缩包,请全部下载后再解压 下载地址如下: Java 7.0 JDK 7 API CHM part05: http://download.csdn.net/source/3487478 Java 7.0 JDK 7 API CHM part04: ...
Java 7.0 JDK 7 API CHM part04 本资源有五个压缩包,请全部下载后再解压 下载地址如下: Java 7.0 JDK 7 API CHM part05: http://download.csdn.net/source/3487478 Java 7.0 JDK 7 API CHM part04: ...
Java Development Kit(JDK)是Java编程语言的核心组件,提供了编写、编译、调试和运行Java应用程序所需的...对比JDK 7与更高版本的源代码,可以帮助开发者追踪语言的发展,理解新特性的实现原理,从而提升编程能力。
JDK是由Sun Microsystems(现已被Oracle公司收购)开发并维护的,自Java诞生以来,它一直是Java开发者的首选SDK。本文将深入探讨JDK的主要组件、功能及其不同版本的下载链接。 1. JDK的主要组件: - **javac**:...
标题提到的"jdk-7u191"指的是JDK的第7个主要版本的第191次更新。此版本在发布时是一个重要的里程碑,因为Java 7引入了许多新特性,如动态类型、字符串inswitch、try-with-resources语句等,极大地提高了开发效率。 ...
总的来说,了解并掌握tools.jar在JDK中的作用,有助于我们更好地理解和维护Java开发环境,提高开发效率。遇到问题时,通过正确诊断和处理,可以确保开发工具的正常运行,进而保证软件开发流程的顺利进行。
OpenJDK 8是基于Java SE 8规范的开源实现,它与Oracle JDK 8在功能上非常接近,但OpenJDK是免费且无版权限制的,而Oracle JDK则包含一些闭源的特性和服务。 在OpenJDK 7和8中,有一些重要的新特性和改进: 1. **...
**Java Development Kit (JDK) 1.7.0_79详解** JDK(Java Development Kit)是Oracle公司提供的用于开发和运行Java应用程序的重要工具集。本文将深入探讨JDK 1.7.0_79版本,该版本特别针对Windows x64操作系统进行...
**Java Development Kit (JDK) 7 for Windows 32位详解** JDK(Java Development Kit)是Oracle公司提供的用于开发和运行Java应用程序的核心工具集。JDK 7,也称为Java SE 7 (Java Standard Edition 7),是Java语言...
虽然描述中没有明确指出Jdk7绿色版包含MySQL,但是提到了“使用”,这可能意味着该版本提供了一种简便的方法来与MySQL配合,可能是通过预配置的连接驱动或其他工具。 关于JDK7的重要知识点: 1. **多线程改进**:...
https://javaserverfaces.dev.java.net/ mojarra-1.2._11_b0_FCS JDK 1.5 绝对能用 good luck
JDK7,全称为Java SE 7 (Java Platform, Standard Edition 7),是Java平台的一个重大更新,于2011年发布,引入了许多新特性和改进,提升了开发者的工作效率和程序性能。"JDK7win安装版"表明这是专门为Windows操作...
Java JDK 7是Java开发工具包的一个重要版本,它的全称是Java Development Kit,是用于构建和运行Java应用程序的关键组件。...通过这份PDF学习笔记,读者将能深入理解JDK 7的新特性,并能将其应用到实际项目中。
1. **多语言支持**:Java 7增加了对其他编程语言的支持,如Groovy、Scala等,通过JEP(JDK Enhancement Proposals)292,使得这些语言可以在Java虚拟机(JVM)上运行。 2. **try-with-resources**:这是一个语法糖...
Java Development Kit (JDK) 1.7 64位官方正式版,即`jdk-7u76-linux-x64.tar.gz`,是Oracle公司为Linux 64位操作系统提供的Java开发工具集。这个版本的JDK对于开发和运行基于Java技术的应用程序至关重要,特别是当...