首页 > 代码库 > 在一个继承Activity的类中,不能同时让onCreate和构造函数同时出现吗?
在一个继承Activity的类中,不能同时让onCreate和构造函数同时出现吗?
在一个继续Activity的类中,不能同时让onCreate和构造函数同时出现吗??
参考:http://bbs.csdn.net/topics/390321638
如果不能,原因为何?
如果能,为什么会出现错误?
先看一下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,都会调用到无参构造.
//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
如果改成 MainActivity()
将会出现
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.test/com.example.test.MainActivity}: java.lang.IllegalAccessException: access to constructor not allowed
如果改成
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.方便快捷.