关于String

本文探讨了Java中String类的常用方法,如length()与getBytes().length的区别,特别是处理中文字符时的不同表现。同时介绍了如何安全地转换对象为字符串,以及判断字符串是否为空的有效方式。

转自:http://hi.baidu.com/nemolfairy/blog/item/efb847f63e4528e57709d76b.html

今天看SqlAction中,发现了这么两行代码:

byte []buf = colName.getBytes();    String len = String.valueOf(buf.length);

其中,colName是String类型。当时我就在想为什么不直接用colName.length()呢?哦,对了,length()返回的整型,而上面的len是String类型的。原来,这儿String.valueOf是将int转化为String类型的。

那么这个参数与toString()方法有什么区别呢?

String.valueOf(Object)的基础是Object.toString()。但它与Object.toString()又有所不同。使用Object.toString()时需保证不为null。但采用String.valueOf(Object)时,将不用担心object是否为null值这一问题。为了便于说明问题,分析一下相关的源代码。Jdk里String.valueOf(Object)源码如下:  

     public static String valueOf(Object obj) {

        return (obj == null) ? "null" : obj.toString();
     }

从上面的源码可以很清晰的看出null值不用担心的理由。但是,这也恰恰有了隐患。应当注意到,当object为null时,String.valueOf(object)的值是字符串"null",而不是null 。在使用过程中切记要注意。试想一下,如果用


if(String.valueOf(object)==null)
{
       System.out.println("传入的值是null!");
}


这样的语句将可能会发生什么问题。再想一下,向控制台输出时,在视觉上如下语句在执行的结果上有什么不同:


System.out.println(String.valueOf(null));
System.out.println(null);


可以看到的输出将是一模一样的东西:null,但它们意义很明显是不一样的。

 

判断一个字符串为空

s为一个字符串,判断它为空的方法:
if(null==s ||"".equals(s)){
      ......
}

注意:这里的null==s和"".equals(s)不要写成s==null和s.equals(s),因为""这个值是已经确定的,预知的,而s是未知的,所以用得不小心的时候s.equals("")就会出现nullpoint异常。不一定的equals方法,包括其它很多处理,如果用确定的值处理问题会比未确定的处理少很多bug。

那么String.length()和String.getBytes().length有什么区别呢?

"ABCD".length() 结果是 4
"ABCD".getBytes().length 的结果也是4


不过如果换成中文就不一样了


"你好".length() 结果是 2
"你好".getBytes().length 的结果是4

还没完,需要补充,哈哈,看来小问题看出大文章来了,这与编码是有关系的,不是那么绝对的事情。

"张某某".getBytes("utf-8").length = 9
"张某某".getBytes("GBK").length = 6
"张某某".getBytes("ISO8859-1").length = 3
"张某某".getBytes().length = 6       //在windows中文版上运行
"张某某".getBytes().length = 3       //在SCO UNIX上运行

### Java 中关于 String 的常见面试题 #### 1. **String 是不可变的吗?** 是的,`String` 在 Java 中是不可变的。一旦创建了一个 `String` 对象,其内容就不能更改[^2]。每次修改字符串的操作实际上都会返回一个新的 `String` 实例。这种特性有助于线程安全以及缓存哈希值等功能。 #### 2. **String str1 = "abc"; 与 String str1 = new String("abc"); 的区别是什么?** 使用 `"abc"` 方式定义的字符串会被直接存储在字符串常量池中;而通过 `new String("abc")` 创建的对象则是显式地分配内存空间,在堆区生成新的对象实例[^1]。这意味着即使两个字符串具有相同的字符序列,只要一个是通过 `new` 关键字构建出来的,那么它们就不会共享同一个引用地址。 #### 3. **如何判断两个字符串是否相等?** 判断两个字符串的内容是否一致应当使用 `equals()` 方法而不是 `==` 操作符。后者仅用于比较两者的引用地址是否相同即是否指向同一块实际存在的数据区域。例如: ```java String s1 = "hello"; String s2 = "hello"; System.out.println(s1 == s2); // true (因为s1和s2都指向字符串常量池中的"hello") String s3 = new String("hello"); System.out.println(s1.equals(s3)); // true (内容相同) System.out.println(s1 == s3); // false (不同对象) ``` #### 4. **什么是字符串驻留(Interning)?** 字符串驻留是指当 JVM 加载某个类时会将其中出现过的所有字符串文字放到一个特殊的内存区域——字符串常量池中去管理[^4]。对于任何新产生的字符串如果发现已有匹配项存在于该表之内则不再重复制造而是重用已有的那个副本。可以通过调用 `intern()` 来强制让某特定字符串进入这个优化结构当中。 #### 5. **replace() 函数有哪些重载形式及其作用分别是什么?** 存在两种主要形式的替换方法:一种是以单个字符为目标进行置换(`char oldChar, char newChar`);另一种允许更灵活地指定子串作为目标来进行整体替换成另一段文本 (`CharSequence target, CharSequence replacement`)[^3]。如下所示: ```java String originalStr = "Hello world!"; // 单字符替换 String resultSingleCharReplace = originalStr.replace('l', 'x'); // 输出:"Hexxo worxd!" // 整体字符串替换 String resultWholeWordReplace = originalStr.replace("world", "Java"); // 输出:"Hello Java!" ``` --- ### 总结 通过对这些经典问题的学习可以帮助求职者深入理解 Java 编程语言的核心概念之一 —— `String` 类型的工作机制及其背后涉及的一些重要理论依据如可变性、内存布局规划等方面的知识点[^2][^3][^4]。掌握这些问题不仅能提高个人技术水平还能增加面对技术筛选环节的信心水平。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值