예를 들어, 대출 금액, 이자율, 대출 기간 및 미래 가치를 기반으로 주택 대출에 대한 월 금액을 계산하는 메서드를 보자.
public double computePayment(
double loanAmt,
double rate,
double featureValue,
int numPeriods)
){
double interest = rate /100.0;
double partiall = Math.pow((1 + interest),
- numPeriods);
double demonimator = (1 - partiall) / interest;
double answer = (-loanAmt / denominator)
- ((futureValue * partiall) / denominator);
return answer;
}
이 메서드는 파라미터를 네개 갖고있다. 대출 금액, 이자율, 미래 가치 및 대출 기간.
처음 세개는 double, float 타입 숫자들이고 마지막은 integer 타입이다.
이 파라미터들은 메서드 바디 내에서 사용되고 런타임에 전달된 인수를 사용한다.
파라미터들은 메서드 선언에서 변수 목록을 나타낸다. 인수(Arguments)는 메서드가 호출 될 때 전달되는 실제 값이다. 메서드를 호출할 때, 인수는 선언의 매개변수와 타입과 순서가 일치해야 한다.
메서드나 생성자의 파라미터는 모든 데이터 타입을 사용할 수 있다. 여기에는 위 메서드에서 본것처럼, double, float, integer같은 기본타입과 objects와 arrays 같은 참조 데이터가 포함된다.
아래 인자로 배열을 받는 메서드 예제가 있다. 이 예제에서 메서드는 Polygon 객체를 생성하고 Point라는 객체의 배열을 인수로 받아 초기화한다.(Point를 x,y 좌표를 나타내는 클래스로 가정한다.)
public PolygonFrom(Point[] corners) {
// 메서드 바디는 여기 위치한다.
}
만약 메서드 안으로 메서드를 전달하고 싶다면, 람다식이나 메서드 참조를 사용한다.
varargs 라는 생성자를 이용하면 메서드에 임의의 갯수 값을 전달할 수 있다. varargs 는 특정 타입의 인자가 메서드에 전달될지 모를 때 사용한다. 이건 배열을 수동으로 생성할 수 있는 지름길이다.
varargs를 사용하기위해, 줄임표(...)와 공백, 파라미터 이름으로 된 마지막 파라미터를 따른다. 이 메서드는 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
}
메서드 안에서, corners가 배열로 관리됨을 볼 수 있다. 이 메서드는 배열이나 일련의 인자로 호출될 수 있다. 이 메서드의 코드는 두 경우 모두(배열이나 일련의 인자로 호출) 매개 변수를 배열로 처리할 것이다.
pringing 메서드에서 varags를 쉽게 볼 수 있다. (예: printf) :
public PrintStream printf(String format, Object... args)
임의의 갯수의 객체를 인쇄하고 싶다면 다음과 같이 호출한다. :
System.out.printf("%s: %d, %s%n", name, idnum, address);
또는
System.out.printf(%s: %d:, %s, %s%n", name, idnum, address, phone, email);
또는 아직 다른 인자가 있다.
메서드나 생성자의 매개변수를 선언할 때 해당 매개변수의 이름을 제공한다. 이 이름은 전달된 인자를 참조하기 위해 메서드 바디 안에서 사용된다.
파라미터 이름은 해당 범위에서 반드시 유니크해야한다. 같은 메서드나 생성자의 다른 파라미터와 같은 이름이 될 수 없고, 메서드와 생성자 내부의 지역변수 이름일 수 없다.
이 파라미터는 클래스의 필드중 하나와 같은 이름을 가질 수 있다. 이 경우엔 shadow the field 라고 한다. Shadowing fields 는 코드를 읽기 어렵게 만들고 일반적으로 특정 필드를 설정하는 생성자와 메서드 내에서만 사용한다.
예를 들자.
public class Circle {
private int x, y, radius;
public void setOrigin(int x, int y) {
...
}
}
Circle 클래스는 필드 세개(x, y, radius)가 있다. setOrigin 메서드는 파라미터가 두개 있고, 필드 중 같은 이름이 있다. 각 메서드 파라미터는 이름을 공유하는 필드를 shadows 한다. 따라서 x,y같은 심플한 이름은 메서드 파라미터를 참조하고, 필드는 하면 안된다. 필드에 접근하려면, 정규화된 이름을 사용해야한다. 이 주제는 키워드 사용에서 다시 다룬다.
int나 double같은 기본인자는 value 로 메서드에 전달된다. 즉, 파라미터 값들에 대한 모든 변경사항은 메서드 내에서만 유효하다. 메서드가 리턴될 때, 파라미터는 사라지고 파라미터에 대한 변경사항이 사라진다.
package arguments;
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;
System.out.println("After invoking passMethod, p = " + p);
}
}
결과는 아래와 같다.
After invoking passMethod, p = 10
After invoking passMethod, x = 3
passMethod 내부의 파라미터 p 에 대한 값 10은 메서드가 종료되면서 사라지고 x만 남게 되었다.
Object같은 참조 데이터 타입또한 메서드에 value 에 의해 전달된다. 즉, 메서드가 리턴되면 전달된 참조는 전과 동일한 객체를 참조한다.
그러나 객체 필드 값들은 적절한 접근 레벨에서 메서드 내에서 변할 수 있다.
예를 들어, 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);
}
그리고 다음 인자로 메서드를 호출한다.
moveCircle(myCircle, 23, 56)
메서드 내부에 circle 은 myCircle을 참조한다. 이 메서드는 circle의 참조 객체, 즉 myCircle의 x,y 좌표를 23, 56으로 변경한다. 이 변화는 메서드가 리턴될 때도 유지된다. 그러면 circle은 새 Circle 객체에 대한 참조가 할당된다(x = y = 0). 그러나, 참조가 value로 전달되었고, 변경할 수 없기 때문에 이 재할당은 영구적이지 않다. 메서드 내에서, circle을 가리키는 객체는 변했지만, 메서드가 리턴될 때 myCircle은 메서드 호출 전과 같이 여전히 같은 Circle 객체를 참조한다.
출처
https://docs.oracle.com/javase/tutorial/java/javaOO/arguments.html