Java 模拟 Scala 的运行机制|学习笔记

简介: 快速学习 Java 模拟 Scala 的运行机制。

开发者学堂课程【Scala 核心编程-基础Java 模拟 Scala 的运行机制】学习笔记,与课程紧密联系,让用户快速学习知识。

课程地址:https://developer.aliyun.com/learning/course/609/detail/8884


Java 模拟 Scala 的运行机制

 

目录

一、 反编译代码

二、 使用 Java 模拟 scala 运行机制代码

 

接下来通过模拟代码来查看 Scala 编译的执行过程。前面已经使用 ed 将流程展示完了,但是并没有写一段模拟代码,所以本节课将使用 java 写一段模拟代码来展示它是怎样运行的。


一、 反编译代码

这里以 TestScala 为例,代码如下:

package com. atguigu.chapter01

object Testscala {

def main(args: Array[String]): unit = {

println(“hello,scala,idea…”)

}

}

运行结果:

D:\program\jdk8\bin\java…

hello, scala, idea…

Process finished with exit code 0

为什么运行出 hello, scala, idea 呢?写一段模拟代码:

新建一个 New Package 名为 test,打开反编译工具,找到

需要注意的是整个 scala 项目会默认放在,如若不知道放在哪可以右键项目找到 Show in Explorer,打开后就可以发现项目的路径是 C:\Users\Administrator\IdeaProjects\java0705scala\src\main\scala\com\atguigu\chapter01里。

image.png

那么使用反编译寻找:首先找到 C 盘下的用户;打开里面的 Administrator 文件;选择 IdeaProjects,这里面有很多项目文件夹,选择刚才所建的 java0705scala 文件;这里有3个文件夹:.idea、src、target。选择 src 文件, src 是源代码,源代码就是所写的那部分代码;如所写的 main 里的 scala 部分代码,继续往下路径就找到了。

但是这里需要找到 class 文件,则应该在 target 里寻找,发现这里已经有 TestScala.class 文件,将其打开,可以看到代码如下:

package com.atguigu.chapter01;

import scala.reflect.ScalaSignature;

@ScalaSignature(bytes=”\006\001%:Q!\001\002\t\002$\t\021\002v3tiN\033\027\r\\1\013\005\r!\021!C2Icb$XM\035\0312\025\t)a!A\004bi\036,\03”)

public final class Testscala

{

public static void main(String[] paramArrayOfString)

{

Testscala..MODULE$ .main (pararArrayOfString) ;

}

}

 

二、 使用 Java 模拟 scala 运行机制代码

可以看到以上代码里有一个 Testscala,由于要模拟它所以创建与它一样的名字,则在 Idea 新建一个 javaClass,名称就为 Testscala。整体代码就显示出来了,这里直接将以上代码复制在其中,代码如下:

package com.atguigu.chaptero1.test;

public class Testscala {

public static void main(string[] paramArrayOfString) {

//Testscala..MODULE$.main(paramArrayOfString);

Testscala$.MODULE$.main(paramArrayOfString);//调用 MODULE$静态函数,再调用 main 函数,paramArrayOfString是其参数。

}

}

这里会报错,是因为代码没有写全,则需要将 Testscala$里的代码复制过来,由于这段代码就已经是 java 代码了,所以复制过来就是反编译 java,将其整理之后代码如下:

final class Testscala$

{

public static final TestScala$ MODULE$;  //补充类型

static

{

MODULE$ = new Testscala$();  //初始化

}

public void main(string[ ] args)

{

System.out.println(“hello,scala,idea...”);//这部分代码在调用时是 Scala 部分,这里不做使用,而是输出一句话。

}

//private Testscala$() {MODULE$ = this; }

}

反编译与实际代码是有区别的,因此在这里做了改进,以上这样就改写完了,可以看出和反编译之后的代码很相像。首先在 TestScala 里写了一个 Object 之后会生成两个 class,即上面代码中的 public class Testscala final class Testscala$TestScala 里代码如下:

package com.atguigu.chapter01

object TestScala {

def maih( args : Array[String]): unit = {

println(“hello,scala,idea...”)

}

}

真正的 main 入口是在 public class Testscala 代码里,但是实际的代码是在下面的 final class Testscala$代码里做了包装,可以理解为 scala 在运行时做了包装。至于做包装的原因由于太复杂这里只做简单解答:scala 是把一个类的静态和非静态分成两个部分,所以需要做包装;如若只有一个类则不会做包装。

所以这里写了一个 Object 就会生成两个值,写了一个主函数进来调用 Testscala$里的 MODULE$。思考在整个运行过程中的 MODULE$对象是否始终是同一个对象呢?也就是说在 scala 里写了一个 object 对象也就等价于 TestScala的一个静态对象而且是单例的,这个在之后会详细讲解。

总结:

只要以后看到有 object,应该有这样的认识:

1. object Testscala 对应的是一个 Testscala$的一个静态对象 MODULE$

2. 在程序中,是一个单例。

运行,观察代码是否能够跑起来:

image.png

D:\program\jdks\bin\java...

hello,scala,idea...

Process finished with exit code 0

可以看到结果是一样的。简单来理解就是它做了一个包装,在调用时底层用了一个静态对象来调用主函数。

以上包装就讲解到这里。

相关文章
|
设计模式 人工智能 安全
AQS:Java 中悲观锁的底层实现机制
AQS(AbstractQueuedSynchronizer)是Java并发包中实现同步组件的基础工具,支持锁(如ReentrantLock、ReadWriteLock)和线程同步工具类(如CountDownLatch、Semaphore)等。Doug Lea设计AQS旨在抽象基础同步操作,简化同步组件构建。 使用AQS需实现`tryAcquire(int arg)`和`tryRelease(int arg)`方法以获取和释放资源,共享模式还需实现`tryAcquireShared(int arg)`和`tryReleaseShared(int arg)`。
537 32
AQS:Java 中悲观锁的底层实现机制
|
11月前
|
Java API 微服务
2025 年 Java 从入门到精通学习笔记全新版
《Java学习笔记:从入门到精通(2025更新版)》是一本全面覆盖Java开发核心技能的指南,适合零基础到高级开发者。内容包括Java基础(如开发环境配置、核心语法增强)、面向对象编程(密封类、接口增强)、进阶技术(虚拟线程、结构化并发、向量API)、实用类库与框架(HTTP客户端、Spring Boot)、微服务与云原生(容器化、Kubernetes)、响应式编程(Reactor、WebFlux)、函数式编程(Stream API)、测试技术(JUnit 5、Mockito)、数据持久化(JPA、R2DBC)以及实战项目(Todo应用)。
565 5
|
前端开发 Java 关系型数据库
基于Java+Springboot+Vue开发的鲜花商城管理系统源码+运行
基于Java+Springboot+Vue开发的鲜花商城管理系统(前后端分离),这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Java编程技能,同时锻炼他们的项目设计与开发能力。通过学习基于Java的鲜花商城管理系统项目,大学生可以在实践中学习和提升自己的能力,为以后的职业发展打下坚实基础。技术学习共同进步
761 7
|
存储 Java
# 【Java全栈学习笔记-U1-day02】变量+数据类型+运算符
本篇笔记主要围绕Java全栈学习的第二天内容展开,涵盖了变量、数据类型、运算符以及Scanner类的应用。首先介绍了变量的概念与命名规范,以及如何定义和使用变量;接着详细讲解了Java中的基本数据类型,包括整型、浮点型、字符型、布尔型等,并通过实例演示了数据类型的运用。随后,深入探讨了各类运算符(赋值、算术、关系、逻辑)及其优先级,帮助理解表达式的构成。最后,介绍了如何利用Scanner类实现用户输入功能,并通过多个综合示例(如计算圆面积、购物打折、变量交换及银行利息计算)巩固所学知识。完成相关作业将进一步加深对这些基础概念的理解与实践能力。
263 13
|
12月前
|
人工智能 Java 关系型数据库
Java——SPI机制详解
SPI(Service Provider Interface)是JDK内置的服务提供发现机制,主要用于框架扩展和组件替换。通过在`META-INF/services/`目录下定义接口实现类文件,Java程序可利用`ServiceLoader`动态加载服务实现。SPI核心思想是解耦,允许不同厂商为同一接口提供多种实现,如`java.sql.Driver`的MySQL与PostgreSQL实现。然而,SPI存在缺陷:需遍历所有实现并实例化,可能造成资源浪费;获取实现类方式不够灵活;多线程使用时存在安全问题。尽管如此,SPI仍是Java生态系统中实现插件化和模块化设计的重要工具。
668 0
|
8月前
|
小程序 Java 知识图谱
Java 学习笔记 —— BMI & BMR 计算器
这是一个使用 Java 编写的 BMI 与 BMR 计算器小程序,可输入年龄、性别、身高和体重,计算身体质量指数(BMI)和基础代谢率(BMR),并输出健康评估结果。通过该项目,掌握了 Java 的输入处理、数据验证、条件判断、数学运算及格式化输出等基础知识,是 Java 初学者的理想练习项目。
|
8月前
|
Java
Java 数组学习笔记
本文整理Java数组常用操作:遍历、求和、查找、最值及二维数组行求和等典型练习,涵盖静态初始化、元素翻倍、去极值求平均等实例,帮助掌握数组基础与应用。
|
10月前
|
人工智能 前端开发 安全
Java开发不可不知的秘密:类加载器实现机制
类加载器是Java中负责动态加载类到JVM的组件,理解其工作原理对开发复杂应用至关重要。本文详解类加载过程、双亲委派模型及常见类加载器,并介绍自定义类加载器的实现与应用场景。
368 4
|
Java 区块链 网络架构
酷阿鲸森林农场:Java 区块链系统中的 P2P 区块同步与节点自动加入机制
本文介绍了基于 Java 的去中心化区块链电商系统设计与实现,重点探讨了 P2P 网络在酷阿鲸森林农场项目中的应用。通过节点自动发现、区块广播同步及链校验功能,系统实现了无需中心服务器的点对点网络架构。文章详细解析了核心代码逻辑,包括 P2P 服务端监听、客户端广播新区块及节点列表自动获取等环节,并提出了消息签名验证、WebSocket 替代 Socket 等优化方向。该系统不仅适用于农业电商,还可扩展至教育、物流等领域,构建可信数据链条。
|
缓存 Dubbo Java
理解的Java中SPI机制
本文深入解析了JDK提供的Java SPI(Service Provider Interface)机制,这是一种基于接口编程、策略模式与配置文件组合实现的动态加载机制,核心在于解耦。文章通过具体示例介绍了SPI的使用方法,包括定义接口、创建配置文件及加载实现类的过程,并分析了其原理与优缺点。SPI适用于框架扩展或替换场景,如JDBC驱动加载、SLF4J日志实现等,但存在加载效率低和线程安全问题。
687 7
理解的Java中SPI机制