您现在的位置是:主页 > news > 做短视频网站好/百度应用商店下载安装

做短视频网站好/百度应用商店下载安装

admin2025/6/9 20:45:19news

简介做短视频网站好,百度应用商店下载安装,有经验的江苏网站建设,上辽宁建设工程信息网站今天在看HashMap的源码时,其hash算法使用了无符号右移16位的操作,好奇Java内存中到底是怎么存放这些数字的。虽然以前知道,计算机都是使用补码的形式存放的整数值,但我都没深究过内存中的字节。今天查查资料,把自己所学…

做短视频网站好,百度应用商店下载安装,有经验的江苏网站建设,上辽宁建设工程信息网站今天在看HashMap的源码时,其hash算法使用了无符号右移16位的操作,好奇Java内存中到底是怎么存放这些数字的。虽然以前知道,计算机都是使用补码的形式存放的整数值,但我都没深究过内存中的字节。今天查查资料,把自己所学…

今天在看HashMap的源码时,其hash算法使用了无符号右移16位的操作,好奇Java内存中到底是怎么存放这些数字的。虽然以前知道,计算机都是使用补码的形式存放的整数值,但我都没深究过内存中的字节。今天查查资料,把自己所学的记录在此。

java中基本整型的长度

java中基本整型的长度如下图:

byte:8位,short:16位,int:32位,long:64位0591ab35d47caf5406f1c743f987c916.png

而计算机中,程序员用得最多的是十进制和十六进制,十进制符合人的计算习惯,而二进制因为0101太长看起来不方便,将机器内的二进制转为十六进制方便人查看。

Java也提供了这两种进制的字面量,不写任何前缀如int i = 10;即代表该整型i是赋值十进制的10,而int i = 0x10;则表示i赋值的是十六进制的10,即十进制的16。System.out.println(i);默认以十进制打印出i,而System.out.printf("%x",i);则是以16进制打印i。

但值得注意的是0x10这个字面量是以int类型的,如0xff表示的是int类型的255,如果将其赋值给byte类型byte b = 0xff,编译器会报错,因为byte最大为127。这样的话,难道我就不能为一个byte赋值为全1吗?可以的,但是需要借由int来强制转换,如下:

int i = 0x00_00_00_ff; // JDK1.7之后可以使用下划线来分割整型字面量,便于阅读

byte b = (byte) i; // int类型强制转化为byte,会取最右边八位,即ff

复制代码

内存中存储的是补码

我们知道,计算机在内存中存储的都是整数的补码,空口无凭,那怎么来验证一下呢?程序如下,将int位-1的每一个字节都以十六进制打印出来,确实是补码:0xff_ff_ff_ff

@Test

public void test(){

int i = -1;

byte[] bs = new byte[4];

bs[0] = (byte)(i >>> 24);

bs[1] = (byte)(i >>> 16);

bs[2] = (byte)(i >>> 8);

bs[3] = (byte) i;

for(byte b : bs){

System.out.printf("%x ", b);

}

}

复制代码

结果如下:d5fab2b726cfcdacac9912075e248167.png

反向验证一下,将byte设置为0xff,看打印是否为-1。

@Test

public void test(){

int i = 0x01_23_45_ff;

byte b = (byte) i;

System.out.printf("%d", b);

}

复制代码

得证,结果如下:740d59ffc2bfcb3f5c29114fad1b4060.png

一切皆0101

计算机中所有的东西都是0101,那么,现在我想用这些0101来组装一个句子“我喜欢你",打印出来可以吗?答案是,当然没问题,只要你知道这些文字的编码即可。上网查找到,“我喜欢你”这几个字的utf8编码是:\xE6\x88\x91\xE5\x96\x9C\xE6\xAC\xA2\xE4\xBD\xA0(\x表示十六进制),那可以使用byte[]数组来构建字符串了,如下:

@Test

public void test() throws UnsupportedEncodingException{

byte[] bs = {(byte)0xe6, (byte)0x88, (byte)0x91,

(byte)0xe5, (byte)0x96, (byte)0x9c,

(byte)0xe6, (byte)0xac, (byte)0xa2,

(byte)0xe4, (byte)0xbd, (byte)0xa0};

String s = new String(bs, "utf8");

System.out.printf("%s", s);

}

复制代码

结果如下:1e99c89f479a79ae819ab93842eac970.png

当然,搜索unicode编码或其他编码,然后以该编码解码形成String字符串也可。

既然反向能形成字符串,正向也能从字符串获取到编码值,如下,将“我喜欢你”编码为unicode编码:

@Test

public void test() throws UnsupportedEncodingException{

String s = "我喜欢你";

byte[] bs = s.getBytes("unicode");

for(byte b : bs){

System.out.printf("%x ", b);

}

}

复制代码

结果如下,fe ff是unicode头,其余每2字节代表一个中文。ad36566134023ad281d5323bdd8c04c5.png

Java字节序endian

写完之后发现遗漏了Java字节序相关的,等下班再补补。其实字节序很简单,就是超过一个字节时,字节在内存中是按什么顺序放置的。像int是四个字节,那么如果存放一个0x12_34_56_78,是在内存地址中按顺序12345678存放还是其他存放方式。这就是字节序。

以上。