1.函数参数传递方式
虽然java通过引用操作对象,所有的对象变量都是引用,然而,java不能通过引用
传递方法参数,它通过值传递
。基本类型传递的是值的副本,引用类型传递的是引用的副本。如果函数内修改了该参数,仅改变副本,而原始值保持不变
。
public void tricky(Point arg1, Point arg2)
{
arg1.x = 100;
arg1.y = 100;
//交换
Point temp = arg1;
arg1 = arg2;
arg2 = temp;
}
public static void main(String [] args)
{
Point pnt1 = new Point(0,0);
Point pnt2 = new Point(0,0);
System.out.println("X: " + pnt1.x + " Y: " +pnt1.y);
System.out.println("X: " + pnt2.x + " Y: " +pnt2.y);
System.out.println(" ");
tricky(pnt1,pnt2);
System.out.println("X: " + pnt1.x + " Y:" + pnt1.y);
System.out.println("X: " + pnt2.x + " Y: " +pnt2.y);
}
//输出结果
X: 0 Y: 0
X: 0 Y: 0
X: 100 Y: 100
X: 0 Y: 0
即使该方法是值传递,但它还是成功的输出了pnt1的值。然而,pnt1和pnt2的却没有交换成功。这两个参数引用
传递给方法时事实上是把原始引用复制了一份。函数方法内的交换只是复制引用地址的交换,原始引用并没有发生变化。传给方法后,一个对象至少有两个引用
。在函数方法里面可以修改对象的数据
。

2.实现函数参数的“任意化”的手段
可以通过Object和泛型实现参数的“任意化”,相比较的优缺点:
- Object要做显式的强制类型转换,而这种转换是要求开发者对实际参数类型可以预知的情况下进行的。而泛型的好处是在编译的时候检查类型安全,并且所有的强制转换都是自动和隐式的,提高代码的重用率。
- 从安全的角度来看,由程序员自己强制类型转换,出错率很高。采用范型后由编译器生成强制类型转换的代码,降低了出错率。JDK1.5以后就有了泛型。
3.动态参数
4.函数方法使用final 修饰参数的作用。
参数(如果是引用类型,引用类型参数是所指的引用副本)不能被重新赋值,否则编译就通不过。是否使用final修饰参数,对外部的影响实际效果是一样的
。
如果函数方法里面使用匿名内部类,并且内部类中使用该参数。那么参数必须用final修饰。局部内部类(包括匿名局部内部类和普通内部类)中使用局部变量,那么这个局部变量必须使用final修饰
。如:
public class Outer {
{
//x和y必须用final修饰,否则编译不通过
final int x=100;
final int y=100;
//内部类
class BlockInner{
int z=100;
public int addXYZ(){return x+y+z;}
}
BlockInner bi=new BlockInner();
num=bi.addXYZ();
}
private int num;
}
用final修饰是因为:
(1)对于普通局部变量他的作用域就是该方法内,当方法结束该局部变量就随之消失
;但局部内部类可能产生隐式的“闭包”,闭包将使得局部变量脱离他所在的方法继续存在。此时就会出现一种情况,就是内部类要访问一个不存在的局部变量
。如下面代码:
//name 必须使用final修饰,否则编译不通过
public void mRun(final String name){
new Runnable() {
public void run() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(name);
}
}.start();
}
//方法myRun已调用结束(局部变量已死亡),但是匿名内部类(线程)对象仍然活着,需要使用外部局部变量name。
(2)上面代码说明局部类的对象生命期会超过局部变量
,解决这一问题的办法就是使用final修饰局部变量,使内部类扩大
局部变量的作用域。其原理通过将final局部变量"复制"一份, 复制品直接作为方法内部类中的数据成员
,方法内部类访问的其实是这个局部变量的复制品!而且,由于被final修饰的变量赋值后不能再修改,所以就保证了复制品与原始变量的一致
。
注:JDK1.8版本以后,可以不用final修饰,都是隐式处理的
。但是本质上该变量还是final的。这该版本的新特性。
网友评论