void : 비어있음
개념 설명
void는 메서드가 어떤 값도 반환하지 않음을 나타내는 키워드다. 메서드가 실행되고 난 후 호출한 곳으로 돌려주는 값이 없다는 것을 의미한다.
택배로 비유하자면
- 일반 메서드 : 물건을 배달하고 영수증을 가져오는 일
- void 메서드 : 물건만 배달하고 돌아오는 일 (가져오는 것 없음)
기본적으로 메서드라는 것은 행동과 결과를 가진다. 그런데 그 결과를 명시적인 값으로 반환하려면 return을 사용해야한다. 하지만 함수라는 것이 반드시 결과값을 가지는 것은 아니다.
public class StringBuilder {
private String text = "";
// 결과를 만들지만 return은 없는 경우
public void append(String str) {
this.text += str;
}
// 결과를 확인하는 별도의 메서드
public String getText() {
return this.text;
}
}
특정 변수의 값을 조정하기만 할 수도 있다. 만약에 이런식으로 별도로 명시적인 결과값을 반환하지 않는 경우엔 반드시 메서드에 void를 사용해서 반환되는 값이 없음 명시적으로 선언해줘야한다.
즉, 자바에서 메서드(함수)를 선언할려면 return과 void 둘 중 하나를 택 1해서 사용해야한다.
- return 없으면 → void 필수
- 물론 return; 같이 값 없이 return; 형태로 메서드를 중간에 종료하고 싶을 때 사용할 수도 있다.
- void 아닌 타입 쓰면 → return 필수
//값이 없는 return 예시
public void example() {
if (condition) {
return; // 메서드 조기 종료
}
// 나머지 코드
}
혼동하기 쉬운 경우
void 메서드지만 return 값이 있다고 착각할 수 있는 경우가 있는데 바로 출력 메서드들이다.
// 주요 print 계통 메서드들
System.out.print("Hello"); // 단순 출력
System.out.println("Hello"); // 출력 후 줄바꿈
System.out.printf("Name: %s", name); // 형식화된 출력
System.err.println("Error"); // 에러 출력
print 계통 메서드들은 실제로 값을 반환하긴 하지만
- 프로그램 → 콘솔(화면)으로 데이터를 보내는 것이지
- 프로그램 → 프로그램으로 데이터를 반환하는 것이 아니다.
// 초보자가 흔히 혼동하는 점: 출력 메서드의 반환
// 1. 이것은 값을 반환하는 메서드
public String getMessage() {
return "Hello"; // 프로그램 내에서 "Hello"라는 값이 반환됨
}
// 2. 이것은 값을 반환하지 않는 메서드 (void)
public void printMessage() {
System.out.println("Hello"); // 콘솔에 출력만 함
}
/*
실행 결과는 둘 다 "Hello"를 볼 수 있지만:
- getMessage()는 프로그램에서 사용할 수 있는 값을 돌려줌
- printMessage()는 단순히 콘솔에 보여주기만 함
*/
역할
- 메서드의 반환 여부 명시
- 코드의 의도 명확화
- 컴파일러의 타입 체크 지원
//void의 활용 범위
// 1. 메서드 반환 타입 (★★★ 가장 일반적이고 자주 사용)
// - 반환값이 없는 메서드 정의할 때 사용
public void doSomething() { }
// 2. 생성자 (★★★ 매우 자주 사용)
// - 모든 생성자는 void 타입이지만 명시적으로 작성하지 않음
public MyClass() { }
// 3. 제네릭의 타입 매개변수 (★★ 비동기 처리시 자주 사용)
// - 반환값이 없는 작업을 표현할 때 Void 클래스 사용
Future<Void> future = CompletableFuture.runAsync(() -> {});
// 4. 함수형 인터페이스 (★★ 모던 자바에서 자주 사용)
// - 매개변수만 있고 반환값이 없는 함수형 인터페이스
Consumer<String> consumer = str -> System.out.println(str);
// - 매개변수도 없고 반환값도 없는 함수형 인터페이스
Runnable runnable = () -> System.out.println("실행");
// 5. 람다식 (★★ 이벤트 처리 등에서 자주 사용)
// - 반환값이 없는 람다식 표현
() -> System.out.println("Lambda");
// 6. 메서드 참조 (★ 가끔 사용)
// - void 메서드를 참조할 때 사용
System.out::println
// 7. 익명 클래스의 메서드 (★ GUI 프로그래밍 등에서 사용)
// - 인터페이스 구현시 void 메서드 오버라이딩
new ActionListener() {
public void actionPerformed(ActionEvent e) { }
}
// 주의: 클래스 선언에는 사용 불가
void class MyClass { } // 컴파일 에러!
사용 이유와 목적
- 단순 실행만 필요한 작업 수행
- 상태 변경만 필요한 경우
- 출력 작업 같은 단방향 동작
- 코드의 명확성 향상
자주하는 실수
- void 메서드에서 return 값 지정
- void 메서드의 결과를 변수에 할당
- 클래스 선언에 void 사용
- 반환값이 필요한 상황에서 void 사용
//1. void 메서드에서 return 값 지정
public void calculateSum(int a, int b) {
int sum = a + b;
return sum; // 컴파일 에러! void 메서드는 값을 반환할 수 없음
}
// 올바른 방법
public int calculateSum(int a, int b) { // void 대신 int 사용
int sum = a + b;
return sum;
}
//2. void 메서드의 결과를 변수에 할당
List<String> list = new ArrayList<>();
int result = list.add("item"); // 컴파일 에러! void 메서드의 결과를 변수에 저장 불가
// 올바른 방법
list.add("item"); // void 메서드는 단순 실행만
boolean contains = list.contains("item"); // 확인이 필요하면 별도의 메서드 사용
//3. 클래스 선언에 void 사용
void class MyClass { // 컴파일 에러! 클래스에는 void 사용 불가
// ...
}
// 올바른 방법
public class MyClass {
// ...
}
//4. 반환값이 필요한 상황에서 void 사용
// 잘못된 설계
public void getUserAge(String name) {
int age = database.findAgeByName(name);
System.out.println(age); // 단순히 출력만 함
}
// 올바른 설계
public int getUserAge(String name) {
int age = database.findAgeByName(name);
return age; // 호출한 곳에서 나이 값을 활용할 수 있음
}
// 사용 예시
void processUserAge() {
// 잘못된 방법
getUserAge("John"); // 나이 값을 활용할 수 없음
// 올바른 방법
int age = getUserAge("John");
if (age >= 18) {
// 성인 처리 로직
}
}
반환 타입 비교
구분 | void | 반환 타입 있음 |
---|---|---|
반환값 | 없음 | 지정된 타입의 값 |
사용 | return; 또는 생략 | return 값; |
결과 저장 | 불가능 | 변수에 저장 가능 |
주요 용도 | 상태 변경, 출력 | 값 계산, 정보 전달 |
실무 활용 예시
// 1. 데이터 저장
public void saveUser(User user) {
database.save(user);
}
// 2. 상태 변경
public void updateStatus(String status) {
this.status = status;
}
// 3. 화면 출력
public void displayMessage() {
System.out.println("작업 완료");
}
// 4. 초기화
public void initialize() {
this.count = 0;
this.name = "";
}
// 5. 이벤트 처리
public void handleClick() {
processUserAction();
updateUI();
}
// 6. 리소스 정리
public void cleanup() {
connection.close();
buffer.clear();
}
// 7. 로깅
public void logError(String message) {
logger.error(message);
}
// 8. 알림 전송
public void sendNotification(String message) {
notificationService.send(message);
}
실무에서는 주로:
- 데이터베이스 작업
- UI 업데이트
- 로깅
- 리소스 관리
- 이벤트 핸들링
등에 void 메서드가 활용됩니다.