코딩 기록들

[Java Programming] 10.3 사용자 예외 발생시키기 본문

Java

[Java Programming] 10.3 사용자 예외 발생시키기

코딩펭귄 2024. 1. 30. 17:19

Java에서 제공하는 내장 ExceptionJava Application이 동작할 때, 코드의 조건을 만족하지 못했을 때 :

-> 지정된 Exception이 발생하도록 되어있음

개발자가 직접 조건을 정의하고 지정된 Exception을 발생시킬 수도 있음 -> 사용자 예외, 커스텀 예외

ex) 사용할 수 없는 ID 입니다. / 이미 사용중인 ID 입니다 / ID는 최소 8글자 이상 입력하세요 / 비밀번호는 영어, 숫자, 특수기호를 사용해 10자리이상 입력하세요 등등

 

 

사용자 예외는 항상, 반드시 RuntimeException을 상속받아 생성

public class InvalidUserIdException extends RuntimeException{
}

 

- RuntimeException오버로딩된 생성자들 -

 

public class RuntimeException extends Exception {

//기본생성자 : 예외를 발생시킬때 아무런값도 전달하지 않음 -> 예외 받았을때 아무런 정보를 사용자가, 개발자가 받을수 없음 (안씀)

    public RuntimeException() {

        super();

    }

// 예외를 발생시킬 때 원인이 된 메시지를 파라미터로 전달 (아래 메소드 2개를 가장 많이 사용)

    public RuntimeException(String message) { 

        super(message);

    }

// Throwable은 모든 예외들의 Root Class임. 

// 메소드가 exception던지면 반드시 try-catch가 필요함. 하지만 runtimeException던지면 if문만으로 처리가 가능함.( try-catch 필요없음)

// 보통 try ~ catch 에서 처리한 ExceptionRuntimeException으로 변경하여 다시 발생시킬 때 주로 사용

// message : 예외를 발생시킨 원인이 되는 메시지 전달

// cause : catch에서 처리한 예외 전달 (RuntimeException이 발생된 원인이 됨)

// 해당 예외가 개발자뿐만 아니라 사용자에게까지 전달됨

    public RuntimeException(String message, Throwable cause) {

        super(message, cause);

    }

//해당예외는 개발자범위에서 핸들링함 (실제론, 사용안함)

// 예외를 발생시킬 때 원인이 된 예외를 파라미터로 전달

    public RuntimeException(Throwable cause) { 

        super(cause);

    }

 

InvalidUserIdException을 발생시키기 - idroot, admin, system 인 경우 위 예외를 발생시키는 코드 ( throw Exception객체 코드를 통해서 예외를 발생 )
public static void main(String[] args) {
 
    Scanner input = new Scanner(System.in);
    System.out.println("ID를 입력하세요.");
    String userId = input.nextLine();
    if (userId.equals("root") || userId.equals("admin") 
        || userId.equals("system")) {
        InvalidUserIdException iuie = 
               //new InvalidUserIdException(userId + "는 사용할 수 없습니다.");
        //throw iuie;
        // 예외를 발생시킬 경우는 위 두줄을 합쳐 아래 코드처럼 한 줄로 사용
        throw new InvalidUserIdException(userId + "는 사용할 수 없습니다.");
    }
}

자바어플리케이션에서는 의미가 없지만, 웹어플리케이션에서는 굉장히 중요함

 

실무에서는 .printStackTrace(); 사용하지 말것

- 민감한 코드가 노출되기 때문

- 굉장히 긴 코드가 출력되기 때문 -> CPU, 램을 굉장히 많이 소비함

 

예제 : id가 root, admin, system 인 경우 위 예외를 발생시키는 코드 다시 만들어보기

- 만드는 클래스는 (예외이기 때문에)~exception으로 끝나기

- 모든 사용자예외는 RuntimeException 상속(extends) 받는다

package exception_handling.exceptions;
/**
 * 시스템 계정으로 회원가입을 하려는 시도를 막아주는 예외
 */
public class InvalidUserIdException extends RuntimeException{ //extends RuntimeException 이게 있어야 사용자예외(custom)임

	private static final long serialVersionUID = 7295367015806491807L; 
	
	// InvalidUserIDException 생성자 만들기 (필요한 생성자만 호출해주면 됨)
	public InvalidUserIdException(String message) {
		//받은메시지를 런타임으로 보내주겠다
		super(message);
	}
	public InvalidUserIdException(String message, Throwable cause) {
		super(message, cause);
	}
}
package exception_handling.exceptions;
/**
 * 이미 가입된 아이디로 회원가입을 시도할 때 발생할 예외
 */
public class AlreadyUseUserIdException extends RuntimeException {

	private static final long serialVersionUID = 6484701918827388900L;
	
	public AlreadyUseUserIdException(String message) {
		super(message);
	}
	public AlreadyUseUserIdException(String message, Throwable cause) {
		super(message, cause);
	}
}
package exception_handling.exceptions;
/**
 * 파일을 읽을 수 없을 때 발생하는 예외
 */
public class ReadFailException extends RuntimeException{

	private static final long serialVersionUID = 2588425091797741407L;
	
	public ReadFailException(String message) {
		super(message);
	}
	public ReadFailException(String message, Throwable cause) {
		super(message, cause);
	}
}
package exception_handling.exceptions;
/**
 * 8글자 미만의 아이디로 회원가입 시도할때 발생할 예외
 */
public class UserIdLengthException extends RuntimeException {

	private static final long serialVersionUID = 3586920514556025639L;

	public UserIdLengthException(String message) {
		super(message);
	}
	public UserIdLengthException(String message, Throwable cause) {
		super(message, cause);
	}
}

실행코드

package exception_handling;

import java.util.Scanner;

import exception_handling.exceptions.AlreadyUseUserIdException;
import exception_handling.exceptions.InvalidUserIdException;
import exception_handling.exceptions.UserIdLengthException;

public class MemberJoin {

	public void join() {
		
		Scanner keyboard = new Scanner(System.in);
		
		System.out.println("Id를 입력하세요");
		String id = keyboard.nextLine();
		
		if (id != null &&
			id.equals("system") ||
			id.equals("root") || 
			id.equals("admin")) {
			throw new InvalidUserIdException(id + "는 사용할 수 없습니다.");
		}
		else if(id != null && 
				 id.equals("ktds")) {
			throw new AlreadyUseUserIdException(id + "는 이미 사용중입니다.");
		}
		else if (id != null &&
				  id.length() < 8) {
			throw new UserIdLengthException("Id는 최소 8글자이상 입력하세요.");
		}
		// id는 null값이 될 수 없으므로 아래코드는 dead code 
		//-> String id = keyboard.nextLine();로 인해 키보드에서 아무것도 안쓰고 엔터쳐도 \n\r 이 붙어있으므로 (\n : 엔터쳐라, \r : 다음줄)
		//else if (id == null) {
		//throw new InvalidUserIdException("Id는 필수입력값입니다.");
		//}
		else { // 이 과정을 다 패스한것
			System.out.println(id + "로 가입을 완료했습니다.");
		}	
	}
	public static void main(String[] args) {
		MemberJoin memberJoin = new MemberJoin();
		memberJoin.join();
	}
}
package exception_handling;

import java.io.File;
import java.nio.file.Files;
import java.util.List;
import exception_handling.exceptions.ReadFailException;
import java.io.IOException;

public class TryCatchExamUserException {

	// 사용자예외처리 2번째 이점
	// try-catch 안에도 에러가 발생한 원인 적어주는것
	public static List<String> readFile2(File path){
		try {
			return Files.readAllLines(path.toPath());
		}
		catch (IOException ioe) {
			throw new ReadFailException("파일을 읽을 수 없습니다.", ioe); //exception_handling.exceptions.ReadFailException: 파일을 읽을 수 없습니다.
		}
	}
    
public static void main(String[] args) {
		
	// 시스템 드라이브에서 특정경로에 있는 파일 또는 폴더를 읽어온다.
	File imageFile = new File("c:\\sdfsdfsdf"); //생성자 뭐가있는지 궁금할땐 괄호쓰지않고 생성자 이름만쓰고 ctrl space
		
	//이점2
	readFile2(imageFile);
}