本帖最后由 行意天下 于 2015-1-21 23:00 编辑
Java中对象在内存中初始化过程详解
一、内存
在java中,内存被划分为3大区域:栈内存、堆内存、方法区(也叫做共享区、数据区)
栈内存:栈内存是用来存放局部变量,默认不会对其初始化,所以局部变量只有赋值后才能参与运算。 堆内存:堆内存是用来存放数组及对象(也即new出来的东西),相应对象的非静态成员变量也会存储在堆内存当中。默认在堆内存中会对数组、成员变量初始化。 方法区:方法区可分为静态区与非静态区。静态区存放静态方法与静态变量,非静态方法区存放非静态方法与变量。 用画图的方式来分析代码中各个对象和变量在内存中是怎么分配空间的,可以更高效和轻松的理解Java中难以弄懂的概念,避免混淆。 二、对象初始化 下面我以下面的源代码为例来写一下自己的感悟
- <strong>/**
- 对象初始化过程
- */
- class Person
- {
- String name;
- int age;
- static String country = "CN";
-
- public static void main(String[] args){
- Person p = new Person("zhangsan",20);
- p.speak();
- Person.show();
- }
- static{
- System.out.println("Person类的静态代码块执行语句1");
- }
- static{
- System.out.println("Person类的静态代码块执行语句2");
- }
- {
- System.out.println("Person类的构造代码块执行语句1");
- }
- {
- System.out.println("Person类的构造代码块执行语句2");
- }
- Person(){
- }
- Person(String name,int age){
- this.name = name;
- this.age = age;
- }
- void speak(){
- System.out.println("我叫" + name + "我的年龄是" + age + "岁");
- }
- static void show(){
- System.out.println("我来自" + country);
- }
- }
- </strong>
复制代码
在命令行编译结果如下:
从编译结果来看,对象创建过程如下:
1.由JVM(java虚拟机)在classpath环境变量路径下寻找Person.class这个主类,并且加载至内存当中。加载这个Person主类的同时,会执行静态代码块的执行语句,有几个静态代码块就执行几个,且只执行一次。同时Java会在方法区为Person类开辟内存空间,并创建静态成员变量country,也会为Person类的两个方法speak()和show()在方法区开辟内存空间。
2.在栈中为Person主类的main()函数开辟内存空间,并在栈内存当中创建一个Person类型的引用变量p,同时在堆内存中创建Person类的对象,并创建对象的两个成员变量name和age,将这个对象的内存地址赋值给p变量。在堆内存中创建Person对象,会执行Person类的构造代码块,然后去执行它的构造方法。
3.p.speak()会在栈内存中调用方法区中的speak()方法,同理p.show()也会在栈内存中调用方法区中的show()方法。
由此可见,在分析源代码的时候同时思考内存中的变化,更有利于我们深刻地从本质上理解源代码的执行顺序。
|