반응형
해당 글에서는 Java에서 Enum에 대해 이해하고 이를 활용할 수 있는 방안에 대해서 알아봅니다.
1) Enum(Enumerated type) : 열거형
💡 Enum(Enumerated type) : 열거형
- 특정 값들의 집합을 나타내는 데이터 타입을 의미하며 서로 연관되어 있는 ‘미리 정의된 상수 집합’을 표현하는 데 사용되는 특수 클래스입니다.
- 변수가 정해진 명시적인 값을 가질 수 있도록 하며 코드의 가독성을 높이며 안정성을 향상하는데 도움이 됩니다.
- Enum의 데이터 구조는 일반적으로 ‘이름’과 ‘값’의 쌍으로 구성되어 있습니다. 각 이름은 고유하고 일반적으로 문자열로 표시되며 값은 숫자입니다. 이러한 이름-값 쌍은 Enum 내에서 중복될 수 없습니다.
- 예를 들어 ‘요일’ Enum에서 월요일-1, 화요일-2과 같이 각 요일에 고유한 숫자 값을 할당할 수 있습니다.
💡 사용예시
- Day라는 enum 구조에서는 MONDAY라는 ‘이름(name)’과 월요일이라는 ‘값(value)’으로 구성되어 있습니다.
public enum Day {
MONDAY("월요일"),
TUESDAY("화요일"),
WEDNESDAY("수요일"),
THURSDAY("목요일"),
FRIDAY("금요일"),
SATURDAY("토요일"),
SUNDAY("일요일");
private final String korean;
Day(String korean) {
this.korean = korean;
}
public String getKoreanTranslation() {
return this.korean;
}
}
2) Enum 사용 이전 사용 형태
💡 Enum 사용 이전 사용 형태
- Enum은 Java 1.5부터 사용이 되었습니다. 이를 사용하기 이전에 사용되었던 형태에 대해서 알아봅니다.
- final 상수, 인터페이스 상수, 자체 클래스 상수 형태가 있습니다.
1. final 상수
💡 final 상수
- 자바에서 특정 변수가 한 번 초기화되면 그 이후로 변경이 불가능한 상수를 의미합니다.
- 또한 final 키워드 앞에 static 키워드를 붙여서 클래스 레벨에서 공유가 되는 변수가 됩니다. 즉 상수로써 어떤 객체에서도 동일한 값에 접근이 가능한 형태를 의미합니다.
💡 [사용예시 : 선언부]
- 아래는 final 상수를 이용하여 정규식을 구성한 예시입니다.
public class RegExpConstants {
// 1. 문자열만 허용하는 정규식 - 공백 미 허용
public static final String REGEXP_PATTERN_CHAR = "^[\\\\w]*$";
// 2. 문자열만 허용하는 정규식 - 공백 허용
public static final String REGEXP_PATTERN_NO_CHAR = "^[\\\\W]*$";
// 3. 숫자만 허용하는 정규식
public static final String REGEXP_PATTERN_NUMBER = "^[\\\\d]*$";
}
💡 [사용예시 : 접근부]
- 아래는 위에 구성한 final 상수를 호출하여 정규식을 기반으로 검증을 하는 예시입니다.
- 구체적으로는 숫자만의 사용하는 REGEXP_PATTERN_NUMBER 정규식을 통해 해당 문자열이 숫자인지 여부를 체크하는 예시입니다.
- 아래와 같이 <<클래스.변수>> 형태로 접근이 가능하거나 즉시 클래스 변수를 import 하여서 사용이 가능합니다.
String userNum1 = "1234";
String userNum2 = "U1234";
Boolean isNumber1 = Pattern.matches(RegExpConstants.REGEXP_PATTERN_NUMBER, userNum1);
Boolean isNumber2 = Pattern.matches(RegExpConstants.REGEXP_PATTERN_NUMBER, userNum2);
import static com.adjh.multiflexapi.common.codes.constans.RegExpConstants.REGEXP_PATTERN_NUMBER;
Boolean isNumber3 = Pattern.matches(RegExpConstants.REGEXP_PATTERN_NUMBER, userNum2);
💡 final 상수의 경우 아래와 같은 단점을 가지게 됩니다.
단점 | 설명 |
타입 안전성 | 어떤 데이터 타입도 가질 수 있어, 특정 상수 집합에 대한 타입 안전성을 보장하기 어렵다 |
상수 값의 중복 | 같은 값을 가진 여러 변수를 선언할 수 있어, 실수를 유발할 수 있다 |
코드 가독성 | 여러 FINAL 변수가 코드 내에서 흩어져 있을 수 있어, 코드의 가독성을 해칠 수 있다 |
2. 인터페이스 상수
💡 인터페이스 상수
- 인터페이스에서 정의된 모든 필드에는 자동으로 public, static, final 키워드가 적용되는 것을 의미합니다. 이를 통해 인터페이스 필드는 상수 취급을 받게 됩니다.
- 'public'은 해당 상수가 어디에서든 접근 가능함을 의미하며 'static'은 해당 상수가 인터페이스에 속하며 인스턴스화 없이도 접근할 수 있음을 의미합니다. 'final'은 한번 초기화된 값을 변경할 수 없음을 의미하므로 이 키워드가 붙은 필드는 변하지 않는 상수가 됩니다.
- 따라서, 인터페이스 상수는 변경 불가능한 공용 상수로 사용될 수 있습니다.
💡 [사용예시 : 선언부]
- 아래와 같은 정규식을 interface 내에 선언하여 public, static, final로 선언된 상수와 같이 구성하였습니다.
public interface RegExpConstInterface {
// 1. 문자열만 허용하는 정규식 - 공백 미 허용
String REGEXP_PATTERN_CHAR = "^[\\\\w]*$";
// 2. 문자열만 허용하는 정규식 - 공백 허용
String REGEXP_PATTERN_NO_CHAR = "^[\\\\W]*$";
// 3. 숫자만 허용하는 정규식
String REGEXP_PATTERN_NUMBER = "^[\\\\d]*$";
}
💡 [사용예시: 접근부-1]
- 숫자만의 사용하는 REGEXP_PATTERN_NUMBER 정규식을 통해 해당 문자열이 숫자인지 여부를 체크하는 예시입니다.
- 아래와 같이 <<인터페이스.변수>> 형태로 접근이 가능합니다.
String userNum1 = "1234";
String userNum2 = "U1234";
Boolean isNumber1 = Pattern.matches(RegExpConstInterface.REGEXP_PATTERN_NUMBER, userNum1);
Boolean isNumber2 = Pattern.matches(RegExpConstInterface.REGEXP_PATTERN_NUMBER, userNum2);
💡 [사용예시: 접근부 -2]
- 또한 인터페이스를 구현하는 클래스로 구성하여 접근이 가능합니다. 이를 통해 인터페이스에서 정의된 상수를 호출하면 됩니다.
import java.util.regex.Pattern;
public class TestController implements RegExpConstInterface {
public String test() {
String userNum1 = "1234";
String userNum2 = "U1234";
Boolean isNumber1 = Pattern.matches(REGEXP_PATTERN_NUMBER, userNum1);
Boolean isNumber2 = Pattern.matches(REGEXP_PATTERN_NUMBER, userNum2);
return isNumber1 ? "성공" : "실패";
}
}
💡 interface 상수의 경우 아래와 같은 단점을 가지게 됩니다.
단점 | 설명 |
타입 안전성 부족 | 인터페이스 상수는 특정한 상수 집합을 정의하지 못하므로 타입 안전성을 보장하지 못합니다. |
상속 관련 문제 | 인터페이스 상수는 인터페이스를 구현하는 클래스에서 상속받을 수 있지만, 이로 인해 불필요하거나 예상치 못한 상속 문제가 발생할 수 있습니다. |
객체 지향 프로그래밍 원칙 위반 | 인터페이스는 주로 행동을 정의하는 것이므로, 상수(상태를 정의하는 것)를 인터페이스 내에 정의하는 것은 객체 지향 프로그래밍 원칙에 부합하지 않을 수 있습니다. |
3. 자체 클래스 상수
💡 자체 클래스 상수
- 클래스 내부에 상수를 정의하는 방법으로 클래스의 static final 필드를 사용하여 이루어집니다. 해당 클래스와 관련된 상수를 한 곳에 모아 놓을 수 있다는 장점이 있습니다.
💡 [사용예시 : 선언부]
- 자체 클래스의 상수로 RegExp 클래스의 상수로 REGEXP_PATTERN_CHAR, REGEXP_PATTERN_NO_CHAR, REGEXP_PATTERN_NUMBER가 있음을 선언하였습니다.
public class RegExp {
// 1. 문자열만 허용하는 정규식 - 공백 미 허용
public final RegExp REGEXP_PATTERN_CHAR = new RegExp();
// 2. 문자열만 허용하는 정규식 - 공백 허용
public final RegExp REGEXP_PATTERN_NO_CHAR = new RegExp();
// 3. 숫자만 허용하는 정규식
public final RegExp REGEXP_PATTERN_NUMBER = new RegExp();
}
💡 [호출부]
- final 상수나 인터페이스 상수와 다르게 상수 자체만 정의하고 클래스의 인스턴스로써 상수로 사용됩니다.
💡 자체 클래스 상수의 경우 아래와 같은 단점을 가지게 됩니다.
단점 | 설명 |
타입 안전성 | 원시 유형이나 문자열 등 어떤 데이터 타입도 가질 수 있어 타입 안전성 보장이 어렵습니다. |
상수 값의 중복 | 같은 값을 가진 여러 변수를 선언 가능, 실수 유발 가능성 있습니다. |
코드 가독성 | 여러 클래스 상수는 코드 내에서 흩어져 있을 수 있음, 가독성 해칩니다. |
4. 종합
💡 종합
- final 상수, 인터페이스 상수, 자체 클래스 상수, ENUM을 각각 비교합니다.
비교항목 | final 상수 | 인터페이스 상수 | 자체 클래스 상수 | Enum |
타입 안정성 | 부족 | 부족 | 부족 | 보장 |
상수 값의 중복 | 가능 | 가능 | 가능 | 불가능 |
코드 가독성 | 보통 | 보통 | 보통 | 높음 |
객체 지향 프로그래밍 원칙 적용 | 가능 | 부족 | 가능 | 가능 |
싱글톤 패턴 구현 | 불가능 | 불가능 | 불가능 | 가능 |
3) Enum의 주요 특징
1. 타입 안정성(Type-safe)
💡 타입 안정성(Type-safe)
- Enum 값이 명시적으로 정의되어 있으며 이외의 값은 허용되지 않습니다. 따라서 Enum에 정의되지 않았는데 접근을 하는 경우 ‘컴파일 시점에서 에러를 방지’ 할 수 있습니다.
- 이를 통해 컴파일 시점에 에러를 방지하여 ‘런타임에서 발생하는 에러’를 줄이고 코드의 안정성과 신뢰성을 높이는데 도움이 됩니다.
💡 [사용 예시]
- 아래와 같이 Enum 타입으로 변수를 구성하였습니다.
public enum SeasonEnum {
SPRING,
SUMMER,
FALL,
WINTER
}
💡 위에와 같이 선언된 Enum에 접근하고자 할 때, 컴파일 단계에서 접근 가능한 요소에 대해서 확인이 가능합니다. 그렇기에 런타임 시점에 발생할 수 있는 에러를 방지할 수 있고 ‘타입 안정성’을 가지고 있습니다.
2. 클래스처럼 사용이 됩니다.
💡 클래스처럼 사용이 됩니다
- enum 클래스 내에서는 메서드, 변수, 생성자를 가질 수 있고 클래스가 가질 수 있는 특성을 Enum이 가지고 있기에 클래스처럼 보이게 작성이 됩니다.
public enum Day {
// 변수 영역
MONDAY("월요일"),
TUESDAY("화요일"),
WEDNESDAY("수요일"),
THURSDAY("목요일"),
FRIDAY("금요일"),
SATURDAY("토요일"),
SUNDAY("일요일");
// 변수 영역
private String koreanTranslation;
// 생성자 영역
Day(String koreanTranslation) {
this.koreanTranslation = koreanTranslation;
}
// 메서드 영역
public String getKoreanTranslation() {
return koreanTranslation;
}
}
💡 구성된 Enum을 접근하고자 할때, 메서드로 접근하는 경우 각 요일에 대한 한국어 번역 정보를 얻을 수 있습니다.
System.out.println(Day.MONDAY.getKoreanTranslation()); // 출력: 월요일
3. 싱글턴 패턴 구현
💡 싱글턴 패턴 구현
- 클래스의 인스턴스가 단 하나만 생성되어야 할 때 사용하는 디자인 패턴입니다.
- Enum은 자바에서 싱글톤 패턴을 만드는 가장 안전한 방법으로 간주됩니다. Enum은 싱글톤을 만들 때 직렬화, 스레드 안정성 등에 대한 걱정 없이 싱글톤 패턴을 구현하기 위한 완벽한 솔루션을 제공합니다.
💡 아래와 같이 사용하여 SingletonEnum.INSTANCE는 싱글톤 인스턴스가 되며, SingletonEnum.INSTANCE.performOperation()는 싱글턴 객체의 동작을 정의합니다.
public enum SingletonEnum {
INSTANCE; // 싱글턴 객체를 의미합니다.
// 필요한 멤버 변수와 메서드를 선언할 수 있습니다.
// 싱글턴 객체의 동작을 정의합니다.
public void performOperation() {
// 동작
}
}
💡 [참고] 싱글턴 패턴에 대해 궁금하시면 아래의 글을 참고하시면 도움이 됩니다.
4. Enum 상수와 메서드
💡 Enum 상수와 메서드
- Enum 내부에 메서드를 정의하고 Enum 상수가 이를 오버라이드하게 하여 각 상수가 다른 동작을 하도록 설정할 수 있습니다. 이를 통해 상수별로 다른 동작을 하는 Enum을 만들 수 있습니다.
💡 이런 방식은 각 Enum 상수가 고유한 동작을 가져야 할 때 유용합니다.
public enum Operation {
PLUS {
public int apply(int x, int y) { return x + y; }
},
MINUS {
public int apply(int x, int y) { return x - y; }
},
TIMES {
public int apply(int x, int y) { return x * y; }
},
DIVIDE {
public int apply(int x, int y) { return x / y; }
};
public abstract int apply(int x, int y);
}
4) Enum 메서드
1. Enum 주요 메서드
리턴 타입 | 메서드 | 설명 |
protected Object | clone() | 객체의 복제를 생성하여 새로운 인스턴스를 반환합니다. |
int | compareTo(E o) | 주어진 객체와 이 객체를 비교하고, 순서를 나타내는 정수를 반환합니다. |
boolean | equals(Object other) | 이 객체와 주어진 객체가 동일한지 확인하고, 동일하면 true를 아니면 false를 반환합니다. |
protected void | finalize() | 객체가 가비지 컬렉션에 의해 수거되기 전에 마지막으로 수행할 작업을 정의합니다. |
Class<E> | getDeclaringClass() | 이 열거형의 선언 클래스를 반환합니다. |
int | hashCode() | 이 객체의 해시 코드를 생성하고 반환합니다. |
String | name() | 이 열거형의 이름을 문자열로 반환합니다. |
int | ordinal() | 이 열거형의 값의 순서를 반환합니다. |
String | toString() | 이 객체의 문자열 표현을 생성하고 반환합니다. |
static <T extends Enum<T>> T | valueOf(Class<T> enumType, String name) | 주어진 이름에 해당하는 열거형 값을 반환합니다. |
2. name()
💡 name()
- 호출한 Enum 인스턴스의 이름을 문자열 형태로 반환합니다. 이 이름은 Enum 상수를 선언할 때 사용한 정확한 문자열입니다.
💡 Day.MONDAY.name()을 호출하면 "MONDAY"라는 문자열을 반환합니다.
public enum Day {
MONDAY,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY,
SUNDAY
}
Day.MONDAY.name(); // MONDAY
3. original()
💡 original()
- Enum의 요소가 선언된 순서에 따라 인덱스를 반환합니다. 이 인덱스는 0부터 시작합니다.
💡 "Days.MONDAY.ordinal()"은 0을 반환하고, "Days.TUESDAY.ordinal()"은 1을 반환합니다.
public enum Days {
MONDAY,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY,
SUNDAY
}
Days.MONDAY.ordinal(); // 0
Days.TUESDAY.ordinal(); // 1
4. compareTo()
💡 compareTo()
- Enum 인스턴스들 간의 순서를 비교하는 메서드입니다.
- 해당 메서드는 호출한 Enum 인스턴스가 인자로 받은 Enum 인스턴스보다 앞에 위치할 경우 음수를, 같은 위치에 있을 경우 0을, 뒤에 위치할 경우 양수를 반환합니다.
public enum Days {
MONDAY,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY,
SUNDAY
}
Days.MONDAY.compareTo(Days.WEDNESDAY); // -2
5. valueOf()
💡 주어진 문자열에 해당하는 Enum 상수를 반환합니다. 이 메서드는 주로 문자열을 Enum 타입으로 변환할 때 사용됩니다.
public enum Days {
MONDAY,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY,
SUNDAY
}
Days.valueOf("MONDAY"); // Days.MONDAY
Days.valueOf("NOTTHING"); // IllegalArgumentException 발생
6. values()
💡 values()
- Enum에 속하는 모든 상수를 배열 형태로 반환합니다. 이 메서드는 주로 Enum의 모든 상수를 반복하거나 조회할 때 사용됩니다.
public enum Days {
MONDAY,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY,
SUNDAY
}
for (Object regExp : RegExpEnum.values()) {
regExp.toString(); // MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
5) Enum 메서드 활용 예시
1. Exception 성공 코드 & 에러 코드 관리
💡 사용예시
- API 통신에 대한 '에러 코드'를 Enum 형태로 관리를 한다.
- 해당 Enum 형태로 관리하면 정형화된 데이터로 관리할 수 있습니다. SuccessCode.INSERT에 대해서 ‘코드 상태’, ‘코드 값’, ‘코드 메시지’ 형태로 관리가 가능합니다.
package com.adjh.multiflexapi.common.codes;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
/**
* [공통 코드] API 통신에 대한 '에러 코드'를 Enum 형태로 관리를 한다.
* Success CodeList : 성공 코드를 관리한다.
* Success Code Constructor: 성공 코드를 사용하기 위한 생성자를 구성한다.
*
* @author lee
*/
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public enum SuccessCode {
/**
* ******************************* Success CodeList ***************************************
*/
// 조회 성공 코드 (HTTP Response: 200 OK)
SELECT(200, "200", "SELECT SUCCESS"),
// 삭제 성공 코드 (HTTP Response: 200 OK)
DELETE(200, "200", "DELETE SUCCESS"),
// 전송 성공 코드 (HTTP Response: 200 OK)
SEND(200, "200", "SEND SUCCESS"),
// 삽입 성공 코드 (HTTP Response: 201 Created)
INSERT(201, "201", "INSERT SUCCESS"),
// 수정 성공 코드 (HTTP Response: 201 Created)
UPDATE(204, "204", "UPDATE SUCCESS"),
; // End
/**
* ******************************* Success Code Constructor ***************************************
*/
// 성공 코드의 '코드 상태'를 반환한다.
private int status;
// 성공 코드의 '코드 값'을 반환한다.
private String code;
// 성공 코드의 '코드 메시지'를 반환한다.
private String message;
// 생성자 구성
SuccessCode(final int status, final String code, final String message) {
this.status = status;
this.code = code;
this.message = message;
}
}
💡 아래와 같이 호출을 할 때는 SuccessCode.INSERT의 메서드 형태인 getStatus(), getCode(), getMessage()로 접근이 가능합니다.
/**
* [API] 코드 등록
*
* @param codeDto codeDto
* @return ResponseEntity<Integer> : 응답 결과 및 응답 코드 반환
*/
@PostMapping("/code")
@Operation(summary = "코드 등록", description = "코드 등록")
public ResponseEntity<ApiResponse<Object>> insertCode(@RequestBody @Validated CodeDto codeDto) throws IOException {
log.debug("코드를 등록합니다.");
int resultList = codeService.insertCode(codeDto);
ApiResponse<Object> ar = ApiResponse.builder()
.result(resultList)
.resultCode(SuccessCode.INSERT.getStatus())
.resultMsg(SuccessCode.INSERT.getMessage()).build();
return new ResponseEntity<>(ar, HttpStatus.OK);
}
💡 [참고] 해당 코드에 대한 출처는 아래의 글을 참고하시면 도움이 됩니다.
2. 상수형태로 정규식을 관리
💡 사용예시 -2 : 상수형태로 정규식을 관리
- Java 내에서 사용하는 정규식을 상수로 구성합니다.
package com.adjh.multiflexapi.model.enums;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
/**
* ENUM 형태로 정규식 모음을 관리합니다.
*
* @author : lee
* @fileName : RegExpEnum
* @since : 2/15/24
*/
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED, force = true)
public enum RegExpEnum {
/**
* [정규식 모음-1] 패턴을 이용한 정규식
*/
// 1. 문자열만 허용하는 정규식 - 공백 미 허용
PATTERN_CHAR("^[\\\\w]*$"),
// 2. 문자열만 허용하는 정규식 - 공백 허용
PATTERN_NO_CHAR("^[\\\\W]*$"),
// 3. 숫자만 허용하는 정규식
PATTERN_NUMBER("^[\\\\d]*$"),
// 4. 숫자가 아닌 경우 허용하는 정규식
PATTERN_NO_NUMBER("^[\\\\D]*$"),
// 5. 공백, 탭을 허용하는 정규식
PATTERN_SPACE_CHAR("^[\\\\s]*$"),
// 6. 공백, 탭이 아닌 경우를 허용하는 정규식
PATTERN_SPACE_NO_CHAR("^[\\\\S]*$"),
/**
* [정규식 모음-2] '문자열'에 대한 정규식
*/
// 1. 대소구분 없는 영문만 허용하는 정규식
EN("^[a-z|A-Z]*$"),
// 2. 소문자만 허용하는 정규식
LOWER_CASE("^[a-z]*$"),
// 3. 대문자만 허용하는 정규식
UPPER_CASE("^[A-Z]*$"),
// 4. 한글만 허용하는 정규식
KR("^[ㄱ-ㅎ|가-힣]*$"),
// 5. 대소구분 없는 영문과 한글만 허용하는 정규식
ONLY_CHAR("^[a-z|A-Z|ㄱ-ㅎ|가-힣]*$"),
ONLY_SPACE_CHAR("^[a-z|A-Z|ㄱ-ㅎ|가-힣| ]*$"),
// 6. 대소구분 없는 영문과 한글, 숫자를 허용하는 정규식
CHAR_NUM("^[0-9a-zA-Zㄱ-ㅎ가-힣]*$"),
CHAR_SPACE_NUM("^[0-9a-zA-Zㄱ-ㅎ가-힣 ]*$"),
// 7. 특수문자 제외에 대한 정규식
NOT_SPECIAL_CHAR_TYPE1("^[^A-Za-z0-9]*$"),
NOT_SPECIAL_CHAR_TYPE2("[\\\\{\\\\}\\\\[\\\\]\\\\/?.,;:|\\\\)*~`!^\\\\-_+<>@\\\\#$%&\\\\=\\\\('\\"]*$"),
/**
* [정규식 모음-3] 숫자에 대한 정규식
*/
// 1. 숫자만 이용하는 정규식
NUMBERS("^[0-9]*$"),
// 2. 숫자가 아닌것에 대한 정규식
NO_NUMBER("^[^0-9]*$"),
/**
* [정규식 모음-4] 사용자 정보 관련 정규식
*/
// 1. 사용자 이메일에 대한 정규식
LIGHT_USER_EMAIL("^[a-zA-Z0-9]+@[0-9a-zA-Z]+\\\\.[a-z]+$"),
TIGHT_USER_EMAIL("^[0-9a-zA-Z]([-_\\\\.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_\\\\.]?[0-9a-zA-Z])*\\\\.[a-zA-Z]{2,3}+$"),
// 2. 사용자 아이디에 대한 정규식 - 영문 숫자 조합 6~10자리
USER_ID("^[a-z]{1}[a-z0-9]{5,10}+$"),
// 3. 사용자 패스워드에 대한 정규식 - 대소문자 + 숫자 + 특수문자 조합으로 10 ~ 128자리로 정의 한다.
USER_PW_TYPE1("^(?=.*[a-zA-Z])((?=.*\\\\d)|(?=.*\\\\W)).{10,128}+$"),
// 4. 핸드폰 번호 타입1에 대한 정규식 => ex) 01023205454
PHONE_TYPE1("^[\\\\d]{11}+$"),
// 5. 핸드폰 번호 타입2에 대한 정규식 => ex) 010-2320-5454
PHONE_TYPE2_1("^01([0|1|6|7|8|9])-([0-9]{3,4})-([0-9]{4})+$"),
PHONE_TYPE2_2("^[\\\\d]{2,3}-[\\\\d]{3,4}-[\\\\d]{4}+$"),
// 6. 핸드폰 번호 타입3에 대한 정규식 => ex) +82-010-2320-5454
PHONE_TYPE3("^\\\\+82-01([0|1|6|7|8|9])-([\\\\d]{3,4})-([\\\\d]{4})+$"),
// 7. 핸드폰 번호 타입4에 대한 정규식 => ex) +82-10-2320-5454
PHONE_TYPE4("^\\\\+82-10-([\\\\d]{3,4})-([\\\\d]{4})+$"),
// 8. 주민등록 번호 타입에 대한 정규식
REGISTRATION_NUM("^[\\\\d]{6}-[1-4][\\\\d]{6}+$"),
// 9. 우편 번호에 대한 정규식
POSTAL_CODE("^[\\\\d]{3}-[\\\\d]{2}+$"),
/**
* [정규식 모음-5] 날짜에 대한 정규식
*/
// [Soft] 날짜에 대한 타입1에 대한 정규식 => ex) 2022-08-03 (YYYY-MM-DD)
DATE_TYPE1("^[\\\\d]{4}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$"),
// [Soft] 날짜에 대한 타입2에 대한 정규식 => ex) 2022/08/03 (YYYY/MM/DD)
DATE_TYPE2("^[\\\\d]{4}]\\\\/(0[1-9]|1[012])\\\\/(0[1-9]|[12][0-9]|3[01])$"),
// [Soft] 날짜에 대한 타입에 대한 정규식 => ex) 2022.08.03 (YYYY.MM.DD)
DATE_TYPE3("^[\\\\d]{4}\\\\.(0[1-9]|1[012])\\\\.(0[1-9]|[12][0-9]|3[01])$"),
// [Hard] 날짜에 대한 정규식 => 19xx 20xx년도에 대해서 추가함 -- 강력하게 유효성 검증
DATE_TYPE4("^(19|20)[\\\\d]{2}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$"),
// 날짜에 대한 정규식 - YYYY/MM/DD hh:mi:ss
DATE_TYPE5("([0-2][0-9]{3})\\\\/([0-1][0-9])\\\\/([0-3][0-9]) ([0-5][0-9]):([0-5][0-9]):([0-5][0-9])(([\\\\-\\\\+]([0-1][0-9])\\\\:00))?"),
/**
* [정규식 모음-6] 시간에 대한 정규식
*/
// 시간에 대한 타입1에 대한 정규식 => ex) 13:47(HH24:mm)
TIME_TYPE1("^([1-9]|[01][0-9]|2[0-3]):([0-5][0-9])$"),
/**
* [정규식 모음-7] IPV4, IVP6 정규식
*/
// IPV4 정규식 패턴
IPV4_ADDR("^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"),
// IPV6 정규식 패턴
IPV6_ADDR("^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4}|([0-9A-Fa-f]{1,4}:){1,7}:|([0-9A-Fa-f]{1,4}:){1,6}:[0-9A-Fa-f]{1,4}|([0-9A-Fa-f]{1,4}:){1,5}(:[0-9A-Fa-f]{1,4}){1,2}|([0-9A-Fa-f]{1,4}:){1,4}(:[0-9A-Fa-f]{1,4}){1,3}|([0-9A-Fa-f]{1,4}:){1,3}(:[0-9A-Fa-f]{1,4}){1,4}|([0-9A-Fa-f]{1,4}:){1,2}(:[0-9A-Fa-f]{1,4}){1,5}|[0-9A-Fa-f]{1,4}:((:[0-9A-Fa-f]{1,4}){1,6})|:((:[0-9A-Fa-f]{1,4}){1,7}|:)|fe80:(:[0-9A-Fa-f]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9A-Fa-f]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])))$"),
// IPV4 OR IPV6 정규식 패턴
IPV4_IPV6_ADDR("(" + IPV4_ADDR + "|" + IPV6_ADDR + ")");
private final String pattern;
RegExpEnum(String pattern) {
this.pattern = pattern;
}
public String getPattern() {
return this.pattern;
}
}
💡 [사용예시]
- enum으로 구성된 정규식의 메서드를 호출하여 각각 요소를 테스트합니다.
import static com.adjh.multiflexapi.model.enums.RegExpEnum.PATTERN_CHAR;
String str1 = "hellow"; // 문자열로만 구성
String str2 = "hellow23"; // 문자열과 숫자로 구성
String str3 = "안녕하세요 :D"; // 문자열과 특수문자로 구성
String tabStr = "hellow "; // 탭이 포함된 문자열
String spaceStr = "hellow "; // 스페이스바가 포함된 문자열
/*
* 문자열 [(a-z, A-Z, 0-9, …)]이 맞는지에 대한 정규식을 수행합니다. (탭, 공백 허용 X)
* "^[\\\\w]*$" 정규식 패턴을 사용
*/
Boolean isCheckStr1 = Pattern.matches(PATTERN_CHAR.getPattern(), str1); // true
Boolean isCheckStr2 = Pattern.matches(PATTERN_CHAR.getPattern(), str2); // true
Boolean isCheckStr3 = Pattern.matches(PATTERN_CHAR.getPattern(), str3); // false
Boolean isCheckStr4 = Pattern.matches(PATTERN_CHAR.getPattern(), tabStr); // false
Boolean isCheckStr5 = Pattern.matches(PATTERN_CHAR.getPattern(), spaceStr); // false
💡[참고] 해당 정규식에 대해 궁금하시면 아래의 글을 참고하시면 도움이 됩니다.
오늘도 감사합니다. 😀
반응형