[JVM] - 继10进制的java.lang.Object查看之后

cmd清除命令:cls

之后查阅了其它博客,发现这位大神同样也在做JVM,并且我很希望用它的10进制转16进制类来测试一下该解析的10进制是否对应着Object的16进制呢?

这位大神的10进制转16进制代码:

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;

public class Test {
    public static String txt2String(File file){
        StringBuilder result = new StringBuilder();
        try{
            BufferedReader br = new BufferedReader(new FileReader(file));//构造一个BufferedReader类来读取文件
            String s = null;
            while((s = br.readLine())!=null){//使用readLine方法,一次读一行
                result.append(System.lineSeparator()+s);
            }
            br.close();
        }catch(Exception e){
            e.printStackTrace();
        }
        return result.toString();
    }
    public static int hixTo(StringBuffer sb){
        int sum=0;
        if(sb.charAt(0)>=48&&sb.charAt(0)<=57){
            sum+=(sb.charAt(0)-48)*16;
        }else{
            sum+=((sb.charAt(0)-96)+9)*16;
        }
        if(sb.charAt(1)>=48&&sb.charAt(1)<=57){
            sum+=(sb.charAt(1)-48);
        }else{
            sum+=((sb.charAt(1)-96)+9);
        }
        return sum;
    }
    public static void main(String[] arts){
        File file = new File("D:\\yff.txt");
        String str=txt2String(file);
        StringBuffer sbBefore=new StringBuffer(str);
        StringBuffer sbAfter=new StringBuffer();
        for(int i=0;i<sbBefore.length();i++){
            if((sbBefore.charAt(i)>=48&&sbBefore.charAt(i)<=57)||(sbBefore.charAt(i)>=97&&sbBefore.charAt(i)<=122)){
                //System.out.print(sbBefore.charAt(i));
                sbAfter.append(sbBefore.charAt(i));
            }
        }
        System.out.println(sbAfter);
        System.out.println();
        for(int i=0;i<sbAfter.length();i=i+2){
            System.out.print(hixTo(new StringBuffer(""+sbAfter.charAt(i)+sbAfter.charAt(i+1)))+" ");
            if(i!=0&&i%100==0)
                System.out.println();
        }
    }
}

这样精湛的代码着实让人敬佩,我翻看了下之前我写的一些类似算法的解析:

import java.util.ArrayList;
public class Fracts {

    public static String convertFrac(long[][] lst) {
        long bigFrac = 1;
        long result = 1;
//        int count = 0;//计算是否还可以
        int fracNum = 0;//原始分母数量
        int maxDLen = 0;
        ArrayList<long[]> divisor = new ArrayList();
        ArrayList<Long> members = new ArrayList<Long>();
        ArrayList<Long> fracs = new ArrayList<Long>();
        // lst是个long型的二维数组,里面的每组元素是分子和分母的组合形式
        // 获取其分母的公共分母,(分子也按需更改),返回三组数据的字符串形式
        for (int i = 0; i < lst.length; i++) {
            for (int j = 0; j < 2; j++) {
                if(j==1) { //开始获取分母
                    //从上面if 开始进来了 所有的分母  多个数的最小公倍数求法:
                    //是素数的保持素数,不是素数的分解
                    long[] fracArray = new long[1];
                    long[] fracArray2 = new long[1];
                    int q;
                    int lastIndex = 0;
                    //分解质因数
                    long frac = lst[i][j];//获取了每个二维数组的元素
                    fracs.add(frac);
                    int count = 0; //[计数]看看这个数有共几个质因数
                    for(q=2;q<frac;q++) {

                        if(frac%q==0) {
                            //如果一个数能分解,就必定还有另一个因数,所以数组大小必须大于长度1
//                            System.out.println("q:"+q);
                            //得到了这个质因数的值(多个,需要数组存放)
                            //如果对每个数值的质因数,生成不同的数组或集合存放呢?
                            count++;//有一个因数分解时,count就递增

//                            System.out.println(""+fracArray.length+":"+count);
                            if(fracArray.length<=count) {
                                fracArray = new long[count+1];//变更数组大小
                                lastIndex=count;
                                for(int h=0;h<fracArray2.length;h++) {
                                    fracArray[h] = fracArray2[h];
                                }
                            }

                            fracArray[count-1] = q; //将质因数添加到数组
//                            System.out.println("q:"+q);
                            fracArray2 = fracArray;
                            frac = frac/q;
//                            System.out.println("frac:"+frac);
                            q=q/q;

//                            

                        }

                    }
                    //将最后的因数装入数组最后
          fracArray2[lastIndex] =q;
                    if(count==0) {
                        //这是个素数
                        fracArray2[0]=frac;
                    }

                    divisor.add(fracArray2);
                    if(fracArray2.length>maxDLen) {
                        maxDLen = fracArray2.length;
                    }

                }
                if(j==0) {
                    long mem = lst[i][j];
                    members.add(mem);
                }

            }

        }
        long[][] resultMatrixArr = new long[lst.length][maxDLen];
        long[][] resultMatrixArr2 = new long[maxDLen][lst.length];
        //将多个分母的分解的质因数装入二维数组,以最长质因数数组长度为二维矩阵宽度.原lst.length为高度.
        for(int l=0;l<lst.length;l++) {
            for(int p=0;p<divisor.get(l).length;p++) {
                    resultMatrixArr[l][p]=divisor.get(l)[p];
            }
        }

        for(int aa=0;aa<lst.length;aa++) {//矩阵高
//            System.out.println(resultMatrixArr[aa]);
            int grow = 0;
            for(int cc=0;cc<maxDLen;cc++) {//矩阵宽
                //获取每行的unique的集合,去除每行存在的重复数字,保留唯一一个.
                long[] rowNum = resultMatrixArr[aa]; //0,0; 0,1; 0,2
                grow=cc;
                while((grow+1)<rowNum.length) {//如果cc+1不是最大数组下标 则+1
                    grow++;
                    if(rowNum[cc]==rowNum[grow]) {
                        resultMatrixArr[aa][grow]=0;
                    }
                }
                //将二维数组倒置装入另一个
                resultMatrixArr2[cc][aa] = resultMatrixArr[aa][cc];
            }
        }

        //竖向去除 ?? 不适用此题
//        for(int tt=0;tt<maxDLen;tt++) {//矩阵高
//            int grow = 0;
//            for(int gg=0;gg<lst.length;gg++) {
//                //获取每列的unique集合,去除每列存在的重复数字,保留唯一一个.
//                grow=gg;
//                long[] rowNum = resultMatrixArr2[tt]; //0,0; 0,1; 0,2
//                while((grow+1)<rowNum.length) {//如果cc+1不是最大数组下标 则+1
//                    grow++;
//                    if(rowNum[gg]==rowNum[grow]) {
//                        resultMatrixArr2[tt][grow]=0;
//                    }
//                }
//            }
//        }
        for(int tt=0;tt<resultMatrixArr2.length;tt++) {//矩阵高
            for(int gg=0;gg<lst.length;gg++) {
                if(resultMatrixArr2[tt][gg]!=0) {
//                    System.out.println(resultMatrixArr2[tt][gg]);
                    result *= resultMatrixArr2[tt][gg];
                }
            }

        }

        String strResult = "";
        //获取分母的最小公倍数后
        for(int kk=0;kk<fracs.size();kk++) {
            if (result<fracs.get(kk)) {
                result=fracs.get(kk);
            }
        }
        for(int kk=0;kk<fracs.size();kk++) {

            strResult += "("+result/fracs.get(kk)*members.get(kk)+","+result+")";
        }
        return strResult;
    }

}

这是在codewars做的一组题其中的一道

现在看起来还有印象的就是将首位的数组进行置换,还是怎样,现在看到它有点晕.

当时解题的思路图↑

当时学2进制还做了一个demo

不说啦,都是过去的事情.

只要不放弃,还是有offer的.

在查看完毕ch02后,要进入作者的ch03教程了.

首先根据那位大神的代码让我们看看查看的Object类的编码是不是跟原始Object的class内容一致.

看到已经将我们通过Go语言获取的Object类的10进制编码转换为了16进制.

并且开头是cafebabe000...34...

对比原始的Object.class文件:

cafe babe 0000 0034 004e 0300 0f42 3f08
0010 0800 2608 002a 0100 0328 2949 0100
1428 294c 6a61 7661 2f6c 616e 672f 4f62
6a65 6374 3b01 0014 2829 4c6a 6176 612f
6c61 6e67 2f53 7472 696e 673b 0100 0328
2956 0100 1528 4929 4c6a 6176 612f 6c61
6e67 2f53 7472 696e 673b 0100 0428 4a29
5601 0005 284a 4929 5601 0015 284c 6a61
...

嗯,同样是cafebabe开头,后面000后有34,,,以及3f08,结尾是02004d,没错了.

以cafebabe开头...

cafe babe
咖啡馆宝贝

转入正题:

那么继续查看ch03.

第三章:解析class文件

前面几章介绍了Java虚拟机从哪里搜索class文件,并且实现了类路径功能,已经可以把class文件读取到内存中.

这一章将讨论class文件格式,编写代码解析class文件.为下一步真正实现Java虚拟机做准备.

以02为蓝本复制到ch03文件夹,创建classfile子目录.

作为类(或者接口)信息的载体,每个class文件都完整地定义了一个类,为了使Java程序可以"编写一次,处处运行",Java虚拟机规范对class文件格式进行了严格的规定.

但是,对于从哪里加载class文件,给了足够多的自由.

Java虚拟机实现可以从文件系统读取和从JAR(或ZIP)压缩包中提取class文件. 以外,还可以通过网络下载,从数据库加载,甚至是在运行中直接生成class文件.

Java虚拟机规范中所指class文件,并非特指位于磁盘中的.class文件,而是泛指任何格式复合规范的class数据.

构成class文件的基本数据单位是字节,可以把整个class文件当成一个字节流来处理.稍大一些的数据由连续多个字节构成,这些数据在class文件中以大端(big-endian)方式存储.

为了描述class文件格式,Java虚拟机规范定义了u1,u2,和u4三种数据类型来表示1,2,4字节无符号整数,分别对应Go语言的uint8,uint16和uint32类型.

相同类型的多条数据一般按表(table)的形式存储在class文件中, 表由表头和表项(item)构成,表头是u2或u4整数,假设表头是n,后面就紧跟着n个表项数据.

Java虚拟机规范使用一种类似C语言的结构体语法来描述class文件格式,整个class文件被描述为一个ClassFile结构.

JDK提供了功能强大的命令行工具javap,可以用它反编译class文件.

原文地址:https://www.cnblogs.com/ukzq/p/10184228.html

时间: 2024-08-10 18:13:13

[JVM] - 继10进制的java.lang.Object查看之后的相关文章

java 16进制转换10进制

public static String toHexString2(byte[] b) { StringBuffer buffer = new StringBuffer(); for (int i = 0; i < b.length; ++i) { buffer.append(toHexString2(b[i])); } return buffer.toString(); } public static String toHexString2(byte b) { char[] buffer =

Java 10进制转2、8、16进制转换 / 2、8、16进制转10进制转换

public static void main(String[] args) { int i = 10; System.out.println("***********10进制转换2进制.8进制.16进制************"); System.out.println(Integer.toBinaryString(i)); // 10转换2进制 System.out.println(Integer.toOctalString(i)); // 10转换8进制 System.out.p

进制转换--Java实现

题目详情 我们通常用的十进制数包含0-9十个数字.假设有一种进制系统包含3种数字,从低到高分别为"oF8",那么从1到9分别表示为F, 8, Fo, FF, F8, 8o, 8F, 88, Foo.给定一种进制的数和两种进制的数字表,请把它从第一种进制转换为第二种进制. 输入格式: 第一行是T表示测测试数据组数.(0<T<=200). 以后T行,每行有3个部分: number number_table1 number_table2 其中number_table1和numbe

Hdu 4278 Faulty Odometer(8进制转10进制)

Faulty Odometer Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1664    Accepted Submission(s): 1146 Problem Description You are given a car odometer which displays the miles traveled as an int

华为笔试练习题----解析9进制,11进制的字符串为10进制的数字输出

                                                                              解析9进制,11进制的字符串为10进制的数字输出 描述: 解析9进制,11进制的字符串为10进制的数字输出,输入的字符串有效位(0v0012345678)长度不超过8位,前面的00不算做有效位.解析后以10进制的数字输出.如果解析到非法字符串则返回-1 9进制: 9进制的数的范围:0,1,2,3,4,5,6,7,8 9进制的开始为:0V或者0

10进制转换成8进制

package cast; import java.util.Collections;import java.util.LinkedList;import java.util.List; public class Cast {    //测试    public static void main(String[] args) {        int a = Cast.castNum(100);        System.out.println(a);            }        

10进制转二进制字符串输出

import java.util.Scanner; /** * Created by longforus on 9:10 PM 5/9/2016 . * IDEA-Test . * 输入10进制 输出二进制字符串 先计算该数包含最大的2次方结果 每减去一个该数 该位二进制 * 就记1 不够减就记0 a减完以后补全0 */ public class Chapter4_37 { public static void main (String[] args) { System.out.println

2进制,10进制,16进制,补码和移位

逢二进一,逢十进一,十六进制 10110101(2) = 128+32+16+4+1 = 181(10) b 5(16) = b*16+5 = 11*16+5 = 181(10) 2进制 int n = 45; System.out.println(Integer.toBinaryString(n)); 计算机的内部(Java)只有2进制数据, 在显示的时候编程语言提供API将2进制转换为10进制显示出来. 计算机只能处理2进制数据, 利用编程语言提供的算法支持了10进制 Java中用于支持2进

数组中hashCode就是内存地址,以及汉字幻化为16进制或10进制

int[] arr4={1,2,3,4,5}; System.out.println("arr4: "+arr4); System.out.println("arr4.hashCode: "+arr4.hashCode()); //将hashCode值转化为16进制的两种方式 System.out.println(Integer.toString(366712642,16));//将整数转化为16进制的数为:15db9742 System.out.println(I