全国大型网站建设,用户冻结wordpress,wordpress类似大前端,有没专门做二手的家具网站今天学习了类、对象及相关知识#xff0c;试着从内存角度分析三者关系#xff0c;如果有不对的地方请指正首先得先介绍java中的三个内存区域#xff1a;栈区用于存放该线程执行方法的信息#xff08;实际参数、局部变量等#xff09;。栈属于线程私有#xff0c;不能实现…今天学习了类、对象及相关知识试着从内存角度分析三者关系如果有不对的地方请指正首先得先介绍java中的三个内存区域栈区 用于存放该线程执行方法的信息实际参数、局部变量等。栈属于线程私有不能实现线程间的共享。栈的存储特性是“先进后出后进先出”。栈是由系统自动分配速度快栈是一个连续的内存空间堆区堆用于存储创建好的对象和数组数组也是对象。JVM只有一个堆被所有线程共享。 堆是一个不连续的内存空间分配灵活速度慢方法区方法区用来存放程序中永远不变或唯一的内容如类、静态变量、字符创常量等。JVM只有一个方法区被所有线程共享。方法区实际是堆中的一个区域只是用于存储类、常量相关的信息JVM内存模型package cn.sxt.oo;public class zhihu {public static void main(String[]args) {B b new B();b.printA();b.printB();}}class B{int a 0;static int b0;public void printA() {System.out.println(a);}public static void printB() {System.out.println(b);}
}
下面来看这一段代码1. 类的加载首先第一步加载zhihu这一个类在方法区中存入类信息和类当中的静态变量、静态方法和常量。总结类的加载是在类第一次被使用的时候从代码上看简单来说就是类名第一次出现的地方。可以是类的第一个对象创建的时候也可以是通过 “类名.静态变量” 调用类中静态变量的时候。2.对象创建完成了class zhihu的加载之后将会执行main方法系统会在栈空间中开一个栈帧存放main方法。然后下一句代码是对象b 的构造方法。但是此时并不马上执行构造方法。因为class B尚未初始化因此在生成对象之前会完成class B的初始化。执行构造方法钱进行class B的初始化初始化class B后在堆空间中分配内存用于存放对象 b的信息执行b中属性的显式初始化并给属性赋数据类型默认的初始值如int a 就赋值0执行对象的显式初始化并给变量赋默认的初始值完成对象空间的分配属性的显式初始化和初始化赋值之后才会执行构造方法此时在栈区中中载入b的构造方法B b new B(); 当执行到B b 的时候main的栈帧中会生成b的局部变量当执行到new 的时候将堆中新建的b对象地址赋给栈中的b。对象初始化之后构造方法会将方法区中的常量赋值给堆中的变量之后构造方法执行结束从栈帧中释放总结对象的创建过程为类的初始化、对象空间分配、属性初始化、执行构造方法并将类中的常量赋值给对象。非静态方法的执行在执行到 b.printA时开新栈帧。printA方法会找到main方法中的对象b根据对象地址找到堆中的printA方法。然后找到变量a并输出执行完成以后该方法的栈帧会被释放静态方法的执行执行到b.printB();时也是一样先开新栈帧。从方法区加载方法p.printB()然后找到方法区中的静态变量b并输出。总结方法的调用本质上就是地址的传递如B b new B(); 本质上是将新创建的b的地址传递给 b再比如b.printA();即通过b的地址找到printA的方法。当然也可以通过类名去找如B.printA();思考静态方法中能否调用非静态方法或非静态变量答案显然是不能的因为类加载的时候不一定有对象而非静态方法和变量只有对象建立之后才有。因此在静态方法中肯定是没有非静态方法或对象的地址的。那么如何实现静态方法调用非静态变量呢只需要提供一个地址即可我们可以在静态方法中建立一个对象通过建立的对象去找到非静态方法。如以下代码public void testPrintA(){B b2 new B():b2.printA();
}思考类与类之间能否互相调用非静态方法肯定是要实例化以后通过 对象名.方法名/变量名 去调用而静态方法是可以互相调用的用类名.方法名/变量名 或者 对象名.方法名/变量名调用class A{ B bpublic void printB1(){ B.printB(); } public void printB2(b){b.printB();}
}思考this关键字的本质——指向当前对象this关键字的用法构造器中用于区分同名的局部变量和成员变量局部变量是方法执行时存放在栈中的与成员变量生重名时this就可以指向堆中的成员变量这样就区分开了。构造器中调用另一个构造器