问题的引入是因为下午在群里看到了一个网友的问题:
给定如下Java 代码,编译运行后,输出结果是( )。
public class Test {
public static void main(String [ ] args) {
StringBuffer a = new StringBuffer(“A”);
StringBuffer b = new StringBuffer(“B”);
operate(a , b);
System.out.println(a + ”,” + b);
}
static void operate(StringBuffer x , StringBuffer y) {
x.append(y);
y = x;
}
}
A. A,B B. AB,B C. A,AB D.AB,AB
朋友可以猜猜这个答案,我也想告诉大家,答案是:B。也许有人会很惊讶,也许有人会很淡定。因为StringBuffer是一个类,对于类的使用,通过new,在堆中创建一个类的实例,利用一个引用来实现对这个对象的操作。当把一个引用当作参数传递到一个函数中的时候,C++采取的是:这个参数是一个地址。而在java中没有地址这个概念,一切都是值传递,那么这里又是怎么控制的。
首先,我做了一个测试:
public class Text {
public static void main(String[] args) {
String s = "b";
f(s);
System.out.println(s);
}
static void f(String s) {
s = "c";
}
} /* output
b
*///~
从结果可以看出:形参的效果并没有作用到实参中。我们继续看下一段代码:
public class Text {
String s = "b";
public static void main(String[] args) {
Text t = new text();
f(t.s);
System.out.println(t.s);
}
static void f(String s) {
s = "c";
}
} /* output
b
*///~
这里的输出结果还是为b。继续:
public class Text {
String s = "b";
public static void main(String[] args) {
Txet t = new Text();
f(t);
System.out.println(t.s);
}
static void f(Text t) {
t.s = "c";
}
} /* output
c
*///~
从结果中可以看出:形参的效果作用到了实参,这里的引用发生了效果。
String为系统带的类,而Text为自定义的类,为了防止是自定义类跟系统类的影响,又使用了另外一个系统类List进行验证:
public class Text {
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();
list.add(33);
l(list);
System.out.println(list);
}
static void l(List<Integer> list) {
list.add(55);
}
} /* output
[33, 55]
*///~
从输出结果中可以看出:类的引用效果得以发挥。
针对上面的结果,我想朋友们会有一些意外,因为在java基础语言学习中,我们曾经对“==”与“equals()”的操作曾经进行了很多的讨论,结果说明:String类是一个引用类型,给出一段代码,以供大家学习:
public class SimpleTypeText {
public static void main(String[] args) {
String s1 = "a";
String s2 = "a";
String s3 = new String("b");
String s4 = new String("b");
System.out.println("s1 == s2 ? " + (s1 == s2) );
System.out.println("s1.equals(s2) ? " + s1.equals(s2));
System.out.println("s2 == s3 ? " + (s2 == s3) );
System.out.println("s2.equals(s3) ? " + s2.equals(s3));
System.out.println("s3 == s4 ? " + (s3 == s4) );
System.out.println("s3.equals(s4) ? " + s3.equals(s4));
(s4, s1);
}
static void f(String s) {
s = "a";
}
static void g(String s, String s1) {
s = "a";
System.out.println("通过常字符串:" + s == s1);
s = new String(s1);
System.out.println("通过new方法:" + s == s1);
}
} /*output:
s1 == s2 ? true
s1.equals(s2) ? true
s2 == s3 ? false
s3.equals(s3) ? true
s3 == s4 ? false
s3.equals(s4) ? true
通过常字符串:true
通过new方法:false
*///~
总结:
1. thinking in java 中对String类型对象有这样一段描述:
String对象是不可变的,没一个看起来会修改String值的方法,实际上都是创建了一个全新的String对象。
对String类型的对象做参数有这样的一段描述:
每当把String对象作为方法的参数时,都会复制一份引用,而该引用所指的对象其实一直待在单一的物理位置上,从未动过。
2. 在字符串的声明中,利用常字符串初始化的时候,系统会从已有的常字符串进行查找,如果存在此字符串常量,则不再生成新的字符串常量,但是new方法不是这样的,即它不进行查找,直接开辟一段新的空间,存储这个字符串。
声明:以上代码均为参考,希望对基础有些帮助。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/yanmushi/archive/2010/05/09/5573022.aspx
给定如下Java 代码,编译运行后,输出结果是( )。
public class Test {
public static void main(String [ ] args) {
StringBuffer a = new StringBuffer(“A”);
StringBuffer b = new StringBuffer(“B”);
operate(a , b);
System.out.println(a + ”,” + b);
}
static void operate(StringBuffer x , StringBuffer y) {
x.append(y);
y = x;
}
}
A. A,B B. AB,B C. A,AB D.AB,AB
朋友可以猜猜这个答案,我也想告诉大家,答案是:B。也许有人会很惊讶,也许有人会很淡定。因为StringBuffer是一个类,对于类的使用,通过new,在堆中创建一个类的实例,利用一个引用来实现对这个对象的操作。当把一个引用当作参数传递到一个函数中的时候,C++采取的是:这个参数是一个地址。而在java中没有地址这个概念,一切都是值传递,那么这里又是怎么控制的。
首先,我做了一个测试:
public class Text {
public static void main(String[] args) {
String s = "b";
f(s);
System.out.println(s);
}
static void f(String s) {
s = "c";
}
} /* output
b
*///~
从结果可以看出:形参的效果并没有作用到实参中。我们继续看下一段代码:
public class Text {
String s = "b";
public static void main(String[] args) {
Text t = new text();
f(t.s);
System.out.println(t.s);
}
static void f(String s) {
s = "c";
}
} /* output
b
*///~
这里的输出结果还是为b。继续:
public class Text {
String s = "b";
public static void main(String[] args) {
Txet t = new Text();
f(t);
System.out.println(t.s);
}
static void f(Text t) {
t.s = "c";
}
} /* output
c
*///~
从结果中可以看出:形参的效果作用到了实参,这里的引用发生了效果。
String为系统带的类,而Text为自定义的类,为了防止是自定义类跟系统类的影响,又使用了另外一个系统类List进行验证:
public class Text {
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();
list.add(33);
l(list);
System.out.println(list);
}
static void l(List<Integer> list) {
list.add(55);
}
} /* output
[33, 55]
*///~
从输出结果中可以看出:类的引用效果得以发挥。
针对上面的结果,我想朋友们会有一些意外,因为在java基础语言学习中,我们曾经对“==”与“equals()”的操作曾经进行了很多的讨论,结果说明:String类是一个引用类型,给出一段代码,以供大家学习:
public class SimpleTypeText {
public static void main(String[] args) {
String s1 = "a";
String s2 = "a";
String s3 = new String("b");
String s4 = new String("b");
System.out.println("s1 == s2 ? " + (s1 == s2) );
System.out.println("s1.equals(s2) ? " + s1.equals(s2));
System.out.println("s2 == s3 ? " + (s2 == s3) );
System.out.println("s2.equals(s3) ? " + s2.equals(s3));
System.out.println("s3 == s4 ? " + (s3 == s4) );
System.out.println("s3.equals(s4) ? " + s3.equals(s4));
(s4, s1);
}
static void f(String s) {
s = "a";
}
static void g(String s, String s1) {
s = "a";
System.out.println("通过常字符串:" + s == s1);
s = new String(s1);
System.out.println("通过new方法:" + s == s1);
}
} /*output:
s1 == s2 ? true
s1.equals(s2) ? true
s2 == s3 ? false
s3.equals(s3) ? true
s3 == s4 ? false
s3.equals(s4) ? true
通过常字符串:true
通过new方法:false
*///~
总结:
1. thinking in java 中对String类型对象有这样一段描述:
String对象是不可变的,没一个看起来会修改String值的方法,实际上都是创建了一个全新的String对象。
对String类型的对象做参数有这样的一段描述:
每当把String对象作为方法的参数时,都会复制一份引用,而该引用所指的对象其实一直待在单一的物理位置上,从未动过。
2. 在字符串的声明中,利用常字符串初始化的时候,系统会从已有的常字符串进行查找,如果存在此字符串常量,则不再生成新的字符串常量,但是new方法不是这样的,即它不进行查找,直接开辟一段新的空间,存储这个字符串。
声明:以上代码均为参考,希望对基础有些帮助。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/yanmushi/archive/2010/05/09/5573022.aspx