本文共 3026 字,大约阅读时间需要 10 分钟。
将方法区放在堆上是为了便于理解,逻辑上方法区为堆的一部分
1.jvm虚拟机启动,java堆创建,此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例以及数组都应当在堆上分配
2.将main方法栈帧压入栈,当java虚拟机遇到一条new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用的类是否已被加载,解析和初始化过,如果没有,那必须先执行类加载过程,:1.加载:编译类.java文件成.class文件(加载类元信息),2.链接(校验class文件正确性和安全性,生成方法表并分配元空间内存) 3.加载cat类的static变量跟static方法还有构造方法进入方法区.(类对象初始化:执行类变量赋值和静态代码块),此时新建类对象完毕。 4在栈上新建变量oldCat,bigCat,smallCat,并约束类型为Cat,新建变量Cats,约束类型为List,在堆上开辟内存地址,新建对象,通过同样的内存地址连接起来(实例对象加载的过程,1.对象实例化,在堆中分配内存 ,2.初始化零值,设置对象头,执行init方法,3.将引用指向内存空间,创建新Catclass对象完毕。) 5.调用cats.add(bigCat);时,去方法区寻找类的方法表,根据方法表找到内存地址中的add()方法,将此方法压入栈中(入栈),往对象cats中新增一个bigCat对象 6.cats.add(bigCat);运行结束,栈帧出栈销毁; 7.cats.add(smallCat);同上 8.调用oldCat.setName(“大猫”);时,将此方法压入栈中(入栈),将堆上0x001对象的name变量指向常量区"大猫"的内存地址(如果大猫在常量池中不存在,则会先在常量池里新增:大猫) 9.oldCat.setName(“大猫”);运行结束,栈帧出栈销毁 10.oldCat.setOld(10); oldCat.setChild(cats); 同上 11.调用oldCat.say();时,将此方法压入栈中(入栈),在栈帧中生成局部变量:String food = “fish”;打印语句从常量池中获取"我的名字是".从堆对象中获取成员变量的name,将其组合打印出来(常量字符串的“+”操作,编译阶段直接会合成为一个字符串。如string str=”JA”+”VA”,在编译阶段会直接合并成语句String str=”JAVA”,于是会去常量池中查找是否存在”JAVA”,从而进行创建或引用。) (string对象的创建讲解: https://blog.csdn.net/tyyking/article/details/82496901) 12.将hello方法压入栈中,hello是static方法,直接调用方法区已经变异的代码缓存,调用结束,出栈 13.main方法执行完毕,出栈/** * @author Boss * 编写一个类时没有添加无参构造方法,那么编译器会自动添加无参构造方法;(如果自己添加构造函数,无论有参数或是没参数,默认构造函数都将无效) * 编写时添加了有参构造方法而未添加无参构造方法,那么编译器只认有参构造方法而不会默认添加无参构造方法! * 如果需要使用无参构造方法,一定要在类里面添加 */public class Cat { //(成员变量)静态变量 成员变量是属于类的,存在于堆上的方法区,"白色"存在于字符串常量池 static String colore = "白色"; //(成员变量)如果没有使用static修饰,这个成员变量是属于实例的,存在堆上 private String name; private Integer old; private Listchild; public Cat() { } public Cat(String name, Integer old) { this.name = name; this.old = old; } public Cat(String name, Integer old, List child) { this.name = name; this.old = old; this.child = child; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getOld() { return old; } public void setOld(Integer old) { this.old = old; } public List getChild() { return child; } public void setChild(List child) { this.child = child; } public static void hello(){ System.out.println("你好你好你好你好你好"); } public void say() { //局部变量 String food = "fish"; System.out.println("我的名字是" + this.name); System.out.println("我的食物是" + food); System.out.println("我的颜色是" + colore); } public static void main(String[] args) { Cat oldCat = new Cat(); Cat bigCat = new Cat(); Cat smallCat = new Cat(); List cats = new ArrayList<>(); cats.add(bigCat); cats.add(smallCat); oldCat.setName("大猫"); oldCat.setOld(10); oldCat.setChild(cats); oldCat.say(); Cat.hello(); }}