静态变量、实例变量初始化时机,以及子类隐藏父类成员时,创建子类对象的一些问题
2017-09-23 14:59
711 查看
最近在复习java基础,类加载的机制,看到很多篇好的博客,但是比较分散,所以自己总结了一下
代码:
运行结果截图:
为什么是 这样 呢?
以下是个人理解:
main方法里创建子类实例,但是此时父类还未创建,所以先创建父类(新手用不来这个编辑器,怎么选择不了,好累)
创建父类过程:{
在类加载的准备阶段,为静态变量分配内存并赋默认值此时 count1=0,count2=0,testClass=null
初始化阶段为静态变量赋值、执行静态代码块,为testClass赋值调用构造方法产生类的对象,此时为实例变量在堆里分配内存并赋值count=“testClass”,接着执行输出语句,输出第一行。
然后count+1,count2+1.输出第二行。
继续为静态变量赋值,count1没有操作,仍为1,count2被重新赋值为0
}
创建
4000
父类之后初始化子类,子类没有声明静态变量,可能会有疑问,没有继承父类的静态变量吗?没有,等下解释
执行子类的默认无参构造方法 注意(构造方法中有 一句 super();),但是子类的count已经覆盖了父类的count属性,但是还未初始化,所以此时输出null 1 0 SUB第三行,因为此时运行的大环境是在子类的无参构造方法里,this指的其实是子类,所以调用的out方法为子类的out方法
接着count1+1,count2+1,此时count1=2,count2=1;同理接着输出第四行
到此为止子类构造方法里的supper()执行完成,子类实例变量初始化,子类count=testsub
最后的输出语句:子类对象调用out方法输出第五行
补充 (这才是重要的):static 变量是类变量,不属于任何对象,但是子类对象可以访问父类的静态变量,如果子类也声明了同名的变量也不会覆盖,只会访问子类自己的静态变量,因为用子类名和父类名访问的是不同的内存空间。
还有构造方法和实例变量初始化究竟是怎样的执行顺序(个人理解):这两个的执行在JVM中都归结到 <init> 方法,在init中的顺序是:supper();+ 实例变量初始化+构造方法里面的代码
欢迎批评指正
代码:
package acx; public class TestClass { public String count="testclass";//实例变量 public static TestClass testClass=getInstence(); public static int count1; public static int count2=0; private TestClass() {//父类构造方法
System.out.println(out()); count1=count1+1; count2=count2+1; System.out.println(out()); } public static TestClass getInstence(){//单例模式 可以了解一下 if(testClass==null){ return new TestClass(); }else{ return testClass; } } public String out(){ return (""+count+" "+count1+" "+count2+" "+"constructor"); } static class Sub extends TestClass{//静态内部类 public String count="testsub"; public String out(){ return (""+count+" "+count1+" "+count2+" "+"SUB"); } } public static void main(String[] args) { Sub sub=new Sub(); System.out.println(sub.out()); } }
运行结果截图:
为什么是 这样 呢?
以下是个人理解:
main方法里创建子类实例,但是此时父类还未创建,所以先创建父类(新手用不来这个编辑器,怎么选择不了,好累)
创建父类过程:{
在类加载的准备阶段,为静态变量分配内存并赋默认值此时 count1=0,count2=0,testClass=null
初始化阶段为静态变量赋值、执行静态代码块,为testClass赋值调用构造方法产生类的对象,此时为实例变量在堆里分配内存并赋值count=“testClass”,接着执行输出语句,输出第一行。
然后count+1,count2+1.输出第二行。
继续为静态变量赋值,count1没有操作,仍为1,count2被重新赋值为0
}
创建
4000
父类之后初始化子类,子类没有声明静态变量,可能会有疑问,没有继承父类的静态变量吗?没有,等下解释
执行子类的默认无参构造方法 注意(构造方法中有 一句 super();),但是子类的count已经覆盖了父类的count属性,但是还未初始化,所以此时输出null 1 0 SUB第三行,因为此时运行的大环境是在子类的无参构造方法里,this指的其实是子类,所以调用的out方法为子类的out方法
接着count1+1,count2+1,此时count1=2,count2=1;同理接着输出第四行
到此为止子类构造方法里的supper()执行完成,子类实例变量初始化,子类count=testsub
最后的输出语句:子类对象调用out方法输出第五行
补充 (这才是重要的):static 变量是类变量,不属于任何对象,但是子类对象可以访问父类的静态变量,如果子类也声明了同名的变量也不会覆盖,只会访问子类自己的静态变量,因为用子类名和父类名访问的是不同的内存空间。
还有构造方法和实例变量初始化究竟是怎样的执行顺序(个人理解):这两个的执行在JVM中都归结到 <init> 方法,在init中的顺序是:supper();+ 实例变量初始化+构造方法里面的代码
欢迎批评指正
相关文章推荐
- java 父类子类成员变量,静态变量,构造器创建先后顺序
- 尝试创建一个父类和子类,分别创建一个构造方法,然后向父类和子类添加成员变量和方法,并总结构造子类对象时的顺序。
- JAVA final 、super 关键字以及继承关系中父类与子类实例变量初始化的 理解
- java 程序加载过程---3--类中申明同时申明类的静态对象 创建类的实例 访问类的静态变量 调用类的静态方法 使用反射方法 初始化类的子类对象 直接使用java.exe 调用某个类
- Objective-C 2.0 with Cocoa Foundation---对象的初始化以及实例变量的作用域(2)
- 构造方法的调用顺序和成员变量的初始化时机以及动态绑定
- Objective-C 2.0 with Cocoa Foundation---对象的初始化以及实例变量的作用域(2)
- “黑马程序员”声明类Student,包含3个成员变量:name、age、score,创建5个对象装入TreeSet,按照成绩排序输出结果(考虑成绩相同的问题)
- C++ 类的继承,子类以及之类的对象 对父类成员函数的访问权限
- Objective-C 2.0 with Cocoa Foundation--- 7,对象的初始化以及实例变量的作用域
- java 中的 成员变量、局部变量、静态变量、类变量、非静态变量、实例变量、向前引用、非法向前引用、静态代码块、非静态代码块 执行时机
- Objective-C 2.0 with Cocoa Foundation--- 7,对象的初始化以及实例变量的作用域
- java 父类子类静态成员,实例成员,构造函数初始化的顺序
- C++初始化列表问题,类中有一个对象类型的数组成员变量,在初始化列表中初始化时报错“[]”操作符语法错误
- java 中的 成员变量、局部变量、静态变量、类变量、非静态变量、实例变量、向前引用、非法向前引用、静态代码块、非静态代码块 执行时机
- 子类实例初始化父类(接口)对象
- Objective-C 2.0 with Cocoa Foundation---对象的初始化以及实例变量的作用域(3)
- java基础问题----------TreeSet里面放对象,如果同时放入了父类和子类的实例对象
- [C++]父类与子类的静态成员变量、实例成员变量、构造函数的执行顺序
- [笔试题 9][c/c++]关于成员变量,对象成员的初始化问题