day6-jvm

今日总结

jvm 黑马 108-139p

JVM

2 字节码指令

javap -v xxx.class

字节码执行流程

main方法类加载,放在方法区,常量池(class数据)放入运行时常量池
小的数字放在放的方法的字节码指令,超过范围放在常量池

  • x=x++为什么没用

因为先把x放到操作数栈,然后x++,最后又将操作数栈的值给x,这时候还是0。
i++是先load再自增,++i是先自增再load

  • cinit

编译器按按从上至下的顺序, 将所有的静态代码块和静态成员赋值的代码,合并成一个特殊的方法,()V

  • init

实例对象。
init方法,也是按顺序,构造方法最后执行

  • 方法调用

构造方法:invokespecial
私有:invokespecial
final:invokespecial
public:invokevirtual(因为有可能重写)
接口方法:invokeInterface(支持多态)
静态方法:invokestatic
new 方法:堆中给对象分配内存—分配成功之后把对象的引用放入操作数栈—将栈顶的元素复制一份—invokespecial执行栈顶元素的构造方法并移除—把剩下的一个出栈存到局部变量表中
不要通过对象调用静态方法、变量,会产生两条没用的虚拟机指令

  • 多态的原理

虚方法表在链接阶段就会生成,就生成了虚方法表的入口地址

  1. 通过栈桢中国的对象引用找到对象、
  2. 分析对象头,找到对象的实际classsss
  3. class结构中有vtable,在类加载阶段已经根据方法重写规则生成好了
  4. 查表得到方法的具体地址
  5. 执行方法的字节码
  • 异常的处理

有一个Exception table,监测try代码,出现异常之后进行类型匹配,看是否一致或者是子类异常。
多个catch:异常表里面有多个 。因为只会有一个异常,所以局部变量表只占一个槽位(节省了栈桢的内存)
multi-catch:出现了多个异常。xxx E | xxxE | xxxE:三个不同类型的异常入口是一样的。

  • finally

将finally的代码既放到了try块又放到了catch块
除了try和catch中无法捕获的,都会跳到最后,类型是any,去执行,当然这里面也复制了finally的东西

image.png
20。
try里面放了finally的代码,最终肯定要执行。
所以千万不要在finally中写return,因为可能会异常被吞

image.png
10
没有return语句,会有一个slot来暂存,而且也会throw异常

  • synchronized

如何成对加锁解锁?
先a_load把lock对象加载到操作数栈,表示synchronized开始
然后把引用复制一份放进来存入槽位,给monitorenter和monitorexit来用 (两个会消耗lock引用)
monitorenter 开始lock引用
加载之前的lock,执行monitorexit解锁,异常也一样,都会加载lock对象的引用,进行解锁。

3 编译期处理

编译期间的优化和处理:语法糖 (编译过程自动生成和转换一些代码)

  1. 默认构造器

会生成默认的构造器(没有自己写的情况下),因为所有的都继承自Object。

  1. 自动拆装箱

int->Integer:装箱
Integer->int:拆箱

  1. 泛型集合取值

范型擦除: 编译之后统一设置成Object
返回的时候返回的是Object:用checkcast,将object变成Integer(相当于自动做了一次强制类型转换)
方法体内的信息被擦除了, 局部变量的范型没有被擦除,但是不能通过反射获得,只有在方法的参数和返回值上能通过反射获得

  1. 可变参数

String …args -> String[] args
如果不传参数,传的是一个空的String数组,而不是null值

  1. foreach

数组赋值可以直接int arr[] = {},会变成 int arr[] = new int[]{}
数组foreach 其实就是变成fori
list的foreach是使用的迭代器(实现了Iterator的都可以用)

  1. switch 字符串

实际上比较的hash code

  • 为什么既比较hashcode,又利用equals比较呢?

hashcode是为了提高效率,减少比较,equals是为了比较hash冲突,
因为大多的hashcode都是唯一的。

  • 为什么要重写hashcode和equals?
    • 用于只需要比较一个值的情况,比如不同的对象,id一样就可以认为是同一个

equals相等,hashcode必定相等,hashcode用于快速比较,equals用于绝对相等。hashcode存在冲突情况,所以要进一步用equals比较

  • 为什么重写equals必须重新给i额hashcode
    • 如果两个对象相等,则 hashcode ⼀定也是相同的
    • 两个对象相等,对两个 equals() ⽅法返回 true
    • 两个对象有相同的 hashcode 值,它们也不⼀定是相等的
    • 综上, equals() ⽅法被覆盖过,则 hashCode() ⽅法也必须被覆盖这部分借鉴于:https://juejin.cn/post/7025465769307668516,
  1. switch 枚举

ordinal()

  1. 枚举

本质是一个class,值实际上都是实例对象
是一个final的不能被继承 ,继承了枚举父类(支持范型)
image.png
image.png
构造方法私有
$values把枚举对象放入数组

今日复盘

早上睡了个大懒觉,下午打了会儿球,还是懈怠了。
leetcode做起来啊,代码写起来,项目部署搞起来。
明天还要看看面试题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值