Java:String的字符值(以字节为单位)是否为常量?

时间:2012-07-24 18:22:21

标签: java character-encoding char byte

TL; DR :在Java中,将通过charAt方法从字符串获取的字符转换为字节总是产生相同的值?

我正在阅读用任意(我们未知)字符编码编码的文件。我需要解析这些文件并查找某些单词,例如“标签”。我对文件内容设置了一些限制,例如“在查找标签时,”TAG“的字节必须与它们的ASCII表示相同”。

例如,假设我有以下文件:
0x00 0x11 0x22 0x33 0x54 0x41 0x47 0x77 0x88 0x99 0xaa 0xbb
由于T,A和G的ASCII值分别为0x540x410x47,我可以通过解析字节本身在文件中找到“TAG”。
0x00 0x11 0x22 0x33 0x54 0x41 0x47 0x77 0x88 0x99 0xaa 0xbb

但是,我需要硬编码我要查找的字节的值。为此,我调用String的{​​{1}}方法并将char转换为一个字节
例如,我将如何验证“T”字节表示的任意字节(称为charAt(int i)):
b
String tag = "TAG";
char t = tag.charAt(0);
if ((byte)t == b){
//magic goes here, such as comparing the 'A' and the 'G'
注意:代码实际上并非如此,验证算法更加优雅。

这在我的本地机器上工作正常。但是,这将在可能包含非常奇怪的编码的机器上运行。令我担心的是,将}获得的字符转换为字节是否会产生不同的值,具体取决于计算机。我知道Java总是使用UTF-16字符编码对charAt进行编码,但我担心从String转换为字符然后转换为字节可能会产生奇怪的结果。

那么,简而言之,将通过char方法从String获取的字符转换为字节总是产生相同的值?或者它取决于外部因素?

谢谢你的帮助!

注意:我不能对字节本身进行硬编码(例如,在字节数组中),因为它们可能非常长并且将来可能会经常更改。

4 个答案:

答案 0 :(得分:3)

java.lang.string.charAt将始终返回一个16位UTF-16字符,当你将其转换为一个字节时,它总是相同的,尽管因为char是一个16位无符号数据类型,所以它作为8位签名byte可能会给您带来不必要的行为。但是,如果您的源数据是ASCII,您将获得您期望的行为类型。

答案 1 :(得分:2)

charAt (int)返回Java定义的char类型(UTF-16),因此始终与byte相同。

相反,String.getBytes()根据指定的字符集或操作系统的默认字符集(如果未指定)返回字节。

答案 2 :(得分:0)

使用(byte)将字符转换为字节将在所有系统上提供相同的结果。

但是,您需要混合使用charbyte。你应该真的使用其中一个。混合这些概念会导致你怀疑的混乱。

答案 3 :(得分:0)

您可以使用Character.codePointAt(char c)方法,而不是直接对它们进行类型转换。这应该保证每次都有相同的结果。