JVM学习笔记2 --纯手写读取class文件常量池内容并输出

JVM的class文件定义有严格的规范,当虚拟机读取class文件的二进制数据时,JVM虽然不会管该二进制数据是从java编译期编译而来还是其他例如groovy或者kotlin等等编译而来,只要符号jvm定义的规范,就能够读取,也就能在JVM虚拟机上运行

直接上代码,可能有些粗糙,不喜勿喷哈各位大神:

两个类,没细化处理,一个主类,一个配置类,本人IDEA+JDK1.8运行

1、主类HexConvertString.java

public class HexConvertString {

    private static volatile LinkedHashMap<String, String> constant_pool = new LinkedHashMap<>(10);//保存常量池解析出来的数据

    public static void main(String[] args) {
        FileInputStream fin = null;//用来读取class文件的输入流
        StringWriter sw = new StringWriter();//保存转化后的十六进制的String流
        try {
            //本人本地的测试路径
            fin = new FileInputStream(new File("X:\\Users\\csfxy\\Desktop\\MagnumMain.class"));
            int len = 1;
            byte[] temp = new byte[len];
            //进行16进制的读取转化
            for (; (fin.read(temp, 0, len)) != -1; ) {
                if (temp[0] > 0xf && temp[0] <= 0xff) {//如果是在16到272之间,证明有两位数了,不需要前面加0
                    sw.write(Integer.toHexString(temp[0]));
                } else if (temp[0] >= 0 && temp[0] <= 0xf) {//对于只有1位的16进制数前边补“0”
                    sw.write("0" + Integer.toHexString(temp[0]));
                } else { //对于int<0的位转化为16进制的特殊处理,因为Java没有Unsigned int,所以这个int可能为负数
                    sw.write(Integer.toHexString(temp[0]).substring(6));
                }
            }
            String readResult = sw.toString();//输出转化后的十六进制
            //解析class 文件16进制
            String access_flag = "";//类的访问修饰符
            if (readResult.startsWith("cafebabe")) {
                StringBuffer sb = new StringBuffer(readResult.substring(8));
                //解析版本
                long code = hexParseLong(sb.substring(0, ConstantParam.ITEM * 2)) + hexParseLong(sb.substring(ConstantParam.ITEM * 2, ConstantParam.ITEM * 4));
                System.out.println("该class文件字节码由" + ConstantParam.JdkVersion.getName(code) + "编译");
                sb = new StringBuffer(sb.substring(ConstantParam.ITEM * 4));
                // System.out.println(sb.toString());
                //解析常量池个数
                int CONSTANT_POOL_COUNT = (int) (hexParseLong(sb.substring(0, ConstantParam.ITEM * 2)) - 1);
                Sy
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值