第一題 下列程式輸出啥? public class StringDemo{ private static final String MESSAGE="taobao"; public static void main(String [] args) { String a ="tao"+"bao"; S ...
第一題
下列程式輸出啥?
public class StringDemo{
private static final String MESSAGE="taobao";
public static void main(String [] args) {
String a ="tao"+"bao";
String b="tao";
String c="bao";
System.out.println(a==MESSAGE);
System.out.println((b+c)==MESSAGE);
}
}
解析:
做這道題之前,需要明白三個知識點:
==
符號比較引用類型時,比較的是雙方的地址。String s = "xxx"
或者,String s = "xxx" + "yyy"
,這種創建String類型變數的情況,都是把變數存到常量池中。new 類名()
會在堆中創建一個對象,堆中地址當然和常量池的地址不一樣。兩個一模一樣的玩具,一個在客廳,一個在卧室。
我在做這道題的時候,在想這樣一個問題:靜態常量的字元串也是存在常量池中的嗎?通過在idea中debug,驗證了我的猜想:靜態常量的字元串也是存在常量池中的。
於是,a==MESSAGE
就是對的。
那麼,b+c==MESSAGE
呢?通過追蹤源碼可知,因為b+c
是變數相加,所以在底層會創建一個StringBuilder類型的變數來存儲b+c
的結果,存好之後,又轉換為String類型,這個String類型是由StringBuilder轉化過來的,但是地址還是在堆中,所以它的地址也就和MESSAGE
不同,那麼結果也就是false。
答案:
true false
第二題
下列程式輸出啥
class Test {
public static void main(String[] args) {
System.out.println(new B().getValue());
}
static class A {
protected int value;
public A(int v) {
setValue(v);
}
public void setValue(int value) {
this.value = value;
}
public int getValue() {
try {
value++;
return value;
} finally {
this.setValue(value);
System.out.println(value);
}
}
}
static class B extends A {
public B() {
super(5);
setValue(getValue() - 3);
}
public void setValue(int value) {
super.setValue(2 * value);
}
}
}
解析:
這題考察try-catch和多態的動態綁定機制,還涉及了一點靜態內部類。
必備知識:
- 學會idea的debug功能
- try-catch中如果有return語句
- finally沒有返回值,先把return的值保存起來。執行完finally後,執行return,返回的是保存起來的值,而不是finally中改變的值!
- finally有返回值,會覆蓋掉try-catch中的return語句。
- 執行一個對象的方法時,是看這個對象的運行類型,啥是運行類型?就是new一個對象時,new後面那個類型。如果這個運行類型的類中沒有調用的方法,就一層一層地去父類中找。如果用
super.方法名()
,那麼直接去父類中找方法。再提一嘴,方法名()
等價於this.方法名()
。this是啥?就是程式當前執行的方法的調用者。
回到題目,這道題用語言來描述會有點麻煩,大家可以瞭解一下我前面所說的必備知識,然後自己思考一下執行流程,一定要在idea中debug一下,只需要在main方法中打一個斷點即可,看看整個程式的執行流程,以後再遇到類似的題目,基本沒啥問題。
答案:
22 34 17