关于String的六个问题?

604 阅读3分钟



1:String的长度是否有限制?

String在编译时期 长度为超过65534 就会报


原因:String在编译期最大长度是 65534个 因为 它数据表是CONSTANT_urf8_info格式 他所能代表的长度是u2类型的长度 所以65536个 由于有两个字节需要存储null 故而65536-2等于65534 所以当我们在编译时 输入超过65534个字符时 会出现编译失败


而 String在运行期 他的源码中 长度使用int count 来表示 int的最大值 是Integer.MAX_VALUE 故而在运行时 长度最长可以是Integer.MAX_VALUE ===2147483647



2:如何让String显示出大于65534个字符呢?

解决方法: 由于编译器 和 运行期长度不一样 且 运行期的长度超过该65534个限制 我们可以从运行期思路入手
1:通过拼接字符串的方法: 创建两个字符串长度为上限值 相加


2:通过读取文件方法:通过运行时 读本地文件将文件读取出来


3:通过StringBuilder 和 Stringbuffer 等动态添加




3:equals是什么?为什么这样重写?


equals时Object类的方法 该方法默认用 == 来判断两个对比数据是否是同一个对象
在String中 Java重写了 这个方法 具体看看源码就知道如何进行字符串对比了:

public boolean equals(Object anObject) { 
if (this == anObject) {
///先用== 判断两个是否是同一个对象 
return true;
 }
 if (anObject instanceof String) {
///判断是否是 String 类型 不是的话 就直接return false
 String anotherString = (String)anObject;
///进行转换
 int n = value.length;
///获取当前String 的长度 
if (n == anotherString.value.length) {
///如果两个长度不相等 肯定不是同一个字符
 char v1[] = value;
///如果两个长度相等 进行遍历 判断两个字符串的每个字符是否相等
 char v2[] = anotherString.value; 
int i = 0; while (n-- != 0) { 
if (v1[i] != v2[i])///遍历到某一个不相等说明 两个字符串不相等
 return false; i++;
 }
 return true;
 } 
}
 return false;
 }



4:String 可以改变吗?


很明确的说 String是不能改变的类 为什么呢?

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
        private final char value[];
        }
敲黑板 记住这个final 要考!
final:被final关键字 定义的 类 不可以被继承 final定义的方法 不能被子类覆盖重写 final定义的变量 不可以被修改

所以从上面可以知道 String是不可以被修改

5:为什么要把String设计成不可变

可以看看知乎:www.zhihu.com/question/20… 前几个回答都非常好


6:String 变的到底是啥?

String s="123";
System.out.println(s);
s="456";
System.out.println(s);


输出结果:123
        456
??????不是不可变吗?
为什么这里又变了?骗人?
其实是因为 字符串池 ( StringPool) 这个东西 这个又是啥? 其实他是虚拟机维护一块空间 主要是为了避免字符串大量重建是 造成的开销。
而当我们用 

String s="123";

 这种写法 创建字符串时 虚拟机 会在这个空间 查找是否有相同的内容 如果有 就把当前 s 引向这个地址 如图:


直接指向池中的 “123”
当我们 执行 s="456"时


s又会去指向 456 这个时候 它在String pool中的引用变了 所以 会打印出 456
同时 也真是因为如此 Java 工程师在重写 String的equals方法时 第一个判断会先判断内存地址是否相同 因为有可能会出现 两个String 引用同一个地址的情况