java出现string无法转换 java为何会出现string无法转换_java string数组转string

Java-String

1. 导读

String类也是日常开发中经常用到的类, 今天主要分享下我在看String源码时想到的4个问题:

1.1 String为什么是不可变的; 为什么要设计成不可变的;

1.2 hashCode; 为什么是31;

2. String为什么是不可变的;

public final class String
implements java.io.Serializable, Comparable, CharSequence {
/** The value is used for character storage. */
private final char value[];

这是String源码的前三行代码, 这三行代码给出四个关键信息:

.1 String类是被final修饰的, 不可被继承;

.2 String字符串的底层实现是基于char数组的;

.3 char数组也是被final修饰的, 他的引用是不可被修改的;

.4 value[]被private修饰, 寻遍整个String类, 没有提供value[]公共的getter 和 setter方

法, 那么他的值是不可被外部修改的;

基于以上四点, 我们可以找到String是不可变的原因: String类不可被继承, 那么就不存在引用到

StringChild这种子类, 换言之任何一个声明的String类型引用, 他引用到的对象一定是String对象, 而

不会是其他对象;

当一个String对象被创建时, 其底层的value[]被赋值, 被final修饰, 其引用始终指向同一个内存地

址, 并且String没有提供修改value的方法, 可以认为value[]数组的值是不可被更改的(如果你非要说通过

反射可以修改, 那我只能说反射这种方式不在正常的考虑范围内);

划重点:

.1 基于String整个类, 被final修饰不可继承, 那么String类就是不可变类;

.2 基于String对象, 底层的value[]被final修饰, 不对外提供修改value[]的方法, value[]引用

不变其值不变, 那么整个String对象也就是不可变的;

3. String为什么设计成不可变

上面说明了为什么String是不可变的, 但是为什么要把String设计成不可变的呢? 说不准有人需要个性化定制呢?

我想了下, String类的作者可能有已下几方面的考虑:

.1 线程安全: 我们都知道因为共享变量可能会被多个线程修改, 会引起线程安全问题, 把String设计成不可变以后, 就不需要考虑多线程的安全性了, 因为每个线程只有读的权限;

.2 关注下源码中的hash:

/** Cache the hash code for the string */

private int hash; // Default to 0

hash的作用是将当前String对象的hash值缓存起来, 因为String是不可变的, 因而缓存的hash也是不变的; 那么把hash起来有啥用呢? 举个HashMap的例子, 当String作为HashMap的key时, 多次调用String::hashCode时, 只会在第一次计算hash, 后面所有的调用都会取这个Key缓存的hash, 大大提高了效率;

.3 在JVM设计时, 对String有个优化处理:设计了一个String常量池, ""声明的String对象会先去常量池寻找, 不存在则放入常量池, 反之则取常量池中的String对象;假设10K个"str"的引用, 不需要在堆中new 10K个String对象, 而只需要将引用指向同一个String对象即可;

String::intern方法做的也是同样的事情, 关于JVM对这种设计的变迁以及优缺点放到分享intern方法时再说;

.4 在使用int时, 我们是去考虑int是否可变的, 因为在设计时, int类型就已经具有了不可变性了,

所以在设计Integer这个封装类时, Integer也被设计成了不可变类(后面会有专门分享, 这里不展开);

而String在java世界中的受欢迎程度和基本数据类型没什么差别, 甚至一些java的底层设计都是基于String的, 比如反射的类路径等等; 而且想像一下前一秒还在对String判空, 下一秒调用时抛出了NPE, 这种时候你会不会问候下String的设计者;

从语言设计层面考虑, String在设计之初就是希望把他当做基本数据类型来使用, 那么不可变性是必须的;

.5 在java的其他设计中也使用了String, 还是拿HashMap举例, 有个节点A的key是"1