网站关键字搜索功能,梧州网站建设贝尔利,flash网站开发,wordpress4.8.3下载目录为什么是null回顾类加载原因问题重现总结类加载顺序子类重写被父类构造函数调用的函数注意不能放过不起眼的日志一条日志引发的案子 [11:12:58.505][D][Gen][RTLive][getIns ins 4414717] [11:12:58.774][I][Gen][null][updateShowMode] [11:12:58.864][D][Gen][VideoCame…
目录为什么是null回顾类加载原因问题重现总结类加载顺序子类重写被父类构造函数调用的函数注意不能放过不起眼的日志一条日志引发的案子 [11:12:58.505][D][Gen][RTLive][getIns ins 4414717] [11:12:58.774][I][Gen][null][updateShowMode] [11:12:58.864][D][Gen][VideoCameraCapture][setOrientation ortation 1] [11:12:58.865][D][Gen][VideoCapture][setOrientation ortation 1] [11:12:58.865][D][Gen][VideoCapture][setHardEncode isHardEncode false] 为什么是null
第二行日志中的 “null” 引起了我的关注正常情况下这里应该是该条日志所在的类的类名称现出现了null首先从日志阅读习惯上就不顺了。其次是TAG的值是给null需要弄清楚。还存在TAG 没有初始化的嫌疑。
首先通过updateShowMode找到对应的代码位置。函数第一行就打了日志而TAG是个成员变量定义如下
private String TAG getClass().getSimpleName();public synchronized void updateShowMode() {GenLog.i(TAG,updateShowMode);
}
这样的模型TAG的值为什么是null。那就是类加载时机的问题了。
回顾类加载
先定义如下类
public class Person {private static String staticVar staticVar(“def”);//目的是打日志从日志上看顺序private String var var();//目的是打日志从日志上看顺序public Person(){System.out.println(Person init);}private String var() {System.out.println(Person var);return var;}public static String (String param){System.out.println(Person staticVar param);return staticVar;}static {System.out.println(Person static code);}
}当Person person new Person(); 被执行时输出如下 Person staticVar def Person static code Person var Person init 加载顺序依次如下
静态变量静态代码块成员变量构造函数
当Person.staticVar(“main”); 参数是为了区别外部与内部谁先调用被执行时输出如下 Person staticVar def Person static code Person staticVar main 执行顺序 静态变量的初始化 静态代码块 外部调用的执行
加载顺序还是保持
静态变量静态代码块
出现了上面的nullgetClass().getSimpleName() 会有问题吗我们将成员函数稍微变一下
public class Person {private static String staticVar staticVar(def);private String var var();public Person(){System.out.println(Person init);}private String var() {//这里输出getClass().getSimpleName()的结果String name getClass().getSimpleName();System.out.println(Person var name name);return var;}public static String staticVar(String param){System.out.println(Person staticVar param);return staticVar;}static {System.out.println(Person static code);}
}再次执行Person person new Person(); 结果如下 Person staticVar def Person static code Person var name Person Person init 说明getClass().getSimpleName()没有问题。
到底什么情况呢经过一番折腾发现还有一个继承关系updateShowMode覆盖父类的函数且updateShowMode是在父类构造函数中调用的。
我们再加一个类Any 作为person的父类
public class Any {private static String TAG staticVar();private String var var();private static String staticVar() {System.out.println(Any staticVar);return Any staticVar;}public Any(){System.out.println(Any init);}public void test(){System.out.println(Any test);}private String var(){System.out.println(Any var);return Any var;}static {System.out.println(Any static code);}
}//Person 类变化如下 继承Any
class Person extends Any执行Person person new Person(); 结果如下 Any staticVar Any static code Person staticVar def Person static code Any var Any init Person var name Person Person init 执行顺序依次
父类静态变量父类静态代码块子类静态变量子类静态代码块父类成员变量父类构造函数子类成员变量子类构造函数
原因
出现null是因为没有把握好6和7的顺序。父类构造函数(6)调用了子类重载函数重载函数又访问了子类的成员变量。此时还在执行父类的构造函数子类的成员变量还没有被初始化(7)所以出现了null。
问题重现
我们再次修改Any和Person 的test重载 Any 构造函数调用test()
public class Any {private static String TAG staticVar();private String var var();private static String staticVar() {System.out.println(Any staticVar);return Any staticVar;}public Any(){System.out.println(Any init);//构造函数调用成员函数test();}public void test(){System.out.println(Any test);}private String var(){System.out.println(Any var);return Any var;}static {System.out.println(Any static code);}
}Person 覆盖Any的test(),并输出var
public class Person extends Any{private static String staticVar staticVar(def);private String var var();public Person(){System.out.println(Person init);}private String var() {String name getClass().getSimpleName();System.out.println(Person var name name);return var;}public static String staticVar(String param){System.out.println(Person staticVar param);return staticVar;}Overridepublic void test() {//覆盖重写父类的test函数并访问var 输出varSystem.out.println(Person test var var);}static {System.out.println(Person static code);}
}再次执行Person person new Person(); 输出 Any staticVar Any static code Person staticVar def Person static code Any var Any init Person test var null Person var name Person Person init Person test var null 得到应证。
总结
类加载顺序
父类静态变量父类静态代码块子类静态变量子类静态代码块父类成员变量父类构造函数子类成员变量子类构造函数
没有继承关系的情况下
静态变量静态代码块成员变量构造函数
子类重写被父类构造函数调用的函数注意
重载函数被调用的过程中成员变量是没有被初始化的。
不能放过不起眼的日志
我们要多看日志养成日志规范并充分利用日志解决问题。