深化Java基础之——对象与内存控制
来源:互联网 发布:二手域名 编辑:程序博客网 时间:2024/04/24 01:10
1.实例变量和类变量
看到这个标题大家一定想到的是static关键字,没错,被static关键字修饰的变量,方法,内部类,初始化块,这些都属于类,而不具体属于某个实例对象,可以直接通过类名来调用。关于static可能造成的内存泄漏,在后面的JVM文章里总结。这里我就简单通过两个程序总结一下类成员和实例成员的区别,以及创建一个对象后初始化的顺序。
实例变量属于对象,每实例化一个对象,就会为其在内存中分配一块空间。类变量只会在第一次使用该类时为其分配一份内存空间,无论创建了多少个该类的对象,static变量永远只有一份内存空间。一个类在使用之前,就会在JVM中对该类进行加载-连接-初始化,在连接时就会给类变量分配相应的内存空间。
1 public class B extends A { 2 public int m = method3(); 3 public static int n = method4(); 4 public int t = 0; 5 public B(){ 6 System.out.println(4); 7 } 8 public int method3(){ 9 System.out.println(5);10 return 5;11 }12 public static int method4(){13 System.out.println(6);14 return 6;15 }16 public static void main(String[] args) {17 System.out.println(7);18 A a = new B();19 }20 }21 22 class A {23 public int i = method();24 public static int j = method2();25 public int k = 0;26 public A(){27 System.out.println(1);28 }29 public int method(){30 System.out.println(2);31 return 2;32 }33 public static int method2(){34 System.out.println(3);35 return 3;36 }37 }
A、7 3 2 1 6 4 5 B、3 6 7 2 1 5 4 C、7 3 6 2 1 5 4 D、3 2 1 7 6 5 4
看看上述代码的输出结果应该选哪个呢?
让我们一步一步来分析:A类是B类的父类,在执行程序时,A类先被加载,并且为其类变量分配内存空间,所以先为24行的 j 分配内存,初始化为methond2()方法的返回值,这里的method2()也必须被static修饰,才能被调用,所以先输出3;同理,接下来为B类的类变量分配空间,输出6;然后执行16行main()方法,输出7;实例化B类的对象,先执行其父类(A)的非静态初始化(代码23行),method()方法输出2;然后是父类(A)的构造方法,输出1;然后是B类同理,依次输出5和4,程序结束,所以最终答案是B。
这个代码大家可以复制下来进行单步debug来细细体会。
再来看一个有趣的代码,细细品味。
1 public class PriceTest { 2 3 public static void main(String[] args) { 4 System.out.println(Price.instance.currentPrice); 5 //显示的创建Price对象 6 Price p = new Price(2.8); 7 System.out.println(p.currentPrice); 8 } 9 }10 11 class Price{12 //类变量13 final static Price instance = new Price(2.8);14 //类变量15 static double initPrice = 20;16 //实例变量17 double currentPrice;18 public Price(double discount){19 currentPrice = initPrice - discount;20 }21 }
上述代码输出了两次currentPrice,而且都是通过new Price(2.8)来创建实例,看起来应该是输出两次17.2,亲自运行一下这个代码,会发现结果却是-2.8和17.2。
下面从内存层面上来看看到底发生了什么,当然,首先还是先为Price类的类变量分配内存空间,这个时候两个static变量instance和initPrice值为null和0.0,接下来按这个顺序为它们初始化,instance的值为new Price(2.8),立即执行18行,所以这时的currentPrice是等于0.0 - 2.8的,instance初始化完毕,然后是initPrice初始化为20。所以第4行输出-2.8,执行第6行时,类变量initPrice已经为20,所以第7行输出17.2。
- 深化Java基础之——对象与内存控制
- 深化Java基础之——数组与内存控制
- java基础-----------对象与内存控制
- (二)Java对象与内存控制
- java的对象与内存控制
- java 基础概念 -- 数组与内存控制
- 对象与内存控制
- 对象与内存控制
- 对象与内存控制
- 对象与内存控制
- 对象与内存控制
- 对象与内存控制
- 疯狂java之数组与内存控制
- java之数组与内存控制
- 对象与内存控制之实例变量与类变量
- java基础之流程控制与方法
- Java进阶---对象与内存控制(一)
- java:浅谈数组与对象的内存控制
- ResNet残差网络
- 关于大三找实习的一些思考
- 深化Java基础之——数组与内存控制
- Java I/O 学习总结(一)
- Java I/O 学习总结(二)
- 深化Java基础之——对象与内存控制
- Java实现常见的排序算法
- 栈
- (SystemJS) Can't resolve all parameters for
- @Autowired默认规则
- 关于Office Professional Plus 2013 VOL 和Office Professional Plus 2013
- wget 无法建立ssl连接 ERROR: certificate common name “a.ssl.fastly.net”
- service的简介
- AlexNet论文翻译与解读