String.getBytes()和new String()

在Java中,String.getBytes(String decode)方法会根据指定的decode编码返回某字符串在该编码下的byte数组表示,如

byte[] b_gbk = "中".getBytes("GBK");
byte[] b_utf8 = "中".getBytes("UTF-8");
byte[] b_iso88591 = "中".getBytes("ISO8859-1");

将分别返回“中”这个汉字在GBK、UTF-8和ISO8859-1编码下的byte数组表示,此时b_gbk的长度为2,b_utf8的长度为3,b_iso88591的长度为1。

而与getBytes相对的,可以通过new String(byte[], decode)的方式来还原这个“中”字时,这个new String(byte[], decode)实际是使用decode指定的编码来将byte[]解析成字符串。

String s_gbk = new String(b_gbk,"GBK");
String s_utf8 = new String(b_utf8,"UTF-8");
String s_iso88591 = new String(b_iso88591,"ISO8859-1");

通过打印s_gbk、s_utf8和s_iso88591,会发现,s_gbk和s_utf8都是“中”,而只有s_iso88591是一个不认识 的字符,为什么使用ISO8859-1编码再组合之后,无法还原“中”字呢,其实原因很简单,因为ISO8859-1编码的编码表中,根本就没有包含汉字 字符,当然也就无法通过"中".getBytes("ISO8859-1");来得到正确的“中”字在ISO8859-1中的编码值了,所以再通过new String()来还原就无从谈起了。

因此,通过String.getBytes(String decode)方法来得到byte[]时,一定要确定decode的编码表中确实存在String表示的码值,这样得到的byte[]数组才能正确被还原。

有时候,为了让中文字符适应某些特殊要求(如http header头要求其内容必须为iso8859-1编码),可能会通过将中文字符按照字节方式来编码的情况,如

String s_iso88591 = new String("中".getBytes("UTF-8"),"ISO8859-1"),这样得到的s_iso8859-1字符串实际是三个在 ISO8859-1中的字符,在将这些字符传递到目的地后,目的地程序再通过相反的方式String s_utf8 = new String(s_iso88591.getBytes("ISO8859-1"),"UTF-8")来得到正确的中文汉字“中”。这样就既保证了遵守协 议规定、也支持中文。

### Java 中处理字符串变量 `s` 为空时调用 `getBytes()` 方法引发的空指针异常 当字符串变量 `s` 的值为 `null` 并尝试调用其方法(如 `getBytes()`),将会抛出 `NullPointerException`。为了避免这种情况发生,可以在执行操作前检查字符串是否为 `null` 或者使用一些工具类来简化这一过程。 以下是几种常见的解决方案: #### 解决方案一:显式检查 `null` 通过在调用 `getBytes()` 前增加对 `s` 是否为 `null` 的判断,可以有效防止空指针异常的发生。 ```java if (s != null) { byte[] bytes = s.getBytes(); } else { // 处理 s 为 null 的情况 } ``` 这种方法简单直观,适用于大多数场景[^1]。 --- #### 解决方案二:使用三元运算符提供默认值 如果希望即使 `s` 为 `null` 也能返回一个合理的字节数组,默认情况下可将其设置为空数组或其他预定义值。 ```java byte[] bytes = (s == null ? "".getBytes() : s.getBytes()); ``` 此方式利用了三元表达式的简洁特性,在保持代码清晰的同时避免了潜在的错误[^3]。 --- #### 解决方案三:借助 Apache Commons Lang 库中的 StringUtils 类 Apache Commons 提供了一个非常方便的方法——`StringUtils.defaultIfNull(String str, String defaultStr)` 来替代手动编写逻辑。它允许开发者指定当输入参数为 `null` 时应采用何种备用值。 ```java import org.apache.commons.lang3.StringUtils; String safeS = StringUtils.defaultIfBlank(s, ""); byte[] bytes = safeS.getBytes(); ``` 上述例子展示了如何引入外部库以增强程序健壮性减少重复编码的工作量[^2]。 --- #### 解决方案四:Java 8 Optional API 自 JDK 8 开始新增加的功能之一就是 `Optional<T>` 容器类,旨在鼓励程序员更早考虑可能存在的缺失数据情形。下面是如何运用它的示范: ```java import java.util.Optional; public class Main { public static void main(String[] args) { String s = null; Optional<String> optionalS = Optional.ofNullable(s); byte[] bytes = optionalS.orElse("").getBytes(); System.out.println(new String(bytes)); } } ``` 这种方式强调函数式编程风格并减少了传统防御性编程带来的冗余语句数量。 --- ### 总结 以上介绍了四种不同的策略用于应对因字符串对象设定了非法状态而产生的运行期崩溃风险。每种都有各自的优势以及适用范围,请依据具体需求选取最合适的那一种实现形式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值