从jvm来看,scala中的@究竟是个什么鬼?@模式匹配符号(scala 词法分析 语法分析常用)
从jvm来看,scala中的@究竟是个什么鬼? 我也是初步尝试来看jvm的类文件,又是初次来分析@,如不对的地方,请各位指正!
先看一下@ 是个什么?
object TestScala {
def main(args: Array[String]): Unit = {
val b = Some()
val a@Some() = Some()
println(b)
println(a)
val bb =
val aa@"IMF" = "IMF"
println(bb)
println(aa)
}
}
运行结果:
Some()
Some() IMF
但 @在idea中源代码中点击不开,既不是 函数,也不是运算符,那scala中编译后究竟是什么呢 ?能否 从JVM来看看 ?
1,写2个scala文件,一个包含@,一个不包含@
TestNoOpera.scala 不包含@
object TestNoOpera {
def main(args: Array[String]) {
val b="IMF"
}
}
TestInludeOpera.scala 包含@
object TestInludeOpera {
def main(args: Array[String]) {
val aa@"IMF" ="IMF"
}
}
2,scalac 编译成class文件

3,从 class类查看工具java class viewer分别看一下 TestInludeOpera$.class 和 TestNoOpera$.class文件
3.1:TestNoOpera$.class文件


说明:
opcode [12] - 0000: ldc 16 [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: ldc 16 [String: IMF]//ldc指令从运行时常量池中加载字符串常量 “IMF” (常量池中16的位置,字符串索引为15,名称为IMF),并把IMF推入到JVM的操作数栈。
opcode [4E] - 0002: astore_3 //astore指令把IMF变量从操作数栈顶弹出,存入局部变量表的字段3。
opcode [12] - 0003: ldc 16 [String: IMF] //ldc指令从运行时常量池中加载字符串常量 “IMF” ,并把IMF推入到JVM的操作数栈。
opcode [2D] - 0005: aload_3 //aload 从局部变量表又取出了 IMF变量,将IMF变量推入到操作数栈顶
opcode [3A] - 0006: dstore 4 //dstore 指令将变量IMF从操作数栈顶弹出,存到到局部变量表的字段4 .
opcode [59] - 0008: dup //dup复制操作数栈顶的变量IMF
opcode [C7] - 0009: ifnonnull 12 //ifnonnull判断值是否为空
opcode [57] - 0012: pop // pop指令对操作数栈进行操作,将栈顶的变量IMF弹出
opcode [19] - 0013: aload 4 //aload 从局部变量表的字段4 取出了 IMF变量,将IMF变量推入到操作数栈顶
opcode [C6] - 0015: ifnull 14 //ifnnull判断值是否为空
opcode [A7] - 0018: goto 19 //无条件跳转到偏移量19的位置
opcode [19] - 0021: aload 4 //aload 从局部变量表的字段4 取出了 IMF变量,将IMF变量推入到操作数栈顶
opcode [B6] - 0023: invokevirtual 20 [Methodref: java.lang.Object.equals, parameter = (java.lang.Object), returns = boolean ] //invokevirtual 指令从对象的类中查找要调用的方法,如果找不到方法,就报异常,这里是调用Object的equals方法,入参数是对象,返回值是布尔值
opcode [99] - 0026: ifeq 11 //判定是否相等
opcode [12] - 0029: ldc 16 [String: IMF] // //ldc指令从运行时常量池中加载字符串常量 “IMF” ,并把IMF推入到JVM的操作数栈。
opcode [3A] - 0031: dstore 5 ///dstore 指令将变量IMF从操作数栈顶弹出,存到到局部变量表的字段5
opcode [19] - 0033: aload 5 // //aload 从局部变量表取出了 IMF变量,将IMF变量推入到操作数栈顶
opcode [4D] - 0035: astore_2 // //astore指令把IMF变量从操作数栈顶弹出,存入局部变量表的字段2。
opcode [B1] - 0036: return // return返回
//以下是异常的处理
opcode [BB] - 0037: name_new 22 [Class: scala.MatchError] //new指令的操作数是一个unit16的索引,这里是22,我们通过这个索引 ,从类的运行时常量池中找到类符号引用 ,解析这个类符合引号,那就可以拿到类数据,创建对象,并且将对象引用推入到操作数栈顶,new指令完成.
opcode [59] - 0040: dup //dup复制操作数栈顶的变量MatchError
opcode [2D] - 0041: aload_3 //aload 从局部变量表取出了 IMF变量,将IMF变量推入到操作数栈顶
opcode [B7] - 0042: invokespecial 25 [Methodref: scala.MatchError.<init>, parameter = (java.lang.Object), returns = void] //invokespecial 调用MatchError方法
opcode [BF] - 0045: athrow //athrow是引用类指令,将MatchError异常对象引用从操作数栈顶弹出,并跳转到异常处理代码.

四:结论:
@符号在scala编译中做了一个模式配置的工作,将字符串做了比对,如果值相等,将将这个值取到赋值给变量;如果值不相等,匹配不上,就报一个异常.
从jvm来看,scala中的@究竟是个什么鬼?@模式匹配符号(scala 词法分析 语法分析常用)的更多相关文章
- Akka系列(五):Java和Scala中的Future
前言....... 随着CPU的核数的增加,异步编程模型在并发领域中的得到了越来越多的应用,由于Scala是一门函数式语言,天然的支持异步编程模型,今天主要来看一下Java和Scala中的Futrue ...
- Scala学习(五)---Scala中的类
Scala中的类 摘要: 在本篇中,你将会学习如何用Scala实现类.如果你了解Java或C++中的类,你不会觉得这有多难,并且你会很享受Scala更加精简的表示法带来的便利.本篇的要点包括: 1. ...
- Programming In Scala笔记-第十一章、Scala中的类继承关系
本章主要从整体层面了解Scala中的类层级关系. 一.Scala的类层级 在Java中Object类是所有类的最终父类,其他所有类都直接或间接的继承了Object类.在Scala中所有类的最终父类为A ...
- 第85讲:Scala中For表达式的强大表现力实战
今天来学一下scala中的For表达式的用法. package scala.learn case class Persons(name:String,isMale:Boolean,children:P ...
- Scala中的函数
Scala中的函数 提纲 1.Scala中的函数简介 2.Scala中的函数的各种写法 1.Scala中的函数简介 =================== Scala是函数式编程和面向对象式编程的混合 ...
- Scala中的流程控制
一.分支控制if-else //Scala中if-else语句中,代码块内最后一句代码就是返回值 def main(args: Array[String]): Unit = { var age:Int ...
- scala学习手记4 - Java基本类型对应的scala类
在Java中变量类型分为两大类:基本类型和引用类型.虽然在JDK1.5以后引入了自动装箱和自动拆箱机制,大大减少了我们在直接类型和引用类型之间的纠结,但仍有一些我们不得不考虑的问题.比如我在工作遇到的 ...
- [转] Scala 中的异步事件处理
在任何并发性应用程序中,异步事件处理都至关重要.无论事件的来源是什么(不同的计算任务.I/O 操作或与外部系统的交互),您的代码都必须跟踪事件,协调为响应它们而执行的操作.应用程序可以采用两种基本方法 ...
- 第52讲:Scala中路径依赖代码实战详解
今天学习了scala中的路径依赖,来看一下实战代码 class Outer{ private val x = 10 class Inner{ private val y = x +10 } ...
随机推荐
- c++ malloc与free
今天看STL内存配置器的时候,第一级配置器就是直接用malloc.free来管理内存. 而free和malloc都只需要传入或传出一个指针就能分配和释放内存了. 编译器是如何知道,这个指针指向的空间的 ...
- 【大数据系列】FileSystem Shell官方文档翻译
appendToFile cat checksum chgrp chmod chown copyFromLocal copyToLocal count cp createSnapshot delete ...
- 【Java基础】System的arraycopy方法拷贝数组
一.在System类中查看方法的定义 二.示例 public class SystemArrayCopyTest { /** * @Description: System的arrayCopy方法测试 ...
- 【linux系列】配置免密登陆
一.SSH无密码登录原理 此操作是为了搭建hadoop集群进行的操作 Master(NameNode|JobTracker)作为客户端,要实现无密码公钥认证,连接到服务器Salve(DataNode| ...
- jQuery事件处理(六)
1.通过一步步调试的的方法观察了一下存放到cache中的事件及其处理程序的数据格式: { events : { // 根据事件类型存放添加到该元素上的所有事件,下面以click为例 click : [ ...
- Word 2010 小技巧篇
1.选择文本的妙招
- 学习项目部署Django+uwsgi+Nginx生产环境部署
绪论 项目生产环境部署,是很重的一个知识点.第一,Django自带的服务器很简陋,由于测试和开发环境尚可,无法用于生产环境,保障安全性和可靠性.以及性能.此外,学习部署方式,还有利于了解生产部署后的项 ...
- 【CF860E】Arkady and a Nobody-men 长链剖分
[CF860E]Arkady and a Nobody-men 题意:给你一棵n个点的有根树.如果b是a的祖先,定义$r(a,b)$为b的子树中深度小于等于a的深度的点的个数(包括a).定义$z(a) ...
- css如何设置label的字间距
css.html如何设置label的字间距 .myClass label{ letter-spacing: 10px; } 如果label需要居中,需加上 text-indent: 10px; 首行 ...
- tomcat+redis会话共享
1.基础环境: jdk1. tomcat7 redis nginx 2.添加依赖的jar包到tomcat的lib目录(http://pan.baidu.com/s/1eRAwN0Q) 3.配置tomc ...