|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
java主要分三块,j2se:java的基础核心语言。j2me:java的微型模块,专门针对内存小,没有持续电源等小型设备。j2ee:java的企业模块,专门针对企业数据库服务器的连接维护。汉字|成绩1、主题:关于JAVA的中文成绩
JAVA的中文成绩对照凸起,次要体现在把持面板输入,JSP页面输入和数据库会见上。本文只管避开字体成绩,而只谈编码。经由过程本文,你能够懂得JAVA中文成绩的由来,成绩的办理办法,个中提了一下用JDBC会见数据库的办法。
2、成绩形貌:
1)在中文W2000中文窗口编译和运转,用的是国际版的JDK,毗连的是中文W2000下的Cp936编码的SQLSERVER数据库:
J:exercisedemoencodeHelloWorld>make
CreatedbyXCompiler.PhiloSoftAllRightsReserved.
WedMay3002:54:45CST2001
J:exercisedemoencodeHelloWorld>run
CreatedbyXRunner.PhiloSoftAllRightsReserved.
WedMay3002:51:33CST2001
中文
[B@7bc8b569
[B@7b08b569
[B@7860b569
中文
中文
????
中文
中文
????
??
??
??
2)假如在中文W2000的西文窗口(编码为437)下编译,用JAVA运转则因为无字体而没法一般显现,假如象下面一样在中文W2000的中文窗口运转,输入为:
J:exercisedemoencodeHelloWorld>run
CreatedbyXRunner.PhiloSoftAllRightsReserved.
WedMay3002:51:33CST2001
????
[B@7bc0b66a
[B@7b04b66a
[B@7818b66a
????
????
????
????
????
????
中文
中文
????
三)剖析
1)呈现有乱码(也就是?)。因为只呈现?而没呈现小方框,申明只是编码有成绩,而不是字体成绩。在编码中,假如从一种字符集转换到别一种字符集,对照典范的是从GB2312转换到ISO8859_1(即ASCII),那末良多汉字(半个汉字)是没法映照到西笔墨符中往的,在这类情况下,体系就把这些字符用?取代。一样,也存在小字符集没法到年夜字符集的情形,详细缘故原由这里就谈了。
2)呈现了中文情况编译,中文情况运转时汉字显现有准确也有不准确的中央,一样,在西文情况下编译,在中文情况下运转时也呈现相似情形。这是因为主动(默许)或手工(也就newString(bytes[,encode])和bytesgetBytes([encode]))转码的了局。
2.1)在JAVA源文件-->JAVAC-->Class-->Java-->getBytes()-->newString()-->显现的过程当中,每步都有编码的转换历程,这个历程老是存在的,只是有的时分用默许的参数举行。上面我们一步一步剖析为何呈现下面的情况。
2.2)这里是源代码:
HelloWorld.java:
------------------------
publicclassHelloWorld
{
publicstaticvoidmain(String[]argv){
try{
System.out.println("中文");//1
System.out.println("中文".getBytes());//2
System.out.println("中文".getBytes("GB2312"));//3
System.out.println("中文".getBytes("ISO8859_1"));//4
System.out.println(newString("中文".getBytes()));//5
System.out.println(newString("中文".getBytes(),"GB2312"));//6
System.out.println(newString("中文".getBytes(),"ISO8859_1"));//7
System.out.println(newString("中文".getBytes("GB2312")));//8
System.out.println(newString("中文".getBytes("GB2312"),"GB2312"));//9
System.out.println(new
String("中文".getBytes("GB2312"),"ISO8859_1"));//10
System.out.println(newString("中文".getBytes("ISO8859_1")));//11
System.out.println(new
String("中文".getBytes("ISO8859_1"),"GB2312"));//12
System.out.println(new
String("中文".getBytes("ISO8859_1"),"ISO8859_1"));//13
}
catch(Exceptione){
e.printStackTrace();
}
}
}
为了便利起见,在每一个转换的前面加了操纵序号,分离为1,2,...,13。
2.3)必要申明的是,JAVAC是以体系默许编码读进源文件,然后按UNICODE举行编码的。在JAVA运转的时分,JAVA也是接纳UNICODE编码的,而且默许输出和输入的都是操纵体系的默许编码,也就是说在newString(bytes[,encode])中,体系以为输出的是编码为encode的字撙节,换句话说,假如按encode来翻译bytes才干失掉准确的了局,这个了局最初要在JAVA中保留,它仍是要从这个encode转换成Unicode,也就是说有bytes-->encode字符-->Unicode字符的转换;而在String.getBytes([encode])中,体系要做一个Unicode字符-->encode字符-->bytes的转换。
在这个例子中,除谁人英文窗口编码的时分除外,实在情况下默许编码都是GBK(在本例中,我们临时把GBK和GB2312同等对待)。
2.4)因为在未指明在下面的两个用代码完成的转换中,假如未指定encode,体系将接纳默许的编码(这里为GBK),我们以为下面的5,6,7和8,9,10是一样的,8和9、11和12也是一样的,以是我们在会商中将只会商1,9,10,12,13。个中的2,3,4只是用于测试,不在我们的会商局限以内。
2.5)上面我们来跟踪程序中的“中”字的转换过程,我们先说在中文窗口下作的编译和运转历程,注重鄙人面的字母下标中,我无意识地利用了一些数字,以暗示不异,相异仍是相干2.5.1)我们先以下面的13个代码段中的的代码9为例:
步骤内容地址申明
01:C1HelloWorld.javaC1泛指一个GBK字符
02:U1JAVAC读取U1泛指一个Unicode字符
03:C1getBytes()第一步JAVA先和操纵体系交换
04:B1,B2getBytes()第二步然后前往字节数组
05:C1newString()第一步JAVA先和操纵体系交换
06:U1newString()第二步然后前往字符
07:C1println(String)能显现“中”字,内容和本来的不异
2.5.2)然后再以代码段10为例,我们注重到只是:
步骤内容地址申明
01:C1HelloWorld.javaC1泛指一个GBK字符
02:U1JAVAC读取U1泛指一个Unicode字符
03:C1getBytes()第一步JAVA先和操纵体系交换
04:B1,B2getBytes()第二步然后前往字节数组
05:C3,C4newString()第一步JAVA先和操纵体系交换,这时候剖析毛病
06:U5,U6newString()第二步然后前往字符
07:C3,C4println(String)因为中字给分红了两半,在ISO8859_1中恰好也没有字符
能映照上,以是显现为“??”。在下面的示例中,
“中文”两个字就显现为“????”
2.5.3)在完整中文形式下的别的情况相似,我就未几说了
2.6)我们接着看为何在西文DOS窗口下编译出来的类在中文窗口下也呈现相似情况,出格是为何竟然有的情况下还能准确显现汉字。
2.6.1)我们仍是先以代码段9为例:
步骤内容地址申明
01:C1C2HelloWorld.javaC1C2分离泛指一个ISO8859_1字符,“中”字被拆开
02:U3U4JAVAC读取U1U2泛指一个Unicode字符
03:C5C6getBytes()第一步JAVA先和操纵体系交换,这时候剖析毛病
04:B5B6B7B8getBytes()第二步然后前往字节数组
05:C5C6newString()第一步JAVA先和操纵体系交换
06:U3U4newString()第二步然后前往字符
07:C5C6println(String)固然同是两个字符,但已不是最后的“两个ISO8859_1字
符”,而是“两个BGK字符”,“中”显现成了“??”
而“中文”就显现成了“????”
2.6.2)上面我们以代码段12为例,由于它能准确显现汉字
步骤内容地址申明
01:C1C2HelloWorld.javaC1C2分离泛指一个ISO8859_1字符,“中”字被拆开
02:U3U4JAVAC读取U1U2泛指一个Unicode字符
03:C1C2getBytes()第一步JAVA先和操纵体系交换(注重仍是准确的哦!)
04:B5B6getBytes()第二步然后前往字节数组(这是很关头的一步!)
05:C12newString()第一步JAVA先和操纵体系交换(这是更关头的一步,JAVA已晓得B5B6要剖析成一个汉字!)
06:U7newString()第二步然后前往字符(真是一个项两!U7包括了U3U4的信息)
07:C12println(String)这就本来的“中”字,很冤枉被JAVAC冤枉了一回,不外被程序员拨乱归正了一下!固然,“中文”两个字都能准确显现了!
3)那为何有的时分用JDBC的
newString(Recordset.getBytes(int)[,encode])
Recordset.getSting(int)
Recordset.setBytes(String.getBytes([encode]))
和
Recordset.setString(String)
的时分会呈现乱码了呢?
实在成绩就呈现在编写JDBC的的也思索了编码成绩,它从数据库读取数据后,大概自作主意做了一个从GB2312(默许编码)到Unicode的转换,我的这个WebLogicForSQLServer的JDBCDriver就是如许的,当我读字串的时分,收回读到的不是准确的汉字,可爱的是我却能够间接写汉字字串,这让人几有点难以承受!
也就是说,我们不能不在读或写的时分举行转码,只管这个转码有的时分不是那末分明,这是由于我们利用了默许的编码举行转码。JDBCDriver所做的操纵,我们只要进进到源代码外部才干分明,不是吗?
再说第三点:我并没有提到服务器也要整合,然后是IDE,一个好的IDE能够200%提高开发的速度,就说图形方面:你是经过简单托拽和点击就能实现功能好那。 |
|