您的位置:首页 > 职场人生

黑马程序员--03.Java面向对象--04.【对象初始化的过程】【对象调用成员的过程】

2013-07-18 20:05 706 查看

Java面向对象--4

      对象初始化的过程   对象调用成员的过程

----------- android培训java培训、java学习型技术博客、期待与您交流! ------------

给出一段代码:

class Person{
private String name;
private int age =20;
private static String country ="cn";

static{
System.out.println("Staic Block....");
}

//构造代码块
{
System.out.println("Construction Block....name ="+name +"...age ="+age);
}

//构造方法
Person(Stringname, int age){
this.name =name;
this.age =age;
System.out.println("Construction Function....name ="+name +"...age ="+age);
}
}

1.    对象初始化的过程

在测试类的main中,创建两个Person类的对象。

class Test{
public static void main(String[] args) {
Personp =new Person("Benjamin", 28);
Personp1 =new Person("ZXM", 28);
}
}
结论
在调用一个类的构造方法进行对象的创建的时候,进行的动作如下:

【step 1】.
该类中静态成员默认初始化(执行一次,当类加载到内存时)[option]

【step 2】.
该类中静态成员显式初始化(执行一次,当类加载到内存时)
[option]

【step 3】.
执行该类的静态代码块类初始化(执行一次,当类加载到内存时)
[option]

【step 4】. 实例变量默认初始化 (堆内存中的成员具有默认值)

【step 5】. 实例变量显式初始化 [实际上就是直接为这个成员变量赋值]

【step 6】. 构造代码块为该对象进行公共初始化

【step 7】. 构造函数为该对象进行特定初始化

注意:其中,前三步是可选的,如果这个类中存在静态变量和静态代码块,才执行前面三步。但是,仅仅执行一次!!

【总结】Person p =new Person("Benjamin", 28);这句话一执行,都做了什么事情?

<1>. 因为new的时候用到了Person类的构造方法,所以类文件Person.class会被加载到内存中。此时静态成员变量在方法区中开辟了内存空间。

<2>. 为静态成员country进行默认初始化,初始化值为null

<3>. 为静态成员country进行显式初始化,初始化值为cn

<4>. 执行Person类的静态代码块,并输出Staic Block.... country: cn

<5>. OS在堆内存中开辟空间,为Person类的对象分配内存地址

<6>. 在堆内存中建立成员变量,并进行默认初始化

     这里面,name默认初始化为null,age默认初始化为0

<7>. 为堆内存中的成员变量进行显式初始化。age显式初始化为20

<8>. 为该对象进行构造代码块初始化。此处打印出:

        Construction Block....name=null...age =20
<9>. 为该对象进行指定构造函数初始化。name和age分别显式初始化为Benjamin和28
     并且打印出:Construction Function....name=Benjamin...age =28
<10>. 将对象在堆内存中的地址赋值给栈内存中的Person类的引用变量p。

2.    对象调用成员的过程

class Person{
private String name;
private int age =20;
private static String country="cn";

Person(Stringname, int age){
this.name =name;
this.age =age;
}

public void speak(){
System.out.println(this.name +"..."+ this.age);
}

public void setName(String name){
this.name =name;
}

public static void showCountry(){
System.out.println("country ="+ country);
method();
}

public static void method(){
System.out.println("static method is running");
}
}

class Test{
public static void main(String[] args) {
Personp =new Person("Benjamin", 28);
p.setName("ZXM");
Person.showCountry();
}
}
这里面,main方法执行每一条语句,内存变化过程如下:



<1>. 对象初始化过程在前面,并且在栈内存中,为main方法开辟了方法中局部变量的内存空间。此时Person类引用变量p指向堆内存中的Person类对象。

name值为Benjamin  age值为20

<2>. 执行p.setName("ZXM");

首先OS在栈内存中为setName方法开辟了局部变量的内存空间,并且形参name接受main方法中传入的实参,初始化为ZXM。

由于setName为非静态方法,并且调用了该对象的另一个非静态成员。所以,这个name成员所属的对象就是this。这个this就是在主方法中调用setName方法的对象p。因此setName中的this指向堆内存中的那个对象。p.setName(“ZXM”)相当于将p的值赋值给了this每一个非静态方法中都有一个this变量。

执行完之后,栈内存的setName中对应的临时变量name和引用变量this全部释放。

<3>. 执行到Person.showCountry();

    这个是静态方法,在栈内存中开辟了临时变量的内存空间。注意:静态方法中是没有this的!! 此时调用的静态变量country并没有经过堆内存。而是经过方法区中的country。值为cn。

<4>. 静态方法showCountry()中又调用了另一个静态方法method()。此时在栈内存中也为method开辟了一个局部变量对应的内存空间。注意:静态方法中是没有this的!!

请问:showCountry中调用了method()

public
static void
showCountry(){
    System.out.println("country ="+
country);
    method();
}
这个method之前有省略的东西么?

一定有!!因为只要是方法执行了,一定是被调用了,必须先调用,后执行。

静态方法之间相互访问,如果写成直接访问,那省略的一定是“类名.”

public
static void
showCountry(){
    System.out.println("country ="+
country);
    Person.method();
}
【结论】

非静态成员方法直接访问其他的非静态成员,省略的是this.

静态成员方法直接访问其他的静态成员,省略的是类名.

【个人总结】

从上面方法区和栈、堆可以看出,代码和代码中使用到的数据是相对独立的内存区域。

----------- android培训java培训、java学习型技术博客、期待与您交流! ------------

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐