-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
165 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,165 @@ | ||
## 🤔 가변인수란? | ||
|
||
> 가변인수 사용 예시 | ||
```java | ||
static int sum(int... args) { // 명시한 타입의 인수를 0개 이상 받을 수 있다. | ||
int sum = 0; | ||
for (int arg : args) // 배열 args | ||
sum += arg; | ||
return sum; | ||
} | ||
``` | ||
|
||
- 동적으로 여러개의 인수를 받을 수 있게 해주는 문법 | ||
|
||
- 사용시, 인수의 개수와 길이가 같은 배열을 만들고 값들을 해당 배열에 저장하여 메서드에 건내준다. | ||
|
||
- 0개 이상을 받을 수 있다. 즉, 0개의 인수도 받을 수 있다. | ||
|
||
|
||
## 💁♂️ 만약에 인수 개수에 조건을 걸고 싶다면? | ||
|
||
상황에 따라 **1개 이상의 인수** 와 같은 조건을 걸어야 할때가 있다. | ||
|
||
그럴때는 어떻게 해야할까? | ||
|
||
### 1️⃣ if문 유효성 검사 | ||
|
||
> if문 적용 사례 | ||
```java | ||
static int min(int... args) { | ||
if (args.length == 0) //유효성 검사 | ||
throw new IllegalArgumentException("인수가 1개 이상 필요합니다."); | ||
|
||
int min = args[0]; | ||
for (int i = 1; i < args.length; i++) | ||
if (args[i] < min) | ||
min = args[i]; | ||
return min; | ||
} | ||
``` | ||
|
||
- 위와 같이 조건문을 통해 유효성 검사를 할 수 있다. | ||
- 하지만 해당 방법은 **몇가지 문제가 있다.** | ||
|
||
### ❌ 첫번째 방식의 문제점 | ||
|
||
1. 조건에 어긋나는 인수를 넣을시, **런타임에서 예외가 발생한다.** | ||
|
||
2. 코드가 지저분 해진다. | ||
|
||
3. 위 코드의 경우, min의 초기값을 `Integer.MAX_VALUE`를 설정하지 않고는 깔끔한 `for-each문`을 사용할 수 없다. | ||
|
||
### 2️⃣ 대안 : 매개변수를 여러개 받도록 설정하기 | ||
|
||
> 매개변수를 1개 이상 받아야 할때 | ||
```java | ||
static int min(int firstArgs, int... remainingArgs) { // 1개 이상 되어야 하므로 매개변수 2개 받기 | ||
int min = firstArg; | ||
for (int arg : remainingArgs) | ||
if (arg < min) | ||
min = arg; | ||
return min; | ||
} | ||
``` | ||
|
||
- 다음과 같이 매개변수를 여러개 받는 것으로 깔끔하게 해결 가능하다. | ||
|
||
- 예시로 매개 변수를 1개 이상 받아야 할때, 첫번째로 평범한 매개변수로 받게 한다. | ||
|
||
- 그렇게 되면, 0개가 들어왔을때 컴파일 단계에서 문제점을 찾을 수 있다. | ||
|
||
## ⚠️ 주의 사항 | ||
|
||
앞에서 말했듯이, 인수의 개수와 길이가 같은 배열을 만들고 값들을 해당 배열에 저장하여 메서드에 건내준다. | ||
|
||
즉 메서드가 호출될 때마다, **배열을 새로 하나 할당한다.** | ||
|
||
그러면 만약 성능에 민감한 상황에서는 어떻게 해야할까? | ||
|
||
> 대안 : 메서드 다중 정의 | ||
```java | ||
public void foo() { } | ||
public void foo(int a1) { } | ||
public void foo(int a1, int a2) { } | ||
public void foo(int a1, int a2, int a3) { } | ||
public void foo(int a1, int a2, int a3, int… rest) { } | ||
``` | ||
|
||
- 메서드를 인수의 개수마다 다중정의 하면 보완할 수 있다. | ||
|
||
- 만약 메서드 호출의 95%가 인수를 3개 이하로 사용한다면 | ||
- 0개 ~ 4개인 것 까지 메서드를 다중정의한다. | ||
- 그 이상의 개수는 가변인수로 정의한다. | ||
|
||
|
||
- 즉, **자주 사용되는 개수는 다중 정의 메서드로 정의하면** 배열이 계속 새로 할당되는 것을 방지할 수 있다. | ||
|
||
- 실제로 EnumSet의 정적 팩터리로 위와 같은 방시으로 정의되어 있다. | ||
|
||
> EnumSet 정적 팩터리 메서드 | ||
```java | ||
public static <E extends Enum<E>> EnumSet<E> of(E e) { | ||
EnumSet<E> result = noneOf(e.getDeclaringClass()); | ||
result.add(e); | ||
return result; | ||
} | ||
|
||
public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2) { | ||
EnumSet<E> result = noneOf(e1.getDeclaringClass()); | ||
result.add(e1); | ||
result.add(e2); | ||
return result; | ||
} | ||
|
||
public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3) { | ||
EnumSet<E> result = noneOf(e1.getDeclaringClass()); | ||
result.add(e1); | ||
result.add(e2); | ||
result.add(e3); | ||
return result; | ||
} | ||
|
||
public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3, E e4) { | ||
EnumSet<E> result = noneOf(e1.getDeclaringClass()); | ||
result.add(e1); | ||
result.add(e2); | ||
result.add(e3); | ||
result.add(e4); | ||
return result; | ||
} | ||
|
||
public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3, E e4, E e5){ | ||
EnumSet<E> result = noneOf(e1.getDeclaringClass()); | ||
result.add(e1); | ||
result.add(e2); | ||
result.add(e3); | ||
result.add(e4); | ||
result.add(e5); | ||
return result; | ||
} | ||
|
||
@SafeVarargs | ||
public static <E extends Enum<E>> EnumSet<E> of(E first, E... rest) { | ||
EnumSet<E> result = noneOf(first.getDeclaringClass()); | ||
result.add(first); | ||
for (E e : rest) | ||
result.add(e); | ||
return result; | ||
} | ||
``` | ||
|
||
## 📚 정리 | ||
|
||
#### 🙋♂ ️매개변수 개수에 조건을 걸고 싶다면? | ||
|
||
- 필수 매개 변수의 개수를 일반 매개변수로 정의하자. | ||
|
||
#### 🙋♂️ 가변인수를 사용함에 있어서 성능문제가 걱정된다면? | ||
|
||
- 많이 사용되는 매개변수 개수 메서드들을 다중정의하자. |