예외 처리( try~catch )
try {
정상 명령문;
} catch(예외 클래스 e) {
예외 시 명령문;
} catch(예외 클래스 e) {
예외 시 명령문;
}
- 프로그램 실행 중에 사용자의 부주의 등으로 인하여 예기치 않는 상황이 발생하는 것을 "예외"라고 하며 이것을 처리하는 것을 "예외 처리"라고 한다.
- 자바에서 range 범위 초과나 기타 에러가 발생하였을 경우에 예외처리를 하여 오류 시 프로그램이 비정상 종료되는 것을 막을 수 있다.
- 하나의 try 안에 여러개의 catch가 올 수 있다. 근데 각 동작마다 예외처리를 주게되면 너무 타이트하고 코드 가독성이 떨어지고 비효율적이므로, 가장 부모 클래스인 Exception하나만 이용하여 모든 예외처리를 할 수 있다. 근데 또 이렇게 되면 너무 러프해지기 때문에 특정 조건의 예외처리문만 몇개 추가하고 싶을때는 해당 예외처리 클래스만 예외처리 하고 나머지는 Exception으로 하면 이런 문제를 해결할 수 있다.
아래 예시처럼 부모인 Exception이 가장 나중에 와야함.
(단, 예외 처리의 범위가 작은 것 부터 와야함.)
catch (ArithmeticException e) {
}
// ..
// ..
// ..
catch (Exception e) {
}
finally
- finally로 감싸져 있을 경우 예외 발생 여부와 상관 없이 무조건 실행된다.
catch (ArithmeticException e) {
}
catch (Exception e) {
}
finally {
System.out.println("무조건 실행 됌");
}
메소드에서 예외 처리하는 두가지 방법
1. 호출 당한 메소드 안에서 직접 try ~ catch 처리
호출당한 calcDiv() 에서 예외처리
public static void calcDiv(int a, int b) {
try {
int div = a/b;
System.out.println("나누기 결과: "+div);
}
catch(ArithmeticException e) {
System.out.println("0으로 나눌 수 없어요");
}
}
2. 메소드를 호출하는 쪽에 예외처리를 맡긴다 (throws 사용)
- 해당 메소드 맨 뒤에 [throws 예외클래스] 를 추가하여 예외처리를 호출한 쪽에 맡기기
public static void 메소드명 throws 예외클래스명1, 예외클래스명2{
호출한 main()에서 직접 예외처리
public static void calcDiv(int a, int b) throws ArithmeticException {
int div = a/b;
System.out.println("나누기 결과: "+div);
System.out.println("0으로 나눌 수 없어요");
}
public static void main(String[] args) {
try {
calcDiv(9,3);
}catch (ArithmeticException e) {
System.out.println("0으로 나눌수 없어요!");
}
}
RuntimeException 과 이외의 예외처리 특성
1. RuntimeException
예외처리의 종류는 크게 RuntimeException 이냐 아니냐로 나눌 수 있다.
- RuntimeException의 자식들은 사용자가 예외처리를 하지 않아도 컴파일이 가능하고 자바가 예외처리를 해줍니다.
- 물론, 필요하다면 사용자가 직접 예외처리를 할 수도 있음
- 실행이 된다는 것 자체가 자바가 예외처리를 해준거임 (에러가 나와도 에러가 나오는 거 자체가 예외처리 된거임)
예시) ArithmeticException은 RuntimeException의 후손
2. RuntimeException 이 아닐 경우
- 그러나 RuntimeException의 자식이 아닌 것들은 사용자가 반드시 직접 예외처리를 해야한다.
- 만약 사용자가 직접 예외처리를 하지 않으면 컴파일이 되지 않는다.
예시) IOException
public FileWriter(String fileName) throws IOException
- FileWriter 예외처리시 사용되는 IOException은 RuntimeException 자식이 아니기 때문에 필수적으로 예외처리를 해줘야한다. (IOException)
- IOExcepton은 바로 Exception을 상속 받음
FileWriter 실행 시 에러 (예외처리 안해서)
IOException 예외처리 완료
아래 예시 IOException은 RuntimeException의 자식이 아니므로 try ~ catch로 직접 예외해줘야함
try {
FileWriter fw = new FileWriter("c:/temp/hello.txt");
fw.write("hello java");
fw.close();
System.out.println("파일이 생성되었습니다.");
}catch(IOException e) {
System.out.println("예외가 발생");
System.out.println(e.getMessage());
}
강제로 예외 발생 시키기 (throw)
- 때로는 강제로 예외를 발생시켜야 할 경우도 존재하는데 그때는 throw 키워드를 사용 (throws랑 헷갈리지 말것)
- 강제로 예외 발생시켰는데 RuntimeException의 자식이 아니면 당연히 try ~ catch 로 예외처리 해야함
throw new 예외클래스이름("메세지 입력 가능");
System.out.println("hello");
throw new ArithmeticException();
throws - 메소드 안에서 예외 발생 시 메소드를 호출한 쪽에서 예외처리를 할 수 있도록 하는 키워드
throw - 강제로 예외를 발생 시키는 키워드
사용자 정의 예외 만들기
- 예외 처리 클래스를 생성
- throw new [예외처리클래스이름]
class 예외클래스이름 extends Exception{
생성자(String msg){
super(msg);
}
}
class NotFoundException extends Exception {
public NotFoundException(String msg) {
super(msg);
}
}
StringTokenizer
- 특정 델리미터로 배열 분리가능. (String.join 이랑 비슷한 개념인듯)
nextToken() : 하나씩 꺼내옴
hasMoreTokens() : 내용이 있으면 true, 내용이 없으면 false
String data = "홍길동,이순신,유관순,김유신";
StringTokenizer st =new StringTokenizer(data, ",");
String a = st.nextToken(); //홍길동
String b = st.nextToken(); //이순신
String c = st.nextToken(); //유관순
String d = st.nextToken(); //김유신
System.out.println(a);
System.out.println(b);
System.out.println(c);
System.out.println(d);
String data = "홍길동,이순신,유관순,김유신";
StringTokenizer st =new StringTokenizer(data, ",");
while(st.hasMoreTokens()) {
String name = st.nextToken();
System.out.println(name);
}
자바 컬렉션
- 컬렉션은 자료형이 다른것도 담을 수 있다
- 컬레션은 동적인 배열로써 자료의 추가, 삭제가 용이하다
- 데이터를 담는 것 만큼 혹은 데이터를 삭제하는 것 만큼 자동으로 크기가 늘어나고 줄어든다
Set
- 중복된 자료를 허용하지 않음
HashSet - 중복불가, 순서를 유지하지 않음
LinkedHashSet - 중복불가, 순서 유지
TreeSet - 정렬시켜줌
TreeSet에서 유용한 함수
- subSet(1, 10) - set 배열에서 1~9가지의 숫자를 반환 가능
List
- 중복된 자료를 허용 , 순서 유지
ArrayList - 중복된 자료를 허용 , 순서 유지
LinkedList - 중복된 자료를 허용 , 순서 유지
이 두개는 사용법이 동일하나 내부 로직이 조금 다름.
ArrayList 와 LinkedList 차이
- 자료의 추가 삭제가 빈번 할 경우 LinkedList 가 효율적이다
- 그렇지 않을 경우 ArrayList가 용이하다
.remove(인덱스) 로 데이터 삭제 가능
1. ArrayList의 동작 방식
- 데이터 추가 및 삭제하면 해당 데이터 추가 및 삭제 후 한칸씩 늘리고 줄이는 과정을 거침
ArrayList<String> data = new ArrayList<String>();
data.add("홍길동");
data.add("010-1234-5678");
data.add("서울시 마포구 서교동");
System.out.println("이름:" + data.get(0));
System.out.println("전화:" + data.get(1));
System.out.println("주소:" + data.get(2));
2. LinkedList
- 각각 노드가 잡혀있고 1번 노드에 '데이터 1'이 담겨있고 2번 노드의 주소를 가리킴. 2번노드에는 '데이터 2'가 담겨있고 3번노드를 가리킴. 그래서 데이터의 추가 / 삭제할 때, 추가할 노드만 추가해주면 되서 더 로직상 간편함
LinkedList<String> list = new LinkedList<String>();
list.add("사과");
list.add("포도");
list.add("수박");
list.add("포도");
list.add("오렌지");
System.out.println(list);
System.out.println(list.get(0));
list.remove(1);
System.out.println(list);
list.add(0, "체리");
System.out.println(list);
Map
put 을 이용하여 데이터를 넣음
get을 이용하여 데이터를 받음
- key와 value가 한 쌍으로 이루어져 있는 자료구조
- 키의 중복을 허용하지 않음
- 만약 중복된 키값을 추가하게 되면 원래의 값을 반환하고 새로운 값을 저장한다.
hashmap
- 만약에 중복 키를 입력하면 원래있는 값을 반환하고 중복 키를 새로운 값으로 저장
- 없는 키를 요청하면 null 반환
- 순서를 유지하지 않음
HashMap<String, String> data = new HashMap<String, String>();
data.put("name","홍길동");
data.put("phone","010-1234-5678");
data.put("addr","서울시 마포구 서교동");
System.out.println("이름:" + data.get("name"));
System.out.println("전화" + data.get("phone"));
System.out.println("주소:" + data.get("addr"));
Linkedhashmap
- 입력한 순서를 유지
LinkedHashMap<String, String> map2 = new LinkedHashMap<String, String>();
map2.put("이름", "홍길동");
map2.put("나이", "20");
map2.put("주소", "서울");
System.out.println(map2);
TreeMap
- 키를 기준으로 정렬
TreeMap<String, String> map3 = new TreeMap<String, String>();
map3.put("이름", "홍길동");
map3.put("나이", "20");
map3.put("주소", "서울");
System.out.println(map3);
이클립스 실행시 입력 값 넘기기
- args 배열을 이용하여 입력 값을 실행 시에 넘기기
상단 Run - Run Configurations - Argument
입력 값 입력하기 (띄어쓰기 기준으로 구분)
반응형
'개발 > 교육' 카테고리의 다른 글
(Java)15일차 (0) | 2022.04.15 |
---|---|
(Java)13일차 (0) | 2022.04.13 |
(Java) 9일차 (0) | 2022.04.07 |
(Java) 7일차 (0) | 2022.04.05 |
(Java) 6일차 (0) | 2022.04.04 |
댓글