The Java Tutorials have been written for JDK 8.Java教程是为JDK 8编写的。Examples and practices described in this page don't take advantage of improvements introduced in later releases and might use technology no longer available.本页中描述的示例和实践没有利用后续版本中引入的改进,并且可能使用不再可用的技术。See Java Language Changes for a summary of updated language features in Java SE 9 and subsequent releases.有关Java SE 9及其后续版本中更新的语言特性的摘要,请参阅Java语言更改。
See JDK Release Notes for information about new features, enhancements, and removed or deprecated options for all JDK releases.有关所有JDK版本的新功能、增强功能以及已删除或不推荐的选项的信息,请参阅JDK发行说明。
The declaration for a method or a constructor declares the number and the type of the arguments for that method or constructor.方法或构造函数的声明声明了该方法或构造函数的参数数量和类型。For example, the following is a method that computes the monthly payments for a home loan, based on the amount of the loan, the interest rate, the length of the loan (the number of periods), and the future value of the loan:例如,以下是根据贷款金额、利率、贷款期限(周期数)和贷款未来价值计算住房贷款每月付款的方法:
public double computePayment( double loanAmt, double rate, double futureValue, int numPeriods) { double interest = rate / 100.0; double partial1 = Math.pow((1 + interest), - numPeriods); double denominator = (1 - partial1) / interest; double answer = (-loanAmt / denominator) - ((futureValue * partial1) / denominator); return answer; }
This method has four parameters: the loan amount, the interest rate, the future value and the number of periods.该方法有四个参数:贷款金额、利率、未来价值和期间数。The first three are double-precision floating point numbers, and the fourth is an integer.前三个是双精度浮点数,第四个是整数。The parameters are used in the method body and at runtime will take on the values of the arguments that are passed in.参数在方法体中使用,并且在运行时将采用传入的参数值。
You can use any data type for a parameter of a method or a constructor.可以对方法或构造函数的参数使用任何数据类型。This includes primitive data types, such as doubles, floats, and integers, as you saw in the 这包括基本数据类型,如在computePayment
method, and reference data types, such as objects and arrays.computePayment
方法中看到的Double
、Float
和Integer
,以及引用数据类型,如对象和数组。
Here's an example of a method that accepts an array as an argument.下面是一个接受数组作为参数的方法示例。In this example, the method creates a new 在本例中,该方法创建一个新的Polygon
object and initializes it from an array of Point
objects (assume that Point
is a class that represents an x, y coordinate):Polygon
对象,并从Point
对象数组对其进行初始化(假设点是一个表示x,y坐标的类):
public Polygon polygonFrom(Point[] corners) { // method body goes here }
You can use a construct called varargs to pass an arbitrary number of values to a method.可以使用名为varargs的构造将任意数量的值传递给方法。You use varargs when you don't know how many of a particular type of argument will be passed to the method.当您不知道有多少特定类型的参数将传递给该方法时,可以使用varargs。It's a shortcut to creating an array manually (the previous method could have used varargs rather than an array).这是手动创建数组的快捷方式(前面的方法可能使用varargs而不是数组)。
To use varargs, you follow the type of the last parameter by an ellipsis (three dots, ...), then a space, and the parameter name.要使用varargs,请在最后一个参数的类型后面加一个省略号(三点,...
),然后加一个空格和参数名。The method can then be called with any number of that parameter, including none.然后可以使用任意数量的参数调用该方法,包括none。
public Polygon polygonFrom(Point... corners) { int numberOfSides = corners.length; double squareOfSide1, lengthOfSide1; squareOfSide1 = (corners[1].x - corners[0].x) * (corners[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 }
You can see that, inside the method, 您可以看到,在方法内部,corners
is treated like an array.corners
被视为数组。The method can be called either with an array or with a sequence of arguments.可以使用数组或参数序列调用该方法。The code in the method body will treat the parameter as an array in either case.在这两种情况下,方法体中的代码都将参数视为数组。
You will most commonly see varargs with the printing methods; for example, this 您将最常见地看到带有打印方法的varargs;例如,此printf
method:printf
方法:
public PrintStream printf(String format, Object... args)
allows you to print an arbitrary number of objects.允许您打印任意数量的对象。It can be called like this:可以这样调用:
System.out.printf("%s: %d, %s%n", name, idnum, address);
or like this还是像这样
System.out.printf("%s: %d, %s, %s, %s%n", name, idnum, address, phone, email);
or with yet a different number of arguments.或者有不同数量的论点。
When you declare a parameter to a method or a constructor, you provide a name for that parameter.向方法或构造函数声明参数时,请提供该参数的名称。This name is used within the method body to refer to the passed-in argument.此名称在方法体中用于引用传入的参数。
The name of a parameter must be unique in its scope.参数的名称在其作用域中必须是唯一的。It cannot be the same as the name of another parameter for the same method or constructor, and it cannot be the name of a local variable within the method or constructor.它不能与同一方法或构造函数的另一个参数的名称相同,也不能是该方法或构造函数中的局部变量的名称。
A parameter can have the same name as one of the class's fields.参数可以与类的某个字段同名。If this is the case, the parameter is said to shadow the field.如果是这种情况,则称该参数为字段的影子。Shadowing fields can make your code difficult to read and is conventionally used only within constructors and methods that set a particular field.影子字段会使代码难以阅读,并且通常仅在设置特定字段的构造函数和方法中使用。For example, consider the following 例如,考虑下面的Circle
class and its setOrigin
method:Circle
类及其setOrigin
方法:
public class Circle { private int x, y, radius; public void setOrigin(int x, int y) { ... } }
The Circle
class has three fields: x
, y
, and radius
.Circle
类有三个字段:x
、y
和radius
。The setOrigin
method has two parameters, each of which has the same name as one of the fields.setOrigin
方法有两个参数,每个参数与其中一个字段的名称相同。Each method parameter shadows the field that shares its name.每个方法参数都会对共享其名称的字段进行阴影处理。So using the simple names 因此,在方法体中使用简单名称x
or y
within the body of the method refers to the parameter, not to the field.x
或y
将引用参数,而不是字段。To access the field, you must use a qualified name.要访问该字段,必须使用限定名称。This will be discussed later in this lesson in the section titled "Using the 这将在本课程后面标题为“使用this
Keyword."this
关键字”的部分中讨论
Primitive arguments, such as an 原语参数(如int
or a double
, are passed into methods by value.int
或double
)通过值传递给方法。This means that any changes to the values of the parameters exist only within the scope of the method.这意味着对参数值的任何更改只存在于方法的范围内。When the method returns, the parameters are gone and any changes to them are lost.当方法返回时,参数将消失,对它们的任何更改都将丢失。Here is an example:以下是一个例子:
public class PassPrimitiveByValue { public static void main(String[] args) { int x = 3; // invoke passMethod() with // x as argument passMethod(x); // print x to see if its // value has changed System.out.println("After invoking passMethod, x = " + x); } // change parameter in passMethod() public static void passMethod(int p) { p = 10; } }
When you run this program, the output is:运行此程序时,输出为:
After invoking passMethod, x = 3
Reference data type parameters, such as objects, are also passed into methods by value.引用数据类型参数(如对象)也按值传递给方法。This means that when the method returns, the passed-in reference still references the same object as before.这意味着当方法返回时,传入的引用仍然引用与以前相同的对象。However, the values of the object's fields can be changed in the method, if they have the proper access level.但是,如果对象字段具有适当的访问级别,则可以在方法中更改它们的值。
For example, consider a method in an arbitrary class that moves 例如,考虑一个在移动Circle
objects:Circle
对象的任意类中的方法:
public void moveCircle(Circle circle, int deltaX, int deltaY) { // code to move origin of circle to x+deltaX, y+deltaY circle.setX(circle.getX() + deltaX); circle.setY(circle.getY() + deltaY); // code to assign a new reference to circle circle = new Circle(0, 0); }
Let the method be invoked with these arguments:使用以下参数调用该方法:
moveCircle(myCircle, 23, 56)
Inside the method, 在方法内部,circle
initially refers to myCircle
.circle
最初指的是myCircle
。The method changes the x and y coordinates of the object that 该方法将圆引用的对象(即circle
references (that is, myCircle
) by 23 and 56, respectively.myCircle
)的x
和y
坐标分别更改23
和56
。These changes will persist when the method returns.当方法返回时,这些更改将保持不变。Then 然后,circle
is assigned a reference to a new Circle
object with x = y = 0
.circle
被指定为一个x = y = 0
的新圆对象的参照。This reassignment has no permanence, however, because the reference was passed in by value and cannot change.但是,此重新分配没有永久性,因为引用是按值传入的,无法更改。Within the method, the object pointed to by 在该方法中,circle
has changed, but, when the method returns, myCircle
still references the same Circle
object as before the method was called.circle
指向的对象已更改,但是,当该方法返回时,myCircle
仍然引用与调用该方法之前相同的circle
对象。