Java:Char与字符串字节大小
我惊讶地发现以下代码Java:Char与字符串字节大小,java,string,char,byte,Java,String,Char,Byte,我惊讶地发现以下代码 System.out.println("Character size:"+Character.SIZE/8); System.out.println("String size:"+"a".getBytes().length); 输出如下: 字符大小:2 字符串大小:1 我假设一个字符串应该比一个字符占用相同(或更多)的字节 我特别想知道 如果我有一个包含多个字段的JavaBean,那么它的大小将如何增加取决于字段
System.out.println("Character size:"+Character.SIZE/8);
System.out.println("String size:"+"a".getBytes().length);
输出如下:
字符大小:2
字符串大小:1
我假设一个字符串应该比一个字符占用相同(或更多)的字节
我特别想知道
如果我有一个包含多个字段的JavaBean,那么它的大小将如何增加取决于字段的性质(字符、字符串、布尔值、向量等)。我假设所有java对象都有一些(可能是最小的)足迹,并且这些足迹中最小的一个将是单个字符。为了测试这个基本假设,我从上面的代码开始——打印语句的结果似乎违反直觉
了解java在默认情况下存储/序列化字符与字符串的方式将非常有用。
getBytes()
使用默认编码(很可能是ISO-8859-1
)输出字符串,而内部字符字符始终有2个字节。Java内部使用始终字符数组和2字节字符,如果您想了解更多有关编码的信息,请阅读问题注释中的Oded链接。字符大小是字符所需的存储空间,为16位。字符串的长度(也是基础字符数组或字节数组的长度)是字符数(或字节数),而不是以位为单位的大小
这就是为什么你要用8除法来计算尺寸,而不是长度。长度需要乘以2
还请注意,如果指定不同的编码,则将获得字节数组的其他长度。在本例中,在执行getBytes()时执行了到单个或可变大小编码的转换
请参阅:)我想说出我的想法,如果我错了,请纠正我,但您找到的字符串长度是正确的,它显示为1,因为字符串中只有1个字符。长度显示长度,而不是大小。长度和大小是两码事
检查这个。。您发现以错误的方式占用的字节数好吧,字符数组中的1个字符的大小为2个字节,字符串包含的长度为1个字符,而不是1个字节
Java中的字符串
对象包括:
private final char value[];
private final int offset;
private final int count;
private int hash;
只有这样才能确保String
对象比char
数组大。
如果您想了解更多有关对象大小的信息,还可以阅读有关对象头和字符数组的多重性因子的信息。例如或。我想先添加一些代码,然后再做一些解释:
import java.nio.charset.Charset;
public class Main {
public static void main(String[] args) {
System.out.println("Character size: " + Character.SIZE / 8);
final byte[] bytes = "a".getBytes(Charset.forName("UTF-16"));
System.out.println("String size: " + bytes.length);
sprintByteAsHex(bytes[0]);
sprintByteAsHex(bytes[1]);
sprintByteAsHex(bytes[2]);
sprintByteAsHex(bytes[3]);
}
static void sprintByteAsHex(byte b) {
System.out.print((Integer.toHexString((b & 0xFF))));
}
}
输出将是:
Character size: 2
String size: 4
feff061
因此,您实际上缺少的是,您没有为getBytes方法提供任何参数。您可能正在获取字符“a”的UTF-8表示形式的字节
好吧,但是为什么我们要UTF-16时得到了4个字节呢?好的,Java在内部使用UTF-16,那么我们应该得到2个字节,对吗
如果检查输出:
feff061
Java实际上向我们返回了一个BOM:
因此,前2个字节:feff是发送以下字节为UTF-16 Big-Endian的信号所必需的。请参阅维基百科页面了解更多信息
剩下的2个字节:0061是字符“a”的2个字节表示形式。可通过以下方式进行验证:
是的,Java中的一个字符是2个字节,但是当您请求没有特定编码的字节时,您可能不会总是得到2个字节,因为不同的编码将需要不同数量的字节用于不同的字符 字符串的长度是它包含的字符数。一个字符可以用多个字节编码。字符串很可能是UTF-8编码的,所以“A”只需要一个字节。@NiklasB。或者更确切地说是固定宽度的UTF-16(UCS-2)类型格式。不,他使用了getBytes()
,所以他得到的实际上是字节数(这也不足为奇)。是的,这个答案有点离题,并且错误地描述了这个问题。。。我建议进行更新。作为参考,getBytes()
实际上并没有告诉您字符串的实际内存消耗量。我认为您的这句话不正确:“Java内部总是使用带有2字节字符的字符数组。”您可以看到以下链接:对于我,Java在代码中使用UTF-8作为默认编码。@KorayTugay您可能混淆了Unicode在Java中的内部内存表示形式(是的,每个字符序列实现(如String)仍然使用UTF-16格式的2字节字符),以及Java在特定字节编码中导入或导出内部表示形式(文件、网络)。如果您仍然相信您的Java版本(即…?)在内部使用UTF-8,您如何证明这一点?顺便说一句,getBytes()的问题是该函数非常古老,在版本1.1中,UTF-8还不受支持时就已经存在了,因此您无法真正预测它是否使用UTF-8。这没有意义。您是否可以尝试改进语法。。。等