public class Test {
public static void changestr(String str){
str="welcome";
}
public static void main(String[] args) {
String str="1234";
changestr(str);
System.out.println(str);
}
}
public static void changestr(String str){
str="welcome";
}
public static void main(String[] args) {
String str="1234";
changestr(str);
System.out.println(str);
}
}
changestr(str);
System.out.println(str);
java传递的是拷贝,进changestr时,传递一份str的拷贝进去.
进去后你又将拷贝的值改为welcome,但并没有影响到str的原值12134
如下面的例子public static void main(String[] args){
Map<String, String> map = new HashMap<String, String>();
map.put("a", "123");
map.put("b", "234");
System.out.println(map.size());
changeMap(map);
System.out.println(map.size());
}
public static void changeMap(Map map) {
map.put("c", "345");
}得到
2
3
这个str和main中的str是两个不同的局部变量。其实按这个changestr的函数,不管你传入什么字符串,changestr里的str的值都是
welcome,但是当changestr执行完之后chengestr里的局部变量就失效了。所以当你出来changestr到main里试产str时,这个str其实是main里的str,那当然是你定义的str=1234的咯,,,,如果你在changestr里试产str 话就是welcome了。
String x = "111"; 等同于String x = new String("111");
String变量的赋值永远是new个新对象。
例如
public class Test {
public static void changestr(StringBuffer str){
str.setLength(0);
str.append("welcome");
}
public static void main(String[] args) {
StringBuffer str=new StringBuffer("1234");
changestr(str);
System.out.println(str);
}
}打印出来的值就是变成welcome;
String str = "1234";
str = changestr(str);
System.out.println(str);
}楼主应该是这个意思
String str;
private static LTest L=new LTest();
private LTest(){}
public static LTest getInstance(){
return L;
}
public void changstr(String str){
this.str="welcome";
}
}
public class Test{
public static void main(String[] args) {
LTest L1=LTest.getInstance();
L1.str="1234";
L1.changstr(L1.str);
System.out.println(L1.str);
}
}
//这跟单例模式相同,加个类,问题解决。
知道string是使用类修饰符final修饰的么。final意思是什么?
你可以直接在main函数中写str="welcome"最后输出的结果就是你最后一次赋值的结果那么这是为什么呢?因为你只是将值传给了函数,你函数中的str只是一个变量,并不影响主函数中的结果
没有改变str本身的值
所谓引用,就是说将对象在内存中的地址传递给目标对象,就相当于使目标对象和原始对象对应同一个内存存储空间。此时,如果对目标对象进行修改,内存中的数据也会改变。
值传递,例如:
class TestT1
{
public static void main(String[] args)
{
int i = 5;
int j = 6;
System.out.println("before exchange i = "+i);//交换前
exchange(i, j);
System.out.println("after exchange i = "+i);//交换后
}
public static void exchange(int a,int b)
{
int k;
k = a;a = b; b = k;
}
} 程序的结果是5!!!
这说明,原始数据类型是按值传递的,这个按值传递也是指的是进行赋值时的行为。
Java语言明确说明取消了指针,因为指针往往是在带来方便的同时也是导致代码不安全的根源,同时也会使程序的变得非常复杂难以理解,但这只是在Java语言中没有明确的指针定义,实质上每一个new语句返回的都是一个指针的引用。
引用传递,例如:
class TestT2
{
public static void main(String[] args)
{
StringBuffer s= new StringBuffer("good");
StringBuffer s2=s;
s2.append(" afternoon.");
System.out.println(s);
}
} 对象s和s2指向的是内存中的同一个地址因此指向的是同一个对象。
这里的意思是进行对象赋值操作是传递的是对象的引用,因此对象是按引用传递的。
程序运行的输出是:
good afternoon.
这说明s2和s是同一个对象。
总结:
大家都知道,在JAVA中变量有以下两种:
基本类型变量,包括boolean、byte、char、short、int、long、float、double。
引用类型变量,包括类、接口、数组(基本类型数组和对象数组)。
对于基本类型和基本类型变量被当作参数传递给方法时,是值传递。在方法实体中,无法给原变量重新赋值,也无法改变它的值。
而对象作为参数,如果在方法中把对象作为参数,方法调用时,参数传递的是对象的引用,即在方法调用时,实际参数把对对象的引用传递给形式参数。这是实际参数与形式参数指向同一个地址,即同一个对象,方法执行时,对形式参数的改变实际上就是对实际参数的改变,这个结果在调用结束后被保留了下来。
你写的代码里面有两个str,一个是main方法里面的,另一个是changestr方法里面的。
你在main里面调用changestr,是将main里的str赋值给changestr里面的str,然后改变的是changestr里的str,而main里的str没有改变,仍旧是1234,所以输出的是1234。
楼主之所以不理解为什么结果是1234,是因为楼主没有理解值传递、引用传递、局部变量的概念。
用final修饰的量是常量,一旦给定一个值,以后就无法改变(就是只能赋值一次,以后就不能变了)。
public static String changestr(String str){
str="welcome";
return str;
}
public static void main(String[] args) {
String str="1234";
str=changestr(str);
System.out.println(str);
}
}楼主这样改一下就是welcome了
http://blog.csdn.net/u012367513/article/details/24672373
调用changestr(String str)方法后,String str="1234"; 这个str变量的引用地址指向了str="welcome";
String不同于普通的类,String是不可变的,当给changeStr方法中的形参赋值时,是重新分配一块内存,str指向这里。所以与传入的参数str指向的不是同一块地址。
import java.util.Scanner;public class java { public static int i = 0;
public static Scanner sc = new Scanner(System.in);
public static byte[] buffer = new byte[1024*1024*50]; // 50兆的字符串 你猜他会递归多少次呢?
public static String arg = new String(buffer);
public static void digui(String arg) {
int j = ++i;
System.out.println("这个是第 N 次递归了"+j);
sc.next();
digui(arg);
System.out.println("这个是第 N 次递归完成了 "+j);
}
public static void main(String[] args) {
digui(arg);
}
}
public static void changestr(String str){
str="welcome";
}
public static void main(String[] args) {
String str="1234";
changestr(str);
System.out.println(str);
}
} ----------------------------------------------------------
changestr(String str)村中有一个叫str的人,他的知名度是changestr村中;
main()村中也有一个叫str的人,他的知名度在main村中;
当我们在main()村中喊str时,习惯上都是指main()村中的str;
因此输出1234,
说的对,楼上竟然有这么多人都说String是值传递。
其实这种理解是错误的,String是对象,当然是引用传递。这里的问题与是值传递还是引用传递没有关系。这里就算用的不是String,而是StringBuffer的话,在方法中重新赋值了,对原对象也不会有影响。
但是如果是调用StringBuffer的append方法则不一样了,只是String的设计有些特殊,并没有提供类似于StringBuffer的append方法。
其次,java只有值传递
当一个对象实例作为一个参数被传递到方法中时,参数的值就是该对象的引用一个副本。指向同一个对象,对象的内容可以在被调用的方法中改变,但对象的引用(不是引用的副本)是永远不会改变的。
但是int之类的基础类型参数的值就是本身的值最后为啥String的参数传递看上去像int之类的基础类型一样呢?
String类中的每一次看起来会修改String值的方法,实际上都是创建了一个新的String对象。
具体去看jdk里String实现的代码,顺便说下String 是final的
注:下面我解释中的str1是main方法中定义的,str2是changestr定义的,两个都属于局部变量,但是作用域不同
public class Test {
public static void changestr(String str){
str="welcome";
}
//程序执行的入口main方法,从这里开始读程序
public static void main(String[] args) {
String str="1234";
//执行完上面的赋值语句后,系统会分配一块内存,里面存的值是1234,名字是str1
changestr(str);
//此处执行,实参的值str1会传递给方法changestr的形参str2,系统会再分配一块内存,给str2,里面存的值也是1234,
//当执行str="welcome"; 后,str2的值被修改成welcome,方法执行完毕系统将str2擦除,而str1的值没有被修改,还是1234,
System.out.println(str);
}
}关于内存的分析你可以看一下马士兵的视频:尚学堂科技_马士兵_J2SE_5.0_第03章_面向对象\ 06_内存解析_1
\ 07_内存解析_2
\ 08_内存解析_3
所以,在本例中,无论是从值传递的角度看,还是从作用域的角度看,结果都是“1234”。
public static String changestr(String str){
str="welcome";
return str;
}
public static void main(String[] args) {
String str="1234";
String str2 = changestr(str);
System.out.println(str);
}
}改成这样就和你像的一样了
str = "welcome";
return str;
} public static void main(String[] args) {
String str = "1234";
str = changestr(str);
System.out.println(str);
}
呵呵!我得到welcom了
String str2 = "1234"+"";
String str3 = str1+"";
System.out.println(str1==str2);
System.out.println(str1==str3);
System.out.println(str2==str3);