惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

月光博客
月光博客
人人都是产品经理
人人都是产品经理
Hugging Face - Blog
Hugging Face - Blog
有赞技术团队
有赞技术团队
阮一峰的网络日志
阮一峰的网络日志
罗磊的独立博客
博客园_首页
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
大猫的无限游戏
大猫的无限游戏
博客园 - 司徒正美
S
SegmentFault 最新的问题
Jina AI
Jina AI
美团技术团队
酷 壳 – CoolShell
酷 壳 – CoolShell
小众软件
小众软件
WordPress大学
WordPress大学
爱范儿
爱范儿
博客园 - Franky
量子位
V
V2EX
Apple Machine Learning Research
Apple Machine Learning Research
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
雷峰网
雷峰网

博客园 - eafy.ye

Java获取系统信息(cpu,内存,硬盘,进程等)的相关方法 url参数中传递中文 - eafy.ye - 博客园 cglib介绍(转) openfire消息包接受处理流程&Openfire Plugins加载流程 eclipse中开发openfire 垃圾收集器与Java编程(转) Struts2的工作机制及分析(转) Freemarker caching of BeanWrapper models open session and Hibernate事务处理机制 Hibernate/JPA中的继承映射 奥运会开幕 Acegi集成CAS hibernate annotations和hbm.xml配置文件在spring中的并存配置 jBPM-jPDL学习笔记——流程设计与控制(转) JMock来实现孤立测试(转) jBPM开发入门指南 JAVA动态代理实现&&动态字节码生成(asm) java与Groovy的整合 Dom4j 使用简介
java传递是引用的拷贝,既不是引用本身,更不是对象
eafy.ye · 2008-11-28 · via 博客园 - eafy.ye
Code

1、首先弄清楚一个问题:Java有没有指针?

对于在C和C++里头曾经给我们带来欢 乐同时也有无限痛苦的指针,很多人宁愿它再也不要出现在Java里头。然而事实上,Java是有指针的,Java中每个对象(除基本数据类型以外)的标识 符都属于指针的一种。但它们的使用受到了严格的限制和防范,在<Thinking in Java>一书中称它们为句柄。

2、传递句柄
将句柄传递进入一个方法时,指向的仍然是相同的对象。
public class Testit {
private String name;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public static void main(String[] args) {
Testit a = new Testit();
a.setName("a");
Testit b = new Testit();
b.setName("b");
System.out.println("before swap: " + "a=" + a + " name: " + a.getName());
swap(a,b);
}

private static void swap(Testit swap1, Testit swap2) {
System.out.println("swaping: " + "a= " + swap1 + " name: " + swap1.getName());
Testit temp;
temp = swap1;
swap1 = swap2;
swap2 = temp;
}

}

输出结果:
before swap: a=com.lib.Testit@16930e2 name: a
swaping: a= com.lib.Testit@16930e2 name: a

3、一个句柄的传递会使调用者的对象发生意外的改变。
public class Testit {
private String name;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public static void main(String[] args) {
Testit a = new Testit();
a.setName("a");
Testit b = new Testit();
b.setName("b");
System.out.println("before swap: " + "a=" + a + " name: " + a.getName());
swap(a,b);
System.out.println("after swap: " + "a=" + a + " name: " + a.getName());
}

private static void swap(Testit swap1, Testit swap2) {
Testit temp;
temp = swap1;
swap1 = swap2;
swap2 = temp;
swap1.setName("a's name");
swap2.setName("b's name");
}

}

输出结果:
before swap: a=com.lib.Testit@16930e2 name: a
after swap: a=com.lib.Testit@16930e2 name: b's name

我们看到,a依旧是原来那个a,但name却不是原来那个name了!
在swap()方法中,swap1和swap2互相换过来了,这个时候swap2指向的是a,所以在setName()的时候改变的是a的name,而不是b的name。

为什么会这样呢?
liang_chen兄高见:Java里的传值实际上是拷贝引用,而不是拷贝对象。

总结:
1:对于值类型的参数来说,传递的是值的拷贝.
2:对于引用类型的参数来说,传递的是引用本身的拷贝.
所以关键要看你如何理解传值中的这个“值”了。