java虚拟机把内存分成三部分,栈区、堆区、方法区,其中方法区是堆区的一部分。
栈区:自动分配连续空间,后进先出。用于放置局部变量
堆区:不连续,存放new出来的对象(对象的成员变量、成员方法引用)。
方法区:存放类的代码信息、static变量、static方法、常量池。
案例分析
1、对象、属性内存分析
学生类:
public class Student {
//静态的数据
String name;
int id; //学号
int age;
String gender;
int weight;
Computer computer;
//动态的行为
public void study(){
System.out.println(name+"在學習");
}
public void sayHello(String sname){
System.out.println(name+"向"+sname+"說:你好!");
}
}
电脑类:
public class Computer {
String brand;
int cpuSpeed;
}
主程序:
Student s1 = new Student();
s1.name = "高琪";
s1.age = 18;
Computer c = new Computer();
c.brand = "联想";
c.cpuSpeed = 100;
s1.computer = c;
内存分析:
2、多态内存分析
多态构成的三个条件:继承、重写父类非静态方法、父类指针指向子类对象。
class HttpServlet{
public void service(){
doGet();
}
public void doGet(){
System.out.println("HttpServlet.doGet");
}
public static void getInstance(){
System.out.println("获取HttpServlet实例");
}
public static void init(){
System.out.println("初始化配置");
}
}
class MyHttpServlet extends HttpServlet{
@Override
public void doGet() {
System.out.println("MyHttpServlet.doGet");
}
public void doPost(){
System.out.println("MyHttpServlet.doPost");
}
public static void getInstance(){
System.out.println("获取MyHttpServlet实例");
}
}
说明:
每个方法都有两个隐式参数,this、supper。this指向创建的对象,supper指向父类对象。由于编译器问题,父类指针引用子类对象,调用方法的时候只能调用父类中存在的方法;如果子类有覆盖,则调用覆盖后的方法。
测试代码:
HttpServlet servlet1 = new HttpServlet();
servlet1.service();//HttpServlet.doGet
HttpServlet servlet2 = new MyHttpServlet();
servlet2.service();//MyHttpServlet.doGet
//servlet2.doPost();//报错
静态方法是属于某一个类的,子类不能重写父类的静态方法,子类与父类静态方法相同的时候不能构成重写,两个方法没有任何关系,如果子类方法加Override注解则报错。但是子类能继承父类的静态方法。调用的时候不传递this、supper隐式参数。
测试代码:
HttpServlet.getInstance();//获取HttpServlet实例
MyHttpServlet.getInstance();//获取MyHttpServlet实例
//子类调用父类的静态方法
MyHttpServlet.init();//初始化配置