首页 > 试题广场 >

检查程序,是否存在问题,如果存在指出问题所在,如果不存在,说

[单选题]
检查程序,是否存在问题,如果存在指出问题所在,如果不存在,说明输出结果。
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';  
  }  
}  
  • test okandabc
  • test okandgbc
  • goodandabc
  • goodandgbc
推荐
java 中String是 immutable的,也就是不可变,一旦初始化,其引用指向的内容是不可变的。

也就是说,String str = “aa”;str=“bb”;第二句不是改变“aa”所存储地址的内容,而是另外开辟了一个空间用来存储“bb”;同时由str指向

原来的“aa”,现在已经不可达,GC时会自动回收。

因此String作为参数传进来时候,str= "test ok"; 实际给副本引用str指向了新分配的地址,该地址存储“test ok”。

因此,原先的str仍然指向“good”
编辑于 2016-01-17 20:49:58 回复(23)
用内存图说明:字符常量是存储在方法区的,只有一份,执行方法改变了数组中元素的值,所以当方法结束的时候数组改变,而字符串没改变
发表于 2016-09-26 19:36:01 回复(26)
副本与原数据是不相关的,不会相互影响的。不过一般方法传递时候,只有基本数据类型和String才会传递副本,其他的类型是按引用的传递的。
发表于 2016-01-17 19:45:21 回复(18)
首先要知道两个概念:值传递,和引用传递;
1.对这到题而言,String 属于值传递,数组属于引用传递
2.change(String str, char ch[] ) ,若把第一个参数名给成其他, 非“str”,例如: change( String s, char ch[] );最后的输出将会是: test okandgbc
3.所以题目中的  public void change(String str, char ch[]){ 
     str= "test ok"; 
     ch[0]= 'g'; 
  }   
该str 只是参数中的str,而并非原来的str,而参数中的str仅仅是原来的一个副本,所以副本的改变并不会造成原来的也跟着那个改变
4,对于参数中的 ch[]  ,这里是把原来的引用传递了进来,而不是副本,所以这里改变就一定会造成原来的内容的改变
发表于 2016-05-19 14:50:05 回复(11)
别闹了,java只有值传递。所谓的引用传递,不过是传递非基础类型的地址罢了,虽然能达到引用传递的效果,不过本质还是值传递。
发表于 2016-09-07 08:26:29 回复(11)
d 如果传入的参数是引用类型,那么传递过来的就是这个引用参数的副本,该副本存放参数地址。如果函数中没有改变这个副本的地址,而是改变了地址中的值。那么该改变会影响到传入的参数。如果改变了副本的地址,则该副本指向了一个新的地址,此时传入的参数还是指向原来的地址
发表于 2015-04-13 15:21:44 回复(3)
答案:D
String类型和数组属于引用传递,但执行change方法后,数组改变的是ch[0],也就是ch数组引用未改变,但其所指向内容的值被改变
编辑于 2016-01-17 20:49:43 回复(4)
首先进入main方法,new一个Example,会在栈中有一个ex的引用指向堆中的Example对象,同时str和ch也会指向该对象中的对应的String和char[],然后执行change方法,此时会在栈中生成两个局部变量,str和ch[],其中ch[]指向的是Example对象的数组,str此时的值以及hashCode均为变

当执行到str = "test ok"的时候 str的hashcode和值均改变了,这个str是属于change方法的局部变量,防范执行完,是要被回收的,而change方法中的ch[]是Example对象中ch[]的引用,所以ch[0]='g',是要改变数组的值的。
如果说,将change方法中参数String str 换成其他的的,例如a,最后得到的结果就是 test okandgbc

发表于 2019-03-06 12:31:30 回复(4)
Java中只有按值传递,没有按引用传递!
发表于 2016-08-17 20:16:24 回复(0)
在方法的参数中,string作为参数传递并且在方法内部中被改变的时候,会产生一个新的string对象并指向参数string的引用(String类型的值是不可改变的,修改内容只会重新创建一个新的String),但是java中只有值传递,这里改变了传递进来的String的值,就改变了String的哈希值,就跟C语言中修改了指针的地址相同(指针的地址本身已经被改变)。而返回的时候并不会将修改的地址传回去。而对char数组,这里可以理解为一个指针,对指针指向的内容进行了修改。说明char型数组引用内容是可以修改的。而String引用不可以。
代码测试:

可以发现str的哈希值在change方法修改后改变,返回后还是初始的哈希值,char数组ch的哈希值一直没变
编辑于 2017-10-10 21:14:30 回复(0)
创建字符串有两种方式;两种内存区域(heap,pool)
String str = new String("good");在堆内存中创建
String str = "test ok" ;在方法区的常量池中创建
编辑于 2018-01-19 09:54:27 回复(5)
这其实是一个java变量名的问题。在类的方法中,如果参数的的名称和类的属性名相同,如果前面不加this关键字,则在 此方法中出现的变量名称则是参数的变量名称,与类的属性无关。所以ex.str和ex.ch不变,如果str="test ok"改为this.str="test ok",则结果就会改变。当然这种情况不只是针对String这种类类型,如果属性是简单的数据类型,如int,则也符合上述的情况。与String这种 类型本身的特定没有特定的关系
发表于 2015-09-29 22:11:14 回复(6)
引用传递:可以改变所指向对象的属性(比如char[0]),但是不能指向新的对象。
发表于 2015-07-26 14:04:47 回复(0)
1、我觉得这道题考的不是什么String变不变的问题。
2、这道题考的更多地是对象的传参,是值传递还是引用传递。
 具体值传递和引用传递可以去百度,这里只说我理解的结果:
(1)基本类型,比如int,double,char都是值传递
例:
void  change(int a)
{a++;}                               
 public static void main(String[] args)
 { 
    int i=1;
    change(i);
  } 
change执行之后i为1,为什么呢?因为执行change(i)时复制了一份i(pie),然后把复制的i(pie)撇传进去了,这就是值传递,没有影响到原来的i本身。
这里注意,String为值传递,具体原因:记住就行,经常有人用这个考你。
(2)对象类型:比如一个pojo,或者是数组对象
例:
class User
{
    public int id;
 }
void change(User user)
{
    user.id++;
}
public static void main(String[] args)
 { 
     User user = new User();
    user.id=1;
    change(user);
  } 
change执行后的user.id不是之前的1而变成了2,为什么呢?因为执行change(user)时是引用传递,直接将user本身的地址传了进去,实际参数都会发生变化。
数组和对象一样,也是引用传递,具体原因:记住就行,经常有人用这个考你。


这个问题引申出来就会出现对象的复制问题
User a = new User();
User b = a;
不是新建一个和a一样的User b,而是b和a一起引用User a这个对象


    


发表于 2019-11-25 14:35:12 回复(1)
不懂
发表于 2015-08-09 12:48:07 回复(1)
String更改时,会新建一个对象,所以ex.str没有改变。
发表于 2015-07-28 17:46:25 回复(0)
基本类型和String是值传递,因此函数对Str的操作对外面的Str毫无影响
对象和数组是引用传递(传递的是地址),改变char[]会对外部造成影响
因此,本题中字符串str不变,ch数组改变
发表于 2020-07-01 18:15:37 回复(0)
把方法change的参数改成s利于理解,开始str指向good,然后参数s也指向good,理解为两个不同string引用指向good,然后其中的s被修改指向了test,但s指向的good还存在,str指向good仍然成立,在main中打印时自然是good,数组改变就不用说了吧。其实这道题就是坑,故意把参数都设为str,迷惑我们。
发表于 2018-04-01 11:54:21 回复(0)
public class A {
 String str = new String("good");
 char[] ch = { 'a', 'b', 'c' };

 public static void main(String[] args) {
  A ex = new A();
  ex.change(ex.str, ex.ch);
  System.out.print(ex.str + "and");
  System.out.print(ex.ch);
  System.out.println("");
  String str="Hello";
  String str2=str;
  str2+="Word!";
  System.out.println(str);
  System.out.println(str2);
  char[] c="Hello".toCharArray();
  char[] c2=c;
  c2[0]='h';
  System.out.println(c2);
  System.out.println(c);
  
 }

 public void change(String str, char ch[]) {
  str = "test ok";
  ch[0] = 'g';
 }
}
在代码中插入了一段代码,作为比较
运行结果
goodandgbc
Hello
HelloWord!
hello
hello
可以看出String作为值传递
char【】 数组作为引用传递的区别了
发表于 2015-08-12 14:47:45 回复(5)
看了很多人的解释,还是纠结了很久这个问题!
现在这么理解:String不是基本类型,所以当做引用传递,也就是理解为指针,但是String被final修饰,重新赋值时传过去的这个指针没办法改变地址,所以就相当于再重新定义了一个字符串。自然就不会影响原来的值。
如果有更直观的理解也希望被指教!
发表于 2016-06-30 21:59:33 回复(2)
由于String对象的不可变性而产生的,内存分析图如下:
由于String 对象的不可变性,新的不同String对象会另外开辟空间,这就导致了形参str指向的对象发生了改变,而实参str还是指向原来的对象,这就是为什么String类型作为参数传递时表现的却是值传递的特点。如下图分析:

发表于 2016-05-18 17:09:32 回复(0)