java函数的参数传递和String类型

 

java的String类型,你彻底理解吗?看看下面的 题目:

String s=”abc”;

String s1=”abc”;

String s2=new String(“abc”);

String s3=s2.intern();

System.out.println(s1==s);

System.out.println(s1==s2) ;

System.out.println(s1==s3) ;

上面的题目会打印什么?

如果你不确定,那么请打开Eclipse,敲入上面的程 序运行一下,你会发现打印的是true、false、t rue,为什么会有上面的打印呢?了解了下面关于jav a String的细节后,就会明白:

1.双引号字符串是常量字符串,在java文件编译的时 候就放在虚拟机的常量池中,比如s,当创建abc时,发 现常量池中没有就在常量池中创建abc并把abc的地址 赋给s,当再创建s1时,首先会去常量池中去查找abc 是否存在,如果存在就把常量池中abc的地址赋给s1, 所以比较s和s1的地址是相等的

2.如果用new的方法创建一个String时,就和s =”abc”不一样了,s2=new String(“abc”)是在程序运行时创建,不是创 建在常量池而是和其他java对象一样在java堆上创 建,因此它的地址和s不用.

3.如果运行时想把一个String创建到常量池中,j ava提供了一种方法,这个方法也会先检查常量池是否存 在abc,若存在返回abc在池中的地址。所以最后一个 打印时true

在看下面的题目:

String s1=”ab”;

String s2=”cd”;

String s3=”abcd”;

String s4=s1+s2;

String s5=”ab”+"cd”;

System.out.println(s4==s3) ;

System.out.println(s5==s3) ;

这是又会是什么结果呢?答案是false,true,这 个题目说明两个字符串常量连接和还是字符串常量,但是只 要其中一个是变量,就和new的效果一样了,即是在堆上 创建

说完了java的String类型,我们最后看看java函数参数的传递,到底是值传递还是引用传递呢?一般的 说法是对于基本类型比如int、char是值传递,对于 对象类型是引用传递。这种说法没错,但是请看下面的例子 :

String s=”abc”;

change(s);

System.out.println(s);

public void change(String str)

{

  str=”abcd”;

}

上面的程序会有什么结果呢?打印abc还是abcd,运 行程序会发现打印的是abc,完了,似乎不合乎常理,按 理说String 也是对象,应该是引用传递才对啊,有的同学知道java 的String类型是不可变类型,会得出结果abc,具 体解释是String就相当于是char[]的包装类。 包装类的特质之一就是在对其值进行操作时会体现出其对应 的基本类型的性质。在参数传递时,包装类就是如此体现的 。所以,对于String在这种情况下的展现结果的解释 就自然而然得出了。同样的,Integer、Float 等这些包装类和String在这种情况下的表现是相同的 。下面从函数参数传递的方式来理解也可以得出相同的结果 。

java的参数传递本质上都可以认为是值传递,对基本类 型自然不必说,对于对象类型,传递的是对象的地址,地址 是个数字,也是基本类型,所以也还是值传递的, 有了这个基础,上面的题目可以这样理解,s是字符串ab c的地址,调用change方法时,把s的拷贝赋给st r,即str也指向abc,但是在方法里又把str指向 abcd,str就是abcd的地址了,但是s还是指向 的abc。

 

总结: 引用变量在栈上,对象在堆上!

         java方法基本数据类型是传值,对象类型传引用!

 

 

你可能感兴趣的:(java函数的参数传递和String类型)