java를 사용하면서 느낀 단점들
프로그래밍에 손을 대면서 거의 2~3년간 주력으로 C,C++만을 사용했다가 이번에 처음으로 3개월간 OOP를 배우면서 자바를 한동안 쓸일이 생겼었다. 순수하게 짠코드만 대략 3천~4천줄정도될텐데 자바를 쓰면서 느낀것을 한번 풀어보려고 한다. 거의 자바내의 기본문법만을 사용했다.
- 지나치게 많은 지원 메소드와 의미없는 추상 자료구조
cpp stack
java Stack
아마 Stack 내부적으로 ArrayList를 자료구조로 사용하면서 기존 ArrayList의 메소드를 그대로 받아서 사용할 수 있게 되어있는것 같다.작동상 중복되는 메소드가 너무너무 많다. CPP의 stack도 내부적으로 deque를 자료구조로 사용하지만 deque의 메소드를 외부로 노출시키지 않았다. 자바에서는 Stack을 사용함으로 이 자료구조는 “stack구조로만 돌아”라고 보장을 못하는 코드가 되어버렸다.
- 지원 자료구조의 배열선언 불가
코드를 짜다가 2차원 배열에 각 원소가 리스트로 이루어져있는 자료형를 만들일이 있었다
n이 정적이아니라서 C스타일 배열로는 만들수없고 동적할당으로 해결해야한다.
1 2 3 4 5 6 7 8
vector<int>** a = new vector<int>*[b]; for (int i = 0; i < b; i++) { a[i] = new vector<int>[c]; } for (int i = 0; i < b; i++) { delete[] a[i]; } delete[] a;
물론 이렇게 할시에 메모리 해제가 귀찮아진다. 그냥 3차원 벡터를 만들어버리면 가장 간단하게 해결할 수 있다.
1 2 3 4 5
vector<vector<vector<int>>> a; a.resize(b); for (int i = 0; i < b; i++) { a[i].resize(c); }
1
2
3
4
5
6
7
8
9
a = new HashMap<>();
for (int y = 0; y < height; y++) {
HashMap<Integer, LinkedList<Integer>> hashMap = new HashMap<>();
for (int x = 0; x < width; x++) {
LinkedList<Integer> list = new LinkedList<>();
hashMap.put(x, list);
}
a.put(y, hashMap);
}
이런식으로 해쉬맵을 엮어서 배열로 만들든..
LinkedList
1
2
3
public class A extends LinkedList<Integer> {
}
A[][] a = new A[a][b];
-
패키지내 접근이 가능한 protected :상속 관계에서 캡슐화 보장을 못하게 되었다. Cpp의 friend를 안해도 된다는 장점이 생겼지만
-
애매한 final : const가 아닌 final은 애매하다. 일반 변수들은 멤버 변수를 final로 할시에는 변경이 불가능하지만 레퍼런스로 움직이는 클래스들은 그대로 list에 값을 추가한다던가 내부를 변화 시킬수있다.
1 2
const verctor<int> a; vector<int> const a;
뒤에 const를 붙이는 방식으로 굴러간다.
이게 어떻게 스노우볼이 굴러가냐면
1
a.getUsers().add(i);
이런 게터를 통해서 외부에서 값변경이 되버린다. 물론 이거를 복사를 해서 getter를 반환하는 방법이 있겠지만 메모리 할당 + 복사까지 비용을 생각하면 또 신경쓰이는 부분이 되며 이 반환된 값조차 변경이 되기에 이 지금 반하고 사용하는 값이 class의 고유 값으로서 보존된다고 언어에서 보장하지 못한다. 자바만 쓰던 사람이 getter를 const로 반환하는 일반적인 코드베이스인 언어를 쓴다면 경우 로직을 강제로 바꾸게 되는 일이 생길거다.
이 모든 건 자기가 혼자 모든 코드를 짜고 책임을 지면 전혀 상관없는 얘기일지도 모른다 오히려 자유도가 높아서 좀더 자유롭게 코드를 짤 수 있다고 생각할지도 모른다. 하지만 내가 생각하는 이 문제점들은 일반적인 사람의 허용범위를 넘어선 행동을 가능하게하고 이는 나 또는 남들이 일반적인 사람들이 생각하는 코드의 흐름을 “ 클래스는 class 밖의 코드에서 내부 변수를 바꾸는 로직이 없을거야” 깬 코드를 짜고 나중에 디버깅을 힘들게 할 수 있다.