public class Test {
/**
* @param args
*/
public static void change(String str){
System.out.println("before = str*****" + str.hashCode());
str = "welcome";
System.out.println("after = str*****" + str.hashCode());
}
public static void main(String[] args) {
// TODO Auto-generated method stub
//MyTestStr.demoStr();
String str = "hello";
System.out.println("str---" + str);
System.out.println("str---" + str.hashCode());
change(str);
System.out.println("str---" + str);
System.out.println("str---" + str.hashCode());
}
输出结果为
before change,str-----hello
before change,hashcode of str-----99162322
before =,str*****hello
before =, hashcode of str*****99162322
after =,str*****welcome
after =, hashcode of str*****1233099618
after change,str-----hello
after change,hashcode of str-----99162322
如果你在没有执行=之前输出hashcode,那么这个编码应该是和main方法里面的a的hashcode相同的。
但是当你执行了=之后,这个hashcode应该已经不同了,它们不是同一个对象。
看一下String类的源代码,因为String用了一个private final char value[]来保存字符串,也就是这个字符串一旦创建,就不可以修改,直接导致了String类没有set方法。我们也就没法修改String中内容,当你用=给String赋值时,实际上并没有修改原先那个引用的值,而是新给了一个值。
一个变量被当作参数传入了方法,Java是把这个变量的值传入这个方法里面——String是一个应用类型,它在堆里面的值就是一个引用,因此传String的变量到方法,事实上传的是这个引用。当你对这个变量进行赋值的时候,修改的是这个变量的值,而不是这个变量指向(引用)的对象,即可以更改变量引用的地址,但不能改变引用的内容。
如果你要一个String传入一个方法后,方法里面对该String的修改对方法外面有效的话,你可以用StringBuffer,并且在方法里面不是直接对这个变量进行赋值,而是通过StringBuffer的方法对这个字符串的对象进行操作,如append,不过这严格来说也不是String对象了。
再如String a1 = "a1";a1=a1+"bb"时,相当与String tmp=new String(a1) + new String("bb"); a1=tmp;
这样容易看出tmp指向重新在堆中分配内存,a1作为引用被重新赋值不再指向a所指向的堆内存,说明此时a1和a没有任何关系,不难理解了!
分享到:
相关推荐
这意味着当一个变量作为参数传递给方法时,实际传递的是该变量值的一个副本。任何在方法内部对这个副本的修改都不会影响到原始变量的值。 例如,例2中的`Main`方法创建了两个整数变量`a`和`b`,并分别赋值为10。...
当我们讨论"函数调用的传值和传址"时,实际上是在探讨参数传递的方式。理解这一点对于编写高效且无bug的JavaScript代码至关重要。 在JavaScript中,有两种基本的参数传递方式:传值(Pass by Value)和传址(Pass ...
JavaScript是一种动态类型的脚本语言,其变量、传值、传址和参数之间的关系是理解和使用JavaScript中的一个基础但关键点。接下来,我会详细解释这些概念。 首先,JavaScript中的变量可以存储两种类型的数据:基本...
总结来说,JavaScript中的变量处理基于数据类型的不同:不可变类型通过值的复制进行赋值和函数参数传递,而可变类型通过引用的复制进行。这种设计允许JavaScript在处理不同类型数据时更高效地管理内存,同时提供了...
在JavaScript中,不同的数据类型在赋值或作为函数参数传递时,会有不同的行为。 首先,JavaScript有七种数据类型:Undefined、Null、Boolean、Number、String、Symbol(ES6新增)以及Object。其中,前五种是基本...
这意味着当一个对象作为参数传递时,函数内部可以访问并修改该对象的属性,因为它们都共享同一个对象引用。例如: ```javascript function modifyLikeByRef(x) { x[0] = 4; x[1] = 5; x[2] = 6; console.log('x...
传值是将变量的副本传递给函数,而传址则是传递变量的引用。在JavaScript中,基本类型(如Number、String、Boolean、null和undefined)是按值传递的,而引用类型(如Object、Array、Function等)是按址传递的。 按...
JavaScript 中的基本类型(包括 null、undefined、string、number、boolean 和 symbol)是通过值复制的方式来赋值或传递的,而引用类型(包括数组、对象、函数等)则是通过传址的方式来赋值或传递的。 代码分析 ...
- **传址调用**:如果需要在函数内部修改变量,可以传递参数的地址,通过指针实现。例如,`void swap(int *a, int *b)` 函数可以交换两个整数的值。 3. **函数返回值** - **无返回值函数**:函数不一定都有返回值...
函数参数可以指定默认值,当调用时未提供对应参数时使用。例如,`void printMessage(std::string message = "Hello")`,若不传入参数,会默认打印"Hello"。 9. **函数重载**: 同一作用域内,函数可以有相同的...
5. **函数**:函数的定义、调用、参数传递(传值与传址)、递归和匿名函数(函数指针)是面试中常见的主题。理解函数的作用域、返回值和参数的传递方式是必要的。 6. **数据结构**:面试题可能涉及到数组、链表、栈...
- 当数组作为参数传递给函数时,实际上是采用了传址调用的方式。 - 因此,在被调用函数中可以直接修改原数组的内容。 #### 二、字符串常量与字符数组 - **字符串常量**: - 字符串常量是由双引号括起来的一系列...
- 参数传递方式包括传值(ByVal)和传址(ByRef)。 - **示例代码**: - 下面的代码展示了如何在VB中调用`SetFocus`函数: ```vb Dim dl As Long dl = SetFocus(Form1.Hwnd) ``` #### 五、DLL库的加载与管理 - *...
- 参数传递与内联函数:介绍函数参数的传值和传址方式,以及内联函数的概念。 - 重载函数与函数模板:讲解如何通过函数名的重载实现不同功能,以及函数模板的使用。 4. **类与对象**: - 面向对象设计的基本思想...
学生将学习如何定义、调用函数,以及理解参数传递机制,包括传值和传址。 3. **指针**:C语言的指针是其强大之处,允许直接操作内存。学习者需要掌握指针的声明、初始化、指针运算和指针与数组、函数的结合使用。 ...