熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> JSP教程 >> 正文

Class文件詳解 (1)

2022-06-13   來源: JSP教程 

  我們都知道Java編譯器負責將java文件編譯成class文件class文件存儲的是java字節碼java文件無關(只要你願意寫一個編譯器也可以將別的語言寫的源代碼編譯成class文件)本文准備詳細解剖class文件的內部結構並且把class文件結構讀取並顯示出來
  
  Class文件的格式由JVM規范規定一共有以下部分
  
   magic number必須是xCAFEBABE用於快速識別是否是一個class文件
  
   version包括major和minor如果版本號超過了JVM的識別范圍JVM將拒絕執行
  
   constant pool常量池存放所有用到的常量
  
   access flag定義類的訪問權限
  
   this class和super class指示如何找到this class和super class
  
   interfaces存放所有interfaces
  
   fields存放所有fields
  
   methods存放所有methods
  
   attributes存放所有attributes
  
  先寫一個Testjava
  
  package exampletest;
  
  public final class TestClass {
  public int id = ;
  public void test() {}
  }
  
  然後編譯放在C:\example\test\Testclass
  
  我們用Java來讀取和分析classClassAnalyzer的功能便是讀取Testclass分析結構然後顯示出來
  
  package classfileformat;
  
  import javaio*;
  
  public class ClassAnalyzer {
  
  public static void main(String[] args) {
  DataInputStream input = null;
  try {
  input = new DataInputStream(new BufferedInputStream(new FileInputStream(
  C:\\example\\test\\TestClassclass
  )));
  analyze(input);
  }
  catch(Exception e) {
  Systemoutprintln(Analyze failed!);
  }
  finally {
  try { inputclose(); } catch(Exception e) {}
  }
  }
  
  public static void analyze(DataInputStream input) throws IOException {
  // read magic number:
  int magic = inputreadInt();
  if(magic==xCAFEBABE)
  Systemoutprintln(magic number = xCAFEBABE);
  else
  throw new RuntimeException(Invalid magic number!);
  // read minor version and major version:
  short minor_ver = inputreadShort();
  short major_ver = inputreadShort();
  Systemoutprintln(Version = + major_ver + + minor_ver);
  // read constant pool:
  short const_pool_count = inputreadShort();
  Systemoutprintln(constant pool size = + const_pool_count);
  // read each constant:
  for(int i=; i  analyzeConstant(input, i);
  }
  }
  
  public static void analyzeConstant(DataInputStream input, int index) throws IOException {
  byte flag = input.readByte();
  // for read:
  byte n8;
  short n16;
  int n32;
  long n64;
  float f;
  double d;
  byte[] buffer;
  System.out.println("\nconst index = " + index + ", flag = " + (int)flag);
  switch(flag) {
  case 1: // utf-8 string
  System.out.println(" const type = Utf8");
  n16 = input.readShort();
  System.out.println("   length = " + n16);
  buffer = new byte[n16];
  input.readFully(buffer);
  System.out.println("   value = " + new String(buffer));
  break;
  case 3: // integer
  System.out.println(" const type = Integer");
  n32 = input.readInt();
  System.out.println("   value = " + n32);
  break;
  case 4: // float
  System.out.println(" const type = Float");
  f = input.readFloat();
  System.out.println("   value = " + f);
  break;
  case 5: // long
  System.out.println(" const type = Long");
  n64 = input.readLong();
  System.out.println("   value = " + n64);
  break;
  case 6: // double
  System.out.println(" const type = Double");
  d = input.readDouble();
  System.out.println("   value = " + d);
  break;
  case 7: // class or interface reference
  System.out.println(" const type = Class");
  n16 = input.readShort();
  System.out.println("   index = " + n16 + " (where to find the class name)");
  break;
  case 8: // string
  System.out.println(" const type = String");
  n16 = input.readShort();
  System.out.println("   index = " + n16);
  break;
  case 9: // field reference
  System.out.println(" const type = Fieldref");
  n16 = input.readShort();
  System.out.println("class index = " + n16 + " (where to find the class)");
  n16 = input.readShort();
  System.out.println("nameAndType = " + n16 + " (where to find the NameAndType)");
  break;
  case 10: // method reference
  System.out.println(" const type = Methodref");
  n16 = input.readShort();
  System.out.println("class index = " + n16 + " (where to find the class)");
  n16 = input.readShort();
  System.out.println("nameAndType = " + n16 + " (where to find the NameAndType)");
  break;
  case 11: // interface method reference
  System.out.println(" const type = InterfaceMethodref");
  n16 = input.readShort();
  System.out.println("class index = " + n16 + " (where to find the interface)");
  n16 = input.readShort();
  System.out.println("nameAndType = " + n16 + " (where to find the NameAndType)");
  break;
  case 12: // name and type reference
  System.out.println(" const type = NameAndType");
  n16 = input.readShort();
  System.out.println(" name index = " + n16 + " (where to find the name)");
  n16 = input.readShort();
  System.out.println(" descripter = " + n16 + " (where to find the descriptor)");
  break;
  default:
  throw new RuntimeException("Invalid constant pool flag: " + flag);
  }
  }
  }
  
  輸出結果為:
  
  magic number = 0xCAFEBABE
  Version = 48.0
  constant pool size = 22
  
  const index = 1, flag = 1
  const type = Utf8
  length = 22
  value = example/test/TestClass
  
  const index = 2, flag = 7
  const type = Class
  index = 1 (where to find the class name)
  
  const index = 3, flag = 1
  const type = Utf8
  length = 16
  value = java/lang/Object
  
  const index = 4, flag = 7
  const type = Class
  index = 3 (where to find the class name)
  
  const index = 5, flag = 1
  const type = Utf8
  length = 2
  value = id
  
  const index = 6, flag = 1
  const type = Utf8
  length = 1
  value = I
  
  const index = 7, flag = 1
  const type = Utf8
  length = 6
  value =
  
  const index = 8, flag = 1
  const type = Utf8
  length = 3
  value = ()V
  
  const index = 9, flag = 1
  const type = Utf8
  length = 4
  value = Code
  
  const index = 10, flag = 12
  const type = NameAndType
  name index = 7 (where to find the name)
  descripter = 8 (where to find the descriptor)
  
  const index = 11, flag = 10
  const type = Methodref
  class index = 4 (where to find the class)
  nameAndType = 10 (where to find the NameAndType)
  
  const index = 12, flag = 3
  const type = Integer
  value = 1234567
  
  const index = 13, flag = 12
  const type = NameAndType
  name index = 5 (where to find the name)
  descripter = 6 (where to find the descriptor)
  
  const index = 14, flag = 9
  const type = Fieldref
  class index = 2 (where to find the class)
  nameAndType = 13 (where to find the NameAndType)
  
  const index = 15, flag = 1
  const type = Utf8
  length = 15
  value = LineNumberTable
  
  const index = 16, flag = 1
  const type = Utf8
  length = 18
  value = LocalVariableTable

From:http://tw.wingwit.com/Article/program/Java/JSP/201311/19269.html
    推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.