Objects Class에는 equals() 메소드가 존재한다. 기본 equals() 메소드는 단순히 객체의 주소를 비교하는 메소드로, 2개의 객체가 참조하는 것이 동일한 것인지 확인한다. 그래서 서로 다른 객체의 값이 같은지 알아보기 위해서는 기본 equals()를 사용하면 안된다. 객체 값들을 비교하려면 이 equals()를 Overriding 한 후 사용해야 하며, 이 equals()에는 객체의 고유값인 *HashCode 값을 비교하는 로직도 들어가있기 때문에 임의의 값으로 같은 Hashcode를 받을 수 있또록 HashCode를 리턴해주는 hashCode() 메소드도 오버라이딩 해주어야 한다.
이와 같이 오버라이딩 하기 전 참조하는 객체를 동일한지 확인하는 equals의 동작을 동일성(Idetity) 비교라고 하며, 오버라이딩 후 객체의 값을 비교하는 것을 동등성(Equality) 비교라고 한다.
*객체가 가진 고유값을 int값으로 리턴하는 hashCode()는 Collection(HashSet, HashMap, HashTable)의 equals() 과정에서나 사용된다. 그렇다면, Collection에서의 equals 사용 시에만 HashCode()를 오버라이딩 해야하냐 하면, 협업이나 모듈 작성 시 다른 이들이 equals()가 있는 객체를 사용해야할 때 혼란을 일으킬 수 있으므로 eqauls()와 hashCode()는 쌍으로 오버라이딩 해주는게 좋을 것이다.
(아 이 키워드 뭐에 대한 키워드였을까? 타이틀은 일단 남아있는 대로 그대로 작성하였고, 정리하다보니 Ingeter와 Long 타입의 String으로의 변환을 뜻하는 것 같아 찾아보았다.)
int와 long이 아닌 Integer와 Long을(Wrapper Class) String으로 변환하려면 Object Class의 toString을 오버라이딩 한 각 Integer, Long 클래스의 toString() 메소드를 사용한다.
public String toString()
ex)
Integer i = 1;
String s = integer.toString();
Java에서는 예외적인 일이 일어났을 때 '예외(Exception)를 던져'버린다. 예를 들어 null객체의 메소드를 호출한다거나, 배열크기 이외의 인덱스의 값을 호출한다던가 파일을 읽으려고 하는데 해당 파일이 없다던가 하는 예외적인 일들.
이 때 프로그램은 최대한 멈추지 않는 것이 좋으므로, 이 예외를 해결하든 해결하지 못하든 프로그램을 멈추지 않고 처리해야하는데 이 때, try-catch 문을 주로 사용한다.
말 그대로 try - 시도하고, catch - 잡아라(예외를)는 뜻으로, 예외를 처리해야할 코드를 try 블록으로 묶고, 예외가 일어났을 때 실행할 문장들을 catch 문에 삽입한다.
try-catch 블록에서의 동작은 다음과 같다.
*try-catch 블록 사용시 try에서 선언한 변수를 catch가 이용할 수 없다는 점을 고려하여 작성하여야 한다.
또한, catch의 매개변수로 쓰이는 Exception 클래스는 Exception의 하위 클래스들로 세분화하여 사용가능하다. 보통 Exception 클래스 하나를 사용하기 보단 하위클래스들을 사용하여 예외를 세분화하여 각 상황마다 다르게 처리하기를 권유한다. (대표적으로 NullPointerException, ArrayIndexOutOfBoundsException - 예제코드, NumberFormatException 등이 있다) 그리고 마지막 catch문에서는 Exception 클래스를 사용하여 예상치 못한 예외에 대비하는 것이 일반적이다.
설명을 종합하면 여러개의 catch문일 때 try-catch문은 다음과 같이 동작한다.
//try-catch문 예제
int[] array = new int[5];
try {
array[5] = 1;
}
catch(ArrayIndexOutOfBoundsException e) {
System.out.println("배열의 범위를 벗어난 인덱스를 참조합니다.");
System.out.println(e.getMessage()); //세부사항
}
catch(Exception e) {
System.out.println(e.getMessage());
}
이 외에 try-catch 뒤에 붙는 finally 블록이 있는데, 이 finally는 어떠한 경우(예외가 발생하든, 하지 않든)에도 실행하는 블록으로 예외와 관계가 없다. 중복 코드 방지가 목적이다.
Java의 신 참고
Exception과 Error 클래스의 공통 부모클래스는 Throwable 클래스가 있다. (Object는 모든 클래스의 상위 클래스이므로 이도 당연히 해당) Throwable 클래스는 예외와 에러를 처리할 수 있는 최상위 Class인데, 보통 이 최상위 클래스를 바로 사용하지는 않는다. Exception 클래스에서 Overoading한 메소드는 대략 10가지 이상이며, 이 중 자주 쓰이는 세가지는 다음과 같다.
코드를 입력하세요
*printStackTrace() 사용 시 주의점
이 메소드는 개발시에만 사용하도록 하고, 자칫하면 많은 로그가 남을 수 있고 제어하기가 힘든 등의 여러가지 문제 때문에 운영시스템에서는 지양하도록 한다.
java에서 제공하는 log 클래스로 기본적으로 SERVER, WARNING, INFO 수준으로 나뉘며 이를 바탕으로 Formmater로 원하는 형식으로 로그를 만들 수 있다. 또한 Console 및 File 핸들러를 선택하여 로그의 형태를 지정할 수 있다.
cf.loggin framework
말 그대로 log를 처리 및 관리하는 자바의 로그 프레임워크. 대표적으로 logback, log4j, ... 등이 있다.
java logger 및 logger frame사용 시, log에 대한 직접적인 관리가 가능하기 때문에 표준입출력으로 단순한 에러를 표시하는 방식보다 성능상 우세하며 (표준입출력은 속도가 느리다 따라서, 병렬 스레드 같은 동작에 직접적인 영향을 주는 위험성도 존재한다.) 어디에 표시할지, 어떤 형태로 로그를 관리할 지 등의 로그 관련 세부 컨트롤이 가능하다는 여러가지 장점을 가지고 있다.
try(...)에서 선언된 객체들(resource)에 대해서 try가 종료될 때 자동으로 자원을 해제해주는 기능
try(resource1; resource2; ...) {
...
}
이 코드를 사용하지 않으면 finally에서 일일이 조건으로 자원해제 코드를 삽입해야 하므로 코드양 축소에 도움을 준다. 또한 이과정에서도 만약 자원 할당 후 finally에 도달하지 못하는 일이 생기면 제대로 해제가 되지 않아 memory leak이 발생할 수 있는 위험을 줄일 수 있다.
The try-with-resources Statement(The Java™ Tutorials)
따로 정리
자바 소스코드에 추가할 수 있는 메타데이터의 한가지 형태.
컴파일 단계에서 정의된 processor에 의해 바이트코드 혹은 java 파일등을 생성 할 수 있는 기능으로, 런타임에서 추가적인 비용이 들지 않는다.
예로 자바의 @Override와 Lombok(롬북)이라는 라이브러리가 있다.
@Getter, @Seteer, @Builder 등의 Annotation과 Annotation Processor를 제공하여 표준적으로 작성해야 할 코드를 개발자 대신 생성해주는 라이브러리.
컴파일 시점에 Annnotation Processor를 사용하여 abstract syntaxtree를 조작한다.