内存划分:
static作用:Java的JVM在运行程序时,检测程序中所有使用static修饰的成员,把static修饰的内容直接放在内存的静态区域中。
static成员的访问方式:类名.成员名
本质:静态成员属于类,而不属于对象,是公共的
静态成员的生命周期:当程序运行时,在内存的静态区域中存在,当程序关闭后,静态成员在内存的静态区域中销毁。
使用场合:对于所有对象都共同的使用静态。
1.栈(堆栈)
栈是一个只有一个口的容器,存储的数据从该口进出,先进后出,后进先出,遵循(FILO)先进后出的原则.
栈在方法被调用时产生,在方法结束时被销毁.
2.堆
堆是一个没有管理者的容量很大的容器
3.堆\堆栈
- Java在程序运行的时候依靠JVM在系统内存中划出一片很大的区域(约600~700M),该内存被当前程序中所有的数据共享,称为Java的堆内存.
- 在方法被调用的时候,针对每一个方法,JVM会为每一个方法生成一个对应的栈(方法栈),该方法结束的时候栈被销毁,方法栈称为Java的占内存.(方法结束的标志是:做出返回值或者是运行到方法体的最后一行)
4.数据的存储
数据分为基本数据类型和引用数据类型
区分数据类型的方式:存放该数据的变量是否能进行点 **.**操作
基本数据类型:
存放在栈内存中,对int a = 12;来说,int a 称为引用,12称为值,基本数据类型的引用和值都在栈里
引用数据类型
对于int[] array = {…}来说,它的引用部分int[] array
存放在栈里面,而 {...........}
存放在堆里面.我们把堆内存中的数据部分所占的空间的第一个位置在JVM里面的编号存放在int[] arr 里面,该编号是一个十进制的数字,我们把这个数字称为hashcode(哈希值).
注意:Java中没有地址的概念,只有JVM编号,也就是所谓的hashcode
5.两种数据类型修改值的情况
场景一:A方法中定义数据,调用B方法把A方法中定义的数据作为A方法的参数对该数据进行修改
现象:
基本数据类型时,B方法中值的修改无效
public class ValueChangeTest01 { public static void main(String[] args) { //一个int型变量number int number = 10; //输出10 System.out.println("number"); //调用changeNumber方法 changeNumber(number); //输出10 System.out.println(number); } public static void changeNumber(int number) { number = 12; } }
原因是方法随着调用的时候而分配栈内存,
当该方法结束后就会销毁这个栈内存.在方法
被调用的时候,该方法会通过参数列表来创建
一个局部变量(存放在自己的方法栈里面),
代码 number=12;是把12赋值给方法
changeNumber()里的变量number,并且
所以并当此方法结束后会销毁栈,所以在
main方法中显示的还是10
引用数据类型时,B方法中值的修改有效
public class ValueChangeTest02 {
public static void main(String[] args) {
int[] arr = { 10 };
//输出10
System.out.println(arr[0]);
changeNumber(arr);
//输出12
System.out.println(arr[0]);
}
public static void changeNumber(int[] arr) {
arr[0] = 12;
}
}
结论:
- 对于基本数据类型,作为参数的时候传递的并不是数据本身,而是数据的值,叫做值传递
- 对于应用类型数据,作为参数的时候传递的是数据本身(内存中存储这个引用的那块区域的起始的编号),修改是有效的,叫做引用传递
上述结论可以辅助记忆,但不是很准确,可以推翻
7.变量的作用域
- 全局变量:
类的属性就是全局变量,所以全局变量和所有的方法平级,因此可以被所有的方法共享,且无需作为方法的参数传入(全局变量一般都不设置初始值,但也可以设置) - 局部变量
方法内部定义的变量以及方法参数列表中的参数称为方法的局部变量,它们专属于该方法,可以通过传参的方式传递给其他方法使用----值传递和引用传递.