我们一直在使用简单类型做为形参传递给方法,然而,向方法传递对象也是正确的,而且十分常见,例如,下面这个程序定义了存储三维块长度的名为Block的类:
public class test2 { // @param args public static void main(String args[]) { Block ob1 = new Block(10,2,5); Block ob2 = new Block(10,2,5); Block ob3 = new Block(3,3,3); System.out.println("ob1 same dimensions as ob2:"+ob1.sameBlock(ob2)); System.out.println("ob1 same dimensions as ob3:"+ob1.sameBlock(ob3)); System.out.println("ob1 same volume as ob3:"+ob1.sameVolume(ob3)); } } class Block { int a,b,c,volume; Block(int i,int j,int k) { a = i; b = j; c = k; volume = a * b * c; } boolean sameBlock(Block ob) { if(ob.a == a && ob.b == b && ob.c == c) return true; else return false; } boolean sameVolume(Block ob) { if(ob.volume == volume) return true; else return false; } }
输出:
ob1 same dimensions as ob2:true ob1 same dimensions as ob3:false ob1 same volume as ob3:false
sameBlock()和sameVolume()方法比较了作为形参传递给他们的Block对象.sameBlock()比较的是对象的各个维的长度,如果两个块一样,就返回true.sameVolume()比较的是两个块是否相等.注意,在这两个类中,形参ob指定Block为其类型,尽管Block是程序创建的类类型,但他也可以作为Java的内置类型.
如何传递实参
如前所述,向方法传递对象是一件很简单的事情,然而,示例中并没有显示出传递对象的一些细节的不同之处.在某些情况下,传递对象与传递非对象实参是有些不同的.为了解其间的缘由,你还需要理解两种向子例程传递实参的方法.
当向方法传递基本类型时,如int或double,传递的是值,因此将创建实参的副本,无论接收实参的形参发生什么事情,都不会对方法以外产生影响.例如,考虑下面的程序:
public class test2 { // @param args public static void main(String args[]) { testObj obj = new testObj(); int a = 15,b = 20; System.out.println("a and b before call:"+a+" : "+b); obj.noChange(a, b); System.out.println("a and b after call:"+a+" : "+b); } } class testObj { void noChange(int i,int j) { i = i + j; j = -j; } }
输出:
a and b before call:15 : 20 a and b after call:15 : 20
如你所见,在noChange()内部发生的运算并没有影响调用中使用的a和b的值.
当向方法传递对象时,情况就大不一样了,因为对象是通过引用来传递的.切记,当创建类类型的变量时,就在创建对象的引用.实际传递给方法的引用而不是对象本身.因此,当向方法传递引用时,接收引用的形参与实参会指向同一对象.这就意味着向方法传递对象使用的是引用调用.方法内部对对象的修改就会影响做为实参的对象,例如,考虑下面的程序:
public class test2 { // @param args public static void main(String args[]) { testObj obj = new testObj(15,20); System.out.println("a and b before call:"+obj.a+" : "+obj.b); obj.noChange(obj); System.out.println("a and b after call:"+obj.a+" : "+obj.b); } } class testObj { int a,b; testObj(int i,int j) { a = i; b = j; } void noChange(testObj obj) { obj.a = obj.a + obj.b; obj.b = -obj.b; } }
输出:
a and b before call:15 : 20 a and b after call:35 : -20
如你所见,在本例中,noChange()内部的动作影响了做为实参使用的对象.记住,当对象引用被传递给方法时,引用本身是使用传值调用方式传递的,然而,因为被传递的值引用了一个对象,所以该值的副本依然引用了被相应实参引用的同一个对象.
问:我可以使用引用来传递基本类型吗?
答:不能直接使用,然而,Java定义了一系列对对象中封装基本类型的类,这些类有double,float.byte,short,integer,long,character.除了允许使用引用来传递基本类型以外,这些封装还定义了几种用来操作这些值的方法.例如,数值类型的封装就包含了将数值从二进制形式转换为可读字符串的方法,以及反向转换的方法.