精华帖 (0) :: 良好帖 (13) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2011-06-28
java 对象的传递中,改变不了对象本身,但是能改变对象的属性元素
|
|
返回顶楼 | |
发表时间:2011-06-28
TO bugmenot:
String确实是传值的,虽然它是普通的对象。在方法中,对传入的String变量做了任何操作,返回到调用者那儿,那个String还没有变。 |
|
返回顶楼 | |
发表时间:2011-06-29
i.phoenix 写道 TO bugmenot:
String确实是传值的,虽然它是普通的对象。在方法中,对传入的String变量做了任何操作,返回到调用者那儿,那个String还没有变。 String是final类。。。 方法调用时,JVM会把String的引用值复制到方法栈中执行。而对于在方法栈中对该引用值作何改动都不会影响主线程的String变量在堆中的值。 数组在Java中是一个对象,而数组类型只不过是相当于对象中的属性而已,与String无关。 楼主对于Java程序在JVM的堆栈中运行过程理解非常清晰,各位不懂的同学真的可以学习下。 |
|
返回顶楼 | |
发表时间:2011-06-29
讨论得很好,学习了^-^...
|
|
返回顶楼 | |
发表时间:2011-06-29
haidii 写道 so easy
java的对象都是引用。 第一个只是把引用的地址改了,原来的字符串没变。 第二个是数组,数组是直接引用地址。 就这么简单。 就是这么简单。。。 |
|
返回顶楼 | |
发表时间:2011-06-29
最后修改:2011-06-29
在java方法中不管传给形参的实参是基本类型,还是对象类型,
形参的操作都不能改变传入的实参的值(可以把这个值理解为内存中的地址) 但是形参可以持有实参传过来的这个值(就如同楼主画图分析的那样), 形参一旦持有实参传过来的值就可以改变实参对象本身的属性, 并且形参所持有的值是可以改变的(即可以指向其他对象),但是如果形参设置为final则形参不能再指向其他对象! 所以在方法中要区分出形参进行的是那种操作 总结:java中都是值传递!很奇怪为什么不叫引用传递呢? 理解不够准确,还请各位指出来 |
|
返回顶楼 | |
发表时间:2011-06-29
最后修改:2011-06-29
kingkan 写道 i.phoenix 写道 TO bugmenot:
String确实是传值的,虽然它是普通的对象。在方法中,对传入的String变量做了任何操作,返回到调用者那儿,那个String还没有变。 String是final类。。。 方法调用时,JVM会把String的引用值复制到方法栈中执行。而对于在方法栈中对该引用值作何改动都不会影响主线程的String变量在堆中的值。 数组在Java中是一个对象,而数组类型只不过是相当于对象中的属性而已,与String无关。 楼主对于Java程序在JVM的堆栈中运行过程理解非常清晰,各位不懂的同学真的可以学习下。 和final没关系。。。final只是不能继承 ps:如果说String的属性是final的,那还是没用。 final只是属性的值不变,field本身是否会改变要另外考虑,如果field里面的值(包括的值的值的值。。。)都是不变,那这个对象才是在普通情况完全不变(别扯字节码甚至直接操作内存啥的) 抱歉的是string里的value巧好是个数组,而恰好数组里面的值java没给我们final这个选项 public static void main(String [] a) throws Exception{ String aa = "iteye"; System.out.println(aa); changeString(aa, "csdn"); System.out.println(aa); } public static void changeString(String dst,String src) throws Exception{ Field value = String.class.getDeclaredField("value"); value.setAccessible(true); char[] valueA = (char[])value.get(dst); char[] valueB = (char[])value.get(src); System.arraycopy(valueB, 0, valueA, 0, Math.min(valueA.length, valueB.length)); } |
|
返回顶楼 | |
发表时间:2011-06-29
JE帐号 写道 ... ...
两段代码,又不相似.没什么可对比的,如果第二段代码的method方法为以下 static void method(String[] a){//12 a = new String[]{"1","2"}; } 在这种情况下如果两段代码结果表现不一样,才有意思. 现在你两个例子里,一个是对传入的参数进行=操作,另一个是对传入的参数里的元素进行=操作.这又什么好对比的? 你第二个调用new 和第一个一样了。 |
|
返回顶楼 | |
发表时间:2011-06-29
JE帐号 写道 ... ... 两段代码,又不相似.没什么可对比的,如果第二段代码的method方法为以下 static void method(String[] a){//12 a = new String[]{"1","2"}; } 在这种情况下如果两段代码结果表现不一样,才有意思. 现在你两个例子里,一个是对传入的参数进行=操作,另一个是对传入的参数里的元素进行=操作.这又什么好对比的? 结果也是变化了啊,有什么意思? |
|
返回顶楼 | |
发表时间:2011-06-29
dotjar 写道
两段代码,结果的差异,请结合代码给图解下内存和执行过程。 public class PassAddr { public static void main(String[] args) { String s=new String("old"); //1 method(s); //3 System.out.println(s); } static void method(String str){ str=new String("new"); //2 } } 这个输出结果为:old public class T { public static void main(String[] args) { String[] arr=new String[2]; arr[0]="old_0"; arr[1]="old_1"; //11 /*arr[0]=new String("old_0"); arr[1]=new String("old_1"); //11 同样*/ method(arr); //14 System.out.println(arr[0]+";"+arr[1]); } static void method(String[] a){//12 a[0]="new_0"; a[1]="new_1"; //13 } }
这个输出却是:new_0;new_1 自己发的问题,想了半天想通了。解析下,希望各位斧正! string://1处时: //2处时: //3处: 由于方法调用已经完成,所以str临时变量在stack中消失,s还是0x001,其地址处对象new String("old")没有被动;所以输出结果还是old; ---------------------------------------------------固执的分割线------------------------------------------------------ //11处内存状态: //12处: //13处时候的内存状况: 此时a[0]和a[1]的值被改变,其实就是arr的相应值改变了。最后就出现了结果如图://14 所以就出现结果改变的情况了。 这么一作图,很直观了。 楼主分析的完全正确!!! |
|
返回顶楼 | |