解决JAVA的String的传值和传地址问题.doc_第1页
解决JAVA的String的传值和传地址问题.doc_第2页
解决JAVA的String的传值和传地址问题.doc_第3页
解决JAVA的String的传值和传地址问题.doc_第4页
解决JAVA的String的传值和传地址问题.doc_第5页
已阅读5页,还剩9页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

(浪曦分享)解决JAVA的String的传值和传地址问题关于Java的String类型,可能你会碰到这种情况,将String类型的变量传到一个函数,在这个函数中修改变量的值,但是,实参的值并没有发生改变。 Java中String的传值/传地址问题:例子引入:1 package blog.GDUTtiantian.String; 2 3 /* 4 * author GDUTtiantian 5 */ 6 public class JavaString 7 8 public static void change(String name) 9 /修改name的值10 name = ChangedName;11 12 13 14 public static void main(String args) 15 String name = GDUTtiantian; 16 17 change(name);18 19 System.out.println(name);20 21 22 23 运行结果: 1 GDUTtiantian 为什么结果不是ChangedName呢?String类的底层实现是用一个字符数组去实现的,就像Integer类,底层也是对int进行封装装箱和拆箱。看String类的修饰部分(源码):1 public final class String2 implements java.io.Serializable, Comparable, CharSequence 3 /* The value is used for character storage. */4 private final char value;注意,String类加了final关键字,所以不能被继承。第4行是字符串底层的存储结构:字符数组。String的内容不能被动态地修改,因为底层是字符数组实现的,数组的大小是在初始化时决定的;如果可以修改,新的字符串长度比原来数组大,那么就会造成数组越界。 String和StringBuffer的比较:1 package blog.GDUTtiantian.String; 2 3 /* 4 * author GDUTtiantian 5 * 6 * String, StringBuffer 在传参过程中的哈希值比较 7 */ 8 public class JavaString4 9 10 11 public static void change(String str) 12 System.out.println(形参的哈希值: + str.hashCode();13 14 str = newString;/修改了形参的值15 System.out.println(修改后: + str.hashCode();16 17 18 public static void change(StringBuffer sb) 19 System.out.println(形参的哈希值: + sb.hashCode();20 sb.append(newStringBuffer);/修改了形参的值21 System.out.println(修改后: + sb.hashCode();22 23 24 25 public static void main(String args) 26 String str = new String(GDUTtiantian);27 StringBuffer sb = new StringBuffer(tiantian);28 29 System.out.println(修改前: + str.hashCode();30 change(str);31 32 System.out.println(n-n);33 34 System.out.println(修改前: + sb.hashCode();35 change(sb);36 37 38 运行结果:1 修改前:-5014512642 形参的哈希值:-5014512643 修改后:-5957064154 5 -6 7 修改前:10367820958 形参的哈希值:10367820959 修改后:1036782095 实参String变量传给形参,是传一个地址过去,并没有重新创建一个对象,StringBuffer变量也是这么做;但是,在修改形参的值后,String变量的哈希值发生了改变,StringBuffer变量的哈希没有发生改变,即String变量指向了一个新建的对象。 看看JDK中String类的一段源码(String类的一个构造方法):1 /* 2 * Allocates a new code String that contains characters from a subarray 3 * of the Unicode code point array 4 * argument. The code offset argument is the index of the first code 5 * point of the subarray and the code count argument specifies the 6 * length of the subarray. The contents of the subarray are converted to 7 * code chars; subsequent modification of the code int array does not 8 * affect the newly created string. 9 *10 * param codePoints11 * Array that is the source of Unicode code points12 *13 * param offset14 * The initial offset15 *16 * param count17 * The length18 *19 * throws IllegalArgumentException20 * If any invalid Unicode code point is found in code21 * codePoints22 *23 * throws IndexOutOfBoundsException24 * If the code offset and code count arguments index25 * characters outside the bounds of the code codePoints array26 *27 * since 1.528 */29 public String(int codePoints, int offset, int count) 30 if (offset 0) 31 throw new StringIndexOutOfBoundsException(offset);32 33 if (count 1.37 if (offset codePoints.length - count) 38 throw new StringIndexOutOfBoundsException(offset + count);39 40 41 final int end = offset + count;42 43 / Pass 1: Compute precise size of char44 int n = count;45 for (int i = offset; i end; i+) 46 int c = codePointsi;47 if (Character.isBmpCodePoint(c)48 continue;49 else if (Character.isValidCodePoint(c)50 n+;51 else throw new IllegalArgumentException(Integer.toString(c);52 53 54 / Pass 2: Allocate and fill in char55 final char v = new charn;56 57 for (int i = offset, j = 0; i end; i+, j+) 58 int c = codePointsi;59 if (Character.isBmpCodePoint(c)60 vj = (char)c;61 else62 Character.toSurrogates(c, v, j+);63 64 65 this.value = v;66 代码57行开始,就是对字符数组进行复制。 这里,用C/C+中的字符串/数组/指针的引用做比较:1 #include 2 3 /形参中数组退化为指针了 4 /这里s是指向array数组的指针 5 void go(char * s) 6 7 s = JavaString;/指针指向另一个空间,JavaString字符串的首地址 8 printf(s:%s#n, s); 9 10 11 /形参中数组退化为指针了12 void change(char * s)13 14 s0 = c;15 s1 = h;16 s2 = a;17 s3 = n;18 s4 = g;19 s5 = e;20 s6 = 0;21 22 23 int main()24 char array100 = GDUTtiantian;25 26 go(array);27 printf(array:%s#n, array);28 29 change(array);30 printf(array:%s#n, array);31 32 return 0;33 第7行 : s = JavaString;这一行比较重要,s是指向main()函数中array数组的首地址的指针,然后在第7行,s指向另外一个字符串的首地址;这里和String变量在形参中的改变有相似之处。第14行: s0 = c;这里的s也是指向main()函数中array数组的首地址的指针,然后把array数组的第一个字符修改为c. 运行结果在CodeBlock编译运行:1 s:JavaString#2 array:GDUTtiantian#3 array:change#4 5 Process returned 0 (0x0) execution time : 0.140 s6 Press any key to continue. Java实现字符串的值修改可以有两种方式:用数组实现1 package blog.GDUTtiantian.String; 2 3 /* 4 * author GDUTtiantian 5 */ 6 public class JavaString2 7 8 public static void change(String name) 9 /修改name的值10 name0 = ChangedName;11 12 13 14 public static void main(String args) 15 String name = GDUTtiantian; 16 17 change(name);18 19 System.out.println(name0);20 21 22 23 运行结果: 1 ChangedName 将String设置为新建类型的一个成员变量1 package blog.GDUTtiantian.String; 2 3 /* 4 * author GDUTtiantian 5 */ 6 7 class NewString 8 private String value; 9 10 public NewString(String str)11 value = str;12 13 14 public String getValue() 15 return value;16 17 18 public void setValue(String value) 19 this.value = value;20 21 22 23 Override24 public String toString() 25 return getValue();26 27 28 29 public class JavaString3 30 private static NewString newName = new NewString(ChangedName);31 32 public static void change(NewString name)33 /修改name的值34 name.setValue(newName.getValue();35 36 37 38 public static void main(String args) 39 NewString name = new NewString(GDUTtiantian); 40 41 change(name);42 43 System.

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论