1、变量就是计算机中一块块内存空间
2、
Java内存管理原理(是三方关系——程序<-->JVM<-->操作系统) :
1)、程序运行前:有些编程语言编写的程序会直接向操作系统请求内存,但 Java 并不支持那么做。这样做的一个重要优点是保证了程序的平台无关性。既然 Java 程序不负责创建内存空间,那由谁创建呢?是由 JVM 完成。当程序准备执行时,由JVM 预先向操作系统请求一定的内存空间,称为初始内存空间。程序执行过程中所需的内存都由Java 虚拟机从这片内存空间中划分。
2)、程序运行中:Java 程序一直向 Java 虚拟机申请内存,当程序所需内存空间超出初始内存空间时,Java 虚拟机会再次向操作系统申请更多的内存供程序使用。
3)、内存溢出:程序接着运行,当 Java 虚拟机已申请的内存达到了规定的最大内存空间,但程序还需要更多的内存,这时会出现内存溢出的错误。
至此可以看出,Java 程序所使用的内存是由 Java 虚拟机进行管理、分配的。Java 虚拟
机规定了 Java 程序的初始内存空间和最大内存空间,开发者只需要关心 Java 虚拟机是如何
管理内存空间的,而不用关心某一种操作系统是如何管理内存的。
3、
内存空间逻辑划分:方法区,堆与栈 ——JVM 会把申请的内存从逻辑上划分为三个区域,即:方法区、堆与栈。
//这个class整体就是一个方法区!
public class Student {
public String name ;
public int age ;
public void study() {
System.out.println("我在学习java!");
}
}
//这个class中的stu和i都是变量,而 new Student()是对象
public class Demo {
public static void main(String[] args) {
Student stu = new Student() ;
stu.name = "张三" ;
stu.age = 18 ;
int i = 10 ;
}
}
Java虚拟机对应的在内存中划分了三个区域“方法区”、“堆区”和“栈区”,分别保存类结构、对象中的数据和变量(基本型和引用型)。 这三个内存区域都有大小限制,任何一个区域内存溢出都会导致程序出现错误,栈内存溢出会发生StackOverflowException错误,堆内存溢出会发生OutOfMemoryError错误。
1)、方法区中的内存分配:方法区默认最大容量为64M,Java虚拟机会将加载的java类存入
方法区,保存类的结构(属性与方法),类静态成员等内容。编写中小型程序时,一般不会
造成方法区的内存溢出。
2)、堆中的内存分配:堆默认最大容量为64M,堆存放对象持有的数据,同时保持对原类的
引用。可以简单的理解为对象属性的值保存在堆中,对象调用的方法保存在方法区。
3)、栈中的内存分配:栈默认最大容量为1M,在程序运行时,每当遇到方法调用时,Java虚拟机就会在栈中划分一块内存称为栈帧(Stack frame),栈帧中的内存供局部变量(包括基本类型与引用类型)使用,当方法调用结束后,Java虚拟机会收回此栈帧占用的内存。
另:还有数组内部也封装了指针,即便是基本数据类型的数组,也封装了指针,数组也是引用类型。
4、
JAVA 数据类型
C 语言可以声明指针类型的变量。那就会问,java 中有没有指针呢?您一定要明确回答:“JAVA 中没有指针”。问题并没有到此终结,您要紧接着说“但 JAVA 底层封装了指针”。对,Java 底层封装了指针,但我们要说java 中没有指针,也就是不能创建指针类型的变量。
但也并不是所有的类型都封装了指针根据这点不同,java 的数据类型分为两类,即:值类型(基本数据类型)和引用类型。
1)、分类原则:根据是否封装指针(分配空间形式)
2)、基本数据类型:值类型(又称基本数据类型和基元数据类型)——只在栈中分配一块内存(四类八种,详见J2SE自学(三)——Java语法基础(一))
3)、引用数据类型(就是底层封装指针的数据类型。):在栈和堆中各各分配一块内存,例如:类、数组、接口等——他们在内存中分配两块空间,第一块内存分配在栈中,只存放别的内存地址,不存放具体数值,我们也把它叫指针类型的变量,第二块内存分配在堆中,存放的是具体数值,如对象属性值等。
5、
声明对象与创建对象
声明对象,相当分配指针类型变量,在栈中分配内存
类是引用类型,那声明对象就相当于在栈中声明指针类型的变量,它的内存不存放具体的数值,而只存放另一块堆中内存的地址。
创建对象,创建具体内存空间,在堆中分配内存
在java 中一般使用new 关键字创建对象(当然还有更高级的反射可以不用new 关键字)例如:
zhouxingxing = new Student()就是创建对象。这行代码一共做了两件事情:第一件是在堆中分配一块存放学生具体数值的内存(例如:35DF),第二件是把这个内存的首地址赋给上面声明的指针变量。
对象必须创建后才能使用,如果只声明不创建,那么调用对象属性和方法时将会报空指针异常(NullPointerException)
只声明对象,只相当于在栈中分配一块不存放具体数值的内存;没有创建,在堆中没创建存放具体数值的内存,当我们调用其属性方法时,系统找不到具体堆内存,则报空指针异常。同时我们也可以反过来说,空指针异常是因为没有指向堆中内存引起的。
6、JAVA 值传参与引用传参——定义:方法根据调用后的效果不同,即是否改变参数的原始数值
按值传递参数数值不变,按引用传递参数数值改变。
对于java的数据类型而言,基本数据类型就是按值传递的,又称为值类型,而引用类型是按引用传递的。如:
public class TestValueAndRef {
/**
* 方法参数有三个
* @param pa 基本类型 值类型
* @param pstu 自定义类 引用类型
* @param parr 数组 引用类型
*/
void change(int pa, Student pstu, int[] parr) {
//方法体中改变值类型pa的值
pa = pa + 10;
//方法体中改变引用类型stu,parr的值
pstu.stuAge = pstu.stuAge + 10;
parr[0] = parr[0] + 10;
System.out.println("方法体改变后pa = " + pa);
System.out.println("方法体改变后pstu.stuAge = " + pstu.stuAge);
System.out.println("方法体改变后parr[0] = " + parr[0]);
}
}
运行类:
public class Test {
public static void main(String[] args) {
Student student = new Student();
student.stuAge = 10;
int a = 10;
int arr[] = new int[]{9, 5, 27};
System.out.println("初始值 a = " + a);
System.out.println("初始值 student.stuAge = " +
student.stuAge);
System.out.println("初始值 arr[0] = " + arr[0]);
TestValueAndRef testValueAndRef = new TestValueAndRef();
testValueAndRef.change(a, student, arr);
System.out.println("调用函数后 a = " + a);
System.out.println("调用函数后 student.stuAge = " +
student.stuAge);
System.out.println("调用函数后 arr[0] = " + arr[0]);
}
}
运行结果:
初始值 a = 10
初始值 student.stuAge = 10
初始值 arr[0] = 9
方法体改变后pa = 20
方法体改变后pstu.stuAge = 20
方法体改变后parr[0] = 19
调用函数后 a = 10
调用函数后 student.stuAge = 20
调用函数后 arr[0] = 19
我们看到,基本数据类型int 变量a 虽然在方法体中改变了数值,但方法调用完后其原始数值并没有改变。而引用数据类型Student 在方法体中改变年龄的数值,方法执行完其数值发生了改变,数组也是引用类型,所以其值也发生了改变。也就是说:值类型按值传递参数,方法调用结束后,原始数值不变,引用类型按引用传递参数方法调用结束后,原始数值改变。
不管是按值传递还是按引用传递,都是把栈中的数据备份了一份给参数变量,只不过值类型备份的是具体的数值,而引用类型备份的是内存地址,所以从这个角度看,我们也可以说Java 全部是按值传参的,因为它都是把数据备份了一份。
7、String类
特例String 类型,虽然它也是引用类型,但用引用传参后,原始数值却不会改变
public class TestString {
public static void main(String[] args) {
String name = "zhangsan";
TestString testString = new TestString();
System.out.println("方法调用前:" + name);
testString.change(name);
System.out.println("方法调用后:" + name);
}
void change(String str) {
str = "张三";
System.out.println("方法体内修改值后:" + str);
}
}
运行结果:
方法调用前:zhangsan
方法体内修改值后:张三
方法调用后:zhangsan
虽然参数String 是引用数据类型,但其值没有发生改变,这是因为String 类是final 的,它是定长。方法体内改变的仅仅是改变了str的引用!对方法体外的name并没有任何影响!
以后遇到类似而的问题要“多思考,多画图,多实践!”
分享到:
相关推荐
**J2SE学习笔记——接口与相关程序** Java 2 Platform, Standard Edition(J2SE)是Java平台的核心部分,提供了开发和运行桌面应用程序、Web应用程序和服务的基础。本笔记主要聚焦于J2SE中的接口(Interface)概念...
JAVA开发环境J2SE实验报告 在本实验中,我们将学习和掌握JAVA开发环境J2SE的基本概念和使用方法。具体来说,我们将学习如何下载和安装J2SE开发工具,熟悉J2SE开发工具的使用,编写简单的Java Application和Java ...
《由浅入深——Java 2自学教程》是一本旨在帮助初学者逐步掌握Java编程语言的书籍。配书光盘中的“由浅入深——Java 2自学教程 配书光盘.rar”压缩包文件,包含了书中所有工程素材和源码,这对于读者实践和理解Java...
【标题】"手工完成java项目(一)——J2SE项目"揭示了这个压缩包文件是关于使用Java标准版(J2SE)进行项目开发的教程。在Java领域,J2SE代表Java 2 Platform, Standard Edition,它是Java平台的核心,主要用于桌面...
"J2SE6.0 API + JAVA-API1.6中文版合集"是一个非常实用的资源,它整合了Java Standard Edition(J2SE)6.0版本和Java API 1.6的中文文档,为开发者提供了详细的API参考,帮助他们更好地理解和使用这两个版本中的各种...
Java J2SE(Java 2 Platform, Standard Edition)是Java平台的核心部分,它提供了用于开发和部署桌面应用程序的API和运行环境。这个平台包含了Java语言的基础类库,如集合、多线程、网络编程、I/O操作等核心功能。在...
3. JVM工作原理:内存管理、字节码执行、垃圾回收。 4. 开发工具:如JDK中的javac编译器、jar打包工具等。 5. 实践应用:编写简单的桌面应用、服务端程序等,加深对J2SE的理解。 通过这个宏观性的总结,你可以逐步...
### 如何才算真正掌握Java(J2SE篇) 在当今的软件开发领域中,Java作为一门重要的编程语言,被广泛应用于各种应用场景之中。对于初学者来说,如何判定自己是否已经掌握了Java,特别是在J2SE(Java 2 Standard ...
java课程设计大作业——用J2SE写的一个坦克大战小游戏java课程设计大作业——用J2SE写的一个坦克大战小游戏java课程设计大作业——用J2SE写的一个坦克大战小游戏java课程设计大作业——用J2SE写的一个坦克大战小游戏...
它的主要特点包括跨平台性(Write Once, Run Anywhere)、垃圾回收机制、自动内存管理、异常处理和丰富的类库。学习Java首先要掌握其语法基础,包括变量、数据类型、运算符、控制结构(如if语句和循环)、函数等。 ...
首先,J2SE6引入了显著的性能提升,包括更快的启动时间和更高效的内存管理。它采用了新的垃圾回收算法,提高了程序运行时的内存效率,降低了应用的暂停时间。此外,J2SE6对Java虚拟机(JVM)进行了优化,使得应用...
这份"JAVA基础入门资料,J2SE入门资料,JAVA培训第一课,JAVA初学者资料,JAVA学习者必须知道的问题汇总"是绝佳的学习资源,涵盖了Java编程的基础知识,将帮助你快速进入Java的世界。 首先,让我们从Java的基础开始...
4. 安全性:Java语言的强类型和内存管理机制,以及JDBC的事务处理,确保了数据的安全性。 综上,“丽婴房库存销售系统”充分利用了J2SE和JDBC的优势,实现了高效的数据管理与业务流程整合,为企业提供了一套完善的...
Java工资管理系统是一款基于J2SE(Java Standard Edition)平台开发的应用程序,主要用于处理企业员工的薪资计算、管理和发放。J2SE是Java的核心版本,提供了丰富的API和工具,支持桌面应用开发。在这个系统中,...
在这个图书管理系统中,Java J2SE为开发提供了基础的编程环境和运行支持。 2. **MySQL**: MySQL是一种广泛使用的开源关系型数据库管理系统,以其高效、稳定和易于使用而著名。在这个系统中,MySQL用于存储和管理...
《JBuilder 9_0程序设计——Java程序员成功之路》是一部专为Java程序员设计的教程,旨在帮助读者熟练掌握JBuilder 9.0这一强大的Java集成开发环境(IDE)。JBuilder是由Borland公司开发的一款专业级的Java应用程序...
本文将深入探讨如何利用Java的标准版(J2SE)和Excel进行高效的人事合同管理。在Java环境中,Swing库为我们提供了丰富的图形用户界面(GUI)组件,而处理Excel文件则可以借助于PIO和JXL这两个强大的库。 首先,Java...
Java 2 Platform, Standard Edition(J2SE)是Java编程语言的核心部分,它提供了开发和运行桌面应用、服务器端应用和服务的基本平台。异常处理是Java编程中的关键概念,也是J2SE课程中不可或缺的一部分。在Java中,...