书中,Java的基本类型,是在谈“对象无处不在”时谈到的,首先它提出:
这里的创建,通常指用new关键字来创建,而在堆上操作没那么高效,所以一些经常使用的类型,它们享受了特殊待遇:使用和C/C++相同的实现机制,无需new,而是直接创建一个自动变量,该变量会直接在栈上保存它的值。
Java就把这种享受特殊待遇的类型称为基本类型。包括如下几种:
上面提到基本类型变量会保存在栈上,书中系统回答了“数据保存在哪里”这个问题,有5种数据存储方式:
讲常量存储时,书上有一句话我不太理解 ,它说:常量通常会直接保存在程序代码中。于是我去查了下Java内存的细节,Java程序的执行过程,总体是这样的:
其中,内存又可分为:堆、方法区、栈、程序计数器、虚拟机栈、本地方法栈。通过分析程序的执行过程可以更好的理解这些概念,极客时间(《Java性能调优实战》)上有个不错的例子,我这里搬运过来供大家参考。代码如下:
- public class JVMClass {
- //常量
- public final static String MAN_SEX_TYPE = "man";
-
- //静态变量
- public static String WOMAN_SEX_TYPE = "woman";
-
- //静态方法
- public static void print(Student stu) {
- System.out.println("name: " + stu.getName() + "; sex:" + stu.getSexType() + "; age:" + stu.getAge()); } // 非静态方法 public void sayHello(Student stu) { System.out.println(stu.getName() + "say: hello"); }}class Student{ String name; String sexType; int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSexType() { return sexType; } public void setSexType(String sexType) { this.sexType = sexType; } public int getAge() { return age; } public void setAge(int age) { this.age = age; }}
- }
-
- //非静态方法
- public void sayHello(Student stu) {
- System.out.println(stu.getName() + "say: hello");
- }
-
- public static void main(String[] args) {
- Student stu = new Student();
- stu.setName("nick");
- stu.setSexType(MAN_SEX_TYPE);
- stu.setAge(20);
-
- JVMCase jvmcase = new JVMCase();
- //调用静态方法
- print(stu);
- //调用非静态方法
- jvmcase.sayHello(stu);
- }
- }
-
- class Student {
- String name;
- String sexType;
- int age;
-
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
-
- public String getSexType() {
- return sexType;
- }
- public void setSexType(String sexType) {
- this.sexType = sexType;
- }
-
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- }
当我们运行以上程序时,JVM的处理过程如下:
1、JVM向操作系统申请内存,在获得内存空间后,JVM会根据配置参数分配堆、栈和方法区的内存大小。
2、class文件加载、验证、准备以及解析,其中准备阶段会为类的常量、静态变量分配内存,即代码中的MAN_SEX_TYPE、WOMAN_SEX_TYPE。
3、初始化(略)
4、启动main线程,执行main方法,开始执行第一行代码,此时在堆内存中创建Student对象stu,而对象的引用放在栈中。然后通过引用设置堆上对象的name、sex、age。
5、在堆内存中创建JVMCase对象jvmcase,调用非静态sayHello,此时sayHello入栈,然后通过栈上stu的引用调用堆中的stu。之后,调用静态方法print,由于是静态方法print不属于jvmcase,而属于JVMCase类,所以从静态区获取print,之后入栈,然后也是通过栈上引用调用堆中stu。
其他: