static의 이해
static 변수의 또 다른 이름들
•
정적변수
•
클래스 변수
•
공용변수
static 변수 특징
•
static 변수는 클래스 변수이다.
•
객체를 생성하지 않고도 static 자원에 접근이 가능하다.
Java에서 static 키워드를 사용한다는 것은 메모리에 한번 할당되어 프로그램이 종료될 때 해제되는 것을 의미
클래스 변수의 접근 방법
•
객체를 생성하지 않고도 클래스이름.변수명 클래스이름.메서드이름 와 같은 식으로 호출이 가능하다. But, 인스턴스 메서드/변수는 반드시 객체를 생성해야만 호출할 수 있다.
class Circle {
static double pi = Math.PI;
static double calArea(int r) {
return Math.pow(r, 2) * pi;
}
}
public class Ex1 {
public static void main(String[] args) {
System.out.println("PI = " + Circle.pi);
double area = Circle.calArea(2);
System.out.println("area = " + area);
}
}
Plain Text
복사
static 활용
•
InstCnt 클래스로 생성된 인스턴스의 갯수를 구하는 코드
class InstCnt {
static int instNum = 0; // 클래스 변수 (static 변수)
InstCnt() {
instNum++;
System.out.println("인스턴스 생성: " + instNum);
}
}
public class Ex2 {
public static void main(String[] args) {
System.out.println(InstCnt.instNum);
InstCnt cnt1 = new InstCnt();
InstCnt cnt2 = new InstCnt();
InstCnt cnt3 = new InstCnt();
}
}
Plain Text
복사
0
인스턴스 생성: 1
인스턴스 생성: 2
인스턴스 생성: 3
Plain Text
복사
static을 언제 붙여야 할까?
1.
클래스를 설계할 때, 멤버변수 중 모든 인스턴스에 공통으로 사용하는 것에 static을 붙인다.
•
카드의 폭, 높이 변수에 static을 붙여서 얻는 이점
◦
모든 인스턴스에서 폭, 높이는 같은 값으로 유지/공유 되어진다.
◦
인스턴스가 생성될 때 마다 폭, 높이 변수 메모리가 할당되지않아 효율적으로 메모리를 쓸 수 있다.
class Card {
String kind ; // 카드의 무늬 - 인스턴스 변수
int number; // 카드의 숫자 - 인스턴스 변수
static int width = 100 ; // 카드의 폭 - 클래스 변수 (static 변수)
static int height = 250 ; // 카드의 높이 - 클래스 변수 (static 변수)
}
Plain Text
복사
1.
인스턴스를 생성하지 않고 사용할 변수, 메서드에 static을 붙인다.
•
변수, 메서드가 어디서든 인스턴스 생성없이 사용되어진다면 public + static을 활용
public final class Math {
···
public static final double PI = 3.14159265358979323846;
···
}
Plain Text
복사
1.
메서드 내에서 인스턴스 변수를 사용하지 않는다면, static을 붙이는 것을 고려한다.
•
static 메서드는 인스턴스 변수를 사용할 수 없다.
◦
static 메서드가 호출되는 시점에 인스턴스 변수가 메모리에 존재한다는 보장이 없기 때문에
class Circle {
int radius = 2; // 인스턴스 변수
static final double pi = Math.PI;
static double getArea(int r) {
//Non-static field 'radius' cannot be referenced from a static context
return radius * radius * pi; //Error!
}
}
Plain Text
복사
println의 정체
public final class System {
···
public static final PrintStream out = null;
···
}
Plain Text
복사
public class PrintStream extends FilterOutputStream implements Appendable, Closeable {
···
public void println() { ··· }
public void println(boolean x) { ··· }
public void println(int x) { ··· }
···
}
Plain Text
복사
•
System : java.lang 패키지에 있는 클래스 이름
•
out : System 클래스에 속한 PrintStream 타입의 static 참조 변수
•
println() : PrintStream 클래스에 속한 메서드, 오버로딩의 대표적 예시
psvm의 정체
public static void main(String[] args) { ··· }
Plain Text
복사
•
public : main 함수는 기본이 되는 함수이기 대문에 어디에서나 접근이 가능해야 한다.
•
static : heap 영역에 함수를 할당한다면 Garbage Collector에 의해서 정리되어질 수 있다.
•
void : 리턴값이 없다.
•
main : 고슬링 아저씨와의 약속
•
String[] args : args라는 변수명으로 문자열을 배열로 입력 받겠다. 어떻게 보면 이 구문도 고슬링 아저씨와의 약속
예외처리
예외(Exception) 란 ?
단순한 문법 오류가 아닌 실행 중간에 발생하는 정상적이지 않은 상황예외란 사용자의 잘못된 조작 또는 개발자의 잘못된 코딩으로 인해 발생하는 프로그램 오류
Exception 종류
•
일반 예외(Exception)
◦
checked 예외
▪
Checked Exception 예외처리를 해주지 않으면 컴파일조차 되지 않는다.
◦
사용자 실수와 같은 외적인 요인
•
실행 예외(Runtime Exception)
◦
unchecked 예외
▪
성공적으로 컴파일되지만, 실행하면 비정상적으로 종료된다.
◦
프로그래머 실수
예외처리
•
자바는 예외처리 메커니즘을 제공한다.
•
프로그램의 비정상 종료를 막고, 정상적인 실행상태를 유지하기 위해 발생한 문제를 수습하는 것
•
예외는 잡거나 던져라
public class Ex3 {
public static void main(String[] args) {
Scanner kb = new Scanner(System.in);
System.out.print("a/b...a? ");
int n1 = kb.nextInt(); // int형 정수 입력
System.out.print("a/b...b? ");
int n2 = kb.nextInt(); // int형 정수 입력
System.out.printf("%d / %d = %d \\n", n1, n2, n1 / n2); // 분모에 0이 오면 예외 발생
System.out.println("Good bye~~!");
}
}
Plain Text
복사
a/b...a? 1
a/b...b? 0
Exception in thread "main" java.lang.ArithmeticException: / by zero
at date220928.Ex3.main(Ex3.java:15)
Process finished with exit code 1
Plain Text
복사
•
JVM의 예외처리기(UncaughtExceptionHandler)가 프로그램을 실행하는 도중에 문제가 발생하면 그 지점에 대한 정보 출력과 프로그램을 종료한다.
try-catch 문
•
try-catch 문 구조
try {
//예외가 발생할 가능성이 있는 문장들을 넣는다.
} catch(Exception1 e) {
//Exception1이 발생했을 경우, 이를 처리하기 위한 문장을 적는다.
} catch(Exception2 e) {
//Exception2이 발생했을 경우, 이를 처리하기 위한 문장을 적는다.
} finally {
// 예외의 발생여부에 관계없이 항상 수행되어야하는 문장들을 넣는다.
// finally블럭은 try-catch문의 맨 마지막에 위치해야한다.
}
Plain Text
복사
public class Ex3 {
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 e) {
System.out.println(e.getMessage());
}finally{
System.out.println("무조건 실행");
}
System.out.println("Good bye~~!");
}
}
Plain Text
복사
a/b...a? 1
a/b...b? 0
/ by zero
무조건 실행
Good bye~~!
Plain Text
복사
•
같은 예외가 발생되었지만 프로그램이 비정상적으로 종료되지 않고 끝까지 실행된다.
printStackTrace()
•
예외발생 당시의 호출스택에 있었던 메서드의 정보와 예외 메시지를 화면에 출력한다.
java.lang.ArithmeticException: / by zero
at date220928.Ex3.main(Ex3.java:14)
Plain Text
복사
getMessage()
•
발생한 예외클래스의 인스터스에 저장된 메시지를 얻을 수 있다.
/ by zero
Plain Text
복사
throws
void method() throws Exception { }
Plain Text
복사
•
메서드에 예외 선언하기
•
이 메서드 내에서 발생할 가능성이 있는 예외를 메서드의 선언부에 명시하여 이 메서드를 사용하는 쪽에서는 이에 대한 처리를 하도록 강요
•
main()에서 method()를 호출했다면
◦
예외 발생시키기
1.
new 연산자를 이용해서 발생시키려는 예외 클래스의 객체를 만들고
Exception e = new Exception("예외 발생!");
Plain Text
복사
1.
throw 키워드를 이용해서 예외를 발생시킨다
throw e;
Plain Text
복사
추가적으로 직접 새로운 예외 클래스를 던지고 싶으면 Exception클래스 or RuntimeException클래스 로부터 상속받아 사용자가 직접 정의한다.
•
요즘은 예외처리를 선택적으로 할 수 있도록 RuntimeException을 상속받아서 작성하는 쪽으로 바뀌어가고 있다.