Class文件详解(四)

前情回顾

上篇博客中我们讲到了class文件的访问标志、类索引、父索引和接口索引集合。本篇博客我们介绍字段表集合。

 

字段表集合

字段表集合是指由若干个字段表组成的集合。对于在类中定义的若干个字段,经过JVM编译成class文件后,会将相应的字段信息组织到一个叫做字段表集合的结构。

比如:如果一个类中定义了5个字段,JVM在编译该类时会生成5个字段表,并将字段表集合计数器(fileds_count)设为5,5个字段表的信息将依次排列在计数器后。

 

字段表

字段表用来描述类或是接口中声明的变量,包括类级变量和实例级变量,但不包括方法内部的局部变量。字段表的结构如下图:

 

我们可以看到字段表的头两个字节是标志位(access_flags),可以表示以下信息:字段的作用域(publc,private,protected),实例变量或类变量(static修饰符),可变性(final),并发可见性(volatile),可否被序列化(transient修饰符),字段数据类型,字段名称。以下是字段访问标志表:

接下来的两个数据项是name_index和descriptor_index。它们分别代表字段的简单名称和字段和方法的描述符(有关简单名称和描述符的见Class文件结构详解(二))。剩下的attributes_count和attributes和属性表集合有关,我们在接下来的章节中讲述。

实例解析:

Comments.class

字段表集合已用蓝色选块标出。

头两个字节时00 04,我们可以得出接下来共有四个字段表,我们将它与字段表和class的常量池对应

 Last modified 2019-7-4; size 1166 bytes
  MD5 checksum f7b9e128edcf563d8216d36602fda343
  Compiled from "Comments.java"
public class com.zust.bean.Comments
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Class              #2             // com/zust/bean/Comments
   #2 = Utf8               com/zust/bean/Comments
   #3 = Class              #4             // java/lang/Object
   #4 = Utf8               java/lang/Object
   #5 = Utf8               comments_no
   #6 = Utf8               Ljava/lang/String;
   #7 = Utf8               comments_name
   #8 = Utf8               comments_context
   #9 = Utf8               news_no
  #10 = Utf8               <init>
  #11 = Utf8               ()V
  #12 = Utf8               Code
  #13 = Methodref          #3.#14         // java/lang/Object."<init>":()V
  #14 = NameAndType        #10:#11        // "<init>":()V
  #15 = Utf8               LineNumberTable
  #16 = Utf8               LocalVariableTable
  #17 = Utf8               this
  #18 = Utf8               Lcom/zust/bean/Comments;
  #19 = Utf8               getComments_name
  #20 = Utf8               ()Ljava/lang/String;
  #21 = Fieldref           #1.#22         // com/zust/bean/Comments.comments_name:Ljava/lang/String;
  #22 = NameAndType        #7:#6          // comments_name:Ljava/lang/String;
  #23 = Utf8               setComments_name
  #24 = Utf8               (Ljava/lang/String;)V
  #25 = Utf8               getComments_context
  #26 = Fieldref           #1.#27         // com/zust/bean/Comments.comments_context:Ljava/lang/String;
  #27 = NameAndType        #8:#6          // comments_context:Ljava/lang/String;
  #28 = Utf8               setComments_context
  #29 = Utf8               getNews_no
  #30 = Fieldref           #1.#31         // com/zust/bean/Comments.news_no:Ljava/lang/String;
  #31 = NameAndType        #9:#6          // news_no:Ljava/lang/String;
  #32 = Utf8               setNews_no
  #33 = Utf8               getComments_no
  #34 = Fieldref           #1.#35         // com/zust/bean/Comments.comments_no:Ljava/lang/String;
  #35 = NameAndType        #5:#6          // comments_no:Ljava/lang/String;
  #36 = Utf8               setComments_no
  #37 = Utf8               SourceFile
  #38 = Utf8               Comments.java

可以得出:

00 02 00 05 00 06 00 00 :private   comments_no    Ljava/lang/String; 

00 02 00 07 00 06 00 00 :private   comments_name    Ljava/lang/String; 

00 02 00 08 00 06 00 00 :private   comments_context    Ljava/lang/String; 

00 02 00 09 00 06 00 00 :private   news_no    Ljava/lang/String; 

与Comments.java的源码对比

package com.zust.bean;

public class Comments {
    private String comments_no;
    private String comments_name;
    private String comments_context;
    private String news_no;

    public String getComments_name() {
        return comments_name;
    }

    public void setComments_name(String comments_name) {
        this.comments_name = comments_name;
    }

    public String getComments_context() {
        return comments_context;
    }

    public void setComments_context(String comments_context) {
        this.comments_context = comments_context;
    }

    public String getNews_no() {
        return news_no;
    }

    public void setNews_no(String news_no) {
        this.news_no = news_no;
    }

    public String getComments_no() {
        return comments_no;
    }

    public void setComments_no(String comments_no) {
        this.comments_no = comments_no;
    }
}

我们可以发现class文件的字段表集合严谨的按照顺序数量记录了类的字段信息。

 

其他知识:

1、字段表集合不会列出从父类或接口中继承而来的字段,但会列出内部类指向外部类实例的字段。

2、对字段来说,在java语言层面无法重载,字段名称必须不一致,但对于字节码来说,只要两个字段描述符不同,那              么重名就是合法的,也就是可以实现重载

 

 

下文提示: 

在本文中我们学习了字段在class文件中的表示方法,下文我们将介绍方法是如何在class文件中组织的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值