///////
Search

static, 예외 처리

날짜
2022/09/28
태그
자바

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을 상속받아서 작성하는 쪽으로 바뀌어가고 있다.