java的基本类型String

  • 2015-09-29
  • 浏览 (55)

java的String是一个类。

一、String类的对象有三种赋值方式

1、类似普通对象,通过new创建字符串对象。
String str = new String("Hello"); 
系统会先创建一个匿名对象"Hello"存入堆内存(我们暂且叫它A),然后new关键字会在堆内存中又开辟一块新的空间,然后把"Hello"存进去,并且把地址返回给栈内存中的str, 此时A对象成为了一个垃圾对象,因为它没有被任何栈中的变量指向,会被GC自动回收。

2、直接赋值。
String str = "Hello";
首先会去缓冲池中找有没有一个"Hello"对象,如果没有,则新建一个,并且入池,所以此种赋值有一个好处,下次如果还有String对象也用直接赋值方式定义为“Hello”, 则不需要开辟新的堆空间,而仍然指向这个池中的"Hello"

以下代码可以测试这一结论 ,最后输出结果为 true, 我们用的是== 测试,输出true,说明两者的地址是一样的
public class TestString{
    public static void main(String args[]){
         String str1 = "Hello";
         String str2 = "Hello";
         System.out.println( str1==str2 );
    }
}

3、手动入池
使用new关键字,也可以使用一个java中的手动入池指令,让所创建的对象入池,以后依然可以被重复使用,利用下面两段代码可以测试, 如下图,结果显然是false,因为二者的地址不同。
public class TestString{
    public static void main(String args[]){
         String str1 = new String("Hello");
         String str2 = "Hello";
         System.out.println( str1==str2 );
    }
}
 
下面程序中,我们使用了intern()方法,手动入池,所以结果是true.
public class TestString{
    public static void main(String args[]){
         String str1 = new String("Hello").intern();//当intern方法被调用时,如果对象池中已经包含这一个相等的字符串对象则返回对象池中的实例,否则添加字符串到对象池并返回该字符串的引用 
         String str2 = "Hello";
         System.out.println( str1==str2 );
    }
}
 
下面程序中,str2没有使用直接赋值,所以结果又变为false
public class TestString{
    public static void main(String args[]){
         String str1 = new String("Hello").intern();
         String str2 = new String("Hello");
         System.out.println( str1==str2 );
    }
}
 
综上所述,开发中,使用直接赋值的方式,显然效率更高。
 
 
二、为什么String类的对象可以直接赋值  
 
打开String.class,有这么一段介绍:
    /**
    * The <code>String</code> class represents character strings. All
     * string literals in Java programs, such as <code>"abc"</code>, are
     * implemented as instances of this class.
     * <p>
     * Strings are constant; their values cannot be changed after they
     * are created. String buffers support mutable strings.
     * Because String objects are immutable they can be shared. For example:
     * <p><blockquote><pre>
     *     String str = "abc";
     * </pre></blockquote><p>
     * is equivalent to:
     * <p><blockquote><pre>
     *     char data[] = {'a', 'b', 'c'};
     *     String str = new String(data);
     * </pre></blockquote><p>
     * Here are some more examples of how strings can be used:
     * <p><blockquote><pre>
     *     System.out.println("abc");
     *     String cde = "cde";
     *     System.out.println("abc" + cde);
     *     String c = "abc".substring(2,3);
     *     String d = cde.substring(1, 2);
     * </pre></blockquote>
     * <p>
     */  

通过上面的介绍,我们可以清楚,直接赋值的话,是通过编译器在起作用,当你对"abc"没有通过new创建时,他会自动默认给你调用构造函数new String(char value[]). 不显式调用String的构造函数(通过new叫显式调用),其实JDK编译器会自动给你加上。


三、String对象作为参数传递的情况

public class Test {
	public static void main(String[] args){	
		String arg = "a";
		testString(arg);
		System.out.println(arg);
	}
	
	public static void testString(String arg){
		arg = "b";//这里生成了一个新的对象
		System.out.println(arg);
	}
}
结果:
b
a


正文到此结束