Java 常识(011):聊聊Java字符串String的那些事

版权声明:本文为博主原创文章,转载请注明出处 https://blog.csdn.net/u010647035/article/details/87479286

1、String 为什么被定义为不可变?

详见:https://blog.csdn.net/u010647035/article/details/87473542

2、String 字符串创建有哪些方式?区别是什么?

详见:https://mp.csdn.net/mdeditor/87477876#

3、String 字符串编码如何转换?

String s1 = "Hello World";
String s2 = new String(s1.getBytes("GB2312"), StandardCharsets.ISO_8859_1);

4、String、StringBuffer、StringBuilder 的区别是什么?

详见:https://blog.csdn.net/u010647035/article/details/80343693

String 是字符串常量,StringBuffer 和 StringBuilder 都是字符串变量,后两者的字符内容可变,而前者创建后内容不可变;

StringBuffer 是线程安全的,而 StringBuilder 是非线程安全的,线程安全会带来额外的系统开销,所以 StringBuilder 的效率比 StringBuffer 高;

String 的每次修改操作都是在内存中重新 new 一个对象出来,而 StringBuffer、StringBuilder 则不用,且提供了一定的缓存功能,默认 16 个字节数组的大小,超过默认的数组长度时扩容为原来字节数组的长度 * 2 + 2,所以使用 StringBuffer 和 StringBuilder 时可以适当考虑下初始化大小,以便通过减少扩容次数来提高代码的高效性。

5、如何判断两个String是否相等?

有两种方式判断字符串是否相等,使用"“或者使用equals方法。当使用”"操作符时,不仅比较字符串的值,还会比较引用的内存地址。大多数情况下,我们只需要判断值是否相等,此时用equals方法比较即可。

还有一个equalsIgnoreCase可以用来忽略大小写进行比较。

String s1 = "abc";
String s2 = "abc";
String s3= new String("abc");
System.out.println("s1 == s2 ? "+(s1==s2)); //true
System.out.println("s1 == s3 ? "+(s1==s3)); //false
System.out.println("s1 equals s3 ? "+(s1.equals(s3))); //true

6、Java 中如何判断一个字符串只包含大写字母

此方法循环遍历字符串中的每个字符,并使用 java.lang.Character#isUpperCase() 判断每个字符是否为大写。

public static boolean testAllUpperCase(String str) {
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            if (!Character.isUpperCase(c)) {
                return false;
            }
        }
        return true;
    }

7、为什么针对安全保密高的信息,char[] 比 String 更好?

String 是不可变的,一旦创建就不能更改,直到垃圾收集器将它回收才能消失,即使我们修改了原先的变量,实际上也是在内存中新建一个对象,原数据还是保留在内存中等待回收。

字符数组 char[] 中的元素是可以更改的,也就是说像密码等保密信息用完之后我们可以马上修改它的值而不留痕迹,从而相对于 String 有更好的安全性。

范式涉及到安全性的问题就是一个敏感的话题,这里我们看一下大牛们的讨论:
https://www.zhihu.com/question/36734157/answer/68767786

FAQ======================

  1. 这种做法意义有多大?

如果没有及时清空而由GC来清除的话,暴露窗口大约是秒这个数量级,如果能够在计算HASH后立即清除,暴露窗口大约是微秒数量级。如此简单的设计就可以降低如此多的被攻击概率,性价比是非常高的。

  1. 如何使用反射来修改String? 和修改char[] 相比,有何区别和风险?

通过reflection机制可以查看String的内部的内存成员,从而可以直接修改其中的数据区。但是这样的做法会有问题,内部化的String为了提高HASH速度,节省空间,值相同的字符串通常只有一个实例。你自己的char[],修改它是没有副作用的。但是String里的char[],很可能是多个String所共享的,你改掉它就会殃及别的String。举个例子,有一个密码是"Password",而你密码框提示密码输入的文字也是"Password",改掉第一个"Password"会把后面那个也改掉。

  1. 如果一点明文也不想出现,应该怎么做?

为了保证“全部处理流程均无明文密码”,需要底层API在给你密码之前就做了HASH,并且这个HASH算法就是你想要的那种。最好还加盐。不过这只是在用户程序方面无明文,底层获取中会不会有明文就保证不了了。

  1. 有没有绝对安全策略?

安全往往是相对于攻击成本而言的,攻击收益越高,黑客就越能接受攻击成本高的方案。因此,你采取的安全策略应该与这个攻击收益相匹配。对于极其敏感和宝贵的数据来源,就需要在安全方面上下很大功夫。目前来看,没有绝对的安全,只有相对的安全。

猜你喜欢

转载自blog.csdn.net/u010647035/article/details/87479286
今日推荐