java的值传递与引用传递
2018-01-05 09:37
169 查看
昨天在群里又看到人问我之前困惑的值传递还是引用传递的问题。
在解答了他之后,回去重新研究了一下,
记下这些,并写了个简单的例子:
结果是:
这里引出的问题不过是为什么String对象的值没变,而StringBuffer的值变了。进而引出一个问题:
关于Java里到底是值传递还是引用传递?
就我理解上,传递的不过是一个指针。
在上述例子中,为了进行比较我新建了一个String对象与一个StringBuffer对象。并通过两个方法进行修改。
可以这么说,这里产生了一个局部变量adder,
在内存中a指向的是“Hello “,a将这个指向传递给了adder。
所以在方法中adder也指向“Hello ”,
方法运行adder+=”World”后产生了一个新的内存“Hello World”,这时候adder就会重新指向这个新的内存。
当方法结束后,改变的不过是adder的指向。在外部的String a 指向的还是“Hello”,所以输出a的值是“Hello”。
若这是一个返回String的函数,在方法的末尾return adder;
意思就是把局部变量adder的指向返回,再用a=addString(a);接收方法返回的指向,这样a就指向了“Hello World”。
String的长度是不可变的,StringBuffer的长度是可变的。
方法中的adder接收了外部b的指向“World”。
而当调用StringBuffer.append(“World”);时,并不会产生一个新的指向“Hello World”,而是将adder的指向“Hello”改变成了“Hello World”。而关键的地方在于:b也指向这个地址,这个地址的内容变了。
所以StringBuffer在方法中会变。
1.对String的修改不会改变String指向与它指向的地址的值,a指向原有的地址,所以a不变。
2.对StringBuffer的append方法,是直接对StringBuffer指向的地址的值修改,b指向原有的地址的值变了,所以变了。
这也引出了我的理解:java不要谈论什么值传递与引用传递,传递的不过是一个指针指向。
也引出这样的结论,在长字符串的拼凑上,String每拼凑一次就会产生一个新的地址,而StringBuffer是对原有地址的值进行修改,所以减少了内存的开销且提供了更好的效率
存在这样一种情况String的效率会更高
String a = “Hello “+”World”;
其实经过虚拟机的优化就是
String a = “Hello World”;
所以内部并没有通过StringBuilder进行拼凑,也就更快了
在解答了他之后,回去重新研究了一下,
记下这些,并写了个简单的例子:
/** * @author : cjd * @Description :值传递还是引用传递 * @create : 2018-01-05 8:37 **/ public class Main { public static void main(String[] args) { String a = "Hello "; StringBuffer b = new StringBuffer("Hello "); addString(a); addStringBuffer(b); System.out.println(a); System.out.println(b); } static void addString(String adder){ adder+="World"; } static void addStringBuffer(StringBuffer adder){ adder.append("World"); } }
结果是:
Hello Hello World
这里引出的问题不过是为什么String对象的值没变,而StringBuffer的值变了。进而引出一个问题:
关于Java里到底是值传递还是引用传递?
就我理解上,传递的不过是一个指针。
在上述例子中,为了进行比较我新建了一个String对象与一个StringBuffer对象。并通过两个方法进行修改。
为什么String的值不变?
关于String的方法中:static void addString(String adder){ adder+="World"; }
可以这么说,这里产生了一个局部变量adder,
在内存中a指向的是“Hello “,a将这个指向传递给了adder。
所以在方法中adder也指向“Hello ”,
方法运行adder+=”World”后产生了一个新的内存“Hello World”,这时候adder就会重新指向这个新的内存。
当方法结束后,改变的不过是adder的指向。在外部的String a 指向的还是“Hello”,所以输出a的值是“Hello”。
若这是一个返回String的函数,在方法的末尾return adder;
意思就是把局部变量adder的指向返回,再用a=addString(a);接收方法返回的指向,这样a就指向了“Hello World”。
为什么StringBuffer的值变了?
如果看懂了上述所说,再理解一下StringBuffer是什么。String的长度是不可变的,StringBuffer的长度是可变的。
方法中的adder接收了外部b的指向“World”。
而当调用StringBuffer.append(“World”);时,并不会产生一个新的指向“Hello World”,而是将adder的指向“Hello”改变成了“Hello World”。而关键的地方在于:b也指向这个地址,这个地址的内容变了。
所以StringBuffer在方法中会变。
结论
这样的一个小例子,说明了这样两点:1.对String的修改不会改变String指向与它指向的地址的值,a指向原有的地址,所以a不变。
2.对StringBuffer的append方法,是直接对StringBuffer指向的地址的值修改,b指向原有的地址的值变了,所以变了。
这也引出了我的理解:java不要谈论什么值传递与引用传递,传递的不过是一个指针指向。
也引出这样的结论,在长字符串的拼凑上,String每拼凑一次就会产生一个新的地址,而StringBuffer是对原有地址的值进行修改,所以减少了内存的开销且提供了更好的效率
存在这样一种情况String的效率会更高
String a = “Hello “+”World”;
其实经过虚拟机的优化就是
String a = “Hello World”;
所以内部并没有通过StringBuilder进行拼凑,也就更快了
相关文章推荐
- java到底是值传递还是引用传递?
- java中是值传递还是引用传递?
- 关于java中的值传递与引用传递的见解
- Java 到底是值传递还是引用传递?
- java是值传递还是引用传递。
- java中的值传递与引用传递
- java是值传递还是引用传递
- JAVA中的值传递和引用传递,String的值传递特性
- Java中的值传递与“引用传递”
- java中按值传递还是按引用传递--string
- java基础学习——值传递与引用传递
- Java方法的值传递和引用传递
- java 值传递,和引用传递的问题
- 为什么java方法中只有值传递,没有引用传递
- Java 到底是值传递还是引用传递
- java是值传递还是引用传递?
- java中函数是值传递还是引用传递?
- java到底是按值传递还是按引用传递?
- java中的值传递以及(址)引用传递实例
- 画重点,Java方法的参数到底是值传递还是引用传递?