String s1 = "a";
String s2 = s1;
s2 = "b";
System.out.println(s1); 也是a
String s2 = s1;
s2 = "b";
System.out.println(s1); 也是a
解决方案 »
- spring和hibernate整合做单元测试时报错:DEFAULT和NULL不允许作为显示标识值
- JS小白 五一给大家送分来了。。。。dhtmlxgrid
- 一个ejb对象为什么不能被并发访问
- AXIS2集成Spring后的Session管理
- 如何调用系统自带的压缩功能来实现压缩,加密
- struts中如何将actionForm中的字符串转换为日期型?
- 救命啊!!!写了两个sessionbean访问entitybean,一个可以跑,一个抛NullPointerException啊!~高手救命啊!!!
- struts的一个很简单的问题
- 我只想聊聊天,因为我很空虚。
- jdk安装
- 小小女菜鸟请大家帮忙,如何使这段代码变得整洁呢?
- struts框架中action的方法执行后跳到html页面的问题
String s2 = s1; //这句话是说吧s1的值赋给s2,也就是说s2的值也是"a"了然后你打印s2,不是"a" 还能是什么?
s1 重新赋值了肯定就是 b 啊,怎么会输出a
这样赋值的话 当int来看 不知道这样说正确否
这样赋值的话 当int来看 不知道这样说正确否好像是吧?我基础不行啊。
首先String s1 = "a";是将"a"放入字符串驻留池同时指向"a"的引用,String s2是指向字符串驻留池的"a"引用,而不是s1的内存地址;
当s1 = "b";是将"b"放入字符串驻留池同时指向"b"的引用,而这时s2还是指向字符串驻留池的"a"引用。
为 s1 变量 重新赋值!
就和 String s1 = "a"; 一个意思
s2=s1 是
赋值! 将 s1 指向的内存地址穿过去了。
。s2 不是依赖s1.
而是直接指向了"a" 的内存地址。
传递的是引用。
然后再建一个引用对象s2, 指向s1的引用,也就是s1指向的内存地址,也就是a
s1 和 s2 共同指向了一个具体的内存地址。
这时,将s1 指向的地址的值改为b
那么他们指向同一个地址,s2也就是b了。
String s2 = s1;
s1 = "b";
System.out.println(s2);
不知道楼主学的是什么语言;我学的是java;就从Java方面解释下,首先java里的字符类有个常量池的概念,如果常量池没有“a”这个字符的话就创建这个对象同时在堆里创建一个引用对象s1,并且把字符a放入常量池里。
第二行代码是把s1在堆中的内存地址赋值给s2,此时s2的内存地址指向的就是常量池中的“a”.第3行代码中的字符“b”和字符“a”一样的创建方式,并且在堆中分配新的物理内存地址给s1,此时的字符“b”的引用对象s1所指向的内存地址已经和前面的内存地址不同了。所以打印s2自然会打印s2内存地址所对应的值“a”.
char *s1 = "a";
char *s2 = s1;
s1 = "b";
printf("%s", s2);
printf("%s", s1);s1,s2作为局部变量放在堆栈区,字符串a,b放在只读段。
s1,s2仅仅是变量而已,所谓指针,也只是一个指针类型的变量。第一行,s1指向字符串a的内存地址,
第二行,s1把地址值赋值给s2,S2也指向字符串a
第三行,s1指向字符串b的内存地址
第四行,打印S2,当然打印的是字符串a了
第五行,打印S1,当然打印的是字符串b了下面是我用的C#写的测试代码,现在没搞C了。
{
static void Main(string[] args)
{
string s1 = "a";
string s2 = s1;
s1 = "b";
Console.Write("s2 = "s2);
Console.Write("s1 = "s1);
Console.Read();
}输出结果s2 = a, s1 = b.
String s2 = s1; // s2引用s1引用的对象,即,s2引用"a"对象
s1 = "b"; // s1现在引用"b"对象(但是s2没有变化对吧)
System.out.println(s2); // s2还是引用"a"对象,打出a// 如果“引用”这个词还不好理解,请把它改成“指向”,并在纸上画出这种指向的关系。String s1 = "a"; // s1指向"a"对象
String s2 = s1; // s2指向s1指向的对象,即,s2指向"a"对象
s1 = "b"; // s1现在指向"b"对象(但是s2没有变化对吧)
System.out.println(s2); // s2还是指向"a"对象,打出aString s1 = "a"; // s1 -> "a"
String s2 = s1; // s2 -> "a" <- s1,注意,不是s2 -> s1 -> "a"
s1 = "b"; // s2 -> "a" s1 -> "b"
System.out.println(s2); // so ...个人觉得问题的关键就是“如何解读=操作”。
这有啥好纠结的
第一句:把"a"在内存中的地址给赋值给s1
第二句:把"a"在内存中的地址复制一份给s2,也就是此时s1、s2均指向内存中的"a"
第三句:把"b"在内存中的地址赋值给s2,此时s2指向内存中的"b",而s1还是指向内存中的"a"
所以打印出a
int[] a = { 1, 2, 3, }; // a引用一个int[]对象,该对象为一个int array,三个元素1,2,3
int[] b = a; // b引用a引用的那个对象,同一个对象
b[0] = 0; // 修改b引用的那个对象(也就是修改了a引用的对象,是同一个对象来着)
for (int i : a) {
System.out.println(i); // a引用的对象变了,0,2,3
}
............
String是字胡窜的意思!
String s2 = s1;
s1 = "b";
System.out.println(s2);为什么输出a? 对象变量s1->对象值a
对象变量s2->对象变量s1->对象值a 实际上 对象变量s2->对象值a
对象变量s1->对象值b
。
在这里如果对象变量s2->对象变量s1
那么 对象变量s2->对象变量s1->对象值b s2=b
。。
没有 那么。
s2=a
s1=b
楼主跟你画个图 你就明白了
首先:
然后是值传递 即s1把自己保存的内存地址复制一份给了s2
然后s1再次赋值 把自己原来保存的"a"的内存地址换成了"b"的内存地址
而s2保存的还是"a"的内存地址
所以输出s2是"a"
String s1 = "a";会牵扯到堆的概念吗,只会停留在栈上面吧。
String s1 = "a"存放在常量池,常量池放在栈中,s1直接指向常量池的这块引用;
如果String s1 = new String("a");才会牵扯到堆,在常量池创建“a”的同时在堆中开辟一块内存,这时才是s1指向堆中的内存地址,堆中的内存地址指向常量池中的"a"引用。
String s2 = s1;(2)
s1 = "b";(3)
(1)行 s1是地址 在栈中,a是内容在内存中(堆),s1指向a
(2)行 s2是地址 在栈中,s2=s1 s1的地址赋给s2,就是说s2也指向了a
(3)行 s1=“b”,s1指向了b
三句话执行下来,s2指向的是a 所以输出a。
过程中s1只是指向的内容变了而已。
变量是一个指向对象的指针,一个对象包含另一个对象也是包含这个对象的指针。java 中如果这个指针没有初始化,会报错不会产生一个随机的结果。String s1 = "a"; //这是s1指向一个匿名对象“a”
String s2 = s1;// 这里s2也指向这个匿名对象“a”,而不是指向S1
s1 = "b"; 这时候s1又指向匿名对象“B”, 而S2还是指向匿名对象“a”
System.out.println(s2);java 中问什么会有普通克隆和深层 克隆的区别。普通的克隆只是给变量的分配了内存空间,对象里变量和原来的对象指向相同。
深层 就是对象里变量也是新的