java基礎:String

JAVA基礎之String

一.概述

1.1 簡介:java

    String是一個複製類型,在java項目中使用最多。在java中String變量值都是存放的String在堆空間中的地址。本文講解下String的地址相關常量池和intern。express

2.2 String的組成:數組

    

    a.數組被放在堆空間。this

    b.數組不能改變大小,每一次改變大小都會從新分配空間(地址改變)。spa

2.4 經常使用的方法code

    能夠去下載幫助文檔(chm文件)查看。對象

二.案例

2.1 初始化
ci

    a.    ==要相等,必須在class文件在加載時,能讓JVM解析並生成的char[]在常量池中。
文檔

    b.    =初始化,JVM直接解析,而後從常量池中尋找相同的值地址空間,並返回;若是沒有值,則建立並返回。
字符串

    c.    new初始化時,將變量值存放爲new String()開闢的堆空間地址,而後在堆空間地址中存放常量池中一樣值的char[]地址,若是沒有則建立並返回

    d. 只有JVM在解析的時候,可以準確的知道=右值的準確地址(包括能夠經過final引用查找到其值,不包括引用地址),則其地址空間都相等。

public static void main(String[] args) {
		final String o1="a";
		String o = "a";
		String a = "a1";
		String b = "a" + 1;
		String c = o + 1;
		String c1 = o1 + 1;
		String d = new String("a1");
		/**
		 * String a: 右值是肯定的基礎變量,沒有引用、new等初始化方式,在加載的時候、JVM解析class文件,a直接存放char[]的地址
		 * String b: 雖然右值使用了+,可是JVM直接將其整合爲char[],放在堆空間
		 * String c: 引用,JVM只有在加載後,運行時才能去人地址
		 * String c1:雖然使用的是引用,可是有final,JVM能夠直接解析
		 * String d: d指向的是,new 在運行時分配堆空間。
		 */
		System.out.println(a == b); // true
		System.out.println(a == c); // false
		System.out.println(a == c1); // true
		System.out.println(a == d); // false
		System.out.println(a.intern());
		System.out.println(a.hashCode()); // 3056
		System.out.println(b.hashCode()); // 3056
	}

2.2 intern

    源碼解釋:

Returns a canonical representation for the string object.
A pool of strings, initially empty, is maintained privately by the class String.
When the intern method is invoked, if the pool already contains a string equal to this String object as determined by the equals(Object) method, then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned.
It follows that for any two strings s and t,  s.intern() == t.intern() is true if and only if s.equals(t) is true.
All literal strings and string-valued constant expressions are interned. String literals are defined in section 3.10.5 of theThe Java™ Language Specification.
返回一個標準的String對象。
String池,開始是空的,用來保存私有的String類。
1.用intern()時:若是這String池裏面有一個可以equals(objects)《即,有一個相同值的char[]》,則返回這個char[];若是沒有,則添加建立一個,並返回。
2.兩個String字符串 s和t,只有在s.equals(t)<值相同>的狀況下,t.intern()==s.intern()爲true。

    案例:

public static void main(String[] args) {
		String a = "a1";
		/*
		 * intern 返回String常量池中地址;相同Unicode的地址引用 將一個 String 類的保存到一個全局 String 表中 ,
		 * 若是具備相同值的 Unicode 字符串已經在這個表中,那麼該方法返回表中已有字符串的地址,
		 * 若是在表中沒有相同值的字符串,則將本身的地址註冊到表中
		 */

		System.out.println("============== 基礎變量 ===============");
		String c00 = "a".intern() + 1; // 方法在,runtime確認
		String c01 = "a" + 1;			//加載時,確認地址
		System.out.println(a == c00); // false
		System.out.println(a == c01);// true
		System.out.println(a == c00.intern());	//(true) runtime方法運行、返回指向的常量池地址

		System.out.println("============== final 引用 ===============");
		final String b1 = "a"; // 運行時確認值
		String c10 = b1.intern() + 1;
		String c11 = b1 + 1;
		System.out.println(a == c10); // false
		System.out.println(a == c11); // true
		System.out.println(a == c01.intern());	//true runtime方法運行、返回指向的常量池地址
		System.out.println("============== 引用 ===============");
		String b2 = a; // 運行時確認值
		String c20 = b2.intern() + 1;
		String c21 = b2 + 1;
		System.out.println(a == c20); // false
		System.out.println(a == c21); //

		System.out.println("==============final new 初始化===============");
		final String b3 = new String("a"); // NEW 運行時確認值
		String c30 = b3.intern() + 1;
		String c31 = b3 + 1;
		System.out.println(a == c30); // false
		System.out.println(a == c31); // false

		System.out.println("============== new ===============");
		String b4 = new String("a"); // final new 運行時確認值
		String c40 = b4.intern() + 1;
		String c41 = b4 + 1;
		System.out.println(a == c40); // false
		System.out.println(a == c41); // true

		System.out.println("============== method ===============");
		final String b5 = getB3(); // 方法運行時確認值
		String c50 = b5.intern() + 1; // 對於引用,可是運行時JVM才知道其值
		String c51 = b5 + 1; // 對於引用,可是運行時JVM才知道其值
		System.out.println(a == c50); // false
		System.out.println(a == c51); // true (說明在同一個常量池)

		System.out.println("============== final method ===============");
		final String b6 = getB4(); // final方法,運行時確認
		String c60 = b6.intern() + 1; // 對於引用,可是運行時JVM才知道其值
		String c61 = b6 + 1; // 對於引用,可是運行時JVM才知道其值
		System.out.println(a == c60); // false
		System.out.println(a == c60); // true (說明在同一個常量池)

	}

	public static String getB3() {
		return "a";
	}

	public final static String getB4() {
		return "a";
	}
相關文章
相關標籤/搜索