您的位置:首页 > 编程语言 > Java开发

Java中的final怎么了,String的值传递还是引用传递?

2015-09-18 10:26 771 查看
final关键词会被用在四个地方;

1、类定义;

2、变量定义;

3、方法定义;

4、方法的入参;

第一种应用,那就是String类了;

第二种应用,定义常量用;

第三种应用,单纯的不希望方法被覆盖;

第四种应用,就涉及到值传递还是引用传递了~~~~~

先看代码:

package string;

public class FinalString {

/**
* final类讨论
*
* @param args
*/
static String strc = "Hust";

public static void main(String[] args) {
// TODO Auto-generated method stub
/**
* @String 是final类,因此不能修改原对象。当非要对他进行修改的时候,也并非是对原对象修改,而是重新创建一个对象
* @str2 指向的还是原对象hust
*/
String str1 = "Hust";
String str2 = str1;
str1 += str1;<span style="white-space:pre"> </span>//此处,你以为你在修改值为hust的String对象,其实你只是在修改str变量的指向!
System.out.println(str1);//HustHust
System.out.println(str2);//Hust
<span style="white-space:pre"> </span>
<span style="white-space:pre">		</span>final String str11 = "Hust";<span style="white-space:pre">	</span>//比如此处str11被定义为final时,str11已经不允许被修改了
<span style="white-space:pre">		</span>//str11 += str11;
/**
* 自定义的StringB不是Final类,他是可修改的,而且是在原对象上修改的,所以strv1和strv2一直指向同一个对象
*/

StringB strv1 = new StringB();
StringB strv2 = strv1;
strv1.name += strv1.name;
System.out.println(strv1.name);//Hust1Hust1
System.out.println(strv2.name);//Hust1Hust1

changestr(strc);
}

public static void changestr(String s) {
/**
* String传值本来是引用传递,下面的判断也可以印证!
*/
System.out.println(s == strc);//true
s = "HustHust";
/**
* 但是String是final的,对s进行修改,s会重新创建,s的指向不在是原来的strc,对s的修改也没有影响到原来strc,
* 造成String传值的假象
*/
System.out.println(s == strc);//false
}

public static void changestr1(final String s, final int v, int k,
final StringB b) {

/**
* s,v的修改都是不允许,他们被定义为final,表示不允许修改。对s修改,则会重新创建String,对s重新指向。如果对v需改,
* 则v会重现指向常量池地址
*/
// s = "HustHust";
// v = 300;
k = 200;
/**
* 尽管b也被设置成final,但是对b.name的修改并不会影响b的指向,所以这种修改是允许的,一旦想要修改b的指向则会报错
*/
b.name = "HustHust";
// b = null;
}

}

/**
* 定义一般类
*
* @author M007
*
*/
class StringB {
String name = "Hust1";
}


看完上面的程序,我想大家应该对被定义成final的String和不是Final的StringB有什么区别了~~
当对String类型的变量进行修改时,会一直创建新的对象,放弃原来对象。

有一个StringBuffer类型可以作为String的替代拼,其实和StringB是一样的,放弃了Final标记。

String导致更改时一直新建新建,为什么要设置成final呢?

答:其中一个理由就是,尽管String类型是引用传递,但是却可以像int,char那样在函数方法中起到值传递的效果!在方法中修改入参的String不会影响原来的String对象!因为String的使用是如此的广泛,作为方法的入参也是非常多,String又不想Integer那样有基本类型的实现,只要借用这种方式实现值传递了!如果不用final的,那就真的是引用传递,通过上面的测试,你能看出对于非final类型的入参,即便添加final标记,也不能阻止引用对象的修改,如果你要问为什么不能阻止,我会说此时的final限制的是变量,不是对象~~

事实上,追本溯源的说final类的意义是不能被继承,指示为了达到这个目的的!并非为了阻止修改类的内容!目前Java似乎还没有提供阻止类被修改的方案,除了一下方式!:

final String str;
final int i;
final StringB strb;


上面定义的str和i看起来都挺像定义常量的,但事实上只有int的定义方式才算是定义常量,String并非是直接定义常量,而是间接实现的,理由上面找!你想问第三行是定义StringB类型的常量吗?不是,第三行定义的是死死盯着某个StringB类型的对象的变量,死死盯着从来不转移目光!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java