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);
}
}
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();
}
}
0
인스턴스 생성: 1
인스턴스 생성: 2
인스턴스 생성: 3
class Card {
String kind ; // 카드의 무늬 - 인스턴스 변수
int number; // 카드의 숫자 - 인스턴스 변수
static int width = 100 ; // 카드의 폭 - 클래스 변수 (static 변수)
static int height = 250 ; // 카드의 높이 - 클래스 변수 (static 변수)
}
public
+ static
을 활용 public final class Math {
···
public static final double PI = 3.14159265358979323846;
···
}
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!
}
}
public final class System {
···
public static final PrintStream out = null;
···
}
public class PrintStream extends FilterOutputStream implements Appendable, Closeable {
···
public void println() { ··· }
public void println(boolean x) { ··· }
public void println(int x) { ··· }
···
}
System
: java.lang 패키지에 있는 클래스 이름out
: System
클래스에 속한 PrintStream
타입의 static
참조 변수println()
: PrintStream
클래스에 속한 메서드, 오버로딩의 대표적 예시 public static void main(String[] args) { ··· }
public
: main
함수는 기본이 되는 함수이기 대문에 어디에서나 접근이 가능해야 한다.static
: heap
영역에 함수를 할당한다면 Garbage Collector
에 의해서 정리되어질 수 있다.void
: 리턴값이 없다.main
: 고슬링 아저씨와의 약속String[] args
: args
라는 변수명으로 문자열을 배열로 입력 받겠다. 어떻게 보면 이 구문도 고슬링 아저씨와의 약속
- 단순한 문법 오류가 아닌 실행 중간에 발생하는
정상적이지 않은 상황
- 예외란 사용자의 잘못된 조작 또는 개발자의 잘못된 코딩으로 인해 발생하는 프로그램 오류
예외처리 메커니즘
을 제공한다.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~~!");
}
}
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
JVM
의 예외처리기(UncaughtExceptionHandler)
가 프로그램을 실행하는 도중에 문제가 발생하면 그 지점에 대한 정보 출력과 프로그램을 종료한다.try {
//예외가 발생할 가능성이 있는 문장들을 넣는다.
} catch(Exception1 e) {
//Exception1이 발생했을 경우, 이를 처리하기 위한 문장을 적는다.
} catch(Exception2 e) {
//Exception2이 발생했을 경우, 이를 처리하기 위한 문장을 적는다.
} finally {
// 예외의 발생여부에 관계없이 항상 수행되어야하는 문장들을 넣는다.
// finally블럭은 try-catch문의 맨 마지막에 위치해야한다.
}
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~~!");
}
}
a/b...a? 1
a/b...b? 0
/ by zero
무조건 실행
Good bye~~!
java.lang.ArithmeticException: / by zero
at date220928.Ex3.main(Ex3.java:14)
/ by zero
void method() throws Exception { }
Exception e = new Exception("예외 발생!");
throw e;
- 추가적으로 직접 새로운 예외 클래스를 던지고 싶으면
Exception클래스
orRuntimeException클래스
로부터 상속받아 사용자가 직접 정의한다.- 요즘은 예외처리를 선택적으로 할 수 있도록
RuntimeException
을 상속받아서 작성하는 쪽으로 바뀌어가고 있다.