一、看下面代碼求值
1 /要求:使用已知的變量,在控制台輸出30,20,10。 2 class Outer { 3 public int num = 10; 4 class Inner { 5 public int num = 20; 6 public void show() { 7 int num = 30; 8 System.out.println(?); 9 System.out.println(??); 10 System.out.println(???); 11 } 12 } 13 } 14 15 class InnerClassTest { 16 public static void main(String[] args) { 17 Outer.Inner oi = new Outer().new Inner(); 18 oi.show(); 19 } 20 }
答案:num、this.num、Outer.this.num
解析:這題你如何明白了上面總結中的第二點,那么非常簡單,考察的就是1、局部變量 2、this,和3、Outer.this,也就是內部類訪問外部類屬性方法的原理。這考察三個東西,
1、在一個方法中,使用直接使用變量名,肯定使用的是局部變量,因為會把大的成員變量給隱藏掉,這題中,也就是說show方法中的num會將內部類中的成員變量num隱藏掉,而內部類中的成員變量num又會把外部類中的成員變量num隱藏掉,所以通過直接輸出num,會是show方法中的 局部變量的值30.
2、使用this.num調用,其this代表的是調用該方法的對象,調用show方法的是oi,oi也就是內部類對象,所以oi.num也就標識內部類的成員變量num的值20
3、Outer.this.num,調用的外部類中的成員變量num的值也就是10,這個如果不清楚就看上面總結中的第二點,就是那個原理。
二、按照要求補齊代碼
1 按照要求,補齊代碼 2 interface Inter { void show(); } 3 class Outer { //補齊代碼 } 4 class OuterDemo { 5 public static void main(String[] args) { 6 Outer.method().show(); 7 } 8 } 9 要求在控制台輸出”HelloWorld”
答案:
interface Inter { void show(); } class Outer { //補齊代碼 public static Inter method(){ return new Inter(){ void show(){ System.out.println("HelloWorld"); } }; } } class OuterDemo { public static void main(String[] args) { Outer.method().show(); } }
解析:這個題目挺有趣的,考了很多東西,一開始只能說我自己度懵逼了,是一個局部匿名內部類。 通過看主方法中的調用,Outer.method(),能直接用類名調用方法,
那么肯定該方法就是一個static方法,然后又直接調用了show()方法,說明這個method方法有一個返回值,其返回值類型就是實現該接口類的類型,因為只有接口中有show()這個方法。所以在method中就是一個匿名內部類。
三、以下代碼運行結果是什么?
1 public class BwfOuterClass { 2 3 private int x = 1; 4 5 private int y = 2; 6 7 private class BwfInnerClass{ 8 9 private int x = 3; 10 11 public void print(){ 12 13 System.out.println("x+y="+(x+y) ); 14 15 } 16 17 } 18 19 public static void main(String[] args) { 20 21 new BwfOuterClass().new BwfInnerClass().print(); 22 23 } 24 25 }
答案:
x+y=5
[面試技術點]
Java中內部類的使用。
[解讀]
在Java中,可以將一個類定義在另一個類里面或者一個方法里面,這樣的類稱為內部類。廣泛意義上的內部類一般來說包括這三種:成員內部類、局部內部類、匿名內部類,如下圖所示:
本題考的是成員內部類。成員內部類是最普通的內部類,它的定義為位於另一個類的內部,類似於一個成員屬性。可以使用修飾符private、default、protected、public。
本題中BwfInnerClass是BwfOuterClass的成員內部類,成員內部類可以無條件訪問外部類的所有成員屬性和成員方法(包括private成員和靜態成員)。但是值得注意的是,當成員內部類擁有和外部類同名的成員變量或者方法時,默認情況下訪問的是成員內部類的成員。如果要訪問外部類的同名成員,需要以下面的形式進行訪問:
外部類.this.成員變量
外部類.this.成員方法
本題中,如果把print方法做如下修改:
public void print(){
System.out.println("x+y=" + (BwfOuterClass.this.x+y));
}
則輸出結果為:x+y=3
四、Anonymous Inner Class(匿名內部類)是否可以繼承其它類?是否可以實現接口?
可以繼承其他類或實現其他接口,在Swing編程和Android開發中常用此方式來實現事件監聽和回調。
五、為什么內部類調用的外部變量必須是final修飾的?
因為生命周期的原因。方法中的局部變量,方法結束后這個變量就要釋放掉,final保證這個變量始終指向一個對象。首先,內部類和外部類其實是處於同一個級別,內部類不會因為定義在方法中就會隨着方法的執行完畢而跟隨者被銷毀。問題就來了,如果外部類的方法中的變量不定義final,那么當外部類方法執行完畢的時候,這個局部變量肯定也就被GC了,然而內部類的某個方法還沒有執行完,這個時候他所引用的外部變量已經找不到了。如果定義為final,java會將這個變量復制一份作為成員變量內置於內部類中,這樣的話,由於final所修飾的值始終無法改變,所以這個變量所指向的內存區域就不會變。
為了解決:局部變量的生命周期與局部內部類的對象的生命周期的不一致性問題