catch
finaly
예시 코드
package exception1;
public class Exception1 {
public static void main(String[] args) {
int i = 10;
int j = 0;
// int k = i/j; //ArithmeticException 발생, 예외 발생 시점부터 마지막 코드까지 실행 안하고 프로그램 중단 O
// System.out.println(k);
try{
System.out.println("예외처리 적용");
int k = i/j; //예외 발생 시점 부터 try의 나머지 코드는 실행하지 않는다
System.out.println(k);
}catch(Exception e){ //try 문 내부에서 예외 발생 시, catch문 내용 실행 -> 프로그램 중단 X
System.out.println("오류 발생 : " + e.toString());
}finally {
System.out.println("오류 발생하든 안하든 실행되는 부분");
}
System.out.println("main 종료");
}
}
/* 실행 결과
예외처리 적용
오류 발생 : java.lang.ArithmeticException: / by zero
오류 발생하든 안하든 실행되는 부분
main 종료
*/
catch
의 “예외클래스” 부분에는 다양한 예외클래스가 들어갈 수 있다.ArithemticException e
를 넣어도 되고, 예상 가능한 특정 예외클래스를 넣어도 된다.Exception e
는 모든 예외를 포괄하는 예외클래스이다.try
부분에서 예외 발생 시, catch
로 파라미터가 넘어옵니다..toString()
메서드를 사용하여 파라미터로 넘어온 예외의 내용을 확인할 수 있습니다.thorws
를 사용하면, 메서드를 호출한 곳에서 예외를 처리하도록 예외를 전달합니다.package thorws1;
public class Throws1 {
public static void main(String[] args) {
int i = 10;
int j = 0;
try{
int k = divide(i, j); // 메서드 호출 과정에서 예외 발생 시, catch 문으로 예외 전달
System.out.println(k);
}catch (Exception e){
System.out.println(e.toString());
}
System.out.println("예외 처리를 잘 했군요!");
}
// 호출되는 메서드 내부에서 예외발생이 예상된다면 "throws 예외클래스"를 사용해
// 프로그램이 중단되는 것이 아닌, 발생하는 예외를 전달시킬 수 있습니다.
public static int divide(int i, int j) throws Exception{
return i/j;
}
}
/* 실행 결과
java.lang.ArithmeticException: / by zero
예외 처리를 잘 했군요!
*/
Exception
이라는 “예외클래스” 부분에 다른 “예외클래스”들을 넣을 수 있습니다.💡 우리가 예상되는 예외를 먼저 발생시켜서 확실하게 예외를 제어할 수 있다.
package throw1;
public class Throw1 {
public static void main(String[] args) {
int i = 10;
int j = 0;
try{
int a = divde(i, j);
System.out.println(a);
}catch (IllegalArgumentException e) {
System.out.println(e.toString());
}catch (Exception e){ //catch 문은 예외에 따라 여러개 사용 가능
System.out.println("나머지 예외 처리 " + e.toString());
}
System.out.println("예외 처리를 잘 했군요!");
}
public static int divde(int i, int j) throws new IllegalArgumeneException{
if(j == 0){
throw new IllegalArgumentException("두번째 인자로 0이 들어올 수 없습니다.");
}
return i/j;
}
}
Java에서 예외는 크게 두 가지로 나눌 수 있습니다
예시 코드
package bizexception;
public class Bizexception extends RuntimeException{ //RuntimeException을 상속받는다
public Bizexception(String msg){
super(msg);
}
}
RuntimeException 클래스를 상속받는 Bizexception 클래스 생성
예외 역할을 하는 클래스의 경우 Exception 또는 RuntimeException 클래스를 상속받아야 한다.
예외 클래스의 생성자의 매개변수
- 기본 생성자 가능 (매개변수 없음)
- 전송 메세지만 받기 가능
- 예외클래스만 받기 가능
- 전송 메세지, 예외클래스 모두 받기 가능
package bizexception;
public class Bizservice {
public void bizMethod(int a){
System.out.println("bizMethod 시작");
if(a < 0){
throw new Bizexception("매개변수 a는 0 보다 작을 수 없습니다");
}
System.out.println(a);
System.out.println("bizMethod 종료");
}
}
Bizexception의 경우, RuntimeException의 자식 클래스이기에 bizMethod에서 throws 생략 가능
package bizexception;
public class Bizmain {
public static void main(String[] args) {
Bizservice bizservice = new Bizservice();
try{
bizservice.bizMethod(10);
bizservice.bizMethod(-3);
}catch (Exception e){
System.out.println(e.toString());
}
}
}
/* 실행 결과
bizMethod 시작
10
bizMethod 종료
bizMethod 시작
bizexception.Bizexception: 매개변수 a는 0 보다 작을 수 없습니다
*/
Object클래스는 모든 클래스의 최상위 클래스
아무것도 상속받지 않으면 자동으로 Object를 상속
Object가 가지고 있는 메소드는 모든 클래스에서 다 사용할 수 있다는 것을 의미
대표적인 Object 클래스의 부모 메서드
public class WrapperExam {
public static void main(String[] args) {
int i = 5;
Integer i2 = new Integer(5); //과거 메서드를 통한 형변환
Integer i3 = 5; //오토박싱
int i4 = i2.intValue(); //과거 메서드를 통한 형변환
int i5 = i2; //오토언박싱
// 기본형 변수에서는 필드나 메서드를 가지고 있지 않기에 사용할 수 없다.
//int j = 10;
//int i6 = j.intValue();
//long i7 = j.longValue();
}
}
public class StringBufferPerformanceTest{
public static void main(String[] args){
// (1) String의 +연산을 이용해서 10,000개의 *를 이어붙입니다.
//시작시간을 기록합니다.(millisecond단위)
long startTime1 = System.currentTimeMillis();
String str="";
for(int i=0;i<10000;i++){
str=str+"*";
}
//종료시간을 기록합니다.(millisecond단위)
long endTime1 = System.currentTimeMillis();
// (2) StringBuffer를 이용해서 10,000개의 *를 이어붙입니다.
//시작시간을 기록합니다.(millisecond단위)
long startTime2 = System.currentTimeMillis();
StringBuffer sb = new StringBuffer();
for(int i=0;i<10000;i++){
sb.append("*");
}
//종료시간을 기록합니다.(millisecond단위)
long endTime2 = System.currentTimeMillis();
// 방법(1)과 방법(2)가 걸린 시간을 비교합니다.
long duration1 = endTime1-startTime1;
long duration2 = endTime2-startTime2;
System.out.println("String의 +연산을 이용한 경우 : "+ duration1);
System.out.println("StringBuffer의 append()을 이용한 경우 : "+ duration2);
}
}
/* 실행 결과
String의 +연산을 이용한 경우 : 24
StringBuffer의 append()을 이용한 경우 : 1
*/
🔥 앞으로 StringBuffer / StringBuilder 를 자주 사용하도록 하자!
public class Box<E> { //클래스 선언부에 < > 를 활용
private E obj; // 입력받은 제네릭으로 필드 타입 지정
public void setObj(E obj){ // 입력받은 제네릭으로 매개변수 타입 지정
this.obj = obj;
}
public E getObj(){ // 입력받은 제네릭으로 메서드 반환 타입 지정
return obj;
}
}
선언시의 제네릭 부분에는 명시되어있는 클래스가 들어갈 수 있다.
가상클래스를 이용하고 싶다면 클래스로서 값을 가지지않는 제네렉명을 넣고
- 변수 선언시에 제네릭을 지정해주면 된다.
- 변수 선언시에 제네릭을 지정하지 않으면 자동으로 Object 클래스로 지정된다.
public class BoxExam {
public static void main(String[] args) {
Box<Object> box = new Box<>(); //필드 obj의 타입을 Object로 결정
box.setObj(new Object());
Object obj = box.getObj();
Box<String> box2 = new Box<>(); //필드 obj의 타입을 String으로 결정
box2.setObj("hello");
String str = box2.getObj();
System.out.println(str);
Box<Integer> box3 = new Box<>(); //필드 obj의 타입을 Integer로 결정
box3.setObj(1);
int value = (int)box3.getObj();
System.out.println(value);
//제네릭 설정 안하면 자동으로 Object로 결정
Box box4 = new Box(); //필드 obj의 타입은 Object로 설정됨
box4.setObj("hello");
String str = box4.getObj();
System.out.println(str);
}
}
package collection0;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class Set0 {
public static void main(String[] args) {
Set<String> set = new HashSet<>();
set.add("cha");
set.add("jae");
set.add("hyeon");
//set.add("cha"); // 이미 set에 중복된 정보가 있기에 "cha"가 추가되지 않으며, false 반환
System.out.println(set.size());
Iterator<String> itr = set.iterator();
while(itr.hasNext()){
System.out.println(itr.next());
}
// Iterator 변수에서 next()는 현재 값을 읽고, 다음으로 읽을값의 위치를 정합니다.
// Iterator 변수에서 hasNext()는 next()에 의해 결정된 다음으로 읽을값이 있는지를 확인합니다.
// while(set.iterator().hasNext()){ // 계속 새로운 Iterator 변수를 만들어내며, next()로 읽을 위치를 지정하지 않기에 무한 루프
// System.out.println(itr.next()); // itr에서 다음에 읽을 수 있는 값이 없는데 읽으려고해서 NoSuchElementException 발생
// }
// while(itr.hasNext()){ // next()로 itr의 다음으로 읽을 값을 지정하지 않기에 무한 루프
// System.out.println(set.iterator().next()); // 계속 새로운 Iterator 변수를 만들어내기에, 맨 처음 값만 출력
// }
}
}
import java.util.ArrayList;
import java.util.List;
public class ListExam {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
// list에 3개의 문자열을 저장합니다.
list.add("kim");
list.add("lee");
list.add("kim");
System.out.println(list.size()); //list에 저장된 자료의 수를 출력 (중복을 허용하므로 3 출력)
for(int i = 0; i < list.size(); i++){
String str = list.get(i); //List는 순서를 가지고 있기에 특정 위치의 데이터 확인 가능
System.out.println(str);
}
}
}
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class MapExam {
public static void main(String[] args) {
// Key, Value가 모두 String 타입인 HashMap인스턴스를 만듭니다.
Map<String, String> map = new HashMap<>();
// key와 value값을 put으로 저장합니다.
map.put("001", "kim");
map.put("002", "lee");
map.put("003", "choi");
// 같은 key가 2개 있을 수 없습니다. 첫번째로 저장했던 001, kim은 001, kang으로 바뀐다.
map.put("001", "kang");
// map에 저장된 자료의 수를 출력합니다. 3이 출력됩니다.
System.out.println(map.size());
// 키가 001, 002, 003인 값을 꺼내 출력합니다.
System.out.println(map.get("001"));
System.out.println(map.get("002"));
System.out.println(map.get("003"));
// map에 저장된 모든 key들을 Set자료구조로 꺼냅니다.
Set<String> keys = map.keySet(); //반환되는 key의 타입에 맞추어 Set의 제네릭 지정
// Set자료구조에 있는 모든 key를 꺼내기 위하여 Iterator를 구합니다.
Iterator<String> iter = keys.iterator();
while (iter.hasNext()) {
// key를 꺼냅니다.
String key = iter.next();
// key에 해당하는 value를 꺼냅니다.
String value = map.get(key);
// key와 value를 출력합니다.
System.out.println(key + " : " + value);
}
}
}