在一個繼承Activity的類中,不能同時讓onCreate和構造函數同時出現嗎?

在一個繼續Activity的類中,不能同時讓onCreate和構造函數同時出現嗎??
參考:http://bbs.csdn.net/topics/390321638 java


若是不能,緣由爲什麼?
app

若是能,爲何會出現錯誤? ide

先看一下java 的例子. 函數

//A.java
public class A {
	public A() {
		System.out.println("===a 構造=====");
	}
}
/B.java
public class B {
	static A a = new A();
	static {
		System.out.println("===B static===");
	}
	public B(){
		System.out.println("B 構造");
	}
	{
		System.out.println("===B 動態===");
	}
}
//C.java
public class C {

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		try {
			Class aClass = Class.forName("B");
			Object anInstance = aClass.newInstance();
		} catch (Exception e) {
			e.printStackTrace();
		}
        System.out.println("====================");
		B b = new B();

	}

}
/*打印結果
===a 構造=====
===B static===
===B 動態===
B 構造
====================
===B 動態===
B 構造
*/

所以,不管new B(),仍是 Class.newInstance()構造B,都會調用到無參構造. this

//A.java
public class A {
	public A() {
		System.out.println("A 無參數構造");
	}
}
//B.java
public class B {
	public B() {
		System.out.println("B 無參數構造");
	}
}
//MainActivity.java
public class MainActivity extends Activity {

	static B b = new B();
	static {
		System.out.println("靜態代碼塊");
	}
	
	A a = new A();
	
	{
		System.out.println("動態代碼塊");
	}

	public MainActivity() {
		System.out.println("Activity 構造");
		//Context ct=this;
		//ct.getText(R.string.app_name);
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		System.out.println("onCreate");
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
	}
}
打印結果

B 無參數構造
靜態代碼塊
A 無參數構造
動態代碼塊
Activity 構造
oncreate

spa

若是改爲 MainActivity() .net

將會出現 code

java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.test/com.example.test.MainActivity}: java.lang.IllegalAccessException: access to constructor not allowed
get

若是改爲 string

public MainActivity() {
System.out.println("Activity 構造");
Context ct=this;
ct.getText(R.string.app_name);
}

將會出現

java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.test/com.example.test.MainActivity}: java.lang.NullPointerException

at com.example.test.MainActivity.<init>(MainActivity.java:25)

at java.lang.Class.newInstanceImpl(Native Method)

at java.lang.Class.newInstance(Class.java:1130)

從中還能夠發現,Class.newInstance.

實際上,成員變量定義的時候是不能同時初始化的(?).只是書寫的時候能夠這樣作,可是編譯的時候被處理掉.

<clinit>方法會這樣初始化:1,靜態成員變量,2靜態代碼塊

<init>(多少個構造方法就有多少個) 順序 1.super()2初始化通常成員變量.3動態代碼塊.4構造方法的除super()剩餘的代碼.若是構造方法存在this(),即調用其餘構造.super()將會在其餘不使用this()的構造中先執行-實際上將this() 替換進去進能夠知道結果了.注意 this().super()都只能寫在第一行.super是存在的. 當使用的是父類的無參構造時能夠不寫.可是其仍是執行的.其餘必須寫!!!

public class G extends H{
	int a;
	int b;

	public G(int a, int b) {
		super(5);
		System.out.println("g(int,int)");
		this.a = a;
		this.b = b;
	}
	public G(int a){
		this(a,3);
		System.out.println("g(int)");
	}
	public G(){	
		
		this(2);
		System.out.println("g()");
	}
	public static void main(String[] args) {
		G g=new G();
	}
}

輸出

g(int,int)
g(int)
g()

從中能夠知道,Android 實例化Activity,是經過Class.newInstance實現的,調用的必須是無參構造,不能是private修飾的!能夠是默認不寫,若是存在帶參數的構造,也必須存在無參構造.也正由於如此,只有無參構造,就沒必要寫這個構造方法了.不寫這個無參構造了,仍是可使用動態代碼塊初始化的.也正由於如此,更加不用顯式地寫這個無參構造了!!!

衆所周知,在Activity中一個重要的橋樑就是上下文 Context.

若是這樣寫

public MainActivity() {
System.out.println("Activity 構造");
Context ct=this;
ct.getText(R.string.app_name);
}

將會出現異常.因此在onCreate以前只能初始化與context無關的,與context有關的都不該該放在onCreate以前.因此,既然不不能調用context有關的方法,在onCreate以前初始化就沒什麼意義了.要初始化的寫成一個init方法,放在onCreate.方便快捷.

相關文章
相關標籤/搜索