String是值传递还是引用传递转载
原创String它是值传递还是引用传递
在今天的工作中,我的同事发现了一个有趣的问题。他放了一张String类型的参数被传递到方法中,并且被引用的值在方法中被更改。 然后,他在方法外部使用此值,并发现如下所示String它仍然是以前的值,并且没有更改。
在这里,我想向大家介绍一下,我们都知道java传递参数时的值 传递 和 引用传递 。当参数是基本类型时,它是一个值传递, 当参数是封装类型时,通过引用传递。例如:
基本类型参数
1
2
3
4
5
6
7
8
9
10
11
public
class
Test {
public
static
void
main(String[] args) {
int
num =
0
;
changeNum(num);
System.out.println(
"num="
+num);
}
private
static
void
changeNum(
int
num) {
num =
1
;
}
}
打印的结果是 num=0
。
包类型参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public
class
Test {
public
static
void
main(String[] args) {
Product p =
new
Product();
p.setProName(
"before"
);
p.setNum(
0
);
changeProduct(p);
System.out.println(
"p.proName="
+p.getProName());
System.out.println(
"p.num="
+p.getNum());
}
private
static
void
changeProduct(Product p) {
p.setProName(
"after"
);
p.setNum(
1
);
}
}
class
Product {
private
int
num;
private
String proName;
public
int
getNum() {
return
num;
}
public
void
setNum(
int
num) {
this
.num = num;
}
public
String getProName() {
return
proName;
}
public
void
setProName(String proName) {
this
.proName = proName;
}
}
运行的结果是: p.proName=after
和 p.num=1
。
上面的两个例子是明显的值传递和引用传递。但如果参数是String是什么类型的?让我们来看一些具体的例子:
1
2
3
4
5
6
7
8
9
10
11
public
class
Test {
public
static
void
main(String[] args) {
String str =
"ab"
;
changeString(str);
System.out.println(
"str="
+str);
}
private
static
void
changeString(String str) {
str =
"cd"
;
}
}
让我们猜猜运行的结果是什么?遵循上一个示例,String它应该是封装类型,它应该是引用传递,它可以改变值, 运行的结果应该是“cd“。让我们实际运行它并查看一下,
str=ab
,这怎么解释呢?是吗String它是基本型的吗?这也说不通。
这就要从java讨论了潜在的机制,java内存模型被划分为 堆 和 栈 。
1.将基本类型的变量放置在堆栈中;
2.在封装类型中,对象被放置在堆中,对象的引用被放置在堆栈中。
java当方法传递参数时,将复制变量,然后将其传递到方法体以供执行。 这句话很难理解,也是为了解释这一点 问题的实质。让我们首先根据这句话解释一下基本的传播类型。
- 已分配虚拟机num一个内存地址和一个值0.
- 该虚拟机复制一个num,我们叫他num’,num’和num内存地址不同,但存储的值都是0。
- 虚拟机讲num‘传入该方法,则该方法将。num‘的值已更改1.
- 方法结束,方法外打印num价值,这是由于num内存中的值未更改,或0,印刷也是如此。0.
我们来解释一下包裹类型的投递:
- 该虚拟机在堆中打开一个。Product的内存空间,它包含在proName和num。
- 在堆栈中分配虚拟机。p内存地址,它是1中的Product内存地址的。
- 该虚拟机复制一个p,我们叫他p’,p和p的内存地址不同,但它们存储的值是相同的,两者1中Product内存地址的。
- 将p‘传入方法后,方法就会改变。1中的proName和num。
- 方法结束,方法外打印p中变量价值,这是由于p和p‘所有存在于1中Product地址的地址,1中Product中的价值, 所以,过时的打印p方法执行后的值为。我们看到的效果是包类型的值发生了更改。
最后,让我们来解释一下String分娩过程中的步骤:
- 虚拟机打开堆中的内存块并并存值。“ab”。
- 在堆栈中分配虚拟机。str一段记忆,这是1地址在。
- 虚拟机复制副本str,我们叫str’,str和str内存是不同的,但存储的值是1的地址。
- 将str‘传入方法体
- 方法体打开堆中的内存块并并存值。“cd”
- 方法体将str‘价值变化,存入5的内存地址
- 方法结束,方法外打印str,由于str存的是1所有打印的结果都是“ab”
所以我们理解java该方法传递参数的全过程。事实上,它仍然是上面更重要的一句话 java当方法传递参数时,将复制变量,然后将其传递到方法体以供执行。
欢迎来到我的个人博客 www.liubo-tech.cn
版权声明
所有资源都来源于爬虫采集,如有侵权请联系我们,我们将立即删除