前几天帮别人写一个SDK的Demo代码,遇到个问题。里面有一个接口,参数为String,要引用传递。然后发现代码执行结束以后,这个String对象的值并没修改。
查了好久才发现又进了一个之前踩过的坑。果然基础知识要定期巩固,就专门对Java的参数传递和String简单汇总整理下。先在上面说了结论,然后再在后面举证。
参数传入方法时,无论该参数在方法内怎样被改变,外部的变量原型总是不变,叫做“值传递”。即方法操作的是参数变量(也就是原型变量的一个值的拷贝)改变的也只是原型变量的一个拷贝而已,而非变量本身。所以变量原型并不会随之改变。
参数传入方法时,方法改变参数变量的同时变量原型也会随之改变,这种特性就叫做“引用传递”,也叫做传址。即方法操作参数变量时是拷贝了变量的引用,而后通过引用找到变量(在这里是对象)的真正地址,并对其进行操作。
String虽然是对象类型,但是String是不可变的对象,在每次对String 类型进行改变的时候,都会生成一个新的 String 对象。因此导致当String作为参数传递的时候,感官上是传值传递。具体的说:当String作为参数传递时,确实是以地址传递过去的,但是在对String类型的变量的值进行改变时,由于String类的值是常量,在创建后不能更改,所以对String参数进行操作,相当于new String(),已经改变了String对象的地址了,所以实参不会改变。
String是不可变的对象, 因此在每次对String 类型进行改变的时候,都会生成一个新的 String 对象,然后将指针指向新的 String 对象
之前在ImportNew的微信公共号上看到一篇关于Java String、StringBuilder和StringBuffer(点击查看)的文章,感觉还不错,推荐一下,也是备忘。
测试代码1:
public class Test{
public static void testFunction(int para){
para = para + 5;
System.out.println("Func para is:"+ para);
}
public static void main(String[] args) {
int a = 5;
System.out.println("Main para is:"+ a);
testFunction(a);
System.out.println("Main para after func is:"+ a);
}
}
运行结果1:
➜ temp javac Test.java && java Test
Main para is:5
Func para is:10
Main para after func is:5
➜ temp
测试代码2:
public class Test {
public static void testFunction(Integer para) {
para = para + 5;
System.out.println("Func para is:" + para);
}
public static void main(String[] args) {
Integer a = 5;
System.out.println("Main para is:" + a);
testFunction(a);
System.out.println("Main para after func is:" + a);
}
}
运行结果2:
➜ temp javac Test.java && java Test
Main para is:5
Func para is:10
Main para after func is:5
➜ temp
概要分析:
测试代码:
public class TestObj {
public String mKey = "";
public TestObj(String para) {
this.mKey = para;
}
public String toString() {
return mKey;
}
}
public class Test {
public static void testFunction(TestObj para) {
para.mKey = para.mKey + " world!";
System.out.println("Func para is:" + para.toString());
}
public static void main(String[] args) {
TestObj a = new TestObj("hello");
System.out.println("Main para is:" + a.toString());
testFunction(a);
System.out.println("Main para after func is:" + a.toString());
}
}
运行结果:
➜ temp javac TestObj.java Test.java && java Test
Main para is:hello
Func para is:hello world!
Main para after func is:hello world!
➜ temp
概要分析:
测试代码:
public class Test{
public static void testFunction(String para){
para = para + " world!";
System.out.println("Func para is:"+ para);
}
public static void main(String[] args) {
String a = "hello";
System.out.println("Main para is:"+ a);
testFunction(a);
System.out.println("Main para after func is:"+ a);
}
}
运行结果:
➜ temp javac Test.java && java Test
Main para is:hello
Func para is:hello world!
Main para after func is:hello
➜ temp
概要分析:
测试代码:
public class Test {
public static void testFunction(StringBuilder para) {
para = para.append(" world!");
System.out.println("Func para is:" + para.toString());
}
public static void main(String[] args) {
StringBuilder a = new StringBuilder("hello");
System.out.println("Main para is:" + a.toString());
testFunction(a);
System.out.println("Main para after func is:" + a.toString());
} }
运行结果:
➜ temp javac Test.java && java Test
Main para is:hello
Func para is:hello world!
Main para after func is:hello world!
➜ temp
概要分析: