两类数据类型
基本数据类型
byte,short,char,int,long,float,double,boolean引用数据类型
类,接口,数组,枚举,注解
栈内存
存放内容
存放无static修饰的基本数据类型变量。
存放引用数据类型指向堆内存的引用地址。栈内存中数据的生命周期
调用函数,进入函数作用域,执行到创建变量的语句时,变量创建,被调用函数执行结束,离开函数作用域,变量释放。
for(//作用域){
//局部变量,随域一次循环结束,释放。
}
if(){
//作用域
}
Person p1 = new Person();
Person p2 = new Person();
p1 = p2;
//p1,p2即存放在栈内存中的引用地址,指向堆内存中开辟的对象空间。
//p1 = p2; 改变的是引用地址的指向(内存地址)。
//即p1在栈内存中的引用变为p2,而不是堆内存中开辟的p2空间覆盖p1空间。
new 做的三件事
1.在内存(堆内存)中开辟一块空间。
2.在开辟的空间中创建对象。
3.调用对象的构造函数初始化对象。
堆内存
存放内容
存放所有类类型的对象。堆内存中数据的生命周期
当堆内存中的对象空间,没有任何引用地址指向时,程序将无法访问该对象,Java的垃圾回收机制(GC)将会回收,释放该对象所占的内存区域。
方法区
静态区
字符串常量池
成员变量与局部变量的区别
成员变量 | 局部变量 | |
---|---|---|
定义位置 | 当前类中 | 函数中 |
应用范围 | 所在类中任何位置都有效 | 形参,函数作用域内 |
生命周期 | 跟随对象创建,消失 | 跟随作用域创建,消失 |
存储位置 | 堆内存 | 栈内存 |
初始值 | 若new时没有赋值,将赋默认值 | 无默认值,想使用必须指定赋初值 |
static
class Demo{
public static int sTest = 1;
public static String mStr = "Test log";
public static void test(){
只能调用静态成员,不能用this,super,原因:静态生命周期
System.out.println(mStr);
}
}
调用方式
public static void main(String[] args) {
Demo.test();
System.out.println(Demo.sTest);
}
注意
static可以修饰成员变量,内部类,但是不能修饰局部变量。原理
类(.class)文件通过加载链接装载进内存,虚拟机会先验证.class文件的字节流,确认包含的信息符合当前虚拟机的要求。
验证结束进入准备阶段,正式为类变量分配内存,并设置类变量的初始值,此时内存分配的仅包括被static修饰的类变量,不包括实例变量。
实例变量将会在对象实例化时随着对象一起分配在堆中。
Java虚拟机类加载机制
- 静态的生命周期
静态变量随着类的加载而存在,随着类的消失而消失
final
class Demo{
final修饰的常量不会被初始化,必须手动赋初值,只能赋值一次
命名规则:所有字母都大写,如果由多个单词组成,单词间通过 _ 连接。
final public static int S_TEST = 1;
final修饰的函数不能被继承,重写
final public static void test(){
System.out.println("Test log");
}
}
内部类定义在类中的局部位置上时,只能访问该局部被final修饰的局部变量。