class Test2 {
String a = "1";
String b = "2";
}
public class NoUpdate {
public static void changeUpd(Test2 t) {
t.a = "abc";
t.b = "123";
}
public static void main(String[] args) {
Test2 t2 = new Test2();
changeUpd(t2);
System.out.println(t2.a + "----" + t2.b);
}
}这个程序输出 abc----123 ;
但是如果修改一下,
publicclass Test1 {
publicstaticvoid changeStr(String str){
str="welcome";
}
public static void main(String[] args) {
String str="1234";
changeStr(str);
System.out.println(str);
}
}
这里就输出 1234
同样传递的是对象,为什么第二个程序的值没有被修改呢?两个程序传递的参数都应该是原对象的引用的,为什么?想不明白,呵呵
String a = "1";
String b = "2";
}
public class NoUpdate {
public static void changeUpd(Test2 t) {
t.a = "abc";
t.b = "123";
}
public static void main(String[] args) {
Test2 t2 = new Test2();
changeUpd(t2);
System.out.println(t2.a + "----" + t2.b);
}
}这个程序输出 abc----123 ;
但是如果修改一下,
publicclass Test1 {
publicstaticvoid changeStr(String str){
str="welcome";
}
public static void main(String[] args) {
String str="1234";
changeStr(str);
System.out.println(str);
}
}
这里就输出 1234
同样传递的是对象,为什么第二个程序的值没有被修改呢?两个程序传递的参数都应该是原对象的引用的,为什么?想不明白,呵呵
str="welcome";
}
可以试试不要void,让它return str;
String是对象,应该是按引用传递,但是String是一种特殊的对象,即他所引用的值是无法改变的
一开始的时候main方法中的str所引用的对象是"1234",当执行到changeStr(str)时,会把changeStr中的str指向"1234",这时候内存中有两个str,所引用的内容都是"1234",在往下,让changeStr中的str引用"welcome",注意这里要提到String对象的一个特性,即他的内容是无法改变的,起初str = "1234",当str = “welcome”时,并没有将1234换成welcome,而是重新分配一个内存存储"weilcome",然后让str引用该内容,而main中的str依然引用的是"1234"
因此我们编程的时候,如果需要频繁的改变字符串内容,应该考虑使用StringBuffer或者StringBuilder(两者的区别在于前者是线程安全的,对于一个线程的情况,用StringBuilder效率更高),以节省内存空间,
String a = "1";
String b = "2";
}
public class NoUpdate {
public static void changeUpd(Test2 t) {
t.a = "abc";
t.b = "123";
}
public static void main(String[] args) {
Test2 t2 = new Test2();
changeUpd(t2);
System.out.println(t2.a + "----" + t2.b);
}
} 这里在内存堆里的对象是t2,你改变的是对象里的内容。
publicclass Test1 {
publicstaticvoid changeStr(String str){
str="welcome";
}
public static void main(String[] args) {
String str="1234";
changeStr(str);
System.out.println(str);
}
} 这里的对象是str,你修改的也是str。
public static void main(String[] args) {
String a = "a";
a = "b";
System.out.println(a);
}
你说a是多少
String a = "1";
String b = "2";
}public class NoUpdate {
public static void changeUpd(Test2 t) {
t.a = "abc";
t.b = "123";
} public static void main(String[] args) {
Test2 t2 = new Test2();
changeUpd(t2);
System.out.println(t2.a + "----" + t2.b);
}
}楼上你在试试这个,并不是final的原因。
String a = "1";
String b = "2";
}
public class NoUpdate {
public static void changeUpd(Test2 t) {
t.a = "abc";
t.b = "123";
}
public static void main(String[] args) {
Test2 t2 = new Test2(); //a=“1”,b=“2”
changeUpd(t2); //a="abc",b="123"
System.out.println(t2.a + "----" + t2.b); //打印
}
}
这个程序输出 abc----123 ;
但是如果修改一下,
public class Test1 {
public static void changeStr(String str){
str="welcome";
}
public static void main(String[] args) {
String str="1234"; //主函数中的str=“1234”
changeStr(str); changeStr中的“welcom”被改为“1234”,但是主函数中的值没被改变
System.out.println(str); //输出主函数中的值是“1234”
}
}
这里就输出 1234
lz说的“两个程序传递的参数都应该是原对象的引用的”,你引用的没错,不过传值并不是一样的
str="welcome";
} 相当于: publicstaticvoid changeStr(String str){
str= new String("welcome");
} 所以,传参都是引用值的复制, 任何引用传递进来之后,如果重新分配一个new 对象,都仅仅发生在复制过来的引用参数上,对原来对象不会产生任何作用,除非是这样的: publicstaticvoid changeStr(MyClass a){
a.attribute = "12123";//注意不是new哦!
} 我之前做了一个比较完善的总结,希望对你有帮助:http://blog.csdn.net/ostrichmyself/archive/2009/10/03/4630976.aspx
public class Test1 {
public static void changeStr(String string){
;//这个时候string和str都引用的是相同的内存地址,其内容是"1234"
string="welcome";//这个时候,不会把"1234"的内容改为"welcome",而是重新分配一块内存存储"welcome",并让string引用该内存,而主函数中的str仍然引用原来的"1234"。这是因为String对象是final的,其内容是无法改变的,只能重新分配内存空间存储新的内容
}
public static void main(String[] args) {
String str="1234"; //主函数中的str=“1234”
changeStr(str); //
System.out.println(str); //输出主函数中的值是“1234”
}
}
String的底层实现是其实是字符型数组,并且该数组也是final的
这里当然会改变, 你应该好好看看大家的回复了, 如果NoUpdate改成:
public class NoUpdate {
public static void changeUpd(Test2 t) {
t = new Test2();
t.a = "abc";
t.b = "123";
}
你再调用试试! 没有改变, 结果还是"1"和"2"了,String a= "welcome" 的作用就是a = new String("welcome");
implements java.io.Serializable, Comparable<String>, CharSequence
{
/** The value is used for character storage. */
private final char value[]; /** The offset is the first index of the storage that is used. */
private final int offset; /** The count is the number of characters in the String. */
private final int count; /** Cache the hash code for the string */
private int hash; // Default to 0
*************************************************
上面是用jad反编译之后得到的源代码,可以看到String其实就是final char value[],因为是final的,所以他的值一旦被确定之后就无法改变,而你写的那个例子如果String a和String b都声明为final,你的代码就错了……
服了,这和final没关系,我知道String是final类型的,你仔细看了我10楼的例子在说。我晕啊。
final class Test2 {
String a = "1";
String b = "2";
}
这里已经声明为final了。
人家final指的是private final char value[]; 这句好不好