关于编码

计算机是只能识别0和1的,我们的文字就多了,语种就不少,汉语,英语,法语等等,随便找十几二十种不难,每种语言又有许多不同的符号,指望计算机直接表示是不可能了,只能使用0和1的组合来表示这些符号了。

最早的流行的编码方式叫做ASIIC码,用一个字节(8个字位)来表示一个符号,说白了就是用0和1给每个字符加个编号,计算机处理时就是用这些编号,至于输出还要联合一下字库等其它组件。当时由于计算机都是一群说英语的人搞的,所以最早的字符编码只考虑了英文,而且由于英语字符少,一个字节都没用完,只用了7个字位,120多个字符。后来计算机普及了,就不能让计算机只识别英文字符了,所以很多人在这个基础上搞了很多编码方案来适应不同的语言,比如我们中国当时搞了个GB2312字符集,一个汉字用两个字节表示,兼容ASIIC码,后来扩展了两次,第一次升级叫做GBK,这个方案目前最通用,第二次升级叫做GB18030,这个字符集很大,包含了很多不常用的字符,所以目前最流行的还是GBK。

但是有些国际组织对此看得更远,希望高出一种更好的编码,可以容纳更多的符号,这就是Unicode。Unicode使用四个字节存储一个符号,也就是说,Unicode最多可以存储大约2的32次方个符号,大约是40亿以上,目前才用了10万多。潜力很大。

Unicode是一种编码方案,具体实施起来又有很多不同的方案,什么UTF-32,UTF-16,UTF-8,固定字长,可变字长,高位在前,低位在前等等,最常见的就是UTF-8,这个方案中每个字符长度不一定,英文是一个字节,汉字就是3个字节,既能表达清其内容,又不太费空间。

java是支持UTF-8的,实际上JAVA支持目前大多数编码格式。但还要考虑源程序文件的存储格式。同样是这个内容,可以用GBK编码存储,也可以用UTF-8,但这时会出现一个问题,汉字在GBK中和UTF-8中表示形式好像不一样,在一种编码格式下很好,换个格式就成乱码了。这也是为什么上一个实验中的计算器中的汉字都是方块了,因为不识别。

这就带来两个问题,为什么课本上的Applet就没有问题?为什么AWT组件中的汉字出问题而Swing的没有?我查了一些资料,汇总了一下,得出一个推论,因为没有明确的资料,只能写下这个推论,谁有更好的,更明确地解释一定要告诉我。

浏览器支持多种编码格式,所以可以识别GBK和UTF-8的编码,所以无论是什么格式,浏览器都没有问题。

AWT窗口为什么有问题呢,因为AWT这个东西其实有问题,当初SUN为了让JAVA做的GUI界面运行在多个系统下,只允许AWT拥有所有操作系统共有组件,比如按钮,文本框,所以没有目录树等组件,为什么要这样设计呢?因为AWT不是完全运行在JAVA虚拟机上的,AWT生成一个组件,是要调用操作系统本身资源来生成一个组件的。所以它不敢在AWT加入太多特性,万一某个功能Windows有而Linux没有就不能跨平台了。可能这样说还有点抽象,再举个例子,比如让AWT生成一个按钮,这个按钮不是java程序本身的,而是操作系统生成的,比如在Windows下,按钮这个组件是C++/C语言写的,那么呈现在用户面前的这个按钮不是靠JAVA语言生成,而是一个C++/C程序,就是JAVA语言调用了C++和C的代码。据《Think in java》这本书介绍,AWT是SUN公司一个月时间搞出来的,所以到了后来SUN自己都看不下去了,又搞了一套纯JAVA编写的Swing组件,AWT用得就很少了。

那么说了这么多,为什么会有汉字变方块的问题呢?我推测,我们写入JAVA程序的字符都是UTF-8,至少是Unicode,因为JAVA本身支持的就是Unicode,如果这些字符都在JAVA虚拟机中处理,不管什么编码都没关系,反正我们写的和虚拟机处理的都一样,比如Swing。但是AWT不同,我们写的是Unicode,AWT工作时却要调用系统资源,中文版Windows处理中文用GBK编码,这和JAVA的Unicode是不一样的,所以会出现方块或者乱码。怎么解决呢,我们可以把源文件存储为GBK编码就可以了,总不能不用中文吧。


在NetBeans中修改编码的方法是在项目栏中找到要修改的项目,在名字上(就是带有咖啡杯图标那个名字)点鼠标右键,在弹出菜单中选择“属性”,打开的属性对话框中最下面有“编码”一项,可以改成GBK或者GB2312,单击“确定”按钮即可。

你可能感兴趣的:(java,虚拟机,windows,swing,存储,语言)