一、内存管理:由JVM管理的
编译期:JVM加载并运行.class字节码文件,生成计算机能识别的二进制
堆:
- 存储new出来的对象(包括实例变量)
- 垃圾:没有任何引用所指向的对象,GC回收的是一些对象
垃圾回收器(GC)
垃圾回收器(GC)不定时到内存中清扫垃圾,回收的过程中透明的(看不到的)
不一定一发现垃圾就立刻回收,通过调用System.gc()建议JVM尽快调度GC来回收
- 实例变量的生命周期:创建对象时会存储在堆中,对象被回收时一并被回收
- 内存泄漏:(简单来说就是内存浪费)不再使用的对象没有被及时的回收,严重的泄露会导致系统的崩溃,建议再使用的对象应该及时将引用设置为null
没有引用指向的对象就是垃圾
Bomb b = new Bomb(100,200);
Bomb bb = b; //将b中的地址赋值给bb了,指向了同一个对象
栈:
- 存储正在调用的方法的局部变量(包括方法的参数)
- 调用方法时,会为该方法在栈中分配一块对应的栈帧,栈帧中存储局部变量(包括方法的参数),地址方法调用结束时,栈帧被自动清除(不是被GC清除的),局部变量一并被清除。再调再分配,调用完再清除。
方法执行完毕以后,会自动清除在栈中存储的该方法的栈帧
1. 系统自动调用main方法,会在栈中给main方法分配一块栈帧,main的栈帧会存放局部变量(和地址)
2. 只要调用show方法,会在栈中在分配一块栈帧给show方法,然后把show方法的局部变量装进去
3. show方法走完之后,会把他的栈帧自动清除
4. 同理main的栈帧会在main方法执行完毕后自动清除
class Aoo{
int a;
void show(int b){
int c = 5;
}
}
一但main结束,内存就清空了(方法区也空了)
局部变量的生命周期
调用方法时存储在栈中,方法调用结束时与栈帧一并被清除
方法区
- 存储.class字节码文件(包括静态变量,所有方法)
- 方法只有一份,通过 this 来区分具体的调用对象
分析:
- 先加载方法区,字节码文件,包括各种静态变量和方法
- 创建一个Bomb的对象,把它存到堆中,以及他的实例变量
- b1是main方法的局部变量,系统默认调用main方法,所以会给main方法分配一块栈帧,栈帧一开始是空的,在方法的执行过程中会把局部变量b1,以及方法的参数存入到main的栈帧中.
- 同理调用b1,b2调用show方法,会把show方法中的局部变量和方法参数存入到show的栈帧中,称为入栈
- 当show方法执行完毕以后,会把他的栈帧自动清除,称为出栈
- 同理,main方法的栈帧会在main方法执行完毕会自动清除
重点
- 出入栈遵循先进后出的原则
- main方法是第一个入栈的,也是最后一个出栈的
- 所以可以理解为使main方法的大括号包含着其他的方法
面向对象三大特征总结
1、封装
1)类:封装对象的属性和行为
2)方法:封装的具体的业务逻辑实现(保护功能实现的安全)
3)访问控制修饰符:封装的是具体的访问权限(保护数据安全)
2、继承
作用:代码的复用
超类:所有派生类所共有的属性和行为
接口:部分派生类所共有的属性和行为
派生/实现类:派生类所特有的属性和行为
单一继承、多接口实现,具有传递性
3、多态
1)行为多态:所有抽象方法都是多态的(通过重写来表现)
对象多态:所有对象都是多态的(通过向上造型来表现)
重写、向上造型、强制类型转换、instanceof判断
object:所有类的鼻祖,所有类都直接或间接继承了Object,默认都继承了object
Aoo o1 = new Aoo();
Object o2 = new Aoo();
ObserveSubmarine o2 = new ObserveSubmarine();
SeaObject o3 = new ObserveSubmarine();
EmemyScore o4 = new ObserveSubmarine();
Object o5 = new ObserveSubmarine();
小面试题:
问:java是值传递还是引用传递?
答:java只有值传递,基本类型传递的是具体的数,引用类型传递的是具体的地址
文档注释:/***/
是功能性的注释,只在三个地方使用:
//文档注释是功能性注释,只在三个地方使用,分别是类上、方法上和常量上
/**
* 在类上使用时用于说明当前类的设计目的和整体功能介绍
* 例如: 此类用于演示java文档注释
*
* @author 作者WKJ
*/
public class ApiDocDemo {
/**
* sayHi方法中使用的问候语
*/
public static final String INFO = "你好!";
/**
* 为指定用户添加问候语
* @param name 指定用户的名字
* @return 含有问候语的字符串
*/
public String sayHi(String name){
return INFO+name;
}
}
getter/setter:
class Student{
private String name;
private int age;
public String getName(){ //getter获取
return name;
}
public void setName(String name){ //setter设置
this.name = name;
}
public int getAge(){ //getter获取
return age;
}
public void setAge(int age){ //setter设置
this.age = age;
}
}
//getter和setter的演示
public class GetterSetterDemo {
public static void main(String[] args) {
Student zs = new Student();
zs.setName("zhangsan");
zs.setAge(25);
System.out.println(zs.getName());
System.out.println(zs.getAge());
Student ls = new Student();
ls.setName("lisi");
ls.setAge(24);
System.out.println(ls.getName());
System.out.println(ls.getAge());
}
}