0
点赞
收藏
分享

微信扫一扫

关于Java String的一些问题和思考

菜菜捞捞 2022-04-19 阅读 53

1.String 类型不可改变

        String类型是public final class String,而其实现主要是private final char value[],

这里 final 修饰基本数据类型,不可被更改,

修饰引用数据类型不可指向其他对象,

修饰方法,该方法不可被重写,

修饰类,不可被继承。


   public static void main(String[] args) {
        String s1 = "abc";
        String s2 = "abc";
        s1 = "def";
        System.out.println(s1 == s2);
        System.out.println(s1);
        System.out.println(s2);

    }

第一个问题 为什么String不可变,s1却可以被重新赋值?

        主要原因还是String里的final修饰的数组不可指向其他对象,而String类只是不可被继承。仿照String自己实现OOO类。

import java.util.Arrays;
public final class OOO {
	private final char value[];
	public OOO(char[] value) {
		this.value = value;
	}
	@Override
	public String toString() {
		return "OOO{" +
			"value=" + Arrays.toString(value) +
			'}';
	}
}

 

 String代表不可变的字符序列

        当字符串重新赋值,需要重写指定内存区域赋值,不能使用原有的value进行赋值

        当对现有的字符串进行连接操作时,也需要重新指定内存区域赋值,不能对使用原有的value进行赋值

        当调用String的replace方法修改指定字符或字符串时,也需要重新指定内存区域赋值,不能使用原有的value进行赋值。

一道面试题

public class StringTest {
	String str = new String("good");
	char[] ch = {'t', 'e', 's', 't'};
	
	public void change(String str, char ch[]) {
		str = "test ok";
		ch[0] = 'b';
	}
	
	public static void main(String[] args) {
		StringTest ex = new StringTest();
		ex.change(ex.str, ex.ch);
		System.out.println(ex.str);//good
		System.out.println(ex.ch);//best
	}
}

这里char ch[]是一定会变化的,因为Java的值传递。

        对于基本类型 ,赋值运算符会直接改变变量的值,原来的值被覆盖。
        对于引用类型,赋值运算符会改变引用中所保存的地址,原来的地址被覆盖掉。但是原来的对象不会被改变

这里ch[]是引用数据类型,所以是一定会改变的,但如果是下面这样ch[]也是不会改变的。

也就是说 change 方法的参数拷贝的是 ch[](实参)的地址,因此,它和 ch 指向的是同一个数组对象。这也就说明了为什么方法内部对形参的修改会影响到实参。

这里建议观看guide哥 为什么java中只有值传递https://javaguide.cn/java/basis/why-there-only-value-passing-in-java.html#%E6%A1%88%E4%BE%8B2-%E4%BC%A0%E9%80%92%E5%BC%95%E7%94%A8%E7%B1%BB%E5%9E%8B%E5%8F%82%E6%95%B01

今天在看Java设计模式时,在享元模式中,作者说了这样一段

 这也就对应了

举报

相关推荐

0 条评论