String解读

1、String类为什么被final修饰?

主要从两方面考虑,安全性和性能。我们知道String使用频率很高,在多线程环境中,如果String不是被final修饰,那么必须使用锁机制来保证线程的安全性,这样就影响了整个系统的性能;

2、String实例在JVM的位置?

   1)想一下,下面String a ="String"将产生几个对象?

public class StringDemo1 {
	public static void main(String[] args) throws  Exception {		
		String a = "String";	
		CyclicBarrier barrier = new CyclicBarrier(2);
		barrier.await();
	}
}

通过 OQL来查询一下,结果如下:


2)如果使用new String创建字符串,又会产生几个实例?

public class StringDemo1 {
	public static void main(String[] args) throws  Exception {		
		String a = new String("String");	
		CyclicBarrier barrier = new CyclicBarrier(2);
		barrier.await();
	}
}

3)还有如下代码会产生几个对象?

public class StringDemo1 {
	public static void main(String[] args) throws  Exception {
		String a = new String("String");
		String b = new String("String");
		CyclicBarrier barrier = new CyclicBarrier(2);
		barrier.await();
	}
}

我们知道凡是被final修饰的成员变量就是常量,一旦赋值就无法改变。在JVM中的常量池(1.7之前包含1.7在方法区,1.7之后移动Java堆中)分为三种静态常量池和运行时常量池。静态常量池保存Class不仅仅包含字符串(数字)字面量,还包含类、方法的信息,占用class文件绝大部分空间;运行时常量池,则是jvm虚拟机在完成类装载操作后,将class文件中的常量池载入到内存中,并保存在方法区中,我们常说的常量池,就是指方法区中的运行时常量池。

在Java文件编译时,预先声明的String字符串,在Java运行时,载入常量池。而使用new String(字符串)创建的字符串,在堆中创建一个对象,私有成员变量value指向常量池对象字符串的value引用。如果在运行时生成字符串,使用intern()方法,将常量池存放一个指向堆中对象的引用。

最后,将String源码中构造函数贴过来。

    public String(String original) {
        this.value = original.value;
        this.hash = original.hash;
    }
	public String(char value[]) {
        this.value = Arrays.copyOf(value, value.length);
    }






猜你喜欢

转载自blog.csdn.net/firefish001/article/details/80836058