理解String不可变

问题的引入:

  java中只有值传递,没有引用传递,这里有两种情况,一种是传对象,一种是传基础类型,传对象其实是传对象的引用,

  http://guhanjie.iteye.com/blog/1683637这篇文章描述了一些情况:

  基础类型传递的时候,直接把内存里面真正的值传递过去,而在对象传递的时候,是把对象的引用传递过去。

  那么问题来了,为什么String作为对象,再方法调用的时候却跟基础类型调用的效果是一样的。

给出代码:

public class Example {
String str = new String("good");
char[] ch = { ‘a‘, ‘b‘, ‘c‘ };
public static void main(String args[]) {
Example ex = new Example();
ex.change(ex.str, ex.ch);
System.out.print(ex.str + " and ");
System.out.print(ex.ch);
}

public void change(String str, char ch[]) {
str="test ok";
ch[0] = ‘g‘;
}
}

这里输出:good and gbc

本例中,str和ch作为对象一起传入方法change,也一同改变,ch变化了,str并没有改变。

解释:

1,如果你看到这里了,那么你应该理解了java中总是值传递(传对象的时候,对象的地址就是他的值)。

2,String是特殊的对象,为什么这么说呢,我们看String的源码可以知道:String是final的,String的成员变量也是final的,首先String实例化出来是不可变的(除非反射)。当我们尝试改变他的时候:

str="test ok";

其实是在内存空间再创建一个"test ok"的对象,并把str引用指向这个新创建的对象,原来的ex.str引用依旧指向了之前的"good"对象的地址。

3,我们要区别对待String,想想看,为什么会引入这样的问题,其实是因为String作为对象却可以跟基础类型数据一样使用+,=等操作。这在语言中本身就已经对String做了特殊的处理。

思考:延续第三点,我们能不能创建一个类似String的对象,即也是final,其成员变量都是final的,然后作为对象传递,在方法体类改变而不影响其原本的值。

时间: 2024-10-13 20:23:20

理解String不可变的相关文章

java String不可变对象,但StringBuffer是可变对象

什么是不可变对象? 众所周知, 在Java中, String类是不可变的.那么到底什么是不可变的对象呢? 可以这样认为:如果一个对象,在它创建完成之后,不能再改变它的状态,那么这个对象就是不可变的.不能改变状态的意思是,不能改变对象内的成员变量,包括基本数据类型的值不能改变,引用类型的变量不能指向其他的对象,引用类型指向的对象的状态也不能改变. 区分对象和对象的引用 对于Java初学者, 对于String是不可变对象总是存有疑惑.看下面代码: [java] view plain copy Str

[转]为什么Java中的String不可变

笔主前言: 众所周知,String是Java的JDK中最重要的基础类之一,在笔主心中的地位已经等同于int.boolean等基础数据类型,是超越了一般Object引用类型的高端大气上档次的存在. 但是稍有研究的人就会发现,String对象是不可修改的,源代码中的String类被定义为final,即为终态,不可继承,String也不提供任何直接修改对象内部值的方法,每次使用replace.substring.trim等方法,或是使用字符串连接符+时,都是返回一个全新的String对象,整个Stri

Java基础3:深入理解String及包装类

Java基础3:深入理解String及包装类 String的连接 @Testpublic void contact () {    //1连接方式    String s1 = "a";    String s2 = "a";    String s3 = "a" + s2;    String s4 = "a" + "a";    String s5 = s1 + s2;    //表达式只有常量时,编译

Java常量字符串String理解 String理解

以前关于String的理解仅限于三点:1.String 是final类,不可继承2.String 类比较字符串相等时时不能用“ == ”,只能用  "equals" 3.String  类不可更改 String 使用非常方便,因此一般涉及字符串时都用该类进行字符串处理至于String类的类在机制,则极少去探究. 直到读到下面这个例子. class X{     public static String strX="hello";}class Y{   public 

深入理解String类(重点)

一.想要理解string类,先看源码: 1 public final class String 2 implements java.io.Serializable, Comparable<String>, CharSequence { 3 /** The value is used for character storage. */ 4 private final char value[]; 5 6 /** Cache the hash code for the string */ 7 pri

深入理解String类

1.String str = "eee" 和String str = new String("eee")的区别 先看一小段代码, 1 public static void main(String[] args) { 2 String str1 = "eee"; 3 String str2 = "eee"; 4 String str3 = new String("eee"); 5 System.out.pri

不可变String及可变StringBuilder

String和StringBuilder.StringBuffer的小总结 一.不可变String 先查看JDK文档看下String <span style="font-size:18px;">public final class String extends Object implements Serializable, Comparable<String>, CharSequence</span> String是final类型,意味着它是不可改变

c#基础系列2---深入理解 String

"大菜":源于自己刚踏入猿途混沌时起,自我感觉不是一般的菜,因而得名"大菜",于自身共勉. 扩展阅读:深入理解值类型和引用类型 基本概念 string(严格来说应该是System.String) 类型是我们日常coding中用的最多的类型之一.那什么是String呢?^ ~ ^ String是一个不可变的连续16位的Unicode代码值的集合,它直接派生自System.Object类型. 与之对应的还有一个不常用的安全字符串类型System.Security.Sec

String — 深入理解String

String类型是我们常用的基础数据类型之一,他是一个特殊的引用类型,在.NET里面算是少有的异类,那么特殊在什么地方呢?接下来就让深入的了解String 一.特殊之处 (1).创建特殊性:String对象不能使用newobj指令创建,而是ldstr指令创建,在实现机制上,CLR给了特殊的照顾优化内存 (2).应用上,String类型表现为值类型,但在内存中,String类型表现为引用类型,存储在托管堆里面 (3).两次创建内容相同的String对象可以指向相同的地址 (4).String类是跨