一、变量
变量有两种:primitive主数据类型和引用,primitive主数据类型用来保存基本数据类型的值,包括整数、布尔、浮点数等;引用变量用来保存对象的引用。
int a=10; //主数据类型变量
Dog d=new Dog(); //引用变量
1、primitive主数据类型包括:
类型 | 位数 | 值域 |
boolean | JVM决定 | true or false |
char | 16bit | 0~65535 |
byte | 8bit | -128~127 |
short | 16bit | -32768~32767 |
int | 32bit | -2147483648~2147483647 |
long | 64bit | -很大~很大 |
float | 32bit | 范围规模可变 |
double | 64bit | 范围规模可变 |
2、引用
事实上没有对象变量这样的东西存在,只有引用(reference)到对象的变量,对象引用变量保存的是存取对象的方法。
对象声明、创建、赋值的三个步骤:
1)Dog d:声明一个引用变量,要求java虚拟机分配空间给引用变量,并将此变量命名为d
2)new Dog():创建对象,要求java虚拟机分配堆空间给新建立的Dog对象
3)=:连接对象和引用
从类的角度说,Java的类体分为两部分:变量的定义+方法的定义。在变量定义部分定义的变量叫做类的成员变量,在方法体中定义的变量叫做局部变量。
成员变量在整个类中都有效(全局变量应该是成员变量的俗称),局部变量只在定义他的方法中有效。
成员变量具有缺省值(定义以后没有赋初值的话就会自动被赋予默认值) 而局部变量则没有(局部变量如果没有初始化,它的值不可知)。
成员变量又分为实例变量和类变量(static静态变量):
类的静态变量在内存中只有一个,java虚拟机在加载类的过程中为静态变量分配内存,静态变量位于方法区,被类的所有实例共享。静态变量可以直接通过类名进行访问,其生命周期取决于类的生命周期。
实例变量取决于类的实例,每创建一个实例,java虚拟机就会为实例变量分配一次内存,实例变量位于堆区中,其生命周期取决于实例的生命周期。
二、堆栈与变量的关系
Java把内存分成两种,一种叫做栈内存,一种叫做堆内存
在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配。当在一段代码块中定义一个变量时,java就在栈中为这个变量分配内存空间,当超过变量的作用域后,java会自动释放掉为该变量分配的内存空间,该内存空间可以立刻被另作他用。
堆内存用于存放由new创建的对象和数组。在堆中分配的内存,由java虚拟机自动垃圾回收器来管理。在堆中产生了一个数组或者对象后,还可以在栈中定义一个特殊的变量,这个变量的取值等于数组或者对象在堆内存中的首地址,在栈中的这个特殊的变量就变成了数组或者对象的引用变量,以后就可以在程序中使用栈内存中的引用变量来访问堆中的数组或者对象,引用变量相当于为数组或者对象起的一个别名,或者代号。
引用变量是普通变量,定义时在栈中分配内存,引用变量在程序运行到作用域外释放。而数组&对象本身在堆中分配,即使程序运行到使用new产生数组和对象的语句所在地代码块之外,数组和对象本身占用的堆内存也不会被释放,数组和对象在没有引用变量指向它的时候,才变成垃圾,不能再被使用,但是仍然占着内存,在随后的一个不确定的时间被垃圾回收器释放掉。这个也是java比较占内存的主要原因,实际上,栈中的变量指向堆内存中的变量,这就是 Java 中的指针!
下面的图片可以很好的解释对象、对象引用变量在内存中的分配
堆和栈的区别:
栈与堆都是Java用来在Ram中存放数据的地方。与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆。
Java的堆是一个运行时数据区,类的对象从中分配空间。这些对象通过new、newarray、anewarray和multianewarray等指令建立,它们不需要程序代码来显式的释放。堆是由垃圾回收来负责的,堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢。
栈的优势是,存取速度比堆要快,仅次于寄存器,栈数据可以共享。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。
栈中主要存放一些基本类型的变量(,int, short, long, byte, float, double, boolean, char)和对象句柄。
栈有一个很重要的特殊性,就是存在栈中的数据可以共享。假设我们同时定义:
int a = 3;
int b = 3;
编译器先处理int a = 3;首先它会在栈中创建一个变量为a的引用,然后查找栈中是否有3这个值,如果没找到,就将3存放进来,然后将a指向3。接着处理int b = 3;在创建完b的引用变量后,因为在栈中已经有3这个值,便将b直接指向3。这样,就出现了a与b同时均指向3的情况。
这时,如果再令a=4;那么编译器会重新搜索栈中是否有4值,如果没有,则将4存放进来,并令a指向4;如果已经有了,则直接将a指向这个地址。因此a值的改变不会影响到b的值。
要注意这种数据的共享与两个对象的引用同时指向一个对象的这种共享是不同的,因为这种情况a的修改并不会影响到b, 它是由编译器完成的,它有利于节省空间。而一个对象引用变量修改了这个对象的内部状态,会影响到另一个对象引用变量。
String是一个特殊的包装类数据。可以用:
String str = new String("abc");
String str = "abc";
两种的形式来创建,第一种是用new()来新建对象的,它会在存放于堆中。每调用一次就会创建一个新的对象。
而第二种是先在栈中创建一个对String类的对象引用变量str,然后查找栈中有没有存放"abc",如果没有,则将"abc"存放进栈,并令str指向”abc”,如果已经有”abc” 则直接令str指向“abc”。
比较类里面的数值是否相等时,用equals()方法;当测试两个包装类的引用是否指向同一个对象时,用==,下面用例子说明上面的理论。
String str1 = "abc";
String str2 = "abc";
System.out.println(str1==str2); //true
可以看出str1和str2是指向同一个对象的。
String str1 =new String ("abc");
String str2 =new String ("abc");
System.out.println(str1==str2); // false
用new的方式是生成不同的对象。每一次生成一个。
因此用第二种方式创建多个”abc”字符串,在内存中其实只存在一个对象而已. 这种写法有利与节省内存空间. 同时它可以在一定程度上提高程序的运行速度,因为JVM会自动根据栈中数据的实际情况来决定是否有必要创建新对象。而对于String str = new String("abc");的代码,则一概在堆中创建新对象,而不管其字符串值是否相等,是否有必要创建新对象,从而加重了程序的负担。
另一方面, 要注意: 我们在使用诸如String str = "abc";的格式定义类时,总是想当然地认为,创建了String类的对象str。担心陷阱!对象可能并没有被创建!而可能只是指向一个先前已经创建的对象。只有通过new()方法才能保证每次都创建一个新的对象。
由于String类的immutable性质,当String变量需要经常变换其值时,应该考虑使用StringBuffer类,以提高程序效率。
综上,使用==比较两个primitive 主数据类型,或者判断两个引用是否引用同-个对象;使用equals()来判断两个对靠是否在意义上相等.(像是两个String对象是否带有相同的字节组合)
- 大小: 139.6 KB
- 大小: 139.1 KB
分享到:
相关推荐
Java数组堆栈的实现是通过创建一个名为ArrayStack的类,该类提供了堆栈的基本操作。该类使用泛型T来表示堆栈中元素的数据类型。 在ArrayStack类中,使用了一个Object类型的数组来存储堆栈中的元素。由于Java不支持...
Java 把内存分成两种,一种叫做栈...当在一段代码块中定义一个变量时,java 就在栈中 为这个变量分配内存空间,当超过变量的作用域后,java 会自动释放 掉为该变量分配的内存空间,该内存空间可以立刻被另作他用。
总之,这个"java 堆栈的演示程序"为我们提供了一个实践和学习Java内存管理的绝佳机会,无论是对于初学者还是经验丰富的开发者,都能从中受益,加深对Java堆栈机制的理解。通过查看源代码并运行程序,我们可以更直观...
Java堆栈是Java虚拟机(JVM)的一部分,主要用于存储方法调用的局部变量、操作数栈、动态链接信息和返回地址等。当一个方法被调用时,一个新的栈帧会被创建并压入堆栈;而当方法执行完毕,相应的栈帧就会被弹出堆栈...
Java 堆栈详解 Java 是一种广泛使用的面向对象的编程语言,它的内存管理机制是其强大特性的关键部分。在 Java 中,内存分为两个主要区域:堆...因此,深入学习和理解Java堆栈对于每一个Java开发者来说都是必要的。
IBM为WebSphere Application Server (WAS) 提供了一款名为"jca467.jar"的线程堆栈分析工具,专门用于处理与IBM Java相关的线程分析任务。 首先,我们来了解一下什么是线程堆栈。线程堆栈是每个线程在执行过程中创建...
当 JVM 激活一个方法时,它从类信息数据得到此方法的局部变量区和操作数堆栈的大小,并据此分配大小合适的堆栈帧压入 Java 堆栈中。 在局部变量区中,类型为 int、float、reference 和 returnAddress 的值占据一项...
Java堆栈内存分析是Java编程中的重要概念,它关乎程序的性能优化和内存泄漏的预防。堆和栈是Java内存管理的两个主要区域,它们各自承担着不同的职责。本笔记将深入探讨这两个区域的工作原理以及如何进行有效的分析。...
### Java堆栈的区别详解 #### 一、预备知识—程序的内存分配 程序在运行时,根据不同的数据类型和用途,会被分配到不同的内存区域。这些区域包括: 1. **栈区(Stack)**:这部分内存由编译器自动管理,主要用于...
#### 一、Java环境变量概览 在计算机系统中,环境变量是操作系统提供的一种机制,用于存储系统级别的信息。对于Java开发者来说,正确配置Java环境变量至关重要,它决定了开发环境能否顺利搭建以及Java应用程序能否...
java学习手册,它包含排序动画执行过程、java运行时堆栈内存结构图,J2SE基础、面试题、编程题以及二千多道选择题等。大部分代码都可以直接在手机上运行、调试,观察运行时变量状态以及变量值。j2se基础包含30章,...
### CoreJava学习笔记 #### 一、JAVA特点与运行原理 **JAVA特点:** 1. **简单性**:Java的设计者们将C++语言中许多不易理解和容易混淆的部分去除,使得Java更容易理解与掌握。 2. **面向对象**:Java几乎一切都...
11. **调用堆栈 (Call stack)**:记录程序运行过程中方法调用顺序的栈,每次方法调用都会压入一个新的栈帧,返回时则弹出。 12. **类型转换 (Casting)**:将一个类型转换为另一个类型的操作,包括基本类型之间的...
堆栈(stack)是 Java 中的一种内存区域,用于存储基本类型的变量和对象的引用变量。堆(heap)是 Java 中的一种动态内存区域,用于存储由 new 创建的对象和数组。 堆栈(stack) 堆栈(stack)是 Java 中的一种...
1. **堆栈的结构**:堆栈是内存中一块连续的空间,用于存储程序中的局部变量、函数调用时的返回地址和帧指针(EBP)。在Intel汇编语言中,堆栈是从高地址向低地址增长的,即“向下”生长。 2. **堆栈操作**:每次...
### Java学习中调试过程中常见错误分析 #### 1. 类名与文件名不一致 **错误提示**:“`Test1.java`:类Test2是公共类,应该在名为Test2.java的文件中被宣告3行1列处” **解释**:Java规定,如果一个类声明为`...
- **学习路线**:这份文档提供了一个详细的Java学习路线图,旨在帮助初学者利用业余时间系统地掌握Java技术。学习路线分为多个阶段,从基础语法到面向对象,再到Lambda表达式、集合框架以及常用类库API的学习。 - **...
总结来说,Java的堆和栈分别服务于不同类型的变量和对象,而常量池则提供了一种优化内存使用的方法。理解这些概念对于编写高效且内存友好的Java代码至关重要。在实际编程中,合理地利用栈、堆和常量池可以帮助我们更...
【Java学习笔记】 Java是一种广泛使用的编程语言,以其跨...这些只是Java学习笔记的一部分,深入学习还包括类的继承、接口、异常处理、集合框架、IO流、多线程、网络编程等多个方面。不断学习和实践是掌握Java的关键。