예외 클래스를 만들어 예외를 정의
class OurBadException extends Exception {
public OurBadException() {
super("위험한 행동을 하면 예외처리를 꼭 해야합니다!");
}
}
class OurClass {
private final Boolean just = true;
public void thisMethodIsDangerous() throws OurException {
if (just) {
throw new OurException();
}
}
}
- 메서드를 실행했을 경우, 그 메서드가 위험하다는 것을 미리 예측
- 예측된 메서드를 throw 메서드를 통해 위험하다고 알림
public class StudyException {
public static void main(String[] args) {
OurClass ourClass = new OurClass();
try {
// 1. 위험한 메소드의 실행을 "시도"
// "시도" 해보는 코드가 들어가는 블럭
ourClass.thisMethodIsDangerous();
} catch (OurException e) { // 어떤 예외를 받아 처리 할지 정함 (모든 예외면 Exception)
// 2. 예외가 발생하면, "잡아서" handling 합니다.
// 예외가 발생하는경우 "handling" 하는 코드가 들어가는 블럭
// 즉 try 블럭 내의 구문을 실행하다가 예외가 발생하면
// 예외가 발생한 줄에서 바로 코드 실행을 멈추고
// 여기 있는 catch 블럭 내의 코드가 실행
// 여러개의 catch문 사용 가능
System.out.println(e.getMessage());
} finally {
// 3. 예외의 발생 여부와 상관없이, 실행시켜야 하는 코드
// 무조건 실행되는 코드가 들어가는 블럭
System.out.println("우리는 방금 예외를 handling 했습니다!");
}
}
}
throw (메서드 안에) & throws (클래스 뒤에)

Throwable Class

initCause()getCause()// 연결된 예외
public class main {
public static void main(String[] args) {
try {
// 예외 생성
NumberFormatException ex = new NumberFormatException("가짜 예외이유");
// 원인 예외 설정(지정한 예외를 원인 예외로 등록)
ex.initCause(new NullPointerException("진짜 예외이유"));
// 예외를 직접 던집니다.
throw ex;
} catch (NumberFormatException ex) {
// 예외 로그 출력
ex.printStackTrace();
// 예외 원인 조회 후 출력
ex.getCause().printStackTrace();
}
// checked exception 을 감싸서 unchecked exception 안에 넣습니다.
throw new RuntimeException(new Exception("이것이 진짜 예외 이유 입니다."));
}
}
// 출력
Caused by: java.lang.NullPointerException: 진짜 예외이유
public String getDataFromAnotherServer(String dataPath) {
try {
return anotherServerClient.getData(dataPath).toString();
} catch (GetDataException e) {
return defaultData;
}
}
public void someMethod() throws Exception { ... }
public void someIrresponsibleMethod() throws Exception {
this.someMethod();
}
public void someMethod() throws IOException { ... }
public void someResponsibleMethod() throws MoreSpecificException {
try {
this.someMethod();
} catch (IOException e) {
throw new MoreSpecificException(e.getMessage());
}
}
// 1. 클래스 이름 뒤에 <> 문법 안에 들어가야 할 타입 변수를 지정
public class Generic<T> {
// 2. 선언 해둔 타입 변수는 해당 클래스 내에서 특정한 타입이 들어갈 자리에 대신 들어갈 수 있다.
private T t;
// 3. 메서드의 리턴타입에 들어가는 것 역시 마찬가지
public T get() {
return this.t;
}
public void set(T t) {
this.t = t;
}
public static void main(String[] args) {
// 4. 클래스에 선언했기 때문에 인스턴스를 만들기 위해서 타입변수에 들어갈 실제 변수의 값을 넣어줘야함
Generic<String> stringGeneric = new Generic<>();
// 5. 타입변수로 대체 해뒀던 곳에 String이 들어가있기 때문에, 이와 같이 사용
stringGeneric.set("Hello World");
String tValueTurnOutWithString = stringGeneric.get();
System.out.println(tValueTurnOutWithString);
}
}
용어
제한
문법
public class Generic<T, U, E> {
public E multiTypeMethod(T t, U u) { ... }
}
Generic<Long, Integer, String> instance = new Generic();
instance.multiTypeMethod(longVal, intVal);
HW4
Main.javapackage hw.week04;
public class Main {
public static void main(String[] args) {
boolean calculateEnded = false;
// 구현 2.
while (!calculateEnded) {
try {
calculateEnded = CalculatorApp.start();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
System.out.println("계산이 끝났습니다.");
}
}
Parser.java
package hw.week04;
import java.util.Objects;
import java.util.regex.Pattern;
public class Parser {
private static final String OPERATION_REG = "[+\\-*/%]";
private static final String NUMBER_REG = "^[0-9]*$";
private final Calculator calculator = new Calculator();
public Parser parseFirstNum(String firstInput) throws BadInputException {
// 구현 1.
if (!Pattern.matches(NUMBER_REG, firstInput)) {
throw new BadInputException("Number값");
}
this.calculator.setFirstNumber(Integer.parseInt(firstInput));
return this;
}
public Parser parseSecondNum(String secondInput) throws BadInputException {
// 구현 1.
if (!Pattern.matches(NUMBER_REG, secondInput)) {
throw new BadInputException("Number값");
}
this.calculator.setSecondNumber(Integer.parseInt(secondInput));
return this;
}
public Parser parseOperator(String operationInput) throws BadInputException {
// 구현 1.
if (!Pattern.matches(OPERATION_REG, operationInput)) {
throw new BadInputException("Operand값");
}
if (Objects.equals("+", operationInput)) this.calculator.setOperation(new AddOperation());
else if (Objects.equals("-", operationInput)) this.calculator.setOperation(new SubstractOperation());
else if (Objects.equals("*", operationInput)) this.calculator.setOperation(new MultiplyOperation());
else if (Objects.equals("/", operationInput)) this.calculator.setOperation(new DivideOperation());
else if (Objects.equals("%", operationInput)) this.calculator.setOperation(new RemainOperation());
return this;
}
public double executeCalculator() {
return calculator.calculate();
}
}
CalculatorApp.java
package hw.week04;
import java.util.Scanner;
public class CalculatorApp {
public static boolean start() throws Exception{
Parser parser = new Parser();
Scanner scanner = new Scanner(System.in);
System.out.println("첫번째 숫자를 입력해주세요!");
String firstInput = scanner.nextLine();
parser.parseFirstNum(firstInput);
System.out.println("연산자를 입력해주세요!");
String operator = scanner.nextLine();
parser.parseOperator(operator);
System.out.println("두번째 숫자를 입력해주세요!");
String secondInput = scanner.nextLine();
parser.parseSecondNum(secondInput);
System.out.println("연산 결과 : " + parser.executeCalculator());
return true;
}
}
BadInputException.java
package hw.week04;
public class BadInputException extends Exception {
public BadInputException(String type) {
super("잘못된 입력입니다! " + type + "을 입력해주세요!");
}
}