3.1.5、将消息传给方法或者构造器

这篇Java教程基于JDK1.8。教程中的示例和实践不会使用未来发行版中的优化建议。

方法和构造器声明声明了该方法和构造器的参数数目和类型。例如,下面是一个方法,它根据贷款的金额、利率、贷款的长度(期限的数量)和贷款的未来价值计算住房贷款的月供。

public double computePayment(double loanAmt,
							double rate,
							double futureValue,
							int numberPeriods){
		double interest = rate / 100.0;
		double partial1 = Math.pow((1 + interest),- numberPeriods);
		double denominator = (1 - partial1) / interest;
		double answer = (-loanAmt / denominator)
                    - ((futureValue * partial1) / denominator);
		return answer;
}

该方法有4个参数:贷款金额,贷款利率,未来价值和贷款期数。前面3个双精度浮点数类型,第4个是int类型。这些参数在方法体中使用,并且在运行时接受传入的参数值。


注意:参数是指方法声明中的变量列表。在方法被调用时参数是指实际传入的变量值。在调用方法时,传入参数在类型和顺序上必须与方法声明时的参数列表一致。


参数类型

对于方法或构造器的参数你可以使用任意的数据类型。包括原始数据类型,比如double、float和int,如同你在 computePayment 中看到的那样,也可以是引用类型,包括object和array。

下面的示例展示了一个接受数组类型作为参数的方法。在该方法中,创建了 一个Polygon 对象,并通过Point 类型的数组来初始化它。

public Polygon polygonFrom(Point[] corners){
//method body goes here
}

注意:如果你想把一个方法传给另一个方法,可以使用Lambda表达式或者方法引用。


任意数量的参数

你可以构造一个可变参数传递给方法。当你不知道会有多少个特定类型的参数会传给方法时可以使用可变参数。可变参数是手动创建数组的简写形式。

为了使用可变参数,在最后一个参数类型后面加上一个省略号(三个点,…),然后是空格和参数名。该方法可以接受任意个该类型的参数,包括0个。

public Polygon polygonFrom(Point... corners){
	int numberOfSides = corners.length;
	double squareOfSide1,lengthOfSide1;
	squareOfSide1 = (corners[1].x - corners[0].x)
					* (corers[1].x - corners[0].x)
					+ (corners[1].y - corners[0].y)
					* (corners[1].y - corners[0].y);

	lengthOfSide1 = Math.sqrt(squareOfSide1);
	// more method body code follows that creates and returns a 
    // polygon connecting the Points
}

你可以看到,在方法中,corners 被当做一个数组处理。该方法可以接受传入数组或者序列,在这两种情况下,方法体内的代码都会把参数当做数组来处理。

经常在print类型的方法中会看到可变参数,比如,printf 方法:

public PrintStream printf(String format,Object... args);

允许你打印任意数量的对象,它可以这样来使用:

System.out.println("%s : %d, %s%n", name,idnum,address);

或者像这样传入多个不同的参数来使用:

System.out.println("%s : %d, %s, %s, %s%n", name,idnum,address,phone,email);
参数名称

当在方法或者构造器中声明参数时,你需要提供一个参数名称。该名称在方法体中将会作为传入参数来使用。

在方法体作用范围内参数名必须是唯一的。在同一个方法和构造器中不能有同名的参数名,也不能与本地变量同名。

参数名可以和类中的字段名相同。如果是这种情况,参数被称作阴影字段。通常来讲,阴影字段会让你的程序在理解上要困难一些,并且只会用在方法或者构造器设置一个字段的场景上。比如,考虑 Circle 类中有一个 setOrigin 方法:

public class Circle{
	private int x,y,radius;
	
	public void setOrigin(int x,int y){
		···
	}
}

Circle 类中有3个字段:x,y和radius,setOrigin 方法有2个参数,这两个参数都与类中的字段同名。每一个与变量同名的参数我们都叫做阴影字段,因此在方法体中使用名称x,y都是指参数x、y而不是字段。要访问字段必须使用字段的全限定名。这将在本课中“使用this关键字”一节中详细介绍。

传递原始类型的参数

原始类型的参数,比如int和double,均是传值引用。这意味着任何该参数值的变化只体现在当前这个方法的作用范围内。方法一旦返回,该参数就会消亡,任何在它上面的改动都会丢失。如下例所示:

public class PassPrimitiveValueByValue{

	public static void main(String[] args){
		int x = 3;
	
		passMethod(x);
	
		System.out.println("After invoking passMethod, x = " + x);
	}
	
	public static void passMethod(int p){
		p = 10;
	}
}

当你执行改程序时,输出如下:

After invoking passMethod, x = 3
传递引用数据类型

引用数据类型,比如objects,传入参数时也是值传递。这意味着当方法返回时,该参数仍然引用着方法调用前的同一个对象。但是,引用对象的字段可以在方法体中改变,只要它有足够的访问等级。

考虑下面的代码片段:

public void moveCircle(Circle circle,int deltaX,int deltaY){
	circle.setX(circle.getX() + deltaX);
	circle.setY(circle.getY() + deltaY);
	
	circle = new Circle(0,0);
}

用下面的参数调用该方法:

moveCircle(myCircle,23,56)

在方法中,circle最开始指向 myCircle。该方法改变了圆形引用对象circle的坐标x,y,这种改变只会持续到方法返回前。circle 指向了x = y = 0的新Circle对象。但这种重新赋值起不到作用,因为传入的引用是值传递,它在方法返回后是不可变的。在方法内部,circle引用是发生了变化,但是方法返回后,circle引用仍然指向方法调用时传递给它的那个对象。

上一篇:CornerNet: Detecting Objects as Paired Keypoints (1)


下一篇:codesys电子凸轮挺杆点的设置与使用