1. Foreach和泛型语法糖
--看看字节码是什么内容:
8:aload_1
9: getfield #27 // Field map:Ljava/util/Map;
12: invokeinterface #44, 1 // InterfaceMethod java/util/Map.e
--可以看到红色那些内容,说明实际上编译器真正使用的还是正常的for循环加迭代器遍历的套路,只不过为了让使用者感觉方便创造了foreach这种看似简单易用的语法糖。还有绿色的checkcast,说明Map<String,String> 这个泛型其实也是颗语法糖,跟C++不一样,JVM并不会创建一个Map<String,String>类型,只是编译器在每个使用到Map<String,String>的代码中,进行了类型转化,可以根据InterfaceMethodjava/util/Map$Entry.getValue:()Ljava/lang/Object;可知道iter.getValue()实际返回值只是Object对象,编译器添加了向下转化代码checkcast,所以整个代码经过编译器转化后应该是这样的:String str = (String)iter.getValue();
2. 接口文件的字节码内容
接口文件字节码的内容是什么呢?这是个有意思的问题,首先看到接口文件其实也是生成一份.class文件,再看看字节码经过javap转译后是什么内容:
--是的,其实跟正常类的字节码布局基本一样,只是方法都被编译器加上了abstract关键字(在源码中并没写该关键字),而且没有CODE段。所以说所谓的“接口”其实本质上就是被编译器阉割(限制)的类而且,就像一个普通人皈依了某宗教,被教律限制了不能做这不能做那,但是对于JVM而言,跟正常类区别不大。另外有特点,如果在定义接口时没有写访问控制权限和抽象关键字,编译器会在生成字节码时在接口前面添加public abstract,所以出现了一个这么特点:你可以不写public abstract,编译器会为你加上,但是你不能写其他限定词,否则编译器就报错不通过。
2. 抽象类的字节码内容:
--可见抽象类和正常类的布局 也基本相同,并且抽象类也是独立生成一个.class文件的,所以说“接口”和“抽象类”其实更多是java上的概念,而这个概念其实是对正常类的阉割,这不能做,那不能做,而这个阉割由编译器来实现(如果违反阉割规则编译器不允许通过编译)。但是从字节码角度看,其实相差不大,都是正常的.class布局。
3. 从字节码角度看try、catch、finally机制
--这段代码编译成字节码:
如果运行时不抛出异常则按绿色标识的CODE段的正常流程走,看看正常流程是怎么走的:1.执行代码File file = new File("");,2. Goto 第44字节开始的命令,3.第44字节开始的命令就是((Throwable) e).getMessage();
如果运行时抛出异常呢?注意红色那段,这是Exception table,当运行时try模块抛出异常后,第一步就是去查询Exception table,红色那两行是什么意思呢?第一行意思就是当从0到10字节中抛出类型为Exception或它的子类异常时,则指令应该跳转到第13字节指令,第13字节开始的指令就是catch模块的e.printStackTrace();,顺着执行,然后执行finally模块中的代码。最后才执行catch模块的return。第二行意思就是当从0到18字节指令也就是try和catch两个模块中抛出任何其他类型的异常时,第一步跳转到第30字节指令,也就是finally模块的代码。
这样一来就保证了无论如何finally模块的代码都必须执行,并且在return之前执行。
如果把finally模块修改下:
则字节码如下:
--可见在fun方法的字节码中增加了一个Exceptions: throws java.lang.Exception段,而且在finally模块指令中执行athrow指令
到此这篇字符串转hashmap(字符串转hashcode 对字符串长度有限制吗 c)的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!
版权声明:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权、违法违规、事实不符,请将相关资料发送至xkadmin@xkablog.com进行投诉反馈,一经查实,立即处理!
转载请注明出处,原文链接:https://www.xkablog.com/cjjbc/32546.html