从jvm来看,scala中的@究竟是个什么鬼?@模式匹配符号(scala 词法分析 语法分析 常用)
2016-12-29 12:06
495 查看
从jvm来看,scala中的@究竟是个什么鬼?我也是初步尝试来看jvm的类文件,又是初次来分析@,如不对的地方,请各位指正!
先看一下@是个什么?
运行结果:
"C:\ProgramFiles\Java\jdk1.8.0_65\bin\java"-Didea.launcher.port=7541"-Didea.launcher.bin.path=.....com.intellij.rt.execution.application.AppMaintest7
Some(2)
Some(1)
2
IMF
Processfinishedwithexitcode0
但@在idea中源代码中点击不开,既不是函数,也不是运算符,那scala中编译后究竟是什么呢?能否从JVM来看看?
1,写2个scala文件,一个包含@,一个不包含@
TestNoOpera.scala不包含@
objectTestNoOpera{
defmain(args:Array[String]){
valb="IMF"
}
}
TestInludeOpera.scala 包含@
objectTestInludeOpera{
defmain(args:Array[String]){
valaa@"IMF"="IMF"
}
}
2,scalac编译成class文件.
3,从class类查看工具javaclassviewer分别看一下 TestInludeOpera$.class和 TestNoOpera$.class文件
3.1:TestNoOpera$.class文件
说明:
opcode[12]-0000:ldc16[String:IMF] //ldc指令从运行时常量池中加载字符串常量“IMF”(常量池中16的位置,字符串索引为15,名称为IMF),并把IMF推入到JVM的操作数栈。
opcode[4D]-0002:astore_2//astore指令把IMF变量从操作数栈顶弹出,存入局部变量表。a意思是操作引用类型。
opcode[B1]-0003:return //什么也没有做,那就return指令返回,没有返回值。将结果返回给调用方。
3.2TestInludeOpera$.class 包含@操作符的类文件
opcode[12]-0000:ldc16[String:IMF]//ldc指令从运行时常量池中加载字符串常量“IMF”(常量池中16的位置,字符串索引为15,名称为IMF),并把IMF推入到JVM的操作数栈。
opcode[4E]-0002:astore_3 //astore指令把IMF变量从操作数栈顶弹出,存入局部变量表的字段3。
opcode[12]-0003:ldc16[String:IMF] //ldc指令从运行时常量池中加载字符串常量“IMF”,并把IMF推入到JVM的操作数栈。
opcode[2D]-0005:aload_3 //aload从局部变量表又取出了IMF变量,将IMF变量推入到操作数栈顶
opcode[3A]-0006:dstore4//dstore指令将变量IMF从操作数栈顶弹出,存到到局部变量表的字段4.
opcode[59]-0008:dup//dup复制操作数栈顶的变量IMF
opcode[C7]-0009:ifnonnull12//ifnonnull判断值是否为空
opcode[57]-0012:pop //pop指令对操作数栈进行操作,将栈顶的变量IMF弹出
opcode[19]-0013:aload4 //aload从局部变量表的字段4 取出了IMF变量,将IMF变量推入到操作数栈顶
opcode[C6]-0015:ifnull14 //ifnnull判断值是否为空
opcode[A7]-0018:goto19//无条件跳转到偏移量19的位置
opcode[19]-0021:aload4//aload从局部变量表的字段4 取出了IMF变量,将IMF变量推入到操作数栈顶
opcode[B6]-0023:invokevirtual20[Methodref:java.lang.Object.equals,parameter=(java.lang.Object),returns=boolean]//invokevirtual指令从对象的类中查找要调用的方法,如果找不到方法,就报异常,这里是调用Object的equals方法,入参数是对象,返回值是布尔值
opcode[99]-0026:ifeq11//判定是否相等
opcode[12]-0029:ldc16[String:IMF]// //ldc指令从运行时常量池中加载字符串常量“IMF”,并把IMF推入到JVM的操作数栈。
opcode[3A]-0031:dstore5///dstore指令将变量IMF从操作数栈顶弹出,存到到局部变量表的字段5
opcode[19]-0033:aload5// //aload从局部变量表取出了IMF变量,将IMF变量推入到操作数栈顶
opcode[4D]-0035:astore_2// //astore指令把IMF变量从操作数栈顶弹出,存入局部变量表的字段2。
opcode[B1]-0036:return//return返回
//以下是异常的处理
opcode[BB]-0037:name_new22[Class:scala.MatchError]//new指令的操作数是一个unit16的索引,这里是22,我们通过这个索引,从类的运行时常量池中找到类符号引用,解析这个类符合引号,那就可以拿到类数据,创建对象,并且将对象引用推入到操作数栈顶,new指令完成.
opcode[59]-0040:dup //dup复制操作数栈顶的变量MatchError
opcode[2D]-0041:aload_3//aload从局部变量表取出了IMF变量,将IMF变量推入到操作数栈顶
opcode[B7]-0042:invokespecial25[Methodref:scala.MatchError.<init>,parameter=(java.lang.Object),returns=void]//invokespecial调用MatchError方法
opcode[BF]-0045:athrow//athrow是引用类指令,将MatchError异常对象引用从操作数栈顶弹出,并跳转到异常处理代码.
四:结论:
@符号在scala编译中做了一个模式配置的工作,将字符串做了比对,如果值相等,将将这个值取到赋值给变量;如果值不相等,匹配不上,就报一个异常.
先看一下@是个什么?
/**
*Createdbyadminon2016/12/29.
*/
objecttest7{
defmain(args:Array[String]){
valb=Some(2)
vala@Some(1)=Some(1)
println(b)
println(a)
valbb=2
valaa@"IMF"="IMF"
println(bb)
println(aa)
}
}
运行结果:
"C:\ProgramFiles\Java\jdk1.8.0_65\bin\java"-Didea.launcher.port=7541"-Didea.launcher.bin.path=.....com.intellij.rt.execution.application.AppMaintest7
Some(2)
Some(1)
2
IMF
Processfinishedwithexitcode0
但@在idea中源代码中点击不开,既不是函数,也不是运算符,那scala中编译后究竟是什么呢?能否从JVM来看看?
1,写2个scala文件,一个包含@,一个不包含@
TestNoOpera.scala不包含@
objectTestNoOpera{
defmain(args:Array[String]){
valb="IMF"
}
}
TestInludeOpera.scala 包含@
objectTestInludeOpera{
defmain(args:Array[String]){
valaa@"IMF"="IMF"
}
}
2,scalac编译成class文件.
3,从class类查看工具javaclassviewer分别看一下 TestInludeOpera$.class和 TestNoOpera$.class文件
3.1:TestNoOpera$.class文件
说明:
opcode[12]-0000:ldc16[String:IMF] //ldc指令从运行时常量池中加载字符串常量“IMF”(常量池中16的位置,字符串索引为15,名称为IMF),并把IMF推入到JVM的操作数栈。
opcode[4D]-0002:astore_2//astore指令把IMF变量从操作数栈顶弹出,存入局部变量表。a意思是操作引用类型。
opcode[B1]-0003:return //什么也没有做,那就return指令返回,没有返回值。将结果返回给调用方。
3.2TestInludeOpera$.class 包含@操作符的类文件
opcode[12]-0000:ldc16[String:IMF]//ldc指令从运行时常量池中加载字符串常量“IMF”(常量池中16的位置,字符串索引为15,名称为IMF),并把IMF推入到JVM的操作数栈。
opcode[4E]-0002:astore_3 //astore指令把IMF变量从操作数栈顶弹出,存入局部变量表的字段3。
opcode[12]-0003:ldc16[String:IMF] //ldc指令从运行时常量池中加载字符串常量“IMF”,并把IMF推入到JVM的操作数栈。
opcode[2D]-0005:aload_3 //aload从局部变量表又取出了IMF变量,将IMF变量推入到操作数栈顶
opcode[3A]-0006:dstore4//dstore指令将变量IMF从操作数栈顶弹出,存到到局部变量表的字段4.
opcode[59]-0008:dup//dup复制操作数栈顶的变量IMF
opcode[C7]-0009:ifnonnull12//ifnonnull判断值是否为空
opcode[57]-0012:pop //pop指令对操作数栈进行操作,将栈顶的变量IMF弹出
opcode[19]-0013:aload4 //aload从局部变量表的字段4 取出了IMF变量,将IMF变量推入到操作数栈顶
opcode[C6]-0015:ifnull14 //ifnnull判断值是否为空
opcode[A7]-0018:goto19//无条件跳转到偏移量19的位置
opcode[19]-0021:aload4//aload从局部变量表的字段4 取出了IMF变量,将IMF变量推入到操作数栈顶
opcode[B6]-0023:invokevirtual20[Methodref:java.lang.Object.equals,parameter=(java.lang.Object),returns=boolean]//invokevirtual指令从对象的类中查找要调用的方法,如果找不到方法,就报异常,这里是调用Object的equals方法,入参数是对象,返回值是布尔值
opcode[99]-0026:ifeq11//判定是否相等
opcode[12]-0029:ldc16[String:IMF]// //ldc指令从运行时常量池中加载字符串常量“IMF”,并把IMF推入到JVM的操作数栈。
opcode[3A]-0031:dstore5///dstore指令将变量IMF从操作数栈顶弹出,存到到局部变量表的字段5
opcode[19]-0033:aload5// //aload从局部变量表取出了IMF变量,将IMF变量推入到操作数栈顶
opcode[4D]-0035:astore_2// //astore指令把IMF变量从操作数栈顶弹出,存入局部变量表的字段2。
opcode[B1]-0036:return//return返回
//以下是异常的处理
opcode[BB]-0037:name_new22[Class:scala.MatchError]//new指令的操作数是一个unit16的索引,这里是22,我们通过这个索引,从类的运行时常量池中找到类符号引用,解析这个类符合引号,那就可以拿到类数据,创建对象,并且将对象引用推入到操作数栈顶,new指令完成.
opcode[59]-0040:dup //dup复制操作数栈顶的变量MatchError
opcode[2D]-0041:aload_3//aload从局部变量表取出了IMF变量,将IMF变量推入到操作数栈顶
opcode[B7]-0042:invokespecial25[Methodref:scala.MatchError.<init>,parameter=(java.lang.Object),returns=void]//invokespecial调用MatchError方法
opcode[BF]-0045:athrow//athrow是引用类指令,将MatchError异常对象引用从操作数栈顶弹出,并跳转到异常处理代码.
四:结论:
@符号在scala编译中做了一个模式配置的工作,将字符串做了比对,如果值相等,将将这个值取到赋值给变量;如果值不相等,匹配不上,就报一个异常.
相关文章推荐
- scala基础语法-match模式匹配
- Scala模式匹配语法讲解
- Scala的模式匹配本质是什么? -从Coursera的响应式编程说起
- Scala语法 Case Class和模式匹配
- Scala编程基础 基本语法 数组 集合 类 模式匹配【Scala 2】
- scala中模式匹配中的@代表什么意思
- @ 符号 在java中是什么语法 代表什么
- 正则匹配时的圆括号及子模式(子组)——关于PCRE正则语法
- 什么是单例模式?C++中单例模式对象的释放控制分析
- XSLT模式匹配的语法
- JAVA中常用设计模式 分析详解
- sphinx检索语法与匹配模式备忘
- [zz]三种模式匹配算法(KMP,MonteCarlo,LasVegas)的比较与分析
- XSL学习笔记4 XSLT模式匹配的语法
- hive 常用语法sql、join分析
- 快学Scala习题解答—第十四章 模式匹配和样例类
- JVM体系架构分析与内存原理模式详解~新
- KMP模式匹配算法分析与实现
- 常用正则表达式模式 -- 匹配 Javascript
- 以太网接口双工模式匹配分析