详解Java语言中一个字符占几个字节?
题主要区分清楚内码(internalencoding)和外码(externalencoding)就好了。
内码是程序内部使用的字符编码,特别是某种语言实现其char或String类型在内存里用的内部编码;
外码是程序与外部交互时外部使用的字符编码。“外部”相对“内部”而言;不是char或String在内存里用的内部编码的地方都可以认为是“外部”。例如,外部可以是序列化之后的char或String,或者外部的文件、命令行参数之类的。
Java语言规范规定,Java的char类型是UTF-16的codeunit,也就是一定是16位(2字节);
char,whosevaluesare16-bitunsignedintegersrepresentingUTF-16codeunits(§3.1).
然后字符串是UTF-16codeunit的序列:
TheJavaprogramminglanguagerepresentstextinsequencesof16-bitcodeunits,usingtheUTF-16encoding.
这样,Java规定了字符的内码要用UTF-16编码。或者至少要让用户无法感知到String内部采用了非UTF-16的编码。
另举一例:
Java标准库实现的对char与String的序列化规定使用UTF-8作为外码。Java的Class文件中的字符串常量与符号名字也都规定用UTF-8编码。这大概是当时设计者为了平衡运行时的时间效率(采用定长编码的UTF-16)与外部存储的空间效率(采用变长的UTF-8编码)而做的取舍。
首先,你所谓的“字符”具体指什么呢?
如果你说的“字符”就是指Java中的char,那好,那它就是16位,2字节。
如果你说的“字符”是指我们用眼睛看到的那些“抽象的字符”,那么,谈论它占几个字节是没有意义的。
具体地讲,脱离具体的编码谈某个字符占几个字节是没有意义的。
就好比有一个抽象的整数“42”,你说它占几个字节?这得具体看你是用byte,short,int,还是long来存它。用byte存就占一字节,用short存就占两字节,int通常是四字节,long通常八字节。当然,如果你用byte,受限于它有限的位数,有些数它是存不了的,比如256就无法放在一个byte里了。
字符是同样的道理,如果你想谈“占几个字节”,就要先把编码说清楚。
同一个字符在不同的编码下可能占不同的字节。
就以你举的“字”字为例,“字”在GBK编码下占2字节,在UTF-16编码下也占2字节,在UTF-8编码下占3字节,在UTF-32编码下占4字节。
不同的字符在同一个编码下也可能占不同的字节。
“字”在UTF-8编码下占3字节,而“A”在UTF-8编码下占1字节。(因为UTF-8是变长编码)
而Java中的char本质上是UTF-16编码。而UTF-16实际上也是一个变长编码(2字节或4字节)。
如果一个抽象的字符在UTF-16编码下占4字节,显然它是不能放到char中的。换言之,char中只能放UTF-16编码下只占2字节的那些字符。
而getBytes实际是做编码转换,你应该显式传入一个参数来指定编码,否则它会使用缺省编码来转换。
你说“newString("字").getBytes().length返回的是3”,这说明缺省编码是UTF-8.如果你显式地传入一个参数,比如这样“newString("字").getBytes("GBK").length”,那么返回就是2.
你可以在启动JVM时设置一个缺省编码,
假设你的类叫Main,那么在命令行中用java执行这个类时可以通过file.encoding参数设置一个缺省编码。比如这样:java-Dfile.encoding=GBKMain这时,你再执行不带参数的getBytes()方法时,newString("字").getBytes().length返回的就是2了,因为现在缺省编码变成GBK了。当然,如果这时你显式地指定编码,newString("字").getBytes("UTF-8").length返回的则依旧是3
否则,会使用所在操作系统环境下的缺省编码。
通常,Windows系统下是GBK,Linux和Mac是UTF-8.但有一点要注意,在Windows下使用IDE来运行时,比如Eclipse,如果你的工程的缺省编码是UTF-8,在IDE中运行你的程序时,会加上上述的-Dfile.encoding=UTF-8参数,这时,即便你在Windows下,缺省编码也是UTF-8,而不是GBK。
由于受启动参数及所在操作系统环境的影响,不带参数的getBytes方法通常是不建议使用的,最好是显式地指定参数以此获得稳定的预期行为。
以上所述是小编给大家介绍的Java语言中一个字符占几个字节详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!