Java中的static关键字表示“全局”或者“静态”的意思,用来修饰成员变量和成员方法,也可以修饰代码块以及内部类。
当JVM加载一个类的时候,如果该类存在static修饰的成员变量和成员方法,就会为这些成员变量和成员方法在固定的位置开辟一个固定大小的内存区域;同时被static修饰的成员变量和成员方法是被该类的所有实例共享的,不依赖于某个特定的实例变量,任何一个实例对其的修改都会导致其他实例的变化。
一。 静态变量与非静态变量的区别:- 内存分配时间:静态变量在应用程序初始化,即类加载时分配内存,直到它所在类的应用程序运行结束时才会消亡;非静态变量需要被实例化后才会分配内存。
- 生存周期:静态变量的生存周期为应用程序的存在周期;非静态变量的存在周期取决于实例化的类的存在周期。
- 共享方式:静态变量是全局变量,在内存中仅有一个,被类的所有实例对象共享,如果一个实例改变了静态变量的值,其他同类的实例读取到的就是变化后的值;非静态变量是局部变量,不共享,每次实例化都是一个新的变量。
- 调用方式:静态变量只能通过“类名.变量名”调用;非静态变量当该变量所在的类被实例化之后,可以通过实例化后的对象名直接访问。
- 访问方式:静态成员不能访问非静态成员;非静态成员可以访问静态成员。
- 被static修饰的方法就是静态方法,即类方法;没有被static修饰的方法就是非静态方法,即实例方法。
- 因为静态方法不属于类的实例成员,所以静态方法只能被重载,而不能被重写,在静态方法中也不能使用 this 或 super。
- 静态方法会在类加载的时候被分配和加载入内存中;非静态方法属于对象的具体实例,只有在类对象创建时,在对象的内存中才有这个方法的代码块。
- 静态方法中不能调用非静态方法和非静态变量;非静态方法可以调用静态方法,也可以调用非静态方法。
- 静态方法可以由实例对象调用,也可以由类名直接调用,即“类名.方法名 或者 对象名.方法名”;非静态方法必须由实例对象来调用,即“对象名.方法名”
- 执行时机:静态代码块是对类进行初始化,在JVM加载类的时候就会执行,而且只执行一次,如果一个类包含多个静态代码块,那就是按照代码顺序执行。非静态代码块是对类对象的初始化,在每次创建对象的时候它都会执行。
- 都是在JVM加载类的时候且在构造方法之前执行,在类中都可以定义多个,一般在代码块中对一些static变量进行赋值。
- 静态代码块在非静态代码块之前执行,非静态代码块可以在普通方法中定义(不过作用不大),而静态代码块不行。
四、相关问题:
1、父类及子类的静态代码块、构造代码块、构造函数、静态成员变量、普通成员变量的执行顺序?
(1)执行父类的静态代码块,并初始化父类静态成员变量;
(2)执行子类的静态代码块,并初始化子类静态成员变量;
(3)执行父类的构造代码块,执行父类的构造函数,并初始化父类普通成员变量;
(4)执行子类的构造代码块, 执行子类的构造函数,并初始化子类普通成员变量;
(先父后子,先静后非)
2、构造代码块与构造函数的区别是:
构造代码块是给所有对象进行统一初始化,而构造函数是给对应的对象初始化,因为构造函数是可以多个的,运行哪个构造函数就会建立什么样的对象,但无论建立哪个对象,都会先执行相同的构造代码块。也就是说,构造代码块中定义的是不同对象共性的初始化内容。
3、全局变量,即静态变量的优缺点:
(1)优点:可以减少变量的个数,减少由于实际参数和形式参数的传递带来的时间消耗。
(2)缺点:
① 占用更多的内存空间。全局变量在程序启动运行时就开始分配内存,程序结束时释放内存,与局部变量的动态分配、动态释放相比,他的生命周期比较长,因此过多的全局变量会占用较多的内存。
② 全局变量会破坏函数的封装性。如果使用了全局变量。那么函数体内的语句就可以绕过函数参数和返回值进行存取,这种情况破坏了函数的独立性,是函数对全局变量产生依赖性,也会降低函数的可移植性。
③ 使得函数代码的可读性差。由于多个函数都可能使用全局变量,函数执行时全局变量的值可能随时发生变化,对于程序的查错和调试都非常不利。
④ 在多线程的情况下,需要同步各个线程对于全局对象的读写 *** 作。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)