课程主页:https://courses.cs.washington.edu/courses/cse351/16sp/

课程资料:

实验部分:https://github.com/vuquangtrong/HW-SW_Interface_Course

实验说明:https://courses.cs.washington.edu/courses/cse351/13sp/lab-0.html

课件:http://academictorrents.com/details/b63a566df824b39740eb9754e4fe4c0140306f4b

课程视频:https://www.bilibili.com/video/BV1Zt411s7Gg?from=search&seid=8781593976070799647

这次回顾第十一部分,这部分介绍了Java vs C。

Java vs C

Java中的数据表示

  • 整数、浮点、双精度、指针——与C相同
    • 是的,Java有指针——它们被称为“引用”。然而,Java引用比C的一般指针有更多约束。
  • Null通常表示为0
  • 字符和字符串
  • 数组
  • 对象
字符和字符串
  • 双字节Unicode而不是ASCII
    • 代表世界上大部分的字母
  • 字符串不受“\0”(空字符)的限制
    • 以字符串开头的隐藏长度字段限定边界

数组
  • 每个元素初始化为0
  • 在数组开头的隐藏字段中指定界限(int——4字节)
    • array.length返回此字段的值
  • 每次访问都会触发边界检查
    • 添加代码以确保索引在范围内
    • 超出边界时出现异常

Java中的数据结构(对象)
  • 对象(结构)只能包含基本数据类型
    • 使用引用包括复杂的数据类型(数组、其他对象等)

指针/引用
  • C中的指针可以指向任何内存地址
  • Java中的引用只能指向对象
    • 只针对它的第一个元素,而不是它的中间部分

指针和引用

指向字段的指针
  • 在C语言中,我们有“->”和“.”来选择字段,这取决于我们是否有指向结构的指针
    • (*r).a是如此常见以至于变成r->a
  • 在Java中,所有变量都是对对象的引用
    • 我们总是用r.a符号
    • 但实际上,在引用r的同时偏移到a,就像C的r->a一样
C中的转换
  • 我们可以将任何指针转换成其他指针

Java中的转换
  • 只能强制转换兼容的对象引用

Java中创建对象

  • “new”
    • 为数据字段分配空间
    • 将对象中的指针添加到类的“虚拟表(vatable)”
      • vtable在类中的所有对象之间共享!
      • 包括“静态字段”和指向方法代码的指针的空间
    • 返回内存中新对象的引用(指针)
    • 运行“构造函数”方法
  • 如果新对象的所有引用都被丢弃,则最终将对其进行垃圾回收

初始化
  • newPoint的字段从指向此类的vtable指针开始初始化
  • 下一步是为此对象类型调用“构造函数”
  • 使用“vtable pointer”找到构造函数代码,并将指针传递给newPoint新分配的内存区域,以便构造函数可以将其x和y设置为0

Java方法
  • Java中的方法只是函数(如在C中一样),但有一个额外的参数:对被调用方法的对象的引用
    • 例如newPoint.samePlace使用指向newPoint的指针(称为“this”)和指向参数p的指针调用samePlace方法。在本例中,这两个都是指向Point类型的对象的指针。
    • 方法变成Point.samePlace(Point this, Point p)
      • $\text{return x==p.x && y==p.y;}$变成$\text{return (this->x==p->x) && (this->y==p->y);}$
子类
class PtSubClass extends Point{
	int aNewField;
	boolean samePlace(Point p2) {
		return false;
	}
	void sayHi() {
		System.out.println("hello");
	}
}
  • “aNewField”去哪儿了?
    • 在Point的字段末尾——允许从子类到父类的转换!
  • 指向两个新方法的代码的指针指向何处?
    • 若要重写“samePlace”,请重写旧指针
    • 在表末尾为新方法“sayHi”添加新指针

虚拟机和运行时环境

实现编程语言
  • 如何实现编程模型有许多选择
  • 编译和解释
    • 在原始源代码中逐行执行
    • 编译器的工作量更少——所有的工作都在运行时完成
    • 更容易调试——翻译更少
    • 更易于在不同的体系结构上运行——只在解释器进程内部的模拟环境中运行
  • 解释性语言有着悠久的历史
    • Lisp是最早的编程语言之一
  • 解释性实现在今天非常流行
    • Python,Javascript,Ruby,Matlab,PHP,Perl…
解释VS编译
  • 解释和编译是两种选择

    • 解释器/编译器或多或少完成的工作

  • Java程序通常由虚拟机运行

    • vm解释一种称为字节码的中间“部分编译”语言
  • Java也可以提前编译(就像C程序一样)或在运行时由实时(JIT)编译器编译

虚拟机模型

Java虚拟机

  • 使Java机器独立
  • 提供强大的保护
  • 基于栈的执行模型
  • 有很多JVM
    • 有些解释
    • 有些编译成汇编
    • 通常用C语言实现

JVM操作栈示例

类文件格式
  • Java源代码中的每个类都被编译成自己的类文件
  • Java类文件结构中的10个部分:
    • Magic number:0xCAFEBABE(James Gosling的易读十六进制——Java的发明者)
    • Version of class file format:类文件的次要和主要版本
    • Access flags:类的一组常量值
    • Access flags:例如类是否是抽象的、静态的等等
    • This class:当前类的名称
    • Super class:超类的名称
    • Interfaces:类中的任何接口
    • Fields:类中的任何字段
    • Methods:类中的任何方法
    • Attributes:类的任何属性(例如源文件的名称等)
  • jar文件收集了程序所需的所有类文件,以及任何附加资源(例如图像)
JVM的其他语言
  • JVM运行在如此多的计算机上,以至于编译程序可以将许多其他语言翻译成Java字节码:
    • AspectJ,Java面向方面的扩展
    • ColdFusion,一种编译成Java的脚本语言
    • Clojure,一种函数式Lisp方言
    • Groovy,一种脚本语言
    • javafxscript,一种面向互联网应用程序域的脚本语言
    • JRuby,一个Ruby的实现
    • Jython,Python的一个实现
    • Rhino,JavaScript的一个实现
    • Scala,一种面向对象的函数式编程语言
    • 还有很多其他语言,甚至包括C
微软的C#以及.NET框架
  • C#与Java有着相似的动机
  • 虚拟机被称为Common Language Runtime;公共中间语言是.NET框架中C#语言和其他语言的字节码