« | October 2025 | » | 日 | 一 | 二 | 三 | 四 | 五 | 六 | | | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | | |
| 公告 |
戒除浮躁,读好书,交益友 |
Blog信息 |
blog名称:邢红瑞的blog 日志总数:523 评论数量:1142 留言数量:0 访问次数:9719727 建立时间:2004年12月20日 |

| |
[java语言]String(byte[] ascii, int hibyte)一个不应存在的构造函数  原创空间, 软件技术, 电脑与网络
邢红瑞 发表于 2007/4/18 13:44:46 |
我一般不愿意谈java底层的问题,正好好友xf所说,那是一滩烂泥,意思很明确,首先你不知道里面有什末,不知深浅,再者一脚踩下去,就很难脱身了。最近写一个applet通讯程序,其实很简单,就是通过socket把服务器的一些信息,收集到本地。因为在客户端执行,使用MS JVM不涉及编码问题。可是偏偏出现编码问题。问题出在这里,将把服务器传过来的字节流转为String时,一位国外的仁兄,使用String tmp = new String(tio.receive(), 0);这个函数作了和tomcat一样的事情,把GBK编码转为了ISO-8859-1编码。这个函数sun的文档说得清楚, 已过时。 该方法无法将字节正确转换为字符。从 JDK 1.1 起,完成该转换的首选方法是通过 String 构造方法,该方法接受一个字符集名称或使用平台的默认字符集。既然这样,这是个bug,就应该fix。如果函数就是设计错了,就应该抹去,因为你的JVM只加载1.1以后的java类。大家从这里可以看到:如果版本号超过了JVM的所能处理的有效范围,JVM不处理该文件。看一下jvm的源文件ClassFileParser.cpp,我原来认为java用c写成的,现在发现是c++的杰作。jdk 1.5的源文件#define JAVA_CLASSFILE_MAGIC 0xCAFEBABE#define JAVA_MIN_SUPPORTED_VERSION 45#define JAVA_MAX_SUPPORTED_VERSION 49#define JAVA_MAX_SUPPORTED_MINOR_VERSION 0
// Used for two backward compatibility reasons:// - to check for new additions to the class file format in JDK1.5// - to check for bug fixes in the format checker in JDK1.5#define JAVA_1_5_VERSION 49jdk 1.6的源文件#define JAVA_CLASSFILE_MAGIC 0xCAFEBABE#define JAVA_MIN_SUPPORTED_VERSION 45#define JAVA_MAX_SUPPORTED_VERSION 50#define JAVA_MAX_SUPPORTED_MINOR_VERSION 0
// Used for two backward compatibility reasons:// - to check for new additions to the class file format in JDK1.5// - to check for bug fixes in the format checker in JDK1.5#define JAVA_1_5_VERSION 49
// Used for backward compatibility reasons:// - to check for javac bug fixes that happened after 1.5#define JAVA_6_VERSION 50
45就是jdk5和jdk6支持的最早的java类,也就是jdk1.1,既然知道在发布jdk1.1之前就知道,这个方法有问题,就完全可以抹去这个方法。因为即使有人在jdk1.0中使用这个方法,后续的JVM也不支持的,真是搞不懂sun的意图。以后还有更有意思的,既然编码被转了,我们使用tomcat下程序员使用的常用手法转回来,s = new String(s.getBytes("ISO-8859-1"), "GBK");这个方法要抛出UnsupportedEncodingException,意思是如果指定的字符集不受支持,如何处理。最近看到程序员杂志说,这个异常永远不会抛出,这句话有问题,在sun的jdk,sun实现所有编码,这个异常永远不会抛出,换个JDK,那就不一定。这个异常在MSJVM下确实抛出了,由于没有写处理的函数,造成了applet无法显示数据,造成了加班。下面代码,在IBM的JDK 1.4.2肯定有问题,抛出java.io.UnsupportedEncodingException: Shift-JIS,最新的IBM J9,已经没有问题。public class Test { public static void main(String[] args) { try { String love=new String("党莹".getBytes("Shift_JIS")); } catch (Exception e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. }
}}原因很简单IBM JDK在编码上和SUN JDK有所区别,如果不信,你用sun的就JDK使用JDBC调用IBM的db2,不出问题就奇怪了。 |
|
|