首页天道酬勤java 内存溢出,java声明静态变量

java 内存溢出,java声明静态变量

张世龙 05-06 03:46 83次浏览

静态

静态的最大原因是节约内存,只存储一部分,对象共享此属性。

静态作用是什么?

场景:

如果每个对象具有相同的属性(如country='China ' ),则会为每个对象所在的堆内存分配一个空间,以保留此属性值country='Chian '。

每个对象的country属性值相同,所以是否只需要一个存储空间? 这将节省堆的内存容量。

答案很好。

静态限定的属性的值由所有对象共享。

注意:由于静态是共享的,因此不能将特定于对象的属性定义为静态。 像Person类这样的name不能是静态的。

例如,如果饮水机是共享的,而所有人都在共享同一台饮水机,则它是静态的;

例如,如果杯子是特有的,每个人都有属于自己的杯子,就不是静态的。

静态特征:

静态限定成员。 优先于对象的存在。

静态限定成员。 随着类的加载进入内存。

静态静态限定成员是共享的,并且存储在对象中是唯一的。

静态静态限定成员不仅可以直接用于对象,还可以直接用于类;

静态好处:

实现共享数据在内存中的唯一存储,节约内存空间;

各对象不需要在堆内存中单独预留空间进行保存,直接使用共享数据即可。

静态缺点:

它驻留在内存中,内存释放周期长,并且只会随着类的消失而消失。

班级什么时候消失?

实际上,类也是一个对象,在JVM启动时加载类路径目录下的类。 如果内存中加载的类太多,JVM GC会根据某种算法清理几个加载的类,从而释放空间。

JVM关闭后,类将消失。

类变量和成员变量的区别

类变量不是类的成员变量

存储位置不同

成员变量。 堆内存中每个对象都有不同的成员变量存储

静态变量在方法区域中是唯一的,是类变量,每个对象共享使用该变量

生命周期不同

成员变量随对象的创建而存在,并随对象回收而释放

静态变量随类加载而存在,并随类丢失而释放

调用方法不同

成员变量。 仅由对象调用

静态变量。 通常直接使用类名调用

成员变量---实例变量,特定于对象的属性

静态变量---对象具有相同属性的类变量

静态限定属性

静态变量也称为类变量

静态变量存储在方法区域的静态区域内存中。

如果每个对象的属性值相同,请考虑使用静态来限定属性。

公共静态字符串计数=' cn ';

方法区域:

方法/函数的存储位置。

方法区域分为静态数据区域、常数区域、代码区域(保存方法代码的区域)等。

需要说明的地方:

类中的代码是如何存储的?

类中可定义的内容:成员变量、类变量、构造方法、常规方法和静态方法。

其中,

成员变量是对象特定的数据,存在于成对内存中

构建方法、一般方法存储在方法区域的非静态区域中

类变量,静态方法。 存储在方法区域的静态区域中

=====================================

静态修饰方法

静态限定的方法是有限的,只能使用静态变量或调用静态方法。

不需要创建方法、工具类或对象

方法可以定义为静态方法,除非有特定于操作对象的数据;

1 .创建对象以调用静态方法,浪费时间、空间,没有意义

---专用结构方法(单实例模式),防止外部通过对象调用静态工具方法;

2 .静态方法无法引用对象,因此静态方法无法处理对象特定的数据();静态存在于对象之前);

由于静态方法先于对象加载到内存中,因此:

静态方法可以使用静态成员(静态属性、静态方法);

静态方法不能使用this/super关键字;

=====================================

静态什么时候使用?

1 .静态变量/类变量(从堆内存节约方面来看) ) ) ) ) )。

对象中成员变量的所有值都相同,如果需要仅使用该值而不进行更改,则将其定义为静态。

如果至少有一个对象可能更改此值,则必须将其定义为成员变量并将其存储在堆内存中。 在这种情况下,不能静态定义。

好处:

每个对象不需要为堆内存中的同一数据分配空间,而只需要在方法区域中存储一个数据。

前提:对象只读取该数据,不修改该数据。 因为大家都共享那个数据。

2.静态方法(从执行代码上考虑,从方法的调用上考虑)

方法能否被定义为静态,就看一点:

方法中是否使用到了对象的特有数据或者调用到了普通方法,如果没有,则定义为静态方法!

好处:

1.不需要创建对象,因为创建对象耗费时间空间,而且静态方法的执行中没有使用到对象的数据。

(创建对象需要在堆内存开辟空间,调用构造方法进行初始化等操作)

2.调用简单,直接通过类名即可调用方法。

注意:不管是静态方法还是非静态方法,都只是一段代码,在方法区中都只存一份,只是存放的区域不同而已!不存在节约内存的说法。

=========================================================================

扩展:主函数main为什么设计成static的

首先,主函数的功能:程序的入口,由JVM调用

主函数专注于:

* 在函数体中创建其它类的对象,指挥这些对象调用它们各自的方法来完成某种功能!

* 代码按功能封装到函数中

* 函数都封装到类中

* 主函数只做一件事:创建那些封装好的类的对象,再调用类的方法!

Java代码

publicclassStaticTest {

/**

* 对象的特有属性,每个对象的id都不同

*/

intid;

/**

* 讨论主函数为什么是静态static的

* 1.主函数是程序的入口。

* 2.主函数中调用其它函数的2种方式:

*      a.静态方法,由类名调用;

*      b.非静态方法,由对象调用

* a.静态方法,被主函数调用,由于静态方法中只能使用类变量,使得静态方法的功能具有局限性(对象的特有属性无法在静态方法中使用,因为对象还未创建),不能满足大多数的功能需求;

* 这样就只留另一条路,调用非静态方法

* b.非静态方法的调用,必须由对象来操作,所以,主函数中必须先创建对象,再通过对象来调用,使得大多数功能的调用都以对象为起点进行

* Java面向对象,以对象为核心,将主函数设计为静态的,强制开发人员通过对象来调用方法!

*

* 哦也!

* @param args

*/

publicstaticvoidmain(String[] args) {

//say(); //静态方法中不能调用非静态方法

//只能通过对象来调用

StaticTest test = newStaticTest();

test.say();

//把say()也变为静态的,也能直接调用啊!其后果是,say()要能执行,那么id也必须静态,静态即共享--->id是对象的特有属性,不同对象有不同的id

//所以,主函数中调用方法,遵从Java的规范,用对象来调用方法!!!

}

publicvoidsay() {

System.out.println(this.id);

}

}public class StaticTest {

/**

* 对象的特有属性,每个对象的id都不同

*/

int id;

/**

* 讨论主函数为什么是静态static的

* 1.主函数是程序的入口。

* 2.主函数中调用其它函数的2种方式:

* a.静态方法,由类名调用;

* b.非静态方法,由对象调用

* a.静态方法,被主函数调用,由于静态方法中只能使用类变量,使得静态方法的功能具有局限性(对象的特有属性无法在静态方法中使用,因为对象还未创建),不能满足大多数的功能需求;

* 这样就只留另一条路,调用非静态方法

* b.非静态方法的调用,必须由对象来操作,所以,主函数中必须先创建对象,再通过对象来调用,使得大多数功能的调用都以对象为起点进行

* Java面向对象,以对象为核心,将主函数设计为静态的,强制开发人员通过对象来调用方法!

*

* 哦也!

* @param args

*/

public static void main(String[] args) {

//say(); //静态方法中不能调用非静态方法

//只能通过对象来调用

StaticTest test = new StaticTest();

test.say();

//把say()也变为静态的,也能直接调用啊!其后果是,say()要能执行,那么id也必须静态,静态即共享--->id是对象的特有属性,不同对象有不同的id

//所以,主函数中调用方法,遵从Java的规范,用对象来调用方法!!!

}

public void say() {

System.out.println(this.id);

}

}

什么叫静态变量和静态方法,静态方法改变静态变量值