1. 程式人生 > >android 匿名內部類使用外部類變數

android 匿名內部類使用外部類變數

方法中的變數必須final 成員變數或者成員變數

reason:

轉載:http://m.blog.csdn.net/blog/lyl_tkb/38562857

如果定義一個匿名內部類,並且希望它使用一個在其外部定的物件,那麼編譯器會要求其引數引用是final的。 

1.匿名內部類肯定是區域性內部類(在一個方法裡面定義的內部類),因為在java中,語句必須寫在方法裡,而匿名內部類其實就是一條特殊的語句; 
2.外部給定的物件就是所有外來的物件:外部方法的形參、區域性變數、基本型別或自定義型別等。 
3.內部類很微妙,它可以直接訪問外部類的private field,這打破了類的封裝。但是內部類又有它自身的好處,比如簡潔,可見性等,於是就把它定位成“只讀”,也就是final。不過這個保護也非常脆弱! 


4.local inner class訪問local var時,那個var必須是final的。因為可以通過enclosing class訪問那個local var,也可以通過inner class訪問,可能造成問題,所以就必須是final的 

5.匿名內部類為什麼只能用final.是變數的作用域的問題,因為匿名內部類是出現在一個方法的內部的,如果它要訪問這個方法的引數或者方法中定義的變數,則這些引數和變數必須被修飾為final。因為雖然匿名內部類在方法的內部,但實際編譯的時候,內部類編譯成Outer.Inner,這說明內部類所處的位置和外部類中的方法處在同一個等級上,外部類中的方法中的變數或引數只是方法的區域性變數,這些變數或引數的作用域只在這個方法內部有效。因為編譯的時候內部類和方法在同一級別上,所以方法中的變數或引數只有為final,內部類才可以引用。

6.在Java中,方法的區域性變數位於棧上,物件位於堆上。因為區域性變數的範圍被限制在該方法內,當一個方法結束時,棧結構被刪除,該變數消失。但是,定義在這個類中的內部類物件仍然存活在堆上,所以內部類物件不能使用區域性變數。除非這些區域性變數被標識為最終的。

public void run() {
			while (true) {
				if (y < screenHeight && flagThread)
				{    
					try {
						y = y + 20;
						// postInvalidate();
						handle.post(new Runnable() {

							@Override
							public void run() {
								// TODO Auto-generated method stub
								
								invalidate();
							}
						});
						Thread.sleep(300);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}

				} else
					break;

			}