[Java] static, 예외 처리

킹발·2022년 9월 28일
0

Java

목록 보기
8/12
post-thumbnail

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);
    }
}

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();
    }
}
0
인스턴스 생성: 1
인스턴스 생성: 2
인스턴스 생성: 3

static을 언제 붙여야 할까?

  1. 클래스를 설계할 때, 멤버변수 중 모든 인스턴스에 공통으로 사용하는 것에 static을 붙인다.
    • 카드의 폭, 높이 변수에 static을 붙여서 얻는 이점
      • 모든 인스턴스에서 폭, 높이는 같은 값으로 유지/공유 되어진다.
      • 인스턴스가 생성될 때 마다 폭, 높이 변수 메모리가 할당되지않아 효율적으로 메모리를 쓸 수 있다.
    class Card {
      String kind ; // 카드의 무늬 - 인스턴스 변수
      int number; // 카드의 숫자 - 인스턴스 변수
      static int width = 100 ; // 카드의 폭 - 클래스 변수 (static 변수)
      static int height = 250 ; // 카드의 높이 - 클래스 변수 (static 변수)
    }
  2. 인스턴스를 생성하지 않고 사용할 변수, 메서드에 static을 붙인다.
    • 변수, 메서드가 어디서든 인스턴스 생성없이 사용되어진다면 public + static을 활용
   public final class Math {
       ···
    	public static final double PI = 3.14159265358979323846;
       ···
    }
  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!
      }
}

println의 정체

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 클래스에 속한 메서드, 오버로딩의 대표적 예시

psvm의 정체

 public static void main(String[] args) { ··· }
  • 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~~!");
    }
}
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 문

  • try-catch 문 구조
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~~!
  • 같은 예외가 발생되었지만 프로그램이 비정상적으로 종료되지 않고 끝까지 실행된다.

printStackTrace()

  • 예외발생 당시의 호출스택에 있었던 메서드의 정보와 예외 메시지를 화면에 출력한다.
java.lang.ArithmeticException: / by zero
	at date220928.Ex3.main(Ex3.java:14)

getMessage()

  • 발생한 예외클래스의 인스터스에 저장된 메시지를 얻을 수 있다.
/ by zero

throws

void method() throws Exception {  }
  • 메서드에 예외 선언하기
  • 이 메서드 내에서 발생할 가능성이 있는 예외를 메서드의 선언부에 명시하여 이 메서드를 사용하는 쪽에서는 이에 대한 처리를 하도록 강요
  • main()에서 method()를 호출했다면

예외 발생시키기

  1. new 연산자를 이용해서 발생시키려는 예외 클래스의 객체를 만들고
Exception e = new Exception("예외 발생!");
  1. throw 키워드를 이용해서 예외를 발생시킨다
throw e;
  • 추가적으로 직접 새로운 예외 클래스를 던지고 싶으면 Exception클래스 or RuntimeException클래스 로부터 상속받아 사용자가 직접 정의한다.
  • 요즘은 예외처리를 선택적으로 할 수 있도록 RuntimeException을 상속받아서 작성하는 쪽으로 바뀌어가고 있다.

0개의 댓글

관련 채용 정보