关于String类内存分配的问题

问题描述

遇到这样一个问题,求高手解释下:public class RefDemo0{public static void main(String args[]){String str1 = "hello" ;// 实例化字符串对象System.out.println("fun()方法调用之前:" + str1) ;fun(str1) ;// 调用fun()方法System.out.println("fun()方法调用之后:" + str1) ;}public static void fun(String str2){// 此处的方法由主方法直接调用str2 = "world" ;// 修改字符串内容}};输出结果为:fun()方法调用之前:hellofun()方法调用之后:hello而class Demo{String temp = "hello" ;// 此处为了方便,属性暂时不封装};public class RefDemo0{public static void main(String args[]){Demo d1 = new Demo() ;// 实例化Demo对象d1.temp = "world" ;// 修改temp属性的内容System.out.println("fun()方法调用之前:" + d1.temp) ;fun(d1) ;System.out.println("fun()方法调用之后:" + d1.temp) ;}public static void fun(Demo d2){// 此处的方法由主方法直接调用d2.temp = "hey";// 修改temp值}};输出结果为:fun()方法调用之前:worldfun()方法调用之后:hey为什么两次输出结果会不同?问题补充zhushidan100 写道

解决方案

String是静态的不能被修改,每次赋值都是改变引用。而方法传值传的是指针比如方法调用fun(str1);这样的,把str1的指针复制一下传入方法,而方法中改变了这个指针指向的对象。但是注意,原来的str1没有变。因为方法内部的str2是str1复制了一遍的。而类的成员变量,改变了指向的对象。
解决方案二:
可以参照 Java编程思想 附录A 有详细的说明
解决方案三:
第一个例子,从程序上直接分析就是fun方法传入参数str2,而str2既不是全局变量,fun方法有没有返回到哪里,所以str1的值都没有得到修改,str1和str2是两个不同的对象从JVM内存上分析,下面是我画的JVM分析图,应该是比较明白的
解决方案四:
换成stringbuffer结果也是一样,哈有StringBuilder也是一样! public class RefDemo0 {public static String fun(String str2) { // 此处的方法由主方法直接调用str2 = "world"; // 修改字符串内容return str2;}public static void main(String args[]) {String str1 = "hello"; // 实例化字符串对象System.out.println("fun()方法调用之前:" + str1);str1 = fun(str1); // 调用fun()方法System.out.println("fun()方法调用之后:" + str1);}} 你只是调用了而没有赋值! 不是么!?
解决方案五:
albeter 写道第一个程序中。str1指向“hello” 调用fun(str1)后 str2也指向"hello" ,并且在方法中创建一个“world”对象,然后让str2指向"world",这时,str1仍然指向"hello"。打印str1仍然是"hello".第二个程序中。都是同一个引用temp改变指向的字符串对象。所以两次打印出来的结果会改变。原来如此,哎,都没想到
解决方案六:
第一个程序中。str1指向“hello” 调用fun(str1)后 str2也指向"hello" ,并且在方法中创建一个“world”对象,然后让str2指向"world",这时,str1仍然指向"hello"。打印str1仍然是"hello".第二个程序中。都是同一个引用temp改变指向的字符串对象。所以两次打印出来的结果会改变。
解决方案七:
第一个是值拷贝操作、第二个是对象引用的传递. 涉及到内存分配问题.
解决方案八:
同问,谁能详细解释一下!
解决方案九:
这个问题太高深了,要追溯到JVM的堆栈分配了
解决方案十:
jdonlkm 写道原来是String类的内容不可改变,感谢李老师的热心指导楼主能详细说说吗?
解决方案十一:
freish 写道都不怕新手贴啊,这类问题在csdn老火了很少上csdn,一直javaeye上混
解决方案十二:
都不怕新手贴啊,这类问题在csdn老火了
解决方案十三:
这个问题高端了...
解决方案十四:
值传递,引用传递 好像是

时间: 2024-08-02 23:09:25

关于String类内存分配的问题的相关文章

class-同一个程序代码,不同的地方new同一个类,内存分配大小不一样

问题描述 同一个程序代码,不同的地方new同一个类,内存分配大小不一样 同样的写法 CLASS A: A* a1=new A: A *a2=new A: 两个语句在代码不同的地方执行而已 new操作符没重载 sizeof(A)得出来的结果是4760, 有人遇到过类似的问题吗,什么原因导致这样的问题, 完全没头绪!!!!!!!!! 解决方案 会不会是内存的对齐产生的问题. 解决方案二: 编译器debug优化关了没

类中的内存分配和指针类型强制转换问题

问题描述 类中的内存分配和指针类型强制转换问题 问题描述: template //element type class list { private: EleT data;//数据本身,即是需要的信息 list* prio;//the pointer of prior element list* next;//the pointer of next element list* last;//the last pointer of list int len;//the length of list

C++ QVector 类介绍及内存分配策略

QVector 介绍 QVector类是一个提供动态数组的模板类. QVector<T>是Qt普通容器类的一种.它将自己的每一个对象存储在连续的内存中,可以使用索引号来快速访问它们.QList<T>.QLinkedList<T>和 QVarLengthArray<T>也提供了相似的功能,它们使用方法如下: l QList一般用得最多,它能满足我们绝大部分需求.像prepend()和insert()这样的操作通常比QVector要快些,这是由于QList存储它

关于Java 数组内存分配一点认识

 可能Java 数组大家都很熟悉,最近我遇到了一个关于Java 数组内存分配的问题.         呵呵.突然就发现许多书上"基本数据类型存储在栈内存当中,对象则保存在堆内存"这句话完全是错误的.下面是个简单的例子代码: public class Test { public static void main(String[] argv) { // 静态初始化数组 String[] names = { "Michael", "Orson", &q

简介C++中的String类

C++中针对C语言中处理字符串的难题,在标准库中设计了string类,因此现在编程中涉及到字符串的处理,就可以直接使用string类了. 之所以抛弃char*的字符串而选用C++标准程序库中的string类,是因为他和前者比较起来,不必 担心内存是否足够.字符串长度等等,而且作为一个类出现,他集成的操作函数足以完成我们大多数情况下(甚至是100%)的需要.我们可以用 = 进行赋值操作,== 进行比较,+ 做串联(是不是很简单?).我们尽可以把它看成是C++的基本数据类型. 首先,为了在我们的程序

JAVA垃圾收集器与内存分配策略详解_java

引言 垃圾收集技术并不是Java语言首创的,1960年诞生于MIT的Lisp是第一门真正使用内存动态分配和垃圾收集技术的语言.垃圾收集技术需要考虑的三个问题是: 1.哪些内存需要回收 2.什么时候回收 3.如何回收 java内存运行时区域的分布,其中程序计数器,虚拟机栈,本地方法区都是随着线程而生,随线程而灭,所以这几个区域就不需要过多考虑回收问题.但是堆和方法区就不一样了,只有在程序运行期间我们才知道会创建哪些对象,这部分内存的分配和回收都是动态的.垃圾收集器所关注的就是这部分内存. 一 对象

Spark On YARN内存分配

本文主要了解Spark On YARN部署模式下的内存分配情况,因为没有深入研究Spark的源代码,所以只能根据日志去看相关的源代码,从而了解"为什么会这样,为什么会那样". 说明 按照Spark应用程序中的driver分布方式不同,Spark on YARN有两种模式: yarn-client模式.yarn-cluster模式. 当在YARN上运行Spark作业,每个Spark executor作为一个YARN容器运行.Spark可以使得多个Tasks在同一个容器里面运行. 下图是y

语言变量声明内存分配

一个由c/C++编译的程序占用的内存分为以下几个部分 1.栈区(stack)- 程序运行时由编译器自动分配,存放函数的参数值,局部变量的值等.其操作方式类似于数据结构中的栈.程序结束时由编译器自动释放. 2.堆区(heap) - 在内存开辟另一块存储区域.一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 .注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵. 3.全局区(静态区)(static)-编译器编译时即分配内存.全局变量和静态变量的存储是放在一块的,初始化的全局

【转载】JVM内存分配与调优参数列表

本文转载自http://shift-alt-ctrl.iteye.com/blog/1842631   一.运行时数据区:   程序计数器:它是一块较小的内存空间,主要作用是当前线程所执行的字节码的行号指示器.由于java虚拟机的多线程是通过轮流切换并分配处理器执行时间的方式来实现的(协作式/抢占式?!),即任何时刻,任一CPU只会正在处理一个线程的指令;为了确保线程切换后能够正确恢复执行的位置,每个线程都有一个独立的程序计数器,每个计数器为线程私有.如果线程正在执行java方法,那么此计数器记