bboyjing's blog


  • 首页

  • 分类

  • 关于

  • 归档

  • 标签

  • 公益404
bboyjing's blog

Java中return和finally到底哪个先执行

发表于 2020-10-27 | 分类于 JVM

  本章节我们从字节码的角度来探究下return和finally到底哪个先执行。下面先来看一段简单地源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class ReturnFinallyDemo {
public static void main(String[] args) {
System.out.println(case1());
}
public static int case1() {
int x;
try {
x = 1;
return x;
} finally {
x = 3;
}
}
}
# 输出
1

上述代码的输出可以简单地得出结论:return在finally之前执行,我们来看下字节码层面上发生了什么事情。下面截取case1方法的部分字节码,并且对照源码,将每个指令的含义注释在后面:

阅读全文 »
bboyjing's blog

Java中方法与字段的重写

发表于 2020-10-27 | 分类于 JVM

  本章我们来看一下,Java中字段和方法是如何参与重写的。

字段的重写

  首先,需要明确一点,Java的字段永远不参与多态,当子类声明了与父类同名的字段时,虽然在子类的内存中两个字段都会存在,但是子类的字段会屏蔽父类的同名字段。我们来看一个简单地例子,该例子来自于《深入理解Java虚拟机》:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public class FieldHashNoPolymorphic {
static class Father {
public int money = 1;
public Father() {
money = 2;
showMeTheMoney();
}
public void showMeTheMoney() {
System.out.println("I am Father, I have $" + money);
}
}
static class Son extends Father {
public int money = 3;
public Son() {
money = 4;
showMeTheMoney();
}
@Override
public void showMeTheMoney() {
System.out.println("I am Son, I have $" + money);
}
}
public static void main(String[] args) {
Father guy = new Son();
// 通过静态类型访问到了父类中的money,输出2
System.out.println("This guy has $" + guy.money);
// 将静态类型强转成Son,访问的就是子类中的money,输出4
System.out.println("This guy has $" + ((Son) guy).money);
}
}
# 输出如下
I am Son, I have $0
I am Son, I have $4
This guy has $2
This guy has $4
阅读全文 »
bboyjing's blog

Java对象头的内存布局探究

发表于 2020-04-24 | 分类于 JVM

  本章节主要来验证下是否开启压缩指针对对象头内存布局的影响,因为在其他地方看到的结论不一样,还是得眼见为实。先看下JVM版本以及默认启动参数:

1
2
3
4
5
~❯ java -XX:+PrintCommandLineFlags -version
-XX:G1ConcRefinementThreads=4 -XX:GCDrainStackTargetSize=64 -XX:InitialHeapSize=268435456 -XX:MaxHeapSize=4294967296 -XX:+PrintCommandLineFlags -XX:ReservedCodeCacheSize=251658240 -XX:+SegmentedCodeCache -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseG1GC
java version "11.0.1" 2018-10-16 LTS
Java(TM) SE Runtime Environment 18.9 (build 11.0.1+13-LTS)
Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.1+13-LTS, mixed mode)

由-XX:+UseCompressedClassPointers可见,默认是开启压缩指针的。下面先引入一个依赖,用于查看对象内存布局:

1
2
3
4
5
<dependency>
<groupId>org.openjdk.jol</groupId>
<artifactId>jol-core</artifactId>
<version>0.10</version>
</dependency>
阅读全文 »
bboyjing's blog

Java强、软、弱、虚引用的直观理解

发表于 2020-04-16 | 分类于 JVM

  众所周知,目前Java的引用分为强引用、软引用、弱引用和虚引用,这四种强度依次逐渐减弱。网上也能搜到很多相关文章,有的写的也很好,可能自身理解能力比较差,每次看过之后总觉得差点意思,本章准备通过几个小例子来加深理解。下面先简单看一下四种引用的定义:

  • 强应用:只要强引用关系还在,垃圾收集器就永远不会回收掉被引用的对象。
  • 软引用:只被软引用关联着的对象,在系统将要发生内存溢出异常前,会把这些对象列进回收范围之中进行第二次回收,如果这次回收还没有足够的内存,才会抛出内存溢出异常。
  • 弱引用:只被弱引用关联的对象只能生存到下一次垃圾收集发生为止。
  • 虚引用:一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象实例。为一个对象设置虚引用关联的唯一目的只是为了能在这个对象被收集器回收时收到一个系统通知。

这是从《深入理解Java虚拟机》第三版中摘抄出来的,下面就用例子来证明上述定义,同时加深对其的理解。

阅读全文 »
bboyjing's blog

HeadFirst设计模式二十四【访问者模式】

发表于 2020-01-15 | 分类于 设计模式

访问者模式的目的是封装一些施加于某种数据结构元素之上的操作。一旦这些操作需要修改的话,接受这个操作的数据结构则可以保持不变。上面的术语不是很好理解,我们来看看下面的场景,就会觉得很熟悉了。

场景描述

假设有下面现在需要建造一辆汽车,简单的实现方式如下:

阅读全文 »
123…30
bboyjing

bboyjing

147 日志
17 分类
20 标签
友情链接
  • bailaohe
© 2021 bboyjing
由 Hexo 强力驱动
主题 - NexT.Mist