Java-Class文件格式(一)

182 阅读5分钟

「这是我参与11月更文挑战的第14天,活动详情查看:2021最后一次更文挑战

Class文件格式

Class文件格式是一种类似C语言结构的伪结构。

这种伪结构只存在两种数据类型:无符号数

  • 无符号数

    基本的数据类型。

    u1: 1个字节的无符号数

    u2: 2个字节的无符号数

    u4: 4个字节的无符号数

    u8: 8个字节的无符号数

  • 符合数据类型,由多个无符号数或其他表作为数据项构成。所有的表名习惯以"_info"结尾。

魔数

每个Class文件的前4个字节被称为魔数

作用: 文件是否为被Java虚拟机识别Class文件

值:0xCAFEBABE(咖啡宝贝)

Class文件版本号

第5、第6字节:次版本号

第7、第8字节:主版本号

Java的版本号都是从45开始的。JDK高版本能向下兼容低版本的Class文件,不能兼容更高版本。

实战操作,大家也可以尝试下:

HelloWorld.java

package com.lkk.study.notes.base;
​
public class HelloWorld {
​
    private String message;
​
    public HelloWorld(String message) {
        this.message = message;
    }
}

使用 javac HelloWorld.java编译,得到

cafe babe 0000 0034 0012 0a00 0400 0d09
0003 000e 0700 0f07 0010 0100 076d 6573
7361 6765 0100 124c 6a61 7661 2f6c 616e
672f 5374 7269 6e67 3b01 0006 3c69 6e69
743e 0100 1528 4c6a 6176 612f 6c61 6e67
2f53 7472 696e 673b 2956 0100 0443 6f64
6501 000f 4c69 6e65 4e75 6d62 6572 5461
626c 6501 000a 536f 7572 6365 4669 6c65
0100 0f48 656c 6c6f 576f 726c 642e 6a61
7661 0c00 0700 110c 0005 0006 0100 2363
6f6d 2f6c 6b6b 2f73 7475 6479 2f6e 6f74
6573 2f62 6173 652f 4865 6c6c 6f57 6f72
6c64 0100 106a 6176 612f 6c61 6e67 2f4f
626a 6563 7401 0003 2829 5600 2100 0300
0400 0000 0100 0200 0500 0600 0000 0100
0100 0700 0800 0100 0900 0000 2a00 0200
0200 0000 0a2a b700 012a 2bb5 0002 b100
0000 0100 0a00 0000 0e00 0300 0000 0700
0400 0800 0900 0900 0100 0b00 0000 0200
0c

查看class文件

终端命令

javap -verbose HelloWorld.class

image.png

常量池

版本号之后就是常量池。通常是Class文件中占用空间最大的部分。在常量池的入口存放的是一个u2类型数字,表示常量池容量计数值

常量池存放两类数据:字面量符号引用。常量池中的每一个常量就是一张表。

访问标志

常量池之后就是访问标志。标志类或者接口的访问信息。

包含:类还是接口;是否为abstract类型;是否为public类型;类是否是final类型;...

类索引、父类索引、接口索引集合

类索引和父类索引都是u2类型数据;接口索引集合是u2类型数据的集合。

tips:

(每日积累) 常见线程安全的类

  1. 通过synchronized 关键字给方法加上内置锁来实现线程安全 TimerTimerTaskVectorStackHashTableStringBuffer
  1. 通过Unsafe 类的native方法实现线程安全

    原子类Atomicxxx—包装类的线程安全类,如 AtomicLongAtomicInteger等等

  1. 通过使用定义为final的ReentrantLock作为类属性显式加锁实现同步的 BlockingQueue 和**BlockingDeque**

    BlockingDeque接口继承了BlockingQueue接口,BlockingQueue 接口的实现类有 ArrayBlockingQueueLinkedBlockingQueuePriorityBlockingQueueBlockingDeque接口的实现类有LinkedBlockingDeque

  2. CopyOnWriteArrayListCopyOnWriteArraySet CopyOnWriteArraySet的内部实现是在其类内部声明一个final的CopyOnWriteArrayList属性,并在调用其构造函数时实例化该CopyOnWriteArrayListCopyOnWriteArrayList采用的是显式地加上ReentrantLock实现同步,而CopyOnWriteArrayList容器的线程安全性在于在每次修改时都会创建并重新发布一个新的容器副本,从而实现可变性。

  1. Concurrentxxx 最常用的就是 ConcurrentHashMap ,当然还有ConcurrentSkipListSetConcurrentSkipListMap等等。ConcurrentHashMap使用了一种完全不同的加锁策略来提供更高的并发性和伸缩性。ConcurrentHashMap并不是将每个方法都在同一个锁上同步并使得每次只能有一个线程访问容器,而是使用一种粒度更细的加锁机制—— 分段锁 来实现更大程度的共享