java指针与引用(转载)

 1 大家都知道java和C#中没有指针这个概念。但是也导致了编程中常常忽略了对象与引用的区别,难道java真的没有指针吗?句柄是什么?变量地址在哪里?没有地址是不可能的,关键是java中如何避免了指针这个概念。
 2 java中内存的分配方式有两种,一种是在堆中分配,一种是在堆栈中分配,所有new出来的对象都是在堆中分配的,函数中参数的传递是在栈中分配的。通常情况下堆的内存可以很大,比如32位操作系统中的虚拟内存都可以被堆所使用(当内存紧张的时候甚至硬盘都可以是堆的存储空间),而堆栈的内存分配是有限的。
 3 
 4 这和c++中内存分配差不多。java中有几种基本类型如int,float,doublechar,byte等,他们不是对象,除此之外一切都是对象,所有的对象都是在堆上分配的。但好像在C#中这些都有封装好的一些方法,应该算是对象。
 5 
 6 java中对象数组是什么,和c++类似,是句柄数组或者叫指针数组,里面保存的是每个元素的地址。和c++中不同,java没有操作符重载和拷贝构造函数(如果不了解这些也没有关系),因此当创建对象或者对已经创建的对象赋值时(注意是对象,不是基本类型):Object a=new Object 和Object a=b(b是Object的子类型或者同类型)时,进行的是对象地址的传递并复制。这就是所说的句柄的传递和赋值。
 7 
 8 句柄里存储的就是对象的地址,句柄就是指针,只不过是你无法得到的地址,java就是通过这一点巧妙的将指针隐藏起来。当对象作为参数传递到方法中时,传递的就是对象的地址,而行参中保存的是实参地址的副本(这就是最关键的地方,也是值传递,值传递就是将实参的值的副本作为行参)
 9 如:
10 public class Example{
11 
12 int i=0;
13 
14 }
15 
16 public class A{
17 
18 public int i=0;
19 
20 public Example add0(Example e)
21 
22 {
23 
24 e.i++;
25 
26 return e;
27 
28 }
29 
30 
31 
32 public void add1(Example e)
33 
34 {
35 
36 e.i++;
37 
38 }
39 public void modify0(Example e)
40 
41 {
42 
43 Example b=e;//将e行参对象的地址赋给句柄b
44 
45 b.i++;//也同时修改了e.i和实参的值
46 
47 }
48 
49 
50 
51 public void modify1(Example e)
52 
53 {
54 
55 e=new Example();
56 
57 e.i++;
58 
59 }
60 
61 public static void main(String[] args)
62 
63 {
64 
65 Example ex=new Example();
66 
67 A a=new A();
68 
69 a=a.add0(ex);//等价于a.add0(ex),无需返回值,因为通过传递的对象地址(句柄),直接修改了ex中i的值
70 
71 a.add1(ex);//add0,add1都在其中的方法体中直接修改了ex.i的值,因此add0的返回值有点多余
72 
73 a.modify0(ex);//对ex所产生的影响同add1
74 
75 a.modify1(ex);//对ex没有产生任何影响(而且这就是等价于什么也没有做).
76 这可能会让一部分人搞不清了。为什么呢?因为是对象地址的副本"值传递",在modify1中e=new Example();实际上e仅仅是保存ex对象地址的副本的一个句柄,当对e赋值时仅仅是对堆栈中e的赋值(对ex指针副本的变量e赋值),而并没有改变ex的句柄的指向,当方法调用完毕堆栈弹出,e就将要被垃圾回收,没有任何用处。当然你可以将它作为返回值,这就是另外一回事了。
77 
78 }
79 
80 }
81 如果你能明白这个原理,可以避免一些潜在的逻辑错误,如:对象在方法中被改动了,可能你还不知道!记住c++在这一点上和java有很大的不同,c++默认的是值传递,行参会按照位复制实参(如果用指针或者引用就和java很类似了),在方法中作为参数传递对象,java更象是c++中传递引用,当然还是有区别的,那就是c++中对象的引用不可再赋值为另一个对象。

 

转载于:https://www.cnblogs.com/kuiyeit/p/4692922.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值