`
hujiujie
  • 浏览: 3058 次
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

java中String和char,堆和栈的区别

阅读更多

今天在黑马论坛上看到这样一道题:

class lianxi
{
public static void main(String[] args)
{
System.out.println('a'+1);
System.out.println(""+'a'+1);
System.out.println(""+"ab"+1);
System.out.println(""+"a"+1);
}
}

当时一看觉得结果应该是a1,a1,ab1,a1.实际运行后不然。就百度搜单引号和双引号有什么不一样。发现下面这篇好文章copy来共享.

首先弄清楚以下几个问题:

1.String类型可以和char[]进行相互转换,但两种是不同的类型;
2.弄清楚创建的对象在内存中是处于栈还是堆;
3.String中重写了equal(),比较的是两个对象的内容是否一样,如果不重写,和==一样都是比较的对象的引用,new出来的对象都是放在堆中的。

 

那么什么是堆,什么又是栈呢?

堆是先进先出,而栈是先进后处 
 
1. 栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方。与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆。 
 
2. 栈的优势是,存取速度比堆要快,仅次于直接位于CPU中的寄存器。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。另外,栈数据可以共享,详见第3点。堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢
3.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类,以提高程序效率。
文章一开始那道题的正确答案是:98,a1,ab1,a1.
分析:
System.out.println('a'+1);//指向ascii码+1=98
System.out.println(""+'a'+1);//有个"",先变成了字符串所以是a1,你如果把""放到后面就又会变成98
System.out.println(""+"ab"+1);
System.out.println(""+"a"+1);//最后两个都是字符串+字符串+1
完。

  
分享到:
评论

相关推荐

    Java堆和栈的区别

    "Java 堆和栈的区别" Java 堆和栈是 Java 中的两种内存管理机制,它们都是 Java 用来在 RAM 中存放数据的地方。但是,它们有很多不同之处。 Java 堆是一个运行时数据区,类的对象从中分配空间。这些对象通过 new、...

    Java 中的堆和栈

    Java编程语言中,内存管理是至关重要的概念,...总的来说,Java中的堆和栈内存是程序运行的基础,它们共同协作以提供高效、可靠的数据存储和管理。了解这两个内存区域的工作原理,有助于写出更高效、更稳定的Java代码。

    java中堆和栈的区别.pdf

    Java中堆和栈的区别 Java是一种面向对象的编程语言,它的内存管理机制是自动化的,程序员不需要手动地分配和释放内存。Java中堆和栈是两个重要的概念,它们都是Java用于在RAM中存放数据的地方。 栈(Stack)是一块...

    java中堆(heap)和堆栈(stack)有什么区别

    "Java 中堆(heap)和堆栈(stack)的区别" Java 中堆(heap)和堆栈(stack)是两个不同的内存区域,分别用于存储不同的数据类型和对象。堆栈(stack)是 Java 中的一种内存区域,用于存储基本类型的变量和对象的...

    解析Java栈与堆

    Java栈和堆是Java语言中两个最基本的存储机制,它们都是Java用来在RAM中存放数据的地方。与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆。 1. 栈的存储机制: 栈的优势是,存取速度比堆要快,仅次于...

    关于Java栈与堆的思考

    理解和掌握Java中栈与堆的工作原理,以及不同数据类型在其中的存储机制,对于编写高效、健壮的Java应用程序至关重要。通过合理利用栈和堆的特性,程序员可以更好地控制程序的性能和资源使用,避免常见的内存泄漏等...

    Java中堆内存和栈内存详解.doc

    总结一下,Java中的堆内存和栈内存的主要区别在于: 1. 存储对象:栈存存储基本类型和引用,堆存存储对象实例。 2. 管理方式:栈内存由JVM自动管理,对象的生命周期由垃圾回收机制决定;堆内存同样由JVM管理,但涉及...

    java中的栈(深层了解java虚拟机对对象的内存分布)

    Java中的栈和堆分别承担着不同的角色:栈负责快速、高效的存储和管理基本类型和局部变量,而堆则提供了更加灵活的内存管理策略,适用于各种复杂对象和动态数据结构。理解这两种内存区域的工作机制,对于编写高效、...

    Java中堆内存和栈内存详解文.pdf

    栈内存主要用来存储基本类型(如int、char)的变量和对象的引用,而堆内存则用于存储通过`new`关键字创建的对象和数组。 栈内存的工作方式类似于数据结构中的栈,遵循“后进先出”(LIFO)原则。每当一个方法被调用...

    堆和栈的区别可以用如下的比喻来看出

    在计算机科学中,堆和栈是两种不同的内存管理机制,它们在编程语言中扮演着重要的角色,尤其是在Java这样的高级语言中。理解堆和栈的区别对于优化代码性能和避免内存问题至关重要。 首先,栈(Stack)是一种后进先...

    Java中的堆、栈和常量池_.docx

    在Java中,内存被划分为几个不同的区域,包括堆、栈、常量池和寄存器等。下面我们将详细讨论这些概念。 1. 寄存器: 寄存器是计算机硬件的一部分,用于快速访问数据。在Java中,寄存器由编译器根据需要自动分配和...

    老生常谈之Java中堆和栈的概念和区别

    理解堆和栈的区别对于解决Java程序中的内存问题、分析性能瓶颈以及进行性能优化至关重要。例如,频繁创建和销毁对象可能导致堆内存压力增大,而过深的函数调用层次可能会导致栈溢出(StackOverFlowError)。可以通过...

    Java堆、栈和常量池——内存剖析

    ### Java堆、栈和常量池——内存剖析 #### 寄存器 寄存器作为最快的存储区域之一,由编译器自动管理分配与回收,它位于CPU内,用于存储临时变量,例如局部变量和一些操作数。由于寄存器的数量有限且由编译器自动...

    Java核心基础+Java中的数据在内存中的存储

    在探讨Java中数据如何在内存中存储之前,我们需要先理解Java程序运行时内存的几个关键部分:堆(heap)与栈(stack)。 **1.1 栈 (Stack)** - **特点**: - 存取速度快。 - 数据大小和生命周期已知。 - 支持...

    Java堆、栈和常量池

    Java编程语言中的内存管理是通过堆、栈和常量池三个关键区域来实现的,这些区域各有其特定的用途和特点。 首先,寄存器是最快的存储区,它由编译器自动分配和管理,程序员无法直接控制。寄存器主要用于存储运算过程...

    变量在Java栈、堆内存中的运用管理分析.pdf

    基本数据类型包括boolean、byte、char、int、short、long、float和double,它们的值直接存储在栈中。例如,声明一个整型变量`int a = 5;`,`a`的值5会存储在栈中。 2. 引用类型变量 引用类型变量,如数组、类实例、...

    java模拟顺序栈实现回文串的判断

    栈是一种后进先出(Last In First Out, LIFO)的数据结构,就像现实生活中的堆叠物品,最后放进去的物品最先被取出。在Java中,我们可以使用`java.util.Stack`类来创建一个栈,或者简单地用数组模拟栈的操作。 以下...

    java中equals和==的区别.pdf

    基本数据类型(如int、char)的值直接存储在栈内存中,而引用类型的变量(如对象)在栈中存储的是指向堆内存中对象实例的引用。因此,当我们比较两个引用类型的变量时,`==` 操作符实际上是检查这两个引用是否指向同...

Global site tag (gtag.js) - Google Analytics