1. 参考
JVM内存结构 VS Java内存模型 VS Java对象模型-HollisChuang's Blog
《Java编程思想》
2. Java内存结构
3. 各种数据存储在哪里
3.1基本类型
Java有9种基本类型(boolean,char,byte,short,int,long,float,double,void),存储在堆栈中,不用new来创建变量,而是创建一个并非是引用的“自动”变量
3.2 new出来的对象
存储在”堆“中
3.2.1 String
String对象是不可变的,String对象具有只读性(String类中每一个看起来会修改String值的方法,实际上都是创建了一个全新的String对象,以包含修改后的字符串内容),所以指向他的任何引用都不可能改变它的值,因此,也就不会对其他的引用有什么影响
3.3 数组
当创建一个数组对象时,实际上就是创建了一个引用数组,并且每个引用都会自动被初始化为一个特定值,该值拥有自己的关键字null;基本类型的数组如果是数值型的,就被自动初始化为0,如果是字符型(char)的,就被自动初始化为(char)0,如果是布尔型(boolean),就被自动初始化为false
对象数组保存的是引用,基本类型数组直接保存基本类型的值
4. 初始化
在使用new创建一个对象时,将会为对象分配存储空间,并调用相应的构造器
区分重载方法的规则:每个重载的方法都必须有一个独一无二的参数类型列表
默认构造器:如果已经定义了一个构造器,编译器就不会帮你自动创建默认构造器
this关键字:只能在方法内部使用,表示对”调用方法的那个对象“的引用
static:static方法内不能调用非静态方法
4.1 类成员初始化
Java尽力保证:所有变量在使用前都能得到恰当的初始化。对于方法的局部变量,Java以编译时错误的形式来贯彻这种保证。
若类的某个成员是基本数据类型,即使没有进行初始化,Java也会确保它获得一个默认值(char值为0,所以显示为空白);若类的某个成员是对象引用,如果没有进行初始化,会被赋值为null
Java初始化具有顺序性,跟代码的编写顺序有关
public class MethodInit{
int i = f();
int j = g(i);
int f(){return 1;}
int g(int n){ return n+10;}
}
以上代码可以正常初始化,但是下面这样写就不对了
public class MethodInit{
int j = g(i);
int i = f();
int f(){return 1;}
int g(int n){ return n+10;}
}
4.2 构造器初始化
无法阻止自动初始化的进行,它将在构造器被调用之前发生。
4.2.1 构造器初始化顺序
构造器的调用顺序是很重要的。当进行继承时,我们已经知道基类的一切,并且可以访问基类中任何声明为public合protected的成员。这就意味着在导出类中,必须保证基类的所有成员都是有效的:
1)调用基类构造器。这个步骤会不断地反复递归下去,首先是构造这种层次结构的根,然后是下一层导出类,等等,直到最低层的导出类
2)按声明顺序调用成员的初始化方法(不管类的成员变量定义顺序在哪他都是最先被初始化的)
3)调用导出类构造器的主体
4.3 Java对象的初始化顺序
1)基类的静态成员变量和静态代码块初始化,导出类的静态成员变量和静态代码块初始化(静态成员变量和静态代码块只会被执行一次,第一次被加载到jvm时执行;静态变量和静态代码块的执行顺序取决于其定义的顺序);
2)基类构造器
3)导出类非静态变量
4)导出类构造器