[JavaSE] 认识String类 (equals、null、““)
目录
- String补充用法
-
- equals
- null 与 " "
- 字符串不可变?(反射)
String补充用法
上一篇文章我们详细比较了 String 的内存,但是我们大部分使用 String 都是比较内容,那么我们应该怎么做呢?其实很简单,比较内容我们只需要比较哈希值就行啦,或者用 equals方法比较字面值。
equals
用法:比较字面值
public static void main(String[] args) { String str1="12"; String str2="12"; System.out.println(str1.equals(str2)); }//true
注意: 比较前后关系
public static void main(String[] args) { String str1="12"; String str3=null; System.out.println(str3.equals(str1)); }//Exception in thread "main" java.lang.NullPointerException
这样写就歇菜了,引用值不能为null,接着互换位置
public static void main(String[] args) { String str1="12"; String str3=null; System.out.println(str1.equals(str2)); }//false
这样就没问题了!
null 与 " "
再来说一个大家容易忽略的问题
public static void main(String[] args) { String str1="";//str1这个引用指向的字符串是空的 String str2=null;//str2这个引用不指向任何对象 System.out.println(str1.equals(str2)); }//false
结合上面的 equals 例子我们可以知道这样的写法不会报错,因为 str1 的指向是空不是null;
对参数为空判断,大家有没有注意过这种写法
public static void func(String s) { //正确 if(s == null || s.length()==0){ System.out.println("参数不能为空!"); } }
现在做一个更改
public static void func(String s) { //错误 if(s.length()==0 || s==null){ System.out.println("参数不能为空!"); }
这样就不对了,如果 s 为null,那么它是没有长度的,妥妥的给你报空指针异常!
字符串不可变?(反射)
String可以重新定义吗?
我们先来看一个案例,更改int[] 的值
public static void main(String[] args) {//数组的整体赋值只有一次机会,就是在定义的时候final int[] array = {1,2,3,4,5};array = new int[]{4,5,6,7,8};}
答案很显然不行,因为被 final 修饰了
再来看这个例子,我们做到吗?改变value值
public static void main(String[] args) {String s1="12";String s1="11";}//这种写法不可以,这是改变指向
那么我可以通过 对象.value 来修改呢?也不可以,因为源码中是私有的,图片上一篇里有。
那么也做不到吗?其实可以做到,用反射!
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {String s1="12";Class<?> c1 = String.class;// 获取 String 类中的 value 字段,这个 value 和 String 源码中的 value 是匹配的Field valueField = c1.getDeclaredField("value");// 将这个字段访问权限设为 truevalueField.setAccessible(true);// 把 str 中的 value 属性获取到char[] value = (char[]) valueField.get(s1);//修改value[0]的值value[0] = 'h';System.out.println(s1); }
对于这块内容的话 Nick 会在Java进阶中详细的讲,这里稍作了解哈~
为什么 String 要不可变?(不可变对象的好处是什么?)
- 方便实现字符串对象池. 如果 String 可变, 那么对象池就需要考虑何时深拷贝字符串的问题了.
- 不可变对象是线程安全的.
- 不可变对象更方便缓存 hash code, 作为 key 时可以更高效的保存到 HashMap 中.