如何查看class文件内容

java程序在编译过程中,java源码通过javac将代码编译成class文件。如果我们直接打开class文件,大概率是一些乱码。这个时候我们需要借助一些工具来查看class文件。

我这边随意编写了一个java类,如下:

public class User {
    private String age;
    public String userName;
    public static final String count="123";

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public static String getCount() {
        return count;
    }
}

编译后成class文件打开,显示如下内容:

漱壕   4 "
  	  	      ! age Ljava/lang/String; userName count 
ConstantValue <init> ()V Code LineNumberTable LocalVariableTable this LUser; getAge ()Ljava/lang/String; setAge (Ljava/lang/String;)V getUserName setUserName getCount 
SourceFile 	User.java  
   	  User 123 java/lang/Object !            	     
           
     /     *? ?                               /     *? ?                               >     *+? ?       
      
                          /     *? ?                               >     *+? ?       
                      	   	             ?                 

要想解读class文件,我们需要下载一个工具:sublime,下载教程省略。
下载好之后,我们用sublime打开class文件,就会看到如下内容:

cafe babe 0000 0034 0022 0a00 0600 1c09
0004 001d 0900 0400 1e07 001f 0800 2007
0021 0100 0361 6765 0100 124c 6a61 7661
2f6c 616e 672f 5374 7269 6e67 3b01 0008
7573 6572 4e61 6d65 0100 0563 6f75 6e74
0100 0d43 6f6e 7374 616e 7456 616c 7565
0100 063c 696e 6974 3e01 0003 2829 5601
0004 436f 6465 0100 0f4c 696e 654e 756d
6265 7254 6162 6c65 0100 124c 6f63 616c
5661 7269 6162 6c65 5461 626c 6501 0004
7468 6973 0100 064c 5573 6572 3b01 0006
6765 7441 6765 0100 1428 294c 6a61 7661
2f6c 616e 672f 5374 7269 6e67 3b01 0006
7365 7441 6765 0100 1528 4c6a 6176 612f
6c61 6e67 2f53 7472 696e 673b 2956 0100
0b67 6574 5573 6572 4e61 6d65 0100 0b73
6574 5573 6572 4e61 6d65 0100 0867 6574
436f 756e 7401 000a 536f 7572 6365 4669
6c65 0100 0955 7365 722e 6a61 7661 0c00
0c00 0d0c 0007 0008 0c00 0900 0801 0004
5573 6572 0100 0331 3233 0100 106a 6176
612f 6c61 6e67 2f4f 626a 6563 7400 2100
0400 0600 0000 0300 0200 0700 0800 0000
0100 0900 0800 0000 1900 0a00 0800 0100
0b00 0000 0200 0500 0600 0100 0c00 0d00
0100 0e00 0000 2f00 0100 0100 0000 052a
b700 01b1 0000 0002 000f 0000 0006 0001
0000 0002 0010 0000 000c 0001 0000 0005
0011 0012 0000 0001 0013 0014 0001 000e
0000 002f 0001 0001 0000 0005 2ab4 0002
b000 0000 0200 0f00 0000 0600 0100 0000
0800 1000 0000 0c00 0100 0000 0500 1100
1200 0000 0100 1500 1600 0100 0e00 0000
3e00 0200 0200 0000 062a 2bb5 0002 b100
0000 0200 0f00 0000 0a00 0200 0000 0c00
0500 0d00 1000 0000 1600 0200 0000 0600
1100 1200 0000 0000 0600 0700 0800 0100
0100 1700 1400 0100 0e00 0000 2f00 0100
0100 0000 052a b400 03b0 0000 0002 000f
0000 0006 0001 0000 0010 0010 0000 000c
0001 0000 0005 0011 0012 0000 0001 0018
0016 0001 000e 0000 003e 0002 0002 0000
0006 2a2b b500 03b1 0000 0002 000f 0000
000a 0002 0000 0014 0005 0015 0010 0000
0016 0002 0000 0006 0011 0012 0000 0000
0006 0009 0008 0001 0009 0019 0014 0001
000e 0000 001b 0001 0000 0000 0003 1205
b000 0000 0100 0f00 0000 0600 0100 0000
1800 0100 1a00 0000 0200 1b

以上是由sublime解读后的16进制组成的class文件。那么这些16进制各表示什么含义呢?
接下来我们借助官网来解读。首先打开官网链接:https://docs.oracle.com/javase/8/。然后打开如下页面:

在这里插入图片描述
我使用的jdk是8版本,所以查看jdk8的内容:
在这里插入图片描述
点进去之后的文章第4节讲的就是class文件格式的内容
在这里插入图片描述
其中有如下定义:

ClassFile {
    u4             magic;
    u2             minor_version;
    u2             major_version;
    u2             constant_pool_count;
    cp_info        constant_pool[constant_pool_count-1];
    u2             access_flags;
    u2             this_class;
    u2             super_class;
    u2             interfaces_count;
    u2             interfaces[interfaces_count];
    u2             fields_count;
    field_info     fields[fields_count];
    u2             methods_count;
    method_info    methods[methods_count];
    u2             attributes_count;
    attribute_info attributes[attributes_count];
}

那么上面所说的u4,u2代表什么意思呢?
这里的u4就是表示的是上文中16进制的8位,u1表示的就是16进制中的2位。
而文章中的magic,minor_version等表示的含义在文中都有说明。接下来我们根据几个说明简单的介绍一下:
首先以上文中的User.class字节码为例,
u4(magic)=cafe babe。官网中对magic做了解读,为:

magic
The magic item supplies the magic number identifying the class file format; it has the value 0xCAFEBABE.

magic表示了class文件的格式和规范,通常为0xCAFEBABE。
接下的两个u2,分别表示minor_version; major_version;对应的字节码内容为:
0000,0034。对于这两个字段的含义,官网中也有说明,分别表示的是class文件的minor版本号和major版本号。
按照此规律,我们可以推导出其他内容,比如说:constant_pool_count(常量池大小),this_class(本类),super_class(超类)等内容。

我们发现,其实这些16进制就是将我们整个类的内容给展现出来了。只不过被javac编译成了jvm看的懂的16进制形式而已。知道这些,我们也就知道为什么java文件可以编译成class文件,class文件也可以反编译成java文件,因为两者之间的转化是符合上述规律的。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值