17장. 클래스 변수와 메소드
1. static 변수
static 변수의 용어 정리
•
static 변수 = 정적 변수 = 클래스 변수 = 공용 변수
•
인스턴스 변수 앞에 static이 붙은 변수
•
static 변수의 특징
◦
static 변수는 클래스 변수이다.
◦
객체를 생성하지 않고도 static 자원에 접근이 가능하다.
•
Java에서 static 키워드를 사용한다는 것
= 메모리에 한번 할당되어 프로그램이 종료될 때 해제되는 것을 의미
클래스 변수의 접근 방법
1.
클래스 내부 접근
•
static 변수가 선언된 클래스 내에서는 이름만으로 직접 접근 가능
2.
클래스 외부 접근
•
private으로 선언되지 않으면 클래스 외부에서도 접근 가능
•
접근 수준 지시자가 허용하는 범위에서 접근 가능
•
클래스 또는 인스턴스의 이름을 통해 접근
클래스 변수의 접근 예제
예제를 통해 배우는 static 변수
static 변수 예제
카드 예제
원의 넓이 구하기 예제
2. static 메서드
static 메서드와 메모리
•
static 메서드에 인스턴스 변수가 올 수 없는 이유?
class InstCnt {
static int instNum = 0; //클래스 변수(static 변수)
int num = 0; //인스턴스 변수
static public void print() { //static 메서드
instNum++;
num++; //컴파일 오류 발생
}
}
Java
복사
◦
static 메서드는 객체 생성 없이 사용할 수 있기 때문에, static 메서드 내부에서 멤버 변수 또는 메서드를 사용할 수 없다.
static 메서드 호출 시점에 객체가 생성되지 않았을 수 있기 때문에 객체의 변수 및 메서드 접근을 허용하지 않는 것이다. 또한, 객체가 생성되어있다 하더라도 static 메서드에서 어떤 객체의 멤버 변수에 접근해야하는지 알 수 없기 때문이기도 하다.
따라서, static 메서드에서 멤버 변수나 메서드 접근 시, 위와 같은 컴파일 에러가 발생한다.
•
Static 변수 & Static 메서드의 메모리 저장 영역
static으로 생성된 멤버들은 static영역에 할당된다. 모든 객체가 메모리를 공유할 수 있다는 장점이 있지만 garbage collector의 관여가 없어 프로그램이 종료될 때까지 메모리에 값이 유지되기 때문에 너무 많이 사용한다면 프로그램이 무거워진다는 단점도 있다.
•
public static void main(String[] args) { }
◦
public : 모든 클래스가 접근할 수 있게 하는 접근 제어자
◦
static : 인스턴스 생성과 관계 없이 가장 먼저 호출되도록 함
▪
프로그램이 실행되면 main 메서드가 제일 먼저 호출되기 때문에 객체 없이 바로 작업을 수행할 수 있도록 static 사용
◦
void : 메인 메서드에서 호출하는 JVM에서 리턴 값을 요구하지 않기 때문에 사용
◦
String[] args : 프로그램 실행시 매개변수를 보내서 실행할 수 있다는 뜻
◦
한개를 사용할 수도 있고 여러 개를 사용할 수도 있기 때문에 배열을 사용
•
JVM 메모리 구조
1.
메서드 영역 (Method area)
•
프로그램 실행 중 어떤 클래스가 사용되면, JVM은 해당 클래스의 클래스 파일(.class)을 읽어 클래스에 대한 정보를 저장한다. Class Variable도 함께 저장하는데 그것은 Static Variable과 같다. ⇒ 어디서든 공유해 쓸 수 있는 변수를 의미
프로그램 실행 중 사용 되는 class 파일을 JVM이 읽어 클래스에 대한 정보를 저장
해당 클래스의 클래스 변수도 함께 저장
2.
호출 스택 (Call stack)
•
메서드의 작업에 필요한 메모리 공간을 할당한다. 메서드가 호출되면 스택에 호출된 메서드를 위한 메모리가 할당되고, 이 메모리는 메서드의 연산의 중간 결과, 지역 변수, 매개 변수 등을 저장하는데 사용한다. 그리고 메서드의 작업을 마치면 메모리 공간을 반환한다.
메서드 작업에 필요한 메모리 할당
매개 변수, 지역 변수, 연산의 중간 결과 등을 저장
메서드가 작업을 마치면 메모리 반환
3.
힙 영역 (Heap)
•
클래스의 인스턴스와 배열이 저장되는 공간이다. 프로그램 중 생성된 인스턴스는 모두 이곳에 저장되고 인스턴스 변수도 생성된다.
인스턴스가 생성되어 저장되는 메모리 영역
인스턴스 변수 포함
대표적인 static 변수와 메서드
•
System.out.println의 out과 println의 정체는?
java.lang.System.out.println(...);
◦
System은 java.lang 패키지에 묶여 있는 클래스의 이름
◦
그러나 컴파일러가 다음 문장을 삽입해 주므로 java.lang을 생략할 수 있다.
◦
import java.lang.*;
System.out.println(...);
◦
out은 클래스 System의 이름을 통해 접근하므로, 이는 System 클래스의 클래스 변수 이름임을 유추할 수 있다.
System.out.println(...);
◦
println은 out이 참조하는 인스턴스의 메서드이다.
•
main 메서드가 public이고 static인 이유는?
public static void main(String[] args) {...}
◦
static인 이유: 인스턴스 생성과 관계없이 제일 먼저 호출되는 메서드이기 때문이다.
public static void main(String[] args) {...}
◦
public인 이유: main 메서드의 호출 명령은 외부로부터 시작되는 명령이다.
단순히 일종의 약속으로 이해해도 괜찮다.
18. 예외처리
1. 예외(Exception)
예외 개념
•
자바에서 예외(Exception)란, 단순한 문법 오류가 아닌 실행 중간에 발생하는 '정상적이지 않은 상황' 을 의미
◦
사용자의 잘못된 입력
◦
개발자의 잘못된 코딩으로 발생한다.
•
예외처리를 하지 않으면 프로그램은 종료된다.
•
jvm은 프로그램을 실행하는 도중에 예외가 발생하면 해당 예외 클래스로 객체를 생성한다.
빈번하게 나타나는 실행 예외
에러 개념
•
에러는 jvm 실행에 문자가 생긴 것이다.
◦
개발자가 대처할 방법은 프로그램을 다시 짜는 것
◦
즉, 에러를 처리할 방법은 없다.
에러 vs 예외
•
예러
◦
메모리의 부족이나 하드웨어의 오동작 또는 고장으로 인해 응용프로그램 실행 오류가 발생하는 것
◦
에러 발생 시 프로그램 종료
•
예외
◦
사용자의 잘못된 조작(ex. 입,출력) 또는 개발자의 잘못된 코딩으로 인해 발생하는 오류
◦
예외 발생 시 문제가 발생한 지점에 대한 정보 출력과 프로그램 종료
▪
(자바의 기본 예외처리 메커니즘)
◦
예외 처리 (Exception Handling)을 통해 프로그램을 종료하지 않고 정상 실행 상태를 유지할 수도 있다.
사용자 정의 예외
public class XXXException extends [Exception 혹은 RuntimeException]{
public XXXException(){}
public XXXException(String message){super(message);}
}
Java
복사
•
프로그램을 작성할 때 프로그래머가 어떠한 조건에서 예외를 발생해야 하는 상황이 온다.
•
이때 사용하는 것이 사용자 정의 예외이다.
•
사용자 정의 예외 클래스를 작성할 때는 반드시 public class로 작성해야한다.
•
예외를 발생시키기 위해서는..
◦
throw new XXXException(”어떠한 이유때문에 예외가 발생되었다는 메세지”);
◦
위 같이 예외 객체를 생성해줘야 한다.
◦
그리고 throw를 해준다.
사용자 정의 예외 발생 예제
2. 예외 처리(try-catch)
자바의 기본 예외 처리 매커니즘
•
문제가 발생한 지점에 대한 정보 출력
•
프로그램 종료
•
예외의 경우가 발생하는 경우, 개발자는 직접 이 상황에서 실행돼야 할 행위를 지정해줄 수 있는데, 이를 예외 처리 코드라고 한다.
◦
이는 try-catch 구조를 활용하여 작성할 수 있다. 코드를 통해 이해해 보자.
예제) try-catch
try-catch
•
try 블록
◦
예외가 발생할 것 같은 코드를 작성
•
catch 블록
◦
만약 예외가 발생할 경우에 실행되어야 하는 코드들은 catch() 블록에 구현해준다.
◦
try 블록에서 예외 발생 시, 프로그램은 즉시 실행을 멈추고 catch 블록으로 이동
◦
JVM은 프로그램을 실행하는 중 예외가 발생하면, 이 예외 클래스로 객체를 생성함.
▪
따라서 우리가 e.printStackTrace()와 같은 예외 처리 구문을 사용할 수 있는 것임!!
•
fianlly 블록
◦
finally 블록은 예외 여부와 상관없이 무조건적으로 실행된다.
◦
finally는 리소스를 반환할 때 쓰인다.
◦
심지어, try-catch 블록에서 return 문을 사용하더라도 실행된다.
•
다중 catch
◦
try 블록 내에는 정해진 예외가 아닌 다양한 예외가 발생할 수 있다.
◦
ArithmeticException
▪
정수를 0으로 나눌 때 예외 발생
▪
위의 예외가 발생했을 경우, catch 블록의 파라미터에 이 클래스를 활용하여 예외 처리가 가능하도록 한다.
◦
InputMismatchException
▪
nextInt()를 활용하여 정수를 입력받고자 했지만, 사용자가 문자를 입력한 경우 예외 발생
▪
위의 예외가 발생했을 경우 catch() 블록의 파라미터에 이 클래스를 활용하여 예외 처리가 가능하도록 한다.
◦
따라서, 여러개의 catch 블록을 설정해줌으로써, 다양한 예외가 발생했을 경우에 대처할 수 있다.
자바 8 버전부터 멀티 catch 기능을 사용할 수 있다.
예제) catch
예제) 다중 catch()문 작성 시 주의 사항
3. 예외 처리(throws)
throws
•
“에러 던지기”
•
메소드를 호출한 곳(JVM)으로 예외 처리를 떠넘길 때, throws 키워드를 사용한다.
•
throws 키워드는 메소드의 선언부 끝에 작성되며, 떠넘길 예외 클래스들을 쉼표로 구분하여 나열한다.
◦
예외 클래스 여러개 작성 하는 법
public void method() `throws IOException, InputMismatchException` {}
Java
복사
예제)throws(1)
예제)throws(2)
3. 예외 클래스 구분
일반 예외 (Checked Exception)
•
자바 소스를 컴파일 하는 과정에서 예외 처리 코드가 필요한지 검사하기 때문에, 컴파일러 체크 예외, Checked Exception 이라고도 한다.
•
Exception 클래스를 상속받지만, RuntimeException 클래스를 상속받지 않는다.
•
Exception 클래스는 모든 예외처리 클래스의 조상 클래스
실행 예외 (Runtime Exception)
•
프로그램이 동작할 때 발생하는 예외
•
Exception 클래스 뿐만 아니라, RuntimeException 클래스를 상속받는 클래스
•
JVM은 예외 발생 시, 이 예외 클래스가 RuntimeException을 상속받았는지 확인하고, 실행 예외의 발생 여부를 확인한다.
•
컴파일러가 체크하지 않고 오직 개발자의 경험에 의해 실행 예외 처리를 설정해야 한다.