목차
클래스 변수와 클래스 메서드
1. 클래스 변수
1.
모든 인스턴스가 공통된 저장공간을 공유
2.
인스턴스를 생성하지 않고 사용 가능
3.
생성시기 : 클래스가 메모리에 로딩될 때
4.
‘클래스이름.클래스변수’의 형식으로 사용
class AccessWay {
static int num = 0;
AccessWay() { incrCnt(); }
void incrCnt() {
num++; // 클래스 내부에서 이름을 통한 접근
}
}
public class Main {
public static void main(String[] args) {
AccessWay way = new AccessWay();
way.num++; // 외부에서 인스턴스의 이름을 통한 접근
AccessWay.num++; // 외부에서 클래스의 이름을 통한 접근
System.out.println("num = " + AccessWay.num);
}
}
Java
복사
num은 클래스 변수로 값을 공유한다.
1.
AccessWay 생성자 실행으로 인해 num = 1
2.
way.num++ 실행 시 num = 2
3.
AccessWay.num++ 실행 시 num = 3
public class Main {
public static void main(String[] args) {
InstCnt cnt1 = new InstCnt();
InstCnt cnt2 = new InstCnt();
InstCnt cnt3 = new InstCnt();
}
}
class InstCnt {
static int instNum = 0;
//int instNum = 0;
public InstCnt() {
instNum++;
System.out.println("인스턴스 생성 : " + instNum);
}
}
Java
복사
instNum을 클래스 변수로 선언시 모든 인스턴스가 해당 변수를 공유한다.
2. 클래스 메서드
•
인스턴스와 관계없는 메서드를 클래스 메서드로 정의
•
클래스 메서드는 인스턴스 변수를 사용할 수 없다.
◦
클래스 메서드는 인스턴스 생성 없이 호출가능하다.
◦
그러므로, 클래스 메서드가 호출되었을 때 인스턴스가 존재한다는 보장을 할 수 없다.
•
단, 인스턴스 멤버가 클래스 멤버를 사용하는 것은 문제가 없다.
◦
인스턴스 멤버가 존재한다는 것은 클래스 멤버가 이미 메모리에 존재한다는 것을 의미
예외처리
1. 정의
에러(error) vs 예외(exception)
•
에러 : 수습될 수 없는 심각한 오류 (ex. 메모리 부족, 스택오버플로우)
•
예외 : 수습될 수 있는 다소 미약한 오류
◦
RuntimeException클래스와 자손 : 프로그래머의 실수
◦
RuntimeException클래스를 제외한 모든 Exception 클래스의 자손 : 외부 영향
2. 예외처리 - try-catch(직접 처리)
1. 실행 흐름
•
예외 발생 경우
1.
발생 예외와 일치하는 catch블럭 확인
2.
일치하는 catch블럭 존재하면, 블럭 내 문장 수행
3.
전체 try-catch문을 빠져나간다.
4.
그 다음 문장 수행
5.
만약 일치하는 catch블럭이 존재하지 않으면, 비정상 종료된다.
•
예외 발생하지 않은 경우
1.
catch 블럭 거치지 않고 전체 try-catch문을 빠져나가서 수행을 계속함
try - catch문의 마지막에 Exception클래스 타입의 참조변수를 선언한 catch블럭 사용하면 모든예외 처리 가능
import java.util.InputMismatchException;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner kb = new Scanner(System.in);
try {
System.out.print("a/b...a? ");
int n1 = kb.nextInt();
System.out.print("a/b...b? ");
int n2 = kb.nextInt();
System.out.printf("%d / %d = %d \n", n1, n2, n1 / n2); // 예외 발생
} catch (ArithmeticException ae) {
ae.printStackTrace();
System.out.println("예외메시지 : " + ae.getMessage());
} catch (InputMismatchException e) {
e.printStackTrace();
System.out.println("예외메시지 : " + e.getMessage());
} catch (Exception e) {
e.printStackTrace();
System.out.println("예외메시지 : " + e.getMessage());
} finally {
System.out.println("무조건 실행");
}
System.out.println("Good bye~~!");
}
Java
복사
2. printStackTrace() & getMessage()
printStackTrace() : 예외발생 당시의 메서드 정보와 예외 메시지 출력
getMessage() : 예외 객체에 저장된 메시지
3. 멀티 catch블럭
내용이 같은 catch블럭을 하나로 합치는 것 가능
연결된 예외 클래스가 조상-자손 관계는 컴파일 에러 발생
예외 클래스들의 공통 멤버만 사용 가능
try {
...
} catch (ExceptionA e) {
e.printStackTrace();
} catch (ExceptionB e2) {
e2.printStackTrace();
}
Java
복사
try {
...
} catch (ExceptionA | ExceptionB e) {
e.printStackTrace();
}
Java
복사
4. finally 블럭
예외 발생여부와 관계없이 수행되는 코드 - try-catch문의 맨 마지막에 위치
3. 예외 발생시키기 - throw
1.
발생시키려는 예외 클래스 객체 생성
2.
throw를 이용해 예외 발생시키기
1. Exception e = new Exception("예외 발생시키기");
2. throw e;
Java
복사
checked & unchecked 예외
checked 예외
•
컴파일러가 예외 처리 여부를 체크(예외 처리 필수) → Exception클래스와 자손
•
예외 처리 하지 않으면 컴파일조차 되지 않음
unchecked 예외
•
예외 처리 선택 → RuntimeException클래스와 자손
•
예외 처리 하지 않으면 컴파일은 성공하나 실행은 되지 않고, 비정상 종료 됨
4. 예외 선언하기 - throws()
•
발생가능한 예외를 호출하는 쪽에 알리는 것
•
try-catch문의 직접처리와 달리 예외를 떠넘기는 간접처리 방식
•
unchecked 예외는 선언 안하는 것이 기본
void method() throws Exception1, Exception2,... {
}
Java
복사
method()를 호출하면 Exception1, Exception2,… 등의 예외가 발생할 수 있음을 알리는 것
method() 호출한 쪽은 예외에 대한 try-catch블럭으로 예외 처리를 해주어야 함
void method() throws Exception {
}
Java
복사
위 코드처럼 예외 선언하면, 모든 종류의 예외가 발생할 가능성이 있다는 뜻
즉, 해당 메서드를 호출하는 쪽은 모든 종류의 예외에 대해 처리해야한다.
참고사항
메서드 내에서 발생 가능한 예외를 메서드 선언부에 명시하여 해당 메서드를 사용하는 쪽에서 이에 대한 처리를 반드시 하게끔 하는 효과가 있다.
1. 예시
main메서드에서 예외처리
메서드 자체에서 처리
자신을 호출한 메서드에게 예외를 넘겨주는 방법이 가능하나, 중요한 것은 이것으로 예외가 처리된 것이 아니기에 반드시 예외가 발생한 메서드나, 호출한 메서드 쪽 어느 한 곳에 try- catch문으로 예외 처리 해주어야 한다.