我学java的笔记

java和C++中都采用了引用这个概念,但是二者的行为并不一样。java的引用其实更象c++中的指针,而非c++中的引用,的确c++的指针给我们带来强大威力的同时,也给我们带来了危险,大多的攻击也都是利用指针让系统崩溃。在许多书上都没有见到关于java中reference行为的更详细的探讨,本文便从与c++的的区别谈起: 
一.先看java中的引用:

Java代码
  1. class Person  
  2. {  
  3.  private String name;  
  4.  public Person(String name)  
  5.  {  
  6.   this.name=name;  
  7.  }  
  8.  public String getName()  
  9.  {  
  10.   return name;  
  11.  }  
  12.  public void setName(String name)  
  13.  {  
  14.   this.name = name;  
  15.  }  
  16. }  
[java] view plain copy
  1. class Person  
  2. {  
  3.  private String name;  
  4.  public Person(String name)  
  5.  {  
  6.   this.name=name;  
  7.  }  
  8.  public String getName()  
  9.  {  
  10.   return name;  
  11.  }  
  12.  public void setName(String name)  
  13.  {  
  14.   this.name = name;  
  15.  }  
  16. }  


现产生两个对象 :

Java代码
  1. Person p1=new Person("Zhangsan");  
  2. Person p2=new Person("Lisi");  
[java] view plain copy
  1. Person p1=new Person("Zhangsan");  
  2. Person p2=new Person("Lisi");  


引用Person p=p1,p1=p2; 
测试结果p.getName(): Zhangsan; 
p1.getName():Lisi; 
P2.getName :Lisi; 
而在c++的引用中其结果应该都是Lisi即p2的name(因为p1的改变会影响p); 
上述结果显示:在java中referece其行为就是c++中的指针,而不是c++中的引用. 
但是java的referece是一种安全的指针,不仅受到编译器的保护,还受到执行系统的保护。但java没有“指针”运算。c++中的引用感觉叫做别名更合适,许多语言都用alias关键字来定义别名。 
二、java中的参数传递问题--By value or By reference 
java中的参数传递都是采用by value.其实这句话是个笼统的说法,如果不加思索或许不能理解其真正的含义。 
首先说什么是by value,by value是指在参数结合的时候,形参是否是实参的一个副本,如果产生这个副本那么我们说是by value,否则我们说是by reference. 
java中的基本类型和c、c++语言一样采用by value传参是毋庸置疑的。 
那么java有在参数传递的时候有没有by reference?回答是否定的。java中的一切类型在传递参数的时候都是传值的。 
   首先,我们想想c++和java中的对象有什么区别?其实没有什么区别,只是java中的对象必须由reference来持有,而c++的对象可以单独存在。那好,那就让我们看看java是怎么传递对象的:

Java代码
  1. public static void swap(Person person1, Person person2) // doesn't work  
  2. {  
  3.    Person temp = person1;  
  4.    person1 = person2;  
  5.    person2 = temp;  
  6. }  
  7. Person a = new Person("Alice");  
  8. Person b = new Employee("Bob");  
  9. swap(a, b);  
[java] view plain copy
  1. public static void swap(Person person1, Person person2) // doesn't work  
  2. {  
  3.    Person temp = person1;  
  4.    person1 = person2;  
  5.    person2 = temp;  
  6. }  
  7. Person a = new Person("Alice");  
  8. Person b = new Employee("Bob");  
  9. swap(a, b);  


能工作么?不能。为什么? 
我们看看: 
当我们传递参数的时候,我们传递的是对象么?不,是对象的一个句柄(引用、“指针”)。java的对象只能 
由引用来持有。如果你对c++熟悉,那么上面的过程我们翻译过来:

Java代码
  1. static void swap(Person *person1,Person *person2)  
  2. {  
  3.   Person *temp = person1;  
  4.   person1 = person2;  
  5.   person2 = temp;  
  6. }  
  7. Person *a = new Person("Alice");  
  8. Person *b = new Person("Bob");  
  9. swap(a,b);  
[java] view plain copy
  1. static void swap(Person *person1,Person *person2)  
  2. {  
  3.   Person *temp = person1;  
  4.   person1 = person2;  
  5.   person2 = temp;  
  6. }  
  7. Person *a = new Person("Alice");  
  8. Person *b = new Person("Bob");  
  9. swap(a,b);  


这两段代码产生的行为是一样的,都不能正常工作(即无法完成我们的交换工作)。 
那我们先想想c++是怎么实现对象的交换的?你或许一口就说出使用引用和指针做参数。但是上面的参数是指针 
作为参数呀!原因在于:在c++中我们传递的参数的确能是对象:

Java代码
  1. Person a("Alice");  
  2. Person b("Bob");  
  3. swap(a,b);  
[java] view plain copy
  1. Person a("Alice");  
  2. Person b("Bob");  
  3. swap(a,b);  


这样可以成功完成交换动作. 
前两段的代码不能工作的原因在于: 
  但我们传递实参的时候,我们传递的是指针("指针"),传递的过程,指针("指针")进行了复制,如下图示: 
a--->对象1<----a'(其中a',b'分别为a,b在传递参数的时候产生的副本) 
b--->对象2<----b' 
进入函数体后副本发生了交换,如下图示: 
a-->对象1<---b' 
b-->对象2<---a' 
我们可以看出a和b安然无恙的指向了原来的对象.这就是产生上述结果的原因. 
java可以在函数体内修改对象的值:

Java代码
  1. static void changName(Person person){  
  2.  person.setName("Bob");  
  3. }  
  4. changName(a);  
[java] view plain copy
  1. static void changName(Person person){  
  2.  person.setName("Bob");  
  3. }  
  4. changName(a);  


java传递参数总结: 
1)一个方法不能够修改一个基本类型的实参的值 
2)一个方法可以改变对象的状态. 
3)一个方法不能让实参引用指向另一个对象.


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值