cghtom / someTips

log4j日志级别 shell操作手册 面试 总结
0 stars 0 forks source link

java初始化--静态变量,静态方法块,变量,变量块,构造方法的执行顺序 #2

Open cghtom opened 7 years ago

cghtom commented 7 years ago

没有extends时: // 静态变量 // 静态初始化块 // 变量 // 初始化块 // 构造器 extends时: // 静态变量p // 静态初始化块p // 静态变量 // 静态初始化块 // 变量p // 初始化块p // 构造器p // 变量 // 初始化块 // 构造器 总结为:先静态后动态 先定义后初始化块,构造函数 (静态最先执行,定义) 先父静态子静态,父变量,初始化块,构造函数 然后子变量,初始化块,构造函数 为什么?

静态代码是在类加载完毕后执行的,而加载类的顺序是先父类后子类,所以静态代码的执行是先执行父类的,然后执行子类的。 对于非静态变量以及实例初始化块 都是在构造函数代码执行前执行。 所以静态代码是在类加载后执行,而实例代码是在构造函数执行前执行。 显示加载有关两种方法: 1:利用forName方法 java.lang.Class.forName("静态代码初始化的执行顺序.staticInit"); 全类名

2:利用Class对象获取的ClassLoader装载。 ??? class ClassLoaderC extends ClassLoader{ } class test{ public String test(Object a){ System.err.println("asdasdsa"); return "true"; } } main 方法添加如下代码: Class<?> clazz11 = new ClassLoaderC().loadClass("静态代码初始化的执行顺序.test"); Class<?> clazz12 = new ClassLoaderC().loadClass("静态代码初始化的执行顺序.test"); clazz11.getMethod("test", Object.class).invoke(clazz11.newInstance(), clazz12.newInstance());

综上所述可以总结如下: 隐式加载,new一个对象和调用类的静态方法( 静态代码是在类加载后立刻执行), 显示加载(第一种是用java.lang.Class的forName(String str)方法 2 实例化代码执行是在构造函数执行之前,涉及到继承时,父类的构造函数执行之前执行父类里的实例化代码,子类的构造函数执行之前执行父类的实例化代码。所以这样可以保证子类中用到的变量都是已经经过父类初始化的,从而保证了初始化的正确性。 父静态 子静态(先变量,后方法块) 父变量 实例化代码 构造方法 子变量 实例化代码 构造方法