1.String源码解析

1.不变性
这里说的不变性指的是类值一旦被初始化,就不能再被改变了,如果被修改,将会是新的类,如程序1-1所示。

//程序1-1
public class App {
    public static void main(String[] args)  {
        String str = "hello steven";
        System.out.println(str);
        str = "hello mike";
        System.out.println(str);
    }
}

从代码上来看,str的值好像由"hello steven"被修改为"hello mike",但从debug的日志来看,其实是str的内存地址被修改了。也就说str="hello mike"这个看似简单的赋值,其实已经把str的引用指向了新的String,debug的截图如下所示,str的内存地址已经由507被修改为509。
在这里插入图片描述
在这里插入图片描述
源码

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** 该值用于字符存储。*/
    private final char value[];
}

源码解析

  1. String被final关键字修饰,说明String类绝不可能被继承,也就是说任何对String的操作方法,都不会被继承或覆写;
  2. String中保存数据的是一个char型数组value,value也是被final修饰的,也就是说value一旦被赋值,内存地址便无法修改。此外,value的权限修饰符是private,外部不可访问,并且String也没有开放出可以对value进行赋值的方法,所以说 value一旦产生,内存地址就无法修改。

总结
在自定义类时,如果希望类是不可变的,可以参考String类的源码,充分利用final关键字的特性。

2.相等判断
源码

public boolean equals(Object anObject) {
    //判断内存地址是否相同
	if (this == anObject) {
	    return true;
	}
	//判断待比较的对象是否是String类型,如果不是直接返回不相等
	if (anObject instanceof String) {
	    String anotherString = (String)anObject;
	    int n = value.length;
	    //判断两个字符串的长度是否相等,不等则直接返回不相等
	    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;
}

源码解析
首先判断两个String的内存地址是否相等,如果相等则两者相等,如果不相等则判断两者长度,长度不一则不相等,否则就挨个比较char数组中的字符是否相等。

总结
判断两者是否相等,需要从两者的底层结构出发,首先判断两者内存地址是否相同,如果相同则两者相等。如果不相等,则继续判断两者的值是否相等。

发布了46 篇原创文章 · 获赞 0 · 访问量 772

猜你喜欢

转载自blog.csdn.net/Jgx1214/article/details/105424825