본문 바로가기

IT/공부

[프로그래밍] UML, Exception, try-catch, throw, Inner Member / Local / Anonymous Class

private static은 나만 쓸 수 있는 static이다. private이 붙으면 static이라도 외부에서 클래스이름으로 접근할 수 없다. 

<<<UML>>>
+는 public을, #는 protected(상속과 같은 패키지), -는 private를 의미한다.
필드는 변수명 : 데이터타입 으로 적는다.

문제영역을 도메인이라고도 한다. (domain 도메인의 사전적 의미는 시간 혹은 공간적 영역을 의미한다.)

상태값을 변경하지 않는 메서드의 경우 static을 붙인다.

상태값 설정(초기화)을 인스턴스 생성 시 하는 것과 set 메서드 사용 시 하는 방법 모두 사용할 수 있는데, instance 생성 시 상태값을 알고 있을 때에는 생성자에 상태값을 넣어 initialize 하는 것이 편하고, 상태값은 현재 모르지만 인스턴스가 필요한 경우에는 default생성자로 인스턴스를 만들고 상태값 설정은 set method를 이용하는 것이 좋다. 

구체적인 클래스의 메서드 API를 참고하지 않고 인터페이스 클래스의 메서드를 사용하고자 할 때 데이터타입을 인터페이스 클래스로 설정하는 것을 인터페이스 기반 프로그래밍이라 한다.

<<<Exception 예외 처리>>>
예외 처리는 robust견고한 어플리케이션을 개발하기 위해 필요하다. 예외(알맞지 않는 사용) 처리를 하지 않으면 예외사항 발생 시 어플리케이션이 강제 종료된다. 예를 들어 command line argument로 3개를 받아야 하는데 사용자가 2개만 주었다면 ArrayIndexOutOfBoundsException 범위를 넘어가는 오류가 발생한다. 이는 3개를 받아야 하는 코드에 2개를 입력한 사용자의 실수이지 코드의 문제가 아니다. 이런 오류가 발생했으니 사용자에게 수정하라고 전달하는 것을 예외처리라고 한다. 예외 처리를 하게 되면 해당 예외가 발생해도 어플리케이션을 정상 종료할 수 있다. 어플리케이션이 견고하다는 것은 예외 발생 시 정상 종료 된다는 것이고, 이는 예외 처리를 해주어야 가능하다. 
예외 처리 방법에는 try-catch를 이용하는 방법과 throws 키워드를 이용하는 방법이 있다.

<<<try-catch try{}catch(){}>>>
JVM에서 어플리케이션 클래스를 실행할 때 예외사항이 발생한다면 해당 예외 클래스의 인스턴스를 만들어서 .class 파일에 던져준다(자바에서는 발생하는 예외사항까지 추상화 캡슐화하여 Bean 클래스로 만들어주었다). 이에 따라 try-catch(해당 예외 클래스의 인스턴스) 를 이용해 예외를 처리하는 것이다. try 안에 실행문을 넣고, catch(Exception e)로 예외 사항이 발생한 경우를 잡는다. try의 실행문이 여러 줄이라면 위에서부터 예외가 발생하지 않는 실행문은 실행하며 내려오다가 예외가 발생하는 실행문에서 catch로 넘어온다. System.out.println(e);를 하면 발생한 예외의 이름이 나오는데, println시 호출되는 toString 메서드가 적절히 오버라이딩 되었음을 보여준다. catch에서 Exception 클래스의 printStackTrace()메서드를 반드시 사용하자. printStackTrace()메서드는 Stack-LIFO구조-이기에 예외가 발생한 수행문부터 그 수행문을 호출한 수행문까지를 짚어준다. 그래서 어디에서 예외가 발생하는지 추적할 수 있다. 

catch()의 소괄호 안에서 구체적인 Exception의 데이터형을 Throwable까지만(Object는 안 됨) 데이터타입으로 받을 수 있다. (API에선 syntax라고 설명한다) 해당 예외 클래스의 인스턴스는 Exception 데이터 타입으로도 받을 수 있는데 Exception이 예외 클래스의 계열 최상위이기 때문이다. 그리고 이 Exception 클래스는 Throwable 클래스를 상속받는다. 따라서 Throwable 클래스 데이터형도 가능하다. 궁금한 건 Throwable 클래스는 Object 클래스를 상속받았는데 왜 Object는 Exception을 담는 데이터형으로 사용할 수 없냐 하는 것인데, 확실하진 않지만, Exception들이 상속받는 내용은 Throwable이 Object를 상속받은 혹은 오버라이딩한 멤버들이 아니라 Throwable에서 구체적으로 만든 멤버들이기 때문일 것 같다.
(cf. 계열 최상위란 해당 계열의 모든 클래스들이 상속받는 클래스를 말한다. Collection도 이에 해당한다)

try catch는 finally와 함께 사용될 때도 있다. finally{}는 에러가 있든 없든 반드시 실행되는 블럭이다. 만일 try에서 return;을 사용해 예외가 발생하지 않을 때 해당 메서드를 끝낸다면 try 하위의 수행문은 실행하지 않는다. 그러나 finally가 있으면 그 블럭은 위에서 return을 사용해도 finally블럭은 반드시 수행한다. (return이 아니라 System.exit(0)을 사용하면 process를 종료하기 때문에 수행되지 않는다.)

try-catch-catch-...-catch와 같이 다중 catch를 사용할 수도 있다. 예외 종류에 따라 다르게 처리할 경우에도 사용할 수 있지만 이 때 주의할 것은 다른 종류의 예외를 각각 다르게 잡을 수도 있지만 큰 데이터타입으로 모든 오류를 잡을 수 있다는 것이다. 위쪽의 catch문에서 큰 데이터타입으로 예외를 잡을 경우 (Exception 혹은 Throwable로) 하위의 모든 예외들이 잡히므로 예외 종류에 따른 처리는 불가하다. 그러므로 구체적일수록 catch의 위쪽에 두고 마지막에는 큰 데이터타입으로 예상하지 못한 예외까지 잡는 것이 좋다.

2)throws
메서드 안에서 예외가 발생한 경우에 try-catch를 사용해 처리할 수도 있지만 이 메서드를 호출한 곳으로 예외 처리를 위임할 수 있다. 이는 예외를 위임할 뿐 궁극적인 해결책은 아니다. 그러나 메서드만의 입장에서는 예외를 던져 처리했다고 볼 수도 있겠다. 받은 곳에서 try-catch를 사용하지 않으면 예외처리를 하지 않았을 경우와 같은 현상이 나타난다.

<<<checked exception and unchecked exception>>>
예외 사항이 발생했을 때 컴파일 자체가 안되는 경우가 있고 컴파일은 되지만 실행 시 에러가 발생하는 경우가 있다. 모든 예외 클래스는 Exception클래스를 상속한다. 따라서 계열최상위가 Exception클래스라고 했었다. Exception 중에서는 Runtime Exception 하위와 그렇지 않은 Exception 하위 클래스가 있다. 이 때 컴파일 시 어떠한 예외가 발생할 수 있으니 try-catch를 이용해 확인해달라고 하는 예외는 Runtime Exception이 아닌 Exception하위 클래스로 이를 checked exception이라 한다. Runtime Exception은 컴파일 시 발생가능한 예외를 알려주지 않는데, 이는 validation check 유효성체크로 예방할 수 있기 떄문이다.

<<<예외 강제 발생 throw>>>
개발을 할 때 필요에 의해 JVM에서는 예외가 아닌 사항을 예외로 처리하는 게 편한 경우가 발생한다. 예를 들어 핸드폰을 모델링할 때 통화시간에 따라 배터리를 줄이도록 한다고 해보자. 이 때 통화시간을 인풋으로 받는다고 할 때 시간이 -value일 수 없다. 따라서 -value는 예외 처리를 하고 싶지만 JVM은 음수를 예외로 처리하지 않기 때문에 이 경우에 예외로 처리할 것인라고 사용자가 정의해야 한다. [[예외만들기]] 이 때에는 Exception클래스를 상속받는 클래스를 만들고 생성자를 만들어준다. (JVM에서 실행 오류를 throw 인스턴스로 하기 때문에). [[예외 발생시키기]] 예외로 처리하는 상황이 되면 throw new 생성자(); 를 해주는 메서드를 만든다. 그리고 해당 메서드에선 try-catch를 이용해 만든 예외를 처리해준다.

<<<Inner Member / Local / Anonymous Class>>>
Inner class는 자바 문법 중 안드로이드 개발 시 많이 쓰인다. inner class는 특정한 하나의 클래스만 관계를 맺고 다른 어떤 클래스와도 공유, 상속, dependency, association과 같은 관계를 맺지 않는 클래스의 경우에 사용한다. inner member class는 한 클래스의 멤버로 포함된 경우이다. inner member class는 인스턴스 생성 없이 outter class의 필드나 메서드를 사용할 수 있다. outter class의 메서드에서 inner class의 멤버에 접근할 경우 inner class의 인스턴스를 만들어줘야 한다. inner member class에서 this 레퍼런스를 이용해 outter class의 멤버에 접근할 수는 없으며 this를 사용하려면 outter class의 이름.this.멤버이름 과 같이 접근해야한다. 하나의 .java 파일이지만 컴파일 시 inner class와 outter class 모두 .class 파일이 만들어지며 inner class의 경우 OutterClass$InnerClass.class 로 컴파일된다. 
inner local class의 경우 한 클래스의 하나의 메서드와만 관계를 가질 때 사용되며 메서드 안에 class가 local로 들어가는 것이다. inner class를 포함한 method에서 인스턴스 생성이 가능하다. 컴파일시 OutterClass$1InnerLocalClass.class 와 같이 컴파일된다. 
Inner anonymous class는 말 그대로 이름이 없는 클래스이다. 컴파일시 OutterClass$1.class로 컴파일된다.
--------Inner anonymous class 만들기---------
public class B extends A{ 
public void def(String message){
System.out.println(message);
}
}
B b = new B();
b.def("Hi!");
를-----------------------------------------
b가 new B(); 니까 
new B().def("Hi!");로 줄이고
------------------------------------------
public class B extends A{} 클래스 브레이스를 B생성자 자리에 대체하고
new public class B extends A{ 
public void def(String message){
System.out.println(message);
}
}.def("Hi!");
------------------------------------------
B 클래스의 이름을 지운다.
new A{ 
public void def(String message){
System.out.println(message);
}
}.def("Hi!");
------------------------------이렇게 inner Anonymous class를 만든다.

<<<eclipse>>>
eclipse.org에 가면 다운로드 받을 때 여러 OS에 맞춰 지원해 주는 것을 보니 이클립스도 플랫폼 독립적이라는 것을 알 수 있다.
자바 개발환경은 Installation 과정이 필요 없는 경우가 많은데, 이는 자바가 OS 플랫폼에 독립적이기 때문이다. 플랫폼에 독립적이지 않은 어플리케이션들은 OS의 레지스트리를 건드려 남아있는데, 자바는 플랫폼에 독립적이기 때문에 압축만 풀어서 사용하면 된다.
edit plus는 file 단위로 관리했다면 eclipse는 project 단위로 관리한다. 이클립스는 .java 파일은 src 패키지에, 컴파일 된 .class 파일은 bin 폴더에 넣는다. 패키지를 정의하지 않으면 default package로 들어간다.

<<클래스패스는 rt.jar가 아니라 라이브러리에 있는 jar 파일 전부이다.>>

<<<DB DataBase 데이터베이스>>>
데이터는 많지만 어디에 있는지 잘 관리되어야 사용할 수 있다. 관리된 데이터를 데이터베이스라 한다.