4.实例变量和类变量内存分配

合集下载

成员变量、实例变量、类变量和局部变量区别

成员变量、实例变量、类变量和局部变量区别

成员变量、实例变量、类变量和局部变量区别
⼀、成员变量、实例变量、类变量和局部变量区别
1::变量电议部分所定义的变量被称为类的。

也就是说在整个类中都有效,类中的⽅法可以直接调⽤成员变量使⽤。

然⽽成员变量⼜分为实例成员变量(简称)和类变量(简称)
1.1::就是我们正常定义的变量,⽐如int a; a就是
1.2::定义前要加上Static ⽐如static int a;这个a就是静态变量,当在变量定义前加上static的时候就代表着该变量在使⽤的时候有⼀处改变则各个⽤到这个变量的地⽅,该变量都发⽣改变,就是所谓的⼀处改变处处改变,静态变量的⽣存期为整个,但是只能在定义该变量的函数内使⽤该变量。

退出该函数后,尽管该变量还继续存在,但不能使⽤它。

2::在⽅法体中定义的变量和⽅法的参数称。

也就是说只在定义它的⽅法内有效,⽽⽅法外部的其他⽅法⽆法使⽤局部变量。

当局部变量名字与成员变量名字相同,则成员变量被隐藏,即这个成员变量在这个⽅法内暂时失效,以局部变量定义的为准。

⼆.长提到的⽅法有,类⽅法,实例⽅法。

就是名字和类名相同,⽽且没有类型。

类⽅法和实例⽅法的区别就是类⽅法前⾯有static修饰,⽽实例⽅法没有static修饰。

实例⽅法既能对类变量操作,也能对实例变量操作,⽽类⽅法只能对类变量进⾏操作。

c++内存分配机制

c++内存分配机制

C++的内存分配机制可以分为四个区域:堆区、栈区、全局/静态存储区和常量存储区。

1. 堆区:动态内存分配区,程序在运行时可以向该区域申请一定大小的内存,用malloc或new来申请,用free或delete来释放。

2. 栈区:存放函数的参数值和局部变量,由编译器自动分配和释放,其操作方式类似于数据结构中的栈。

3. 全局/静态存储区:全局变量和静态变量被存放在此区域中,包括初始化的全局变量和静态变量(空白初始化的全局变量和静态变量也会被存放在此区域),全局变量和静态变量在程序整个运行期间一直被保留。

4. 常量存储区:常量被存放在此区域中,不允许修改。

C++内存分配机制遵循二八定律,即80%的内存空间被80%的程序所使用,而剩下的20%的内存空间则被浪费。

因此,在编写C++程序时,应该尽可能地利用好内存空间,避免内存空间的浪费。

Java简答题

Java简答题

Java简答题1、类和对象的关系?类定义了一种新的数据类型,可以用新类型来创建该类型的对象。

类(class)是对象(object)的模板,而对象是类的一个实例。

2、定义一个类需要包含什么元素?一个类包含属性和方法。

该类具有哪些特征使用属性表示,该类具有哪些行为使用方法来表示。

3、如何使用this关键字?This指向自己的引用,即当前方法所在的对象。

它的一个主要作用是要将自己这个对象当做参数,传送给别的对象中的犯法。

或者在类定义时使用this来引用自己的属性或方法。

4、类体中的方法包含哪些分类?按返回值分:有返回值、无返回值按参数分:无参数、有参数(单个参数,多个参数)按范围或功能分:实例方法、类方法、构造方法5.什么时候为类中的实例变量分配内存空间?在使用类创建实例对象时会为其分配空间。

(通过new关键字和构造函数为其实例化的时候)6.什么叫方法的重载?构造方法可以重载吗?一个类中可以有多个方法具有相同的名称,但这些犯法的参数必须不同,即或者是参数个数不同,或者是参数的类型不同,或者是参数的顺序不同。

构造方法可以重载,而且构造方法的重载是方法中使用频率最高的一种。

7. 简述类变量和实例变量的不同?(1)不同对象的实例变量将分配不同的内存空间,实例变量则属性独有,改变某一个对象的值不影响其他对象;而所有对象的类变量占用同一块内存空间,类变量是所有对象共有的,改变其中一个对象的值,其他对象得到的就是改变后的结果。

(2)类变量在类被加载到内存是就为其分配内存空间,而实例变量在使用new创建对象时,才为其分配内存空间;(3)类变量可以通过对象和类名访问,而实例变量只能通过对象访问。

(4)类变量通过static关键字修饰,实例变量不需要。

8.通过Student stu;语句定义一个用户类型变量时,是否能在内存中创建对象?通过Student stu;语句仅仅声明了一个类型为Student,名称为stu的引用变量。

内存分配方式范文

内存分配方式范文

内存分配方式范文内存分配是计算机中的重要概念,它指的是将计算机的内存资源分配给不同的程序和数据。

内存分配方式可以根据分配的策略和实现方式来进行分类。

下面将介绍几种常见的内存分配方式。

1.静态分配:静态分配是指在编译或链接阶段将内存空间分配给程序的变量或数据结构。

在静态分配中,内存的分配和释放是由编译器或链接器完成的,程序在运行期间不会改变内存分配的情况。

静态分配的优点是分配速度快,不会发生内存碎片问题,但缺点是需要预先确定内存的大小,不能动态调整。

2.动态分配:动态分配是在程序运行期间根据需要分配和释放内存空间。

常见的动态分配方式有以下几种:- 堆(Heap)分配:堆分配是通过指定大小在堆内存中分配一块连续的内存空间。

它通常用于创建动态分配的数据结构,如链表、树、堆等。

堆分配的优点是可以根据需要分配灵活大小的内存,但缺点是分配和释放的速度较慢,并且容易产生内存碎片。

- 栈(Stack)分配:栈分配是指在程序运行期间分配局部变量和函数调用的内存空间。

栈内存具有后进先出的特性,每次分配内存只需要修改栈指针即可。

栈分配的优点是分配和释放速度快,但缺点是分配的内存大小固定,不适合动态分配。

- 池(Pool)分配:池分配是指事先在内存中创建一定数量的内存块,然后根据需要从池中分配和释放内存。

池分配的优点是分配和释放速度快,且不容易产生内存碎片,但缺点是需要事先确定池的大小,不能动态调整。

3.分区分配:分区分配是指将内存空间分成多个固定大小的分区,每个分区用于分配给不同的程序或数据。

常见的分区分配方式有以下几种:-等大小分区:等大小分区是将内存空间分成大小相等的分区,每个分区只能分配给一个程序或数据。

这种分区方式容易产生内存碎片,但分配和释放速度较快。

-不等大小分区:不等大小分区是将内存空间分成大小不等的分区,每个分区可以根据需要分配给不同大小的程序或数据。

这种分区方式可以更有效地利用内存空间,但分配和释放速度较慢。

C++内存分配的五种方法

C++内存分配的五种方法

在C++中,内存分成5个区,他们分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。

栈,就是那些由编译器在需要的时候分配,在不需要的时候自动清楚的变量的存储区。

里面的变量通常是局部变量、函数参数等。

堆,就是那些由new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个delete。

如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收。

自由存储区,就是那些由malloc等分配的内存块,他和堆是十分相似的,不过它是用free来结束自己的生命的。

全局/静态存储区,全局变量和静态变量被分配到同一块内存中,在以前的C语言中,全局变量又分为初始化的和未初始化的,在C++里面没有这个区分了,他们共同占用同一块内存区。

常量存储区,这是一块比较特殊的存储区,他们里面存放的是常量,不允许修改(当然,你要通过非正当手段也可以修改,而且方法很多,在《const的思考》一文中,我给出了6种方法)明确区分堆与栈在bbs上,堆与栈的区分问题,似乎是一个永恒的话题,由此可见,初学者对此往往是混淆不清的,所以我决定拿他第一个开刀。

首先,我们举一个例子:void f() { int* p=new int[5]; }这条短短的一句话就包含了堆与栈,看到new,我们首先就应该想到,我们分配了一块堆内存,那么指针p呢?他分配的是一块栈内存,所以这句话的意思就是:在栈内存中存放了一个指向一块堆内存的指针p。

在程序会先确定在堆中分配内存的大小,然后调用o perator new分配内存,然后返回这块内存的首地址,放入栈中,他在VC6下的汇编代码如下:00401028 push 14h0040102A call operator new (00401060)0040102F add esp,400401032 mov dword ptr [ebp-8],eax00401035 mov eax,dword ptr [ebp-8]00401038 mov dword ptr [ebp-4],eax这里,我们为了简单并没有释放内存,那么该怎么去释放呢?是delete p么?澳,错了,应该是delete []p,这是为了告诉编译器:我删除的是一个数组,VC6就会根据相应的Cookie信息去进行释放内存的工作。

java语言程序设计(一)第三章补充

java语言程序设计(一)第三章补充

专接本辅导java第三章《面向对象编程基础》补充0.类变量与实例变量区别(类方法与实例方法的区别见习题解答第12题改错)java类的成员变量有两种:一种是被static关键字修饰的变量,叫类变量或者静态变量;另一种没有static修饰,为实例变量。

在语法定义上的区别:静态变量前要加static关键字,而实例变量前则不加。

在程序运行时的区别:实例变量属于某个对象的属性,必须创建了实例对象,其中的实例变量才会被分配空间,才能使用这个实例变量。

静态变量不属于某个实例对象,而是属于类,所以也称为类变量,只要程序加载了类的字节码,不用创建任何实例对象,静态变量就会被分配空间,静态变量就可以被使用了。

总之,实例变量必须创建对象后才可以通过这个对象来使用,静态变量则可以直接使用类名来引用。

例如,对于下面的程序,无论创建多少个实例对象,只在类被第一次装置时初始化一次staticVar变量和sum变量,并且每创建一个实例对象,就会执行一次构造函数;但是,每创建一个实例对象,就会分配一个instanceVar,即可能分配多个instanceVar,并且每个instanceVar的值都只自加了1次。

public class类变量与实例变量{public static int staticVar = 0;//类变量初始化,只会在类装载时进行一次!!public int instanceVar = 0;//实例变量初始化public static int sum=1;public类变量与实例变量()//构造方法{staticVar++;instanceVar++;sum=sum+5;System.out.println("staticVar = "+staticVar+",instanceVar="+instanceVar);System.out.println("sum = "+sum);}public static void main(String []args){类变量与实例变量对象1=new类变量与实例变量();类变量与实例变量对象2=new类变量与实例变量();类变量与实例变量对象3=new类变量与实例变量();}}运行结果:staticVar = 1,instanceVar=1sum = 6staticVar = 2,instanceVar=1sum = 11staticVar = 3,instanceVar=1sum = 16再如下面的程序,涉及static块:class Value{static int c=0;static int d;Value(){c=15;d=65;}Value(int i){c=i;d=c-1;}static void inc(){c++;}}public class Count {Value v0=new Value();//调用无参构造函数建立Value类非静态对象v0,类Count和类Value是has-a关系Value v=new Value(10);//调用有参构造函数建立Value类非静态对象vstatic Value v1,v2;//声明Value类的static对象v1,v2//static Value v1=new Value(),v2=new Value();//声明v1、v2并引用新建立的Value类对象static{//★声明static块,其初始化工作会先于任何其它非static块及非static变量而不管其在源程序书写中出现的先后次序!System.out.println("static块中println语句执行结果:"+"\n"+"v0和v是非静态内部类对象,v1和v2是静态内部类对象(请与教材P58例3.18对比),只有声明没有具体指向某对象时:v1.c="+v1.c+" v2.c="+v2.c+" v1.d="+v1.d+" v2.d="+v2.d);v1=new Value(30);//对象v1引用新建立的Value类对象System.out.println("static块中执行完“v1=new Value(30)之后:”v1.c="+v1.c+" v2.c="+v2.c+" v1.d="+v1.d+" v2.d="+v2.d);v2=new Value(15);//对象v2引用新建立的Value类对象System.out.println("static块中执行完“v2=new Value(15)之后:”v1.c="+v1.c+" v2.c="+v2.c+" v1.d="+v1.d+" v2.d="+v2.d);System.out.println("特别说明:因此时还没有建立Count类对象(Count 类和Value类是has-a关系,前者是外部类,后者是内部类)故非静态对象v0和v无法引用!"+"\n");}public static void main(String[] args) {Count ct1=new Count();//建立Count类(外部类)对象Count ct2=new Count();System.out.print("在main方法中,现在建立Count类(外部类)对象,");System.out.println("ct1的在ct2之前创建!分别指向两个Count类对象,Count类和Value类是has-a关系!"+"\n"+"以下是main方法体中println语句执行结果:");System.out.println("v0是无参构造内部类非静态对象,ct1.v0.c="+ct1.v0.c+" ct1.v0.d="+ct1.v0.d+" ct2.v0.c="+ct2.v0.c+"ct2.v0.d="+ct2.v0.d);// 非静态内部类对象只能通过外部类对象名访问System.out.println("v是有参构造内部类非静态对象,ct1.v.c="+ct1.v.c+" ct1.v.d="+ct1.v.d+" ct2.v.c="+ct2.v.c+" ct2.v.d="+ct2.v.d);// 非静态内部类对象只能通过外部类对象名访问System.out.println("v1是有参构造内部类静态对象,Count.v1.c="+Count.v1.c+" count.v1.d="+Count.v1.d);//静态内部类对象可以通过外部类名访问System.out.println("v2是有参构造内部类静态对象,Count.v2.c="+Count.v2.c+" count.v2.d="+Count.v2.d);Value.inc();//通过类名调用类方法System.out.println("调用类方法inc()之后Count.v1.c="+Count.v1.c+" Count.v1.d="+Count.v1.d);//引用类变量既可以通过类名也可以通过对象名System.out.println("调用类方法inc()之后Count.v2.c="+Count.v2.c+" count.v2.d="+Count.v2.d);Count.v2.inc();//通过类名调用类方法,这种写法不妥!System.out.println("调用类方法v1.inc()之后Count.v1.c="+Count.v1.c+" Count.v1.d="+Count.v1.d);//引用类变量既可以通过类名也可以通过对象名System.out.println("调用类方法v1.inc()之后Count.v2.c="+Count.v2.c+" count.v2.d="+Count.v2.d);ct1.v0.c++;//this.v0.c++;//错误,★不能在静态上下文中使用this关键字:!因为Value是Count的内部类,只能使用其外部类的对象ct2.v0.c++;System.out.println("顺序执行语句:ct1.v0.c++;ct2.v0.c++;后,ct1.v0.c="+ct1.v0.c+" ct2.v0.c="+ct2.v0.c);// 非静态内部类对象只能通过外部类对象名访问}}上面这个程序的行动结果如下:static块中println语句执行结果:v0和v是非静态内部类对象,v1和v2是静态内部类对象(请与教材P58例3.18对比),只有声明没有具体指向某对象时:v1.c=0 v2.c=0 v1.d=0 v2.d=0static块中执行完“v1=new Value(30)之后:”v1.c=30 v2.c=30 v1.d=29 v2.d=29static块中执行完“v2=new Value(15)之后:”v1.c=15 v2.c=15 v1.d=14 v2.d=14特别说明:因此时还没有建立Count类对象(Count类和Value类是has-a关系,前者是外部类,后者是内部类)故非静态对象v0和v无法引用!在main方法中,现在建立Count类(外部类)对象,ct1的在ct2之前创建!分别指向两个Count类对象,Count类和Value类是has-a关系!以下是main方法体中println语句执行结果:v0是无参构造内部类非静态对象,ct1.v0.c=10 ct1.v0.d=9 ct2.v0.c=10 ct2.v0.d=9v是有参构造内部类非静态对象,ct1.v.c=10 ct1.v.d=9 ct2.v.c=10 ct2.v.d=9 v1是有参构造内部类静态对象, Count.v1.c=10 count.v1.d=9v2是有参构造内部类静态对象, Count.v2.c=10 count.v2.d=9调用类方法inc()之后 Count.v1.c=11 Count.v1.d=9调用类方法inc()之后 Count.v2.c=11 count.v2.d=9调用类方法v1.inc()之后 Count.v1.c=12 Count.v1.d=9调用类方法v1.inc()之后 Count.v2.c=12 count.v2.d=9顺序执行语句:ct1.v0.c++;ct2.v0.c++;后,ct1.v0.c=14 ct2.v0.c=14以上运行结果中,有五点值得注意:一是static变量和static块是在类第一次装载时被初始化一次,并供类的所有对象共享,故static变量和static块中内容最先被初始化(早于main方法)。

自考教材《java语言程序设计(一)》第三章习题解答

自考教材《java语言程序设计(一)》第三章习题解答

第三章习题解答3.1什么是面向对象技术?它有什么优点?通过面向对象的方式,将现实世界的物抽象成对象,现实世界中的关系抽象成类、继承,帮助人们实现对现实世界的抽象与数字建模。

程序设计者考虑的是对象的描述、对象间的关系、类的管理、什么时候和什么地方调用对象的哪一种方法。

面向对象技术的最大优点是有效支持重用,使得大的程序也变得相对容易维护。

3.2面积对象的程序设计和面向过程的程序设计有什么区别?面向过程语言编程模式是:程序=数据结构+算法编程时需要考虑和内容是的程序什么、怎么做、重点考虑每个实现的细节。

面向对象的语言的编程模式是:程序=对象+消息程序设计者考虑的是对象的描述、对象间的关系、类的管理、什么时候和什么地方调用对象的哪一种方法。

3.3在程序中类和对象有什么区别?类是同一种对象的描述,类概括了同类对象的共有性质:数据和方法。

类的每个对象都有自己的标识,但它们具有相同的一级属性和提供相同的方法。

在程序中,对象的名称用于捐弃引用对象,对象的成员变量用于存储对象的状态值,对象和方法用于描述对象的行为。

3.4 类变量和实例变量,以及类方法和实例方法的区别。

加载类之前创建对象之后调用方法访问权限成员变量实例变量不分配内存各个对象之间各自分配独立的内存空间对象名.实例变量名被实例方法,构造方法访问类变量直接分配内存各个对象之间共享这段已经分配完的内存对象名.类变量名;类名.类变量名被实例方法,类方法,构造方法访问成员方法实例方法不分配入口地址共享一个入口地址对象名.实例方法名实例变量、类变量,实例方法、类方法类方法直接分配入口地址共享这个入口地址对象名.类方法名;类名.类方法名类变量、类方法3.5 子类能继承超类的哪些成员变量和方法?同包继承不同包继承(import进来的)私有(private)不继承不继承友好(缺省默认)继承不继承受保护(protected)继承继承共有(public)继承继承3.6 子类在什么情况下能隐藏超类的成员变量和方法?解:在子类重载父类的成员变量、方法的情况下。

Java2实用教程习题答案__第三版__耿祥义_清华大学出版社

Java2实用教程习题答案__第三版__耿祥义_清华大学出版社

Java2实用教程(第三版)课后习题参考答案第1章 Java入门1. 开发与运行Java程序需要经过哪些主要步骤和过程?答:(1)编写Java源文件:使用文本编辑器(Edit或记事本),拓展名为.java(2)编译Java源文件:使用Java编译器(javac.exe)。

得到字节码文件*.class(3)运行Java程序:Java应用程序使用Java解释器(java.exe)执行字节码文件;Java小应用程序使用支持Java标准的浏览器来执行。

2. 怎样区分应用程序和小应用程序?应用程序的主类或小应用程序的主类必须用public修饰吗?答:①应用程序必须有main方法,这个方法是程序执行的入口。

小应用程序没有main方法。

②应用程序的主类不一定用public修饰;小应用程序的主类必须用public修饰。

3. Java程序是由什么组成的?一个程序中必须要有public类吗?Java源文件的命名规则是怎样的?答:①Java程序由类组成。

②应用程序可以没有public类;小应用程序一定有一个类是public类(主类)。

③应用程序:如果只有一个类,源文件名与该类的类名相同,拓展名为.java;有多个类时,如果有public类(最多一个),源文件名与public类的类名相同,拓展名是.java;没有public类,源文件名与任何一个类的类名相同即可,拓展名为.java。

小应用程序:源文件名与主类的类名相同,拓展名是.java。

4. 在运行小程序的HTML文件中可以使用codebase属性指定小程序的字节码所驻留的目录。

如果不使用codebase属性,小程序的字节码文件必须和运行它的HTML文件在同一目录中。

编写一个小程序并将小程序的字节码存放在某个目录中,比如C:\5000;把运行该小程序的HTML文件(注意其中的codebase属性): <applet code=你的小程序的字节码 width=200 height=300 codebase=C:\5000></applet>存放在另一个目录中。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实例变量和类变量内存分配
Java向程序员许下一个承诺:无需关心内存回收,java提供了优秀的垃圾回收机制来回收已经分配的内存。

大部分开发者肆无忌惮的挥霍着java程序的内存分配,从而造成java程序的运行效率低下!
java内存管理分为两方面:
1,内存的分配:指创建java对象时,jvm为该对象在堆内存中所分配的内存空间。

2,内存的回收:指当该java对象失去引用,变成垃圾时,jvm的垃圾回收机制自动清理该对象,并回收该对象占用的内存。

jvm的垃圾回收机制由一条后台线程完成。

不断分配内存使得系统中内存减少,从而降低程序运行性能。

大量分配内存的回收使得垃圾回收负担加重,降低程序运行性能。

一,实例变量和类变量(静态变量)
java程序的变量大体可分为成员变量和局部变量。

其中局部变量有3类:形参、方法内的局部变量、代码块内的局部变量。

局部变量被存储在方法的栈内存中,生存周期随方法或代码块的结束而消亡。

在类内定义的变量被称为成员变量。

没使用static修饰的称为成员变量,用static修饰的称为静态变量或类变量。

1.1实例变量和类变量的属性
在同一个jvm中,每个类只对应一个Class对象,但每个类可以创建多个java对象。

【其实类也是一个对象,所有类都是Class实例,每个类初始化后,系统都会为该类创建一个对应的Class实例,程序可以通过反射来获取某个类所对应的Class实例(Person.class 或Class.forName(“Person”))】
因此同一个jvm中的一个类的类变量只需要一块内存空间;但对实例变量而言,该类每创建一次实例,就需要为该实例变量分配一块内存空间。

非静态函数需要通过对象调用,静态函数既可以通过类名调用,也可以通过对象调用,其实用对象调用静态函数,底层还是用类名调用来实现的!
1.2实例变量的初始化时机
对实例变量而言,它属于java对象本身,每次创建java对象时都需要为实例变量分配内存空间,并执行初始化。

从语法角度来看,程序可在三个地方对实例变量执行初始化:
1. 定义实例变量时指定初始值
2. 非静态初始块中对实例变量指定初始值
3. 构造器中对实例变量指定初始值
其中第1、2种方式比第三种方式更早执行,第1、2种方式执行的顺序与他们在源程序中的排列位置相关,在前面的先执行。

每当程序指定构造器来创建java对象时,该构造器必然会获得执行机会。

与此同时,该类所包含的非静态初始化块和定义实例变量指定初始值也将会获得执行机会,并且总是在构造器执行之前获得执行。

1.class TestDemo {
2.public TestDemo(){
3. System.out.println("这是一个构造函数");
4. System.out.println("ser的值为"+ser);
5. }
6. {//这是一个构造代码块
7. System.out.println("这是一个构造代码块");
8. ser=4;
9. }
10.double ser=3.0;
11.public static void main(String[] args) {
12. TestDemo test=new TestDemo();
13. System.out.println("...........");
14. TestDemo test2=new TestDemo();
15. }
16.}
1.<pre name="code"class="java">/*运行结果:
2.这是一个构造代码块
3.这是一个构造函数
4. ser的值为3.0
5. ...........
6.这是一个构造代码块
7.这是一个构造函数
8. ser的值为3.0
9.*/</pre><br>
定义实例变量时指定的初始值,初始块中为实例变量指定初始值的语句的地位是平等的,当经过编译器处理后,他们都将被提取到构造器中。

也就是说,对于类定义中的语句:
double ser = 3.0
实际上会被分成如下2次执行:
1.double ser ;创建java对象时系统根据该语句为该对象分配内存
2.ser =
3.0;赋值动作会被提取到构造器中执行!
实际上,ser所指定的初始化值每次都会被3.0覆盖,因为定义变量时指定的初始值和初始化块中指定的初始值的执行顺序,与它们在源程序中的排列顺序相同。

1.3类变量的初始化时机
类变量属于类本身,只有当jvm加载该类时才会为该类的类变量分配内存空间,并执行初始化。

从程序运行角度看,JVM对一个java类只初始化一次,因此java程序每运行一次,系统只为类变量分配一次内存空间,执行一次初始化。

从语法角度看,程序可在2个地方对类变量执行初始化:
1.定义类变量时指定初始值
2.静态初始化块中对类变量指定初始值。

两种方式的执行顺序与他们在源程序中排列顺序相同。

同样,程序先为所有类变量分配内存空间,再按源代码中两种方法的排列顺序执行相应的初始化值。

总而言之,对象的初始化过程为:
1.在栈内建立变量
2.类加载进内存
3.执行静态代码块
4.在堆内存中开辟空间,分配内存地址
5.在堆内存中建立对象的特有属性,并进行默认初始化
6.对属性进行显示初始化
7.对对象进行构造代码块初始化
8.对对象进行对应的构造函数初始化
9.将内存地址赋给栈内存中的变量。

相关文档
最新文档