String常見題分析

1. 例1

1.1 代碼

package com.ilaoda.day0903;

/**
 * 字符串的常見題1
 * @author iLaoda
 *
 */
public class Test1 {

	public static void main(String[] args) {
		String s1 = "hello";
		String s2 = "world";

		System.out.println(s1 + s2 == "helloworld");  // false
		System.out.println("hello" + "world" == "helloworld");  // true
	}
}

1.2 答案

false true

1.3 解釋

  • 靜態區  常量池中的內容不能重複
  • String s1 = "hello";

    會在棧中聲明s1,並將"hello"存進常量池中,同時s1存"hello"在常量池中的地址 java

  • String s2 = "world";
     會在棧中聲明s2,並將"world"存進常量池中,同時s2存"world"在常量池中的地址
  • System.out.println(s1 + s2 == "helloworld");
     s1 + s2:會產生一個新的地址空間,裏面存的是不知道的地址
     helloworld:此時發現常量池中沒有"helloworld"字符串,就立馬建立,並將建立
     後的字符串地址與s1 + s2後不知名的地址作一比較,發現不想等。因此false
  • System.out.println("hello" + "world" == "helloworld");
     hello:常量池中有,不用建立
     world:常量池中有,不用建立
     "hello" + "world":相加後爲helloworld,發現常量池中已經有helloworld,直接拿來用。
     與後面的helloworld比較以後地址相等(實際就是本身跟本身比較地址,由於內容不能重複)

2. 例2

2.1 代碼

package com.ilaoda.day0903;

/**
 * 字符串的常見題2
 * @author iLaoda
 */
public class Test2 {

	public static void main(String[] args) {
		final String s1 = "hello";
		final String s2 = "world";

		System.out.println(s1 + s2 == "helloworld");
		System.out.println("hello" + "world" == "helloworld");
	}
}

2.2 答案

true  true

2.3 解釋

  • final String s1 = "hello";
     final修飾,表示是常量,此時與棧無關。直接是在常量池中存入"hello"。能夠把s1自己就理解爲常量,不要理解爲引用
  • String s2 = "world";
     final修飾,表示是常量,此時與棧無關。直接是在常量池中存入"world"。能夠把s2自己理解爲常量,不要理解爲引用
  • s1 + s2 == "helloworld"就相等於"hello" + "world" == "helloworld"是一個樣子


3. 例3

3.1 

String s1 = "abc";
String s2 = new String("abc");  //這句話建立了幾個對象
  • 答案: 1個
  • 解釋:第一句已經在常量池中建立一個「abc」,執行第二句時,在堆中new String,發現常量池中已經有「abc」,直接讓堆中的new stirng再指向常量池中的「abc」,因此就建立了一個對象。

3.2

String s1 = new String("abc");   //這句話建立了幾個對象
  • 答案:兩個
  • 解釋:在堆中new String,堆內開闢了空間,建立了一個對象。發現常量池中沒有「abc」,這時再在常量池中建立一個字符串對象。因此兩個。
  • 我以爲這兩句話挺重要的:1. 常量池中的內容不能重複     2.字符串常量池中的內容也做爲字符串對象存在

3.3

String s1 = new String("abc"); // 建立兩個對象
String s2 = new String("abc"); // 建立1個對象

4. 關於final修飾的成員變量和局部變量初始化賦值的幾種形式

    如下代碼沒有執行,可是都沒有報錯。說明語法上沒有問題。 this


package com.ilaoda.day0904;

/**
 * 關於final修飾的成員變量和局部變量初始化賦值的幾種形式
 * @author iLaoda
 *
 */
public class Test3 {
	
	/**
	 * final修飾的成員變量,能夠用如下三種方式初始化賦值:
	 * 		1. 聲明的時候直接賦值
	 * 		2. 構造方法中賦值
	 * 		3. 構造代碼快賦值(其實也是構造方法賦值)
	 */
	
	//1. 聲明的時候直接賦值
	final int a1 = 1;
	final int a2;
	final int a3;
	
	//3. 構造代碼快賦值(其實也是構造方法賦值)
	{
		a2 = 2;
	}
	
	public Test3(int a3) {	
		this.a3 = a3;
	}
	
	// 2. 構造方法中賦值
	Test3 test3 = new Test3(5);
	
	
	/**
	 * final修飾的局部變量,能夠用如下三種方式初始化賦值:
	 */
	public static void haha(int a) {
		//1. 能夠在聲明的時候初始化賦值
		final int a1 = 1;	
		final int a2;
		
		//2. 或者表達式給它賦值。
		a2 = a1 + 5;
		
		final int a3 = a;
	}
	
	public static void main(String[] args) {
		//3. 在第一次使用的經過方法
		haha(3);
	}
}


5. 輸出的結果爲多少呢?

5.1 代碼

package com.ilaoda.day0905;

/**
 * @author iLaoda
 */
class C {	
	C() {
		System.out.print("C");
	}
}

class A {
	/**
	 * 
	 * 對父類中的c成員進行初始化,調用了C類的無參構造
	 *  由於A類中有C類的成員,在Test建立
	 */
	C c = new C();

	A() {
		this("A");
		System.out.print("A");
	}

	A(String s) {
		System.out.print(s);
	}
}

class Test extends A {
	
	/**
	 * 執行父類的帶參構造前要先對父類中的對象進行初始化,
	 */
	Test() {
		super("B");
		System.out.print("B");
	}

	public static void main(String[] args) {
		new Test();
	}
}

5.2 答案

CBB


6. 輸出結果爲多少?

6.1 代碼

package com.ilaoda.day0905;

/**
 * 輸出結果爲多少
 * @author iLaoda
 *
 */
public class Test2 {
	static {
		int x = 5;
	}
	static int x, y;   // 0   0

	public static void main(String args[]) {
		x--;	// x=-1;
		myMethod();
		System.out.println(x + y + ++x); 
		// 從下面可知第一個x爲1,y爲1
		// ++x爲2
		// 因此:結果爲3
	}

	public static void myMethod() {
		y = x++ + ++x; //真正計算時: y = -1 + 1 = 0
		// 第一個 x 進行加運算時爲:-1, x++後爲:0
		// 第二個 x 進行加運算時,這時x已經爲0。因此 ++x後,x爲1
		// 所以 y = 0+1 = 1
	}
}

6.2 答案

3
相關文章
相關標籤/搜索