java参数值和返回值是值还是引用

 

java基础教程-对象的传递与返回

534人阅读 评论(1) 收藏 举报
 
对象的传递与返回
 
现在,我们应该已经相当适应这样的概念了:当你 传递 对象的时候,实际上是在传递对象的引用。
 
对许多编程语言而言,只需按 正规 方式传递对象,就能处理绝大多数情况。然而总有些时候,需要以不太正规的方式处理。于是,事情突然变得复杂起来(在 C++ 中,会变得相当复杂), Java 也不例外。因此,确切理解在传递对象的时候发生了什么,就显得很重要了。
 
“Java 中是否有指针 ?有些人认为,指针既难掌握又很危险,所以指针很糟糕。既然 Java 全部都是优点,还能减轻你的编程负担,所以它不可能包含指针。然而,确切地说, Java 有指针。事实上, Java 中(除了基本类型)每个对象的标识符就是一个指针。但是它们受到了限制,有编译器和运行期系统监视着它们。或者换个说法, Java 有指针,但是没有指针的相关算法。我们 称之为 引用( reference ,你也可以将它们看作 安全的指针 ,就像小学生的安全剪刀,它不尖锐,不故意使劲通常不会伤着人,但是使用起来不但慢而且麻烦。
传引用
将一个引用传入某个方法之后,它仍然指向原来的对象。可以用一个简单的试验证明:
// Passing references around.
 
   public class PassReferences {
        public static void main(String[] args) {
            PassReferences p = new PassReferences();
            System.out.println("p inside main(): " + p);
            f(p);
        }  
        public static void f(PassReferences h) {
            System.out.println("h inside f(): " + h);
        }
   }

 
打印语句自动调用 toString() 方法,而继承自 Object PassReferences 类没有重新定义 toString() 方法。所以使用的是 Object toString() 方法,它打印出类名以及存储对象的地址(不是引用,而是实际的对象)。输出看起来像这样:
p inside main(): PassReferences@ad3ba4
h inside f(): PassReferences@ad3ba4
 
可以看到, p h 都指向同一个对象。像这样只是发送一个参数给方法,比复制一个新的 PassReferences 对象效率要高很多。但它也引出了一个重要的话题。
 
别名效应
别名效应 是指,多个引用指向同一个对象,参见前例。当某人修改那个对象时,别名带来的问题就会显现出来。例如,如果此对象还有其他的引用指向它,而使用那些引用的人,根本没想到对象会有变化,定然会对此感到十分诧异。
 
 
 
克隆对象
需要使用对象的局部拷贝的最可能的原因是:你必须修改那个对象,但又不希望改动调用者的对象。如果你决定要制做一份局部拷贝,可以使用 clone() 方法。这是定义在 Object 类中的 protected 方法。如果要使用它,必须在子类中以 public 方式重载此方法。例如,标准类库中的 ArrayList 类就重载了 clone() ,所以我们才能由 ArrayList 调用 clone() 方法:
 
// The clone() operation works for only a few
// items in the standard Java library.
 
import java.util.*;
 
class Int {
   private int i;
 
   public Int(int ii) {
         i = ii;
   }
 
   public void increment() {
         i++;
   }
 
   public String toString() {
         return Integer.toString(i);
   }
}
 
public class Cloning {
 
   public static void main(String[] args) {
         ArrayList v = new ArrayList();
         for (int i = 0; i < 10; i++) {
               v.add(new Int(i));
         }
         System.out.println("v: " + v);
         ArrayList v2 = (ArrayList) v.clone();
         for (Iterator e = v2.iterator(); e.hasNext();) {
               ((Int) e.next()).increment();
         }
         System.out.println("v: " + v);
 
   }
}
clone() 方法只能生成 Object ,之后必须将其转型为合适的类型。此例演示了 ArrayList clone() 方法,它并不自动克隆 ArrayList中包含的每个对象。克隆的ArrayList只是将原ArrayList中的对象别名化。这通常称为浅层拷贝(shallow copy ),因为它只复制对象 表面 的部分。实际的对象由以下几部分组成:对象的 表面 ,由对象包含的所有引用指向的对象,再加上这些对象又指向的对象,等等。通常称之为 对象网 。将这些全部复制即为深层拷贝( deep copy )。
可以由输出看到浅层拷贝的效果,对 v2 的操作影响了 v
v: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
v: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
不自动对 ArrayList 包含的所有对象执行 clone() 是正确的,因为不能保证那些对象都是可克隆的( cloneable )。
 
 
返回值方面
用打印对象的方式测试一下?
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值