在 Java 中将 char 表示为一个字节

Posted

技术标签:

【中文标题】在 Java 中将 char 表示为一个字节【英文标题】:Representing char as a byte in Java 【发布时间】:2010-10-16 12:08:55 【问题描述】:

我必须将 char 转换为字节或字节数组。在其他语言中,我知道 char 只是一个字节。但是,查看 Java Character 类,它的最小值是 \u0000,最大值是 \uFFFF。这使得 char 看起来像 2 个字节长。

我可以将其存储为一个字节还是需要将其存储为两个字节?

在有人问之前,我会说我正在尝试这样做,因为我正在一个接口下工作,该接口期望我的结果是一个字节数组。所以我必须将我的 char 转换为一个。

请让我知道并帮助我理解这一点。

谢谢, jbu

【问题讨论】:

【参考方案1】:

要将字符转换为字节,您需要指定character encoding。一些字符编码每个字符使用一个字节,而另一些则使用两个或更多字节。事实上,对于许多语言来说,用一个字节编码的字符太多了。

在Java 中,将字符转换为字节的最简单方法是使用String 类的getBytes(Charset) 方法。 (StandardCharsets 类定义了一些常见的编码。)但是,如果字符无法在指定的编码下映射,此方法将默默地用 � 替换字符。如果您需要更多控制,可以配置CharsetEncoder 来处理这种错误情况或使用不同的替换字符。

【讨论】:

使用 UTF-8 并将我的字符存储为单个字节可以吗?我想是的,即使最后一位是一个字节的符号位。 您应该使用您正在工作的界面要求的字符编码。 对于单字节编码,使用 ISO-8859 系列 不,如果您使用的是 UTF-8,并且有任何非 ASCII 字符(char 值 > 127),您应该使用编码 API 转换为字节。非 ASCII 字符在 UTF-8 中需要两个或更多字节。如果您只是将 128-255 范围内的字符转换为字节,则会解码错误的字符。 使用“这个字符串”.getBytes("utf-8");【参考方案2】:

java 中的 char 是一个无符号的 16 位值。如果您拥有的内容适合 7 位,那么只需转换为一个字节(例如 ASCII 适合)。

您也可以查看java.nio.charset API。

【讨论】:

【参考方案3】:

为了扩展其他人的说法,如果您有一个需要作为字节数组的字符,那么您首先创建一个包含该字符的字符串,然后从字符串中获取字节数组:

private byte[] charToBytes(final char x) 
  String temp = new String(new char[] x);
  try 
    return temp.getBytes("ISO-8859-1");
   catch (UnsupportedEncodingException e) 
    // Log a complaint
    return null;
  

当然,使用适当的字符集。效率更高的是开始使用字符串,而不是一次获取一个字符,转换为字符串,然后再转换为字节数组。

【讨论】:

【参考方案4】:

一个 char 在 Java 中确实是 16 位的(也是唯一的无符号类型!!)。

如果您确定字符的编码是 ASCII,那么您可以将它们丢弃在一个字节上(因为 ASCII 仅使用字符的低 7 位)。

如果您不需要修改字符,或了解它们在字符串中的含义,您可以将字符存储在两个字节上,例如:

char[] c = ...;
byte[] b = new byte[c.length*2];
for(int i=0; i<c.length; i++) 
    b[2*i] = (byte) (c[i]&0xFF00)>>8; 
    b[2*i+1] = (byte) (c[i]&0x00FF); 

(如果速度很重要,建议将 2* 替换为右移)。

但是请注意,一些实际(显示的)字符(或更准确地说,Unicode 代码点)写在两个连续的字符上。因此,在两个字符之间进行剪切并不能确保您在实际字符之间进行剪切。

如果您需要以可识别字符串的方式解码/编码或以其他方式操作您的 char 数组,您应该尝试使用 java.io 工具对您的 char 数组或 String 进行解码和编码,以确保正确的字符操作。

【讨论】:

不使用此处显示的代码,而是指定“UTF-16”作为字符编码并使用内置编码 API。更少的代码让您实现、测试和维护,并为代码读者更清楚地捕捉意图。 速度也降低了两个数量级,因为在这种情况下可能不需要编码/解码。 它只是编码,如果它更慢(我怀疑),它不是 100 倍。为什么你认为 UTF-16 编码与你的代码有很大不同?跨度> 因为我已经阅读了 Sun 的代码,而且它使用的是整个 nio 机器,速度明显慢。基准测试后,实际系数在 30 到 50 之间(是的,对于我的应用程序来说,这很重要)。 哦,我忘了提...解码器不是线程安全的。但那是另一回事了……

以上是关于在 Java 中将 char 表示为一个字节的主要内容,如果未能解决你的问题,请参考以下文章

Java中为什么可以用一个char(两个字节)表示一个中文字符

在Java中将字节大小转换为人类可读的格式?

如何在 C# 中将固定字节/字符 [100] 转换为托管字符 []?

char和varchar的区别

byte怎么转换为char

java 详细介绍short,byte,char三种类型,我分不清