2011-01-24 49 views
0

下面是一個例子:爲什麼允許從靜態對象中創建非靜態引用?

public class Test extends Activity { 

    Button button; 
    public int i; 
    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
     button = (Button) findViewById(R.id.Button01); 
     button.setOnClickListener(new View.OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       i = 10; // How can this be possible? 
      } 
     }); 
    } 
} 
+4

什麼讓你覺得這是一個靜態對象? - 編輯:道歉,如果這從snippy脫落。我真的要求澄清。你認爲什麼是靜態的,你爲什麼這麼想? – rfeak 2011-01-24 16:43:48

回答

4
  • 匿名(內)類(在這種情況下new View.OnClickListener())不是靜態的,它們是非靜態內部類。

  • 一個非靜態內部類與包含外部類的實例(在這種情況下爲Test)有一個隱含關係,通過它創建內部類。就像內部階級有一個隱含的伊娃,指向它的外部階級的相關實例。

  • 內部類可以通過這種關係訪問其外部類的ivars,如i

5

這不是一個靜態的對象。這就是爲什麼它是可能的。

+0

如果它是靜態的,你的意思是它不可訪問,是嗎? – 2011-01-24 16:45:22

3

靜態對象在哪裏?你在那裏有一個匿名的內部類,但是當你用new關鍵字調用構造函數時,你創建了它。

1
i = 10; // How can this be possible? 

i是類的成員,它可以通過爲您的代碼類的方法訪問,

能有什麼辦法?

1

這裏沒有靜物。你有一個匿名內部類的實例(View.OnClickListener),但沒有靜態對象。

編輯:我想知道你是否會混淆static變量與local (non-member) final variables這與靜態變量沒有任何直接關係,但我可以看到(自我描述的)新手如何讓他們感到困惑。

任何局部變量,使用形式化方法 參數或異常處理 參數,但沒有宣佈在 內部類必須聲明final, 而且必須在內部類的身體之前,明確賦值 。

修改你的榜樣,下面是這允許的情況下:

@Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
     int i = 0; // This is non-final; access to it from an inner class is not allowed. 
     button = (Button) findViewById(R.id.Button01); 
     button.setOnClickListener(new View.OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       i = 10; // Compiler error 
      } 
     }); 
    } 

這裏還有另一種是允許:

@Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
     final int i = 0; // This is final; read-only access to it from an inner class is allowed. 
     button = (Button) findViewById(R.id.Button01); 
     button.setOnClickListener(new View.OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       i = 10; // Compiler error -- can't modify a final variable. 
      } 
     }); 
    } 

但這允許:

@Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
     final int i = 0; // This is final; read-only access to it from an inner class is allowed. 
     button = (Button) findViewById(R.id.Button01); 
     button.setOnClickListener(new View.OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       int j = i; // OK 
      } 
     }); 
    } 
0

有關說明這樣的:這是可能的,因爲(匿名)類View.OnClickListener你創建類型爲靜態的,因此保持一個隱藏的參考其外部類。話雖這麼說:

 @Override 
     public void onClick(View v) { 
      i = 10; 
     } 

等同於:

 @Override 
     public void onClick(View v) { 
      Test.this.i = 10; 
     } 

這是否有意義?

0

我認爲這個混淆來自OnClickListenerView限定的事實。它實際上並不是static。以下是等價的:

import android.view.View; 
... 
button.setOnClickListener(new View.OnClickListener() { 

import android.view.View; 
import android.view.View.OnClickListener; 
... 
button.setOnClickListener(new OnClickListener() { 
相關問題