对于java中String的特殊性的讨论

finemi 2015-06-10 08:15:59
以前常听人说,我们老师也说的是:String是引用类型,但是具有基本类型的特征,他是值传递而非引用传递
通常说:
public void change(String a){
a = "234";
}
public void test(){
String a = "123";
change(a);
System.out.println(p.toString());//还是123
}

对于上面的代码,好多都会解释说因为String是值传递或者不可变的,所以改变a的值并没有改变

可以问题是:就算String是可变的类型,所谓的引用传递,也是同样的结果!

比如:
public void change(Person p){
p = new Person("李四");
}
public void test(){
Person p = new Person("张三");
change(p);
System.out.println(p.toString());//还是张三
}
这就是一个普通的类Person,不是不可变的,也不是什么值传递的,但是同样他不会改变。

java中根本就没有引用传递,只有传递引用,因为一个对象变量,本身就只是保存的一个地址

而C#之类的不同,他有ref关键字
在C#中可以这样写:
public void change(Person p){
p = new Person("李四");
}
public void test(){
Person p = new Person("张三");
change(p);
System.out.println(p.toString());//李四
}

所以对于String的另外一点:
String str1 = "123";
str1 = "234";
这就是将一个普通对象赋值给已存在的变量,并不存在String有什么特殊点。 要说特殊,也只有常量池和可以直接""构造对象的语法糖了。

最后总结的就是:对于String,把它和普通的类、对象对待,是毫无问题的
不知道这个理解有问题不
...全文
348 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
cfan1236 2016-12-06
  • 打赏
  • 举报
回复
先用引用下你的代码: 比如: public void change(Person p){ p = new Person("李四"); } public void test(){ Person p = new Person("张三"); change(p); System.out.println(p.toString());//还是张三 } 你以上这个代码 输出的为什么不是"李四" ?很显然你的change方法里p这个参数最后是new 了一个新对象,已经和本身的P对象不是同一个对象地址了。如果你在change里不去new ;而是用 比如p.setName("李四"); 你再输出p看下 肯定会改变的。
finemi 2015-06-11
  • 打赏
  • 举报
回复
记录一下。。。 很多语言都有提供两种参数调用的方式(C++、C#等):值调用 和 引用调用。 而很多人认为java对象采用的引用调用,这是一种错误的理解,并且存在普遍的误解。 比如一个普通的swap方法:

public static void swap(Person a,Person b){
      Person tmp = a;
      a = b;
      b = tmp;
}
如果java采用的引用调用,那么这个方法就可以实现交换数据的效果:

Person a = new Person("张三");
Person b = new Person("李四");
swap(a,b);
但是实际情况是:并没有! 所以实际上,对象引用采用的依然是值传递,只不过这个值是对象的引用罢了。 所以在java中,可以“引用传递改变”的是对象的状态,而不是这个对象。 假设String有一个setValue()的方法,我们是否可以这样:

public void change(String str) {
        str.setValue(123);
  }
但实际情况是:Integer、Boolean等包装类,String等都是不可变类,他们没有提供任何修改自身状态(属性、域)的方法,即不可变类。
youzi05 2015-06-10
  • 打赏
  • 举报
回复
好吧, 刚刚大概看了看C#的引用传递, 发现是我看错了, lz首先说
引用
以前常听人说,我们老师也说的是:String是引用类型,但是具有基本类型的特征,他是值传递而非引用传递
我还以为讨论的是String是引用类型, 还是基本类型. java中传递Object可能的确像lz说的是: 传递的引用, lz举得例子个人觉得也没问题, 但是, 现在想起以前一件事, 怎么说呢, 我觉得String在参数传递等方面确实没有什么特殊之处, 但是, String和其他基本类型一样, 是其他所有类的基石, 不知道算不算特殊的地方
finemi 2015-06-10
  • 打赏
  • 举报
回复
引用 8 楼 Raffin 的回复:
String abc = "aaa"; 和String abc = new String("aaa") 好像是不一样
大哥,我现在不是在讨论基础问题呀。
鸣鸣Amadues 2015-06-10
  • 打赏
  • 举报
回复
String abc = "aaa"; 和String abc = new String("aaa") 好像是不一样
鸣鸣Amadues 2015-06-10
  • 打赏
  • 举报
回复
JAVA没有引用传递的
引用 6 楼 finemi 的回复:
[quote=引用 4 楼 Raffin 的回复:]
从表层上看,真的看不出他有什么特殊的,并且他也完全不需要值传递。 底层具体传递是怎么回事的真不知道了。 但是我认为他就是传递的值。和普通的类对象没有任何区别。 唯一特殊的是,对于字符串直接量(直接写在源码中的字符串值),会保存在class字节码文件中,jvm会将这些字符串直接量new一个String对象,对于同值的直接量,不会再次new,而是将之前有的对象引用赋值给它作为另一个变量,这也就是为什么同样值的字符串直接量地址相同,而同样值的new String()地址不同的原因所在。 个人猜想~[/quote] String和int一样,传参的时候是传的值本身。 Object是传地址。
finemi 2015-06-10
  • 打赏
  • 举报
回复
引用 4 楼 Raffin 的回复:
从表层上看,真的看不出他有什么特殊的,并且他也完全不需要值传递。 底层具体传递是怎么回事的真不知道了。 但是我认为他就是传递的值。和普通的类对象没有任何区别。 唯一特殊的是,对于字符串直接量(直接写在源码中的字符串值),会保存在class字节码文件中,jvm会将这些字符串直接量new一个String对象,对于同值的直接量,不会再次new,而是将之前有的对象引用赋值给它作为另一个变量,这也就是为什么同样值的字符串直接量地址相同,而同样值的new String()地址不同的原因所在。 个人猜想~
finemi 2015-06-10
  • 打赏
  • 举报
回复
引用 2 楼 u011004037 的回复:
怎么说呢, 一般情况下, 如果传递的是地址我们就认为是传递指针或者引用传递, 所以, 如果说是值传递也不能算错吧, 但是感觉说引用传递更恰当, 毕竟有这么个概念,
对啊,所以对象变量传递时,某些方面来讲也是值传递,只不过这个值是一个地址而已。本身对象变量就不保存对象数据,只保存一个引用。所以个人感觉引用传递实在不恰当,而因该是传递引用。而C#用了ref关键字,或者php中用了&符号,才是真正意义桑的引用传递。这就好比c#中 public void change(Object o)和public void change(ref Object o)的区别
鸣鸣Amadues 2015-06-10
  • 打赏
  • 举报
回复
String是一个比较特殊的东西,在JAVA里,除了int,float等是基本类型,其他都是类,而String虽然是一个类,但是有一些基本类型的特征,比如说他可以直接赋值,同时在参数里他是值传递的。
鸣鸣Amadues 2015-06-10
  • 打赏
  • 举报
回复
[b]第二个例子不是像你想的那样的,p是地址变量,这个地址变量传进去的时候是值传递的,所以在change里,形参和实参不是同一个,只不过他们指向同一个地址而已,你改了形参指向的地址,不影响实参的。 如果你把想改变的值换成Person里一个属性,经过change后这个属性的值就会变了。
youzi05 2015-06-10
  • 打赏
  • 举报
回复
个人感觉没有问题, 只不过这句:
引用
java中根本就没有引用传递,只有传递引用,因为一个对象变量,本身就只是保存的一个地址
怎么说呢, 一般情况下, 如果传递的是地址我们就认为是传递指针或者引用传递, 所以, 如果说是值传递也不能算错吧, 但是感觉说引用传递更恰当, 毕竟有这么个概念, 就像

public class Student extends Person{
}
可以说Student继承自Object类, 也可以说继承自Person类, 但是说继承自Person类更准确吧
finemi 2015-06-10
  • 打赏
  • 举报
回复
写得有点乱, 总之就是String作为参数时,值未被改变和他特不特殊毫无关系,就算是一个普通的对象变量,这么用也不会改变这个变量的引用。和普通对象的特征是一样的

67,513

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧