关于java字符编码问题

Java中 char 是两字节
我定义char='A'
那A是一个字节还是两个字节呢
百度了很多答案,有说字母和数字占一个字节,有说占两个字节,烦的要死!!!还是说字母占两个字节但高位全为0???注意是字母和数字!汉字占两个字节我知道!
还有system.print.out("aaa".getBytes().length)输出的是3,system.print.out("哈哈哈".getBytes().length)输出的却是6,为什么?????希望能提供有用的答案,很多没用的答案我都看过,根本解决不了疑惑,满意的重金悬赏!!!!
最新回答
痛徹心扉

2024-09-23 06:28:42

首先,我们看getBytes(); JDK文档注释为:
Returns a new byte array containing the characters of this string encoded using the system's default charset.
即根据系统的默认编码方式,返回一个byte数组,byte和char一样吗,显然不一样。下面我们测试一下不同字符集,getBytes()的行为。
以下是我运行的结果,我的系统是linux,字符串就是你的哈哈哈:
字符集:Big5 getBytes()长度6
数组内容:
-85 -94 -85 -94 -85 -94
字符集:Big5-HKSCS getBytes()长度6
数组内容:
-85 -94 -85 -94 -85 -94
字符集:EUC-JP getBytes()长度6
数组内容:
-46 -3 -46 -3 -46 -3
字符集:EUC-KR getBytes()长度6
数组内容:
-7 -21 -7 -21 -7 -21
字符集:GB18030 getBytes()长度6
数组内容:
-71 -2 -71 -2 -71 -2
字符集:GB2312 getBytes()长度6
数组内容:
-71 -2 -71 -2 -71 -2
字符集:GBK getBytes()长度6
数组内容:
-71 -2 -71 -2 -71 -2
字符集:IBM-Thai getBytes()长度3
数组内容:
63 63 63
字符集:IBM00858 getBytes()长度3
数组内容:
63 63 63
字符集:IBM01140 getBytes()长度3
数组内容:
63 63 63
字符集:IBM01141 getBytes()长度3
数组内容:
63 63 63
字符集:IBM01142 getBytes()长度3
数组内容:
63 63 63
字符集:IBM01143 getBytes()长度3
数组内容:
63 63 63
字符集:IBM01144 getBytes()长度3
数组内容:
63 63 63
字符集:IBM01145 getBytes()长度3
数组内容:
63 63 63
字符集:IBM01146 getBytes()长度3
数组内容:
63 63 63
字符集:IBM01147 getBytes()长度3
数组内容:
63 63 63
字符集:IBM01148 getBytes()长度3
数组内容:
63 63 63
字符集:IBM01149 getBytes()长度3
数组内容:
63 63 63
字符集:IBM037 getBytes()长度3
数组内容:
63 63 63
字符集:IBM1026 getBytes()长度3
数组内容:
63 63 63
字符集:IBM1047 getBytes()长度3
数组内容:
63 63 63
字符集:IBM273 getBytes()长度3
数组内容:
63 63 63
字符集:IBM277 getBytes()长度3
数组内容:
63 63 63
字符集:IBM278 getBytes()长度3
数组内容:
63 63 63
字符集:IBM280 getBytes()长度3
数组内容:
63 63 63
字符集:IBM284 getBytes()长度3
数组内容:
63 63 63
字符集:IBM285 getBytes()长度3
数组内容:
63 63 63
字符集:IBM297 getBytes()长度3
数组内容:
63 63 63
字符集:IBM420 getBytes()长度3
数组内容:
63 63 63
字符集:IBM424 getBytes()长度3
数组内容:
63 63 63
字符集:IBM437 getBytes()长度3
数组内容:
63 63 63
字符集:IBM500 getBytes()长度3
数组内容:
63 63 63
字符集:IBM775 getBytes()长度3
数组内容:
63 63 63
字符集:IBM850 getBytes()长度3
数组内容:
63 63 63
字符集:IBM852 getBytes()长度3
数组内容:
63 63 63
字符集:IBM855 getBytes()长度3
数组内容:
63 63 63
字符集:IBM857 getBytes()长度3
数组内容:
63 63 63
字符集:IBM860 getBytes()长度3
数组内容:
63 63 63
字符集:IBM861 getBytes()长度3
数组内容:
63 63 63
字符集:IBM862 getBytes()长度3
数组内容:
63 63 63
字符集:IBM863 getBytes()长度3
数组内容:
63 63 63
字符集:IBM864 getBytes()长度3
数组内容:
63 63 63
字符集:IBM865 getBytes()长度3
数组内容:
63 63 63
字符集:IBM866 getBytes()长度3
数组内容:
63 63 63
字符集:IBM868 getBytes()长度3
数组内容:
63 63 63
字符集:IBM869 getBytes()长度3
数组内容:
63 63 63
字符集:IBM870 getBytes()长度3
数组内容:
63 63 63
字符集:IBM871 getBytes()长度3
数组内容:
63 63 63
字符集:IBM918 getBytes()长度3
数组内容:
63 63 63

可以看出,不同编码集下,不仅getBytes长度不同,连数组的内容都不一样。

下面测试"aaa":

字符集:Big5 getBytes()长度3
数组内容:
97 97 97
字符集:Big5-HKSCS getBytes()长度3
数组内容:
97 97 97
字符集:EUC-JP getBytes()长度3
数组内容:
97 97 97
字符集:EUC-KR getBytes()长度3
数组内容:
97 97 97
字符集:GB18030 getBytes()长度3
数组内容:
97 97 97
字符集:GB2312 getBytes()长度3
数组内容:
97 97 97
字符集:GBK getBytes()长度3
数组内容:
97 97 97
字符集:IBM-Thai getBytes()长度3
数组内容:
-127 -127 -127
字符集:IBM00858 getBytes()长度3
数组内容:
97 97 97
字符集:IBM01140 getBytes()长度3
数组内容:
-127 -127 -127
字符集:IBM01141 getBytes()长度3
数组内容:
-127 -127 -127
字符集:IBM01142 getBytes()长度3
数组内容:
-127 -127 -127
字符集:IBM01143 getBytes()长度3
数组内容:
-127 -127 -127
字符集:IBM01144 getBytes()长度3
数组内容:
-127 -127 -127
字符集:IBM01145 getBytes()长度3
数组内容:
-127 -127 -127
字符集:IBM01146 getBytes()长度3
数组内容:
-127 -127 -127
字符集:IBM01147 getBytes()长度3
数组内容:
-127 -127 -127
字符集:IBM01148 getBytes()长度3
数组内容:
-127 -127 -127
字符集:IBM01149 getBytes()长度3
数组内容:
-127 -127 -127
字符集:IBM037 getBytes()长度3
数组内容:
-127 -127 -127
字符集:IBM1026 getBytes()长度3
数组内容:
-127 -127 -127
字符集:IBM1047 getBytes()长度3
数组内容:
-127 -127 -127
字符集:IBM273 getBytes()长度3
数组内容:
-127 -127 -127
字符集:IBM277 getBytes()长度3
数组内容:
-127 -127 -127
字符集:IBM278 getBytes()长度3
数组内容:
-127 -127 -127
字符集:IBM280 getBytes()长度3
数组内容:
-127 -127 -127
字符集:IBM284 getBytes()长度3
数组内容:
-127 -127 -127
字符集:IBM285 getBytes()长度3
数组内容:
-127 -127 -127
字符集:IBM297 getBytes()长度3
数组内容:
-127 -127 -127
字符集:IBM420 getBytes()长度3
数组内容:
-127 -127 -127
字符集:IBM424 getBytes()长度3
数组内容:
-127 -127 -127
字符集:IBM437 getBytes()长度3
数组内容:
97 97 97
字符集:IBM500 getBytes()长度3
数组内容:
-127 -127 -127
字符集:IBM775 getBytes()长度3
数组内容:
97 97 97
字符集:IBM850 getBytes()长度3
数组内容:
97 97 97
字符集:IBM852 getBytes()长度3
数组内容:
97 97 97
字符集:IBM855 getBytes()长度3
数组内容:
97 97 97
字符集:IBM857 getBytes()长度3
数组内容:
97 97 97
字符集:IBM860 getBytes()长度3
数组内容:
97 97 97
字符集:IBM861 getBytes()长度3
数组内容:
97 97 97
字符集:IBM862 getBytes()长度3
数组内容:
97 97 97
字符集:IBM863 getBytes()长度3
数组内容:
97 97 97
字符集:IBM864 getBytes()长度3
数组内容:
97 97 97
字符集:IBM865 getBytes()长度3
数组内容:
97 97 97
字符集:IBM866 getBytes()长度3
数组内容:
97 97 97
字符集:IBM868 getBytes()长度3
数组内容:
97 97 97
字符集:IBM869 getBytes()长度3
数组内容:
97 97 97
字符集:IBM870 getBytes()长度3
数组内容:
-127 -127 -127
字符集:IBM871 getBytes()长度3
数组内容:
-127 -127 -127
字符集:IBM918 getBytes()长度3
数组内容:
-127 -127 -127
可以看出对于字母,我这里支持的字符集都返回了3,而数组内容有些是97,另外一些是127,97是我们熟悉的ASCii值,127我就不得而知了。

以上测试说明:不同字符集对于字母和汉字(还包括其他非拉丁文字)编码方式是不同的,包括使用单字节还是双字节,也包括如何编码。
测试代码如下:
Map<String, Charset> map = Charset.availableCharsets();
Set<String> keySet = map.keySet();
for(String charSetName: keySet)
{
System.out.println("字符集:" + charSetName + " getBytes()长度" + s.getBytes(map.get(charSetName)).length);
System.out.println("数组内容:");
for(byte b: s.getBytes(map.get(charSetName)))
{
System.out.print(b + " ");
}
System.out.println();
}

下面的问题是char:

int c = 'A';
int d = '哈';
char e = (char) 12345678;
c = e;
System.out.println(e);
12345678显然是超过了char范围了,不过呢它被截断成2字节,并且根据当前的字符集,打印出来一个汉字。
大概就是这样了
总结,如果你写char ,不管赋值为字母还是汉字还是数字,都占两个字节,只不过高位有些为0.
对于字符串,getBytes返回默认编码集下的数组,你可以指定参数获取其他字符集的结果,结果是五花八门的。
如果要了解字符集的编码规范,还请百度相关主题,我这里我不做更多的验证了。
天生傲骨

2024-09-23 08:59:08

首先我不能告诉你答案  因为你太急了   也太纠结一个不必要的东西了 拿到一段代码就上网搜

然后被无数个不相同的答案弄的心慌意乱  

正常的程序是 :拿到代码之后 

  1. 首先看代码的书写是否正确  char='A' ? 这是什么? 我不懂  变量的声明和赋值 应该有类型

       +变量名 然后才能=赋值

2.  代码是否能正确运行 

3.  代码代表的是什么意思  

  一步一步来  然后把不懂的弄懂 

现在来说这个 char a = 'A';的问题 

 char是字符型  字符的长度统统都为1   但是“字节” 和长度不同    字节byte   字母和数字占一个字节   但是char类型的'A'若是转换为字节型 就为一个两位的数字 好像叫什么ascii码  所以占位为2

 

再说.length的问题  。length()方法获取的是长度 但是字节其实是一个大小的单位 GB/MB/KB/B 其中的B就是字节  如果准确的说的话 汉字在windows系统中是占用4个字节的 在linux系统中只占用3个字节  如果你要获取一个什么东西的字节数 建议你用。size()方法     还有一种最笨的方式  :

新建一个记事本  为0KB  然后把你要获取的对象写进去  然后看大小是多少KB 

 

前面的有些概念可能你会看晕  那是因为你基础都没学好 不要急  也不要纠结一些没用的东西

老老实实敲代码 做练习  然后在项目中运用   每段代码至少敲5遍  这样很快不懂的都会懂的

追问
char s='A';这里属于失误,还有我SE已经学完,代码也敲了不少,基础不敢说有多牢固,但该知道的我都明白,只是有些细节方面的实在想不明白,寻找答案又是众说纷纭。你前面说的概念我都知道,就是这个字符编码的问题弄不明白
追答
刚刚我试了下  。size方法 。不出来   看来是行不同的  但是那个笨方法还是可以  就是直接在记事本里面写 然后看大小 
编码格式的问题 是确实存在的 就如taxi_008 所说的 然后不管是浏览器还是记事本文件 都可以修改编码格式的 不同的格式中 字母数字的字节是不会变的 会变的只有汉字的字节
追问
size方法只能得到位数,而且是包装类的静态变量,回头我试试文本里存储字符看看大小。谢谢了
追答
互相学习 哈哈    我才学没多久 还没接触框架 现在想写一个项目都没办法   只能写边边角角 
这个国庆 想写一个同学之间聊天的程序 数据库 DB DAO 都能写了 服务器跟客户端也会写了
就差一个severlet了 你能不能帮我写一个 数据库就帐号 密码 昵称 3个字段 方法名 变量名什么的你随便定 写个注释就好了 我Q1036268230
追问
关于数据库,我只学了mysql,会的也不多,我也开始学习java web了
橘萝卜蹲

2024-09-23 08:17:21

这个跟你的编码格式有关系,如果你的编码格式gbk的时候system.print.out("aaa".getBytes().length)输出的是3,system.print.out("哈哈哈".getBytes().length)输出的却是6;如果你的编码格式是utf-8的时候system.print.out("aaa".getBytes().length)输出的是3,system.print.out("哈哈哈".getBytes().length)输出的却是9;如果是utf-16的时候system.print.out("aaa".getBytes().length)输出的是6,system.print.out("哈哈哈".getBytes().length)输出的却是6,

gbk将字母与数字定义为1个字节,汉字为2个字节
utf-8将字母与数字定义为1个字节,汉字为3个字节
utf-16将全球大部分的字都定义为2个字节。
希望对你有帮助~
追问
那我java中定义一个char类型,无论是数字字母还是都是汉字都是两个字节对么
追答
这个应该是的,其实你申明一个char类型,他对应的是Unicode编码集中该字符所在的位置,可以用来参与运算的
思念满溢

2024-09-23 01:30:28

        //如果如果A当成String类型,那么显然是一个字节
        System.out.println("A".getBytes().length);

        //如果把A当成char类型,那么其实它对应的是一个数值类型,比如A就是65
        System.out.println(String.valueOf((int)'A').getBytes().length);