从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 } ...
随机推荐
- Android Studio 出现 Gradle's dependency cache may be corrupt 解决方案
将 .\项目地址\gradle\wrapper\gradle-wrapper.properties 文件中的 gradle版本 与 正常的版本 修改一致即可.
- ubuntu下升级特定软件与查看软件版本信息
ubuntu 升级软件: sudo apt-get update 更新源 sudo apt-get upgrade 更新已安装的包 sudo apt-get dist-upgrade 升级系统 ubu ...
- C语言工具:LCC-Win32+v3.0
LCC-Win32+v3.0(带汉化).rar 小巧精悍的工具 安装步骤: 1.先安装 LCC-Win32V3.0.exe 假如安装目录为:C:\lcc 2.再安装 LCC-Win32V3.0汉化补 ...
- sencha touch list + carousel scrollable(与其他控件共用滚动条)
有些时候我们需要实现这种效果 上边是一张图片或者一个跑马灯控件,这个布局实现起来比较容易 但是如何让他们共用一个滚动条,来实现以下效果就比较麻烦了. 在官方论坛查找资料得知,可以用以下写法实现: /* ...
- Apache Server Status详解
Apache的日志如果靠分析日志或者查看服务器进程来监视Apache运行状态的话,比较繁冗.不过在Apache 1.3.2及以后的版本中就自带一个查看Apache状态的功能模块server-statu ...
- .net C#中页面之间传值传参的六种方法
1.QueryString是一种非常简单的传值方式,他可以将传送的值显示在浏览器的地址栏中.如果是传递一个或多个安全性要求不高或是结构简单的数值时,可以使用这个方法.但是对于传递数组或对象的话,就不能 ...
- C# DataTbale详细操作
1.创建DataTable对象 DataTable dt = new DataTable("Table_AX"); 2.为DataTable创建列 //方式一(我觉得这种好) dt ...
- 【BZOJ2138】stone Hall定理+线段树
[BZOJ2138]stone Description 话说Nan在海边等人,预计还要等上M分钟.为了打发时间,他玩起了石子.Nan搬来了N堆石子,编号为1到N,每堆包含Ai颗石子.每1分钟,Nan会 ...
- AppScan扫描建议 问题集
1.1 AppScan扫描建议 若干问题的补救方法在于对用户输入进行清理. 通过验证用户输入未包含危险字符,便可能防止恶意的用户导致应用程序执行计划外的任务,例如:启动任意 SQL 查询 ...
- nginx 开机自动启动
接下来聊一聊nginx的开机自启吧 看了看都是用脚本启动的,我也就不扯啥犊子了,都是前人经验 我的操作系统是centos 7 nginx版本是1.10.3 首先看一下自己的nginx配置 我的是 ./ ...