여태 자바를 사용법만 알고 깊이 몰라서 "자바의 신"이라는 책으로 다시 학습하고 있는데 새로 알게 된 내용만 정리해보려고 한다.
CS도 외우기만 하다가 왜 이렇게 사용하는지, 어떤 원리인지 알아봤는데 기억에 더 잘 남고 이전에 이해를 100% 못했던 문제도 퍼즐이 맞춰지는 느낌으로 이해가 되어 좋았다. 자바도 비슷한 느낌을 받을 것 같아 시작했다.
제네릭
타입을 지정해서 컴파일 타임에 오류를 잡기 위해 사용하는 것으로 알고있다.
새로 알게된 내용은 static 메소드에서 제네릭을 사용하려면 앞에 <T>와 같은 제네릭을 사용해야 한다는 것이다. 그래야 메소드가 제네릭 타입을 받아들이는 것으로 인식된다. 내가 작성했던 코드에서도 사용한 부분이 있는데 그땐 오류가 사라지니 그냥 사용했던 것 같다.
public static <T> Response<T> success(T data){
return new Response<>(SUCCESS,data);
}
제네릭을 다시 공부하고 나서 앞에 있는 <T>는 없어도 되는거 아닌가? 하고 지우니까
이렇게 컴파일 에러가 발생한다.
이유를 찾아보니 static을 사용하면 리턴 타입 앞에도 <>를 붙여줘야 한다.
또한 이렇게 리턴 타입 앞에도 제네릭 타입을 선언하면 매개 변수에서 제네릭 타입이 포함된 객체를 받아서 처리가 가능하다. 기존에 제네릭 타입을 파라미터로 받으면 객체 수정이 불가능했다. DTO를 파라미터로 받아서 setter를 사용하지 못했다는 것이다.
Collection - Vector
Vector 클래스는 사용하지 않아서 잘 몰랐다. 대부분의 메소드가 ArrayList와 동일하다. 차이점이 있다면 ArrayList는 thread safe 하지 않고 Vector는 thread safe 하다는 것이다.
또 재밌었던 것은 Stack이 Vector클래스를 extends 했다는 것이다. 즉 Stack도 thread safe하다는 것이다.
Collection - Deque
얘도 잘 사용하지 않아서 몰랐다. 하지만 알고리즘 문제를 풀면서 알게 되었다. Stack과 Queue를 합쳐놓은듯 앞뒤로 넣고 빼고 하는 것이 가능하다.
Map
Map도 HashMap을 많이 사용했다. 이번에 TreeMap을 살펴봤는데 얘는 키를 정렬하여 저장한다. 기본적으로 숫자 > 알파벳 대문자 > 알파벳 소문자 > 한글 순이며 객체의 경우 compareTo 메소드로 우선순위를 정해주면 된다.
compareTo로 우선순위 정해주는 것이 재밌었는데, 다른 객체지만 내부 필드 값들이 동일하다면 같은 객체로 인식된다는 것이다. 난 당연히 다른 인스턴스 객체니까 동일한 값이 나오겠지? 라고 생각했지만 compareTo로 비교하는 과정에서 동등하다고 판단하면 이 객체는 중복으로 취급되고 덮어쓴다.
testMap.put(new Test(3),3);
testMap.put(new Test(3),3);
testMap.put(new Test(2),2);
testMap.put(new Test(1),1);
Set<Map.Entry<Test,Integer>> testEntry = testMap.entrySet();
for(Map.Entry<Test,Integer> testData : testEntry){
System.out.println(testData.getKey() + "=" + testData.getValue());
}
Test(3) 하나가 사라진 결과를 볼 수 있다. 사실 이렇게 쓸 경우는 거의 없을테지만 만약 발생하면 당황하지 않을 것 같다.
추가로 entrySet()으로 키-밸류를 쉽게 뽑아서 확인할 수 있다. 이것도 오늘 알았음..
Properties 클래스
얘도 Map을 구현한 클래스이다. 자세하게는 Hashtable을 extends했다.
Hashtable은 Map 인터페이스를 구현했지만 일반적인 구현 클래스와는 차이가 있다.
1. Map은 컬렉션 뷰를 사용하지만 Hashtable은 Enumeration 객체를 통해 데이터를 처리한다.
2. Map은 키-밸류 쌍으로 데이터를 순환하여 처리가 가능하지만 Hashtable은 키-밸류 쌍으로 데이터를 순환하여 처리할 수 없다.
3. Map은 Itteration을 처리할 때 순서를 보장하지만 Hashtable은 순서를 보장하지 않는다.
HashMap과의 큰 차이도 있는데 HashMap은 키-밸류에 null값이 허용되지만 Hashtable은 아니다. 또한 HashMap은 thread safe 하지 않고 Hashtable은 thread safe 하다.
이렇게 차이가 큰 이유가 Hashtable 클래스는 JDK 1.0에 만들어졌지만 Map 인터페이스의 기능을 구현한 클래스들은 JDK 1.2부터라서 Hashtable을 Map에 맞춰서 보완했기 때문이라고 한다.
여하튼 다시 Properties 클래스로 돌아오면 System클래스의 getProperties()메소드를 호출하면 시스템에서 제공하는 많은 속성들을 쉽게 볼 수 있다. 추가로 Properties에서 다양한 기능을 제공하는데 파일에서 속성을 읽고 파일에 속성을 저장하는 메소드를 제공한다. 즉 애플리케이션에서 사용할 여러 속성값들을 Properties 클래스를 사용해서 데이터를 추가하고 제거하며 읽을 수 있다. 내가 직접 메소드를 만들어야 할 수고를 덜어주는 것이다.
최근 IPC 적용해서 비동기 통신하면 어떨까?라는 생각에 깊게 학습하려 하는데 잘 몰랐던 내용들을 알아서 좋은 것 같다.
이외에도 운영체제나 네트워크도 학습하면서 가상 환경에서 네트워크 흐름이나 프록시의 활용, VPN원리 등을 알아가니 이래서 사용하는구나~라는 생각이 들어 재밌는 것 같다.
'Java > Java' 카테고리의 다른 글
Java 양방향 Socket 통신시 발생한 에러(socket is closed, 무한 readLine) (0) | 2023.12.05 |
---|---|
try-with-resources를 사용하면 정말 close()가 호출될까? (0) | 2023.10.14 |
[Java] 가비지 컬렉션(Garbage Collection)과 5가지 알고리즘 (0) | 2023.04.23 |
[Java] 불변 객체와 final을 사용해야 하는 이유(feat.정적 팩토리 메소드) (0) | 2023.04.23 |
Java 정리(JVM, 객체지향, 싱글톤 패턴) (0) | 2023.01.09 |