자바5.0 으로 갈아타야 하는가?

stadia의 이미지

Quote:
스크립트언어 PHP "자바 비켜라"

에서 나왔던 자바의 generics 문제를 포함한 자바 5.0 에 대해 이야기 해보고 싶어서 쓰레드를 열게 됐습니다.

generics 뿐만 아니라
왜 5.0 으로 넘어가야 하는가? 아니면 5.0이 이따위라서 넘어가지 않겠다
등 재미있는 이야기가 많이 나올 것 같습니다.

pool007의 이미지

저도 자바 generics에 대해서 불만이 많습니다. 구체적으로는 자바 generics는
erasure로 구현되어있고, 그것때문에 실행시간에 받아온 타입정보를 알아내지 못합니다. 그것이 저의 가장 큰 불만거리입니다.

자바의 경우 이러한 선택을 하게 된 배경에는, 클래스 파일의 바이너리
compatability와, 구현의 편이가 배경이 되지 않았나 추측합니다.
물론 표면적인 이유는 C++등에서 있었던 code bloat를 막겠다..
그리고 코드 재사용성을 높이겠다.. 라고 하고 있는 것 같지만,
뭐 어쨌든 맘에 안듭니다. 덕분에 직관적으로는 되야 할 것 같은 일들이 generics에서 제대로 안됩니다..

반면 C#의 경우엔, 예를들어 ArrayList<T> 라는 클래스가 있다면
ArrayList는 타입을 받을 수 있는 클래스이며, 이때 타입 T에 대한
실행시간의 타입 정보는 그대로 옮겨다닙니다. 정말, 우리가 이해하는
generics의 본질에 그대로 맞는 구현입니다. 반면에, 콜렉션을 새로이
정의하면서는 별도의 네임스페이스를 정의하여 generics를 구현하였는데,
이것이 잘한것인가에 대해서는 의문이 남습니다. 같은게 두개라고 봐도
상관없는거니까요.

또 한편 C++도 있는데. C++의 경우엔 템플릿 제대로 쓰기 어렵습니다.
템플릿이 사실 그냥 매크로나 마찬가지라서 code bloat를 막기위해서 공통 코드는 부모 클래스로 빼주어야하는데,
그걸 하는데도 문법이 까다롭습니다. 어떤 클래스가 템플릿인데,
그 클래스에서 operator<< 를 오버로딩하려면 또 까다롭습니다.
솔직히는 어떻게 저딴게 언어인가 싶을때가 한두번이 아닙니다..
그러나 물론 시장에서 많이 쓰이고 있고, 당분간 시장에서 많이 쓰일게
확실하고, 성능도 좋고, 이식성도 좋고 기타 등등의 이유가 있다는 생각에
열심히 공부해보려고 하고 있습니다.

그러나 그 외에 추가된 자바의 기능에는 아무도 불만이 없지 않나요?
enhance for loop, annotation, concurrent utility 등, 정말로
필요하고 개발자의 편의를 크게 높여줄 기능들입니다.

더구나 앞으로 EJB와 JDBC에서는 annotation등을 크게 수용할
것입니다. 자바에 관심있고, 지금 좀 할줄안다면 JDK5를 약간의
고통을 감수하고 배울 필요가 있다고 생각합니다... generics도
골치아프긴 하지만 튜토리얼 읽는건 어차피 하루면 되고,
(적어도 C++의 템플릿의 복잡한 규칙을 다 아는것보단
시간이 덜걸립니다...) 나머지는 삽질 - 어느언어든지 당연한 과정이지만 -
에 달린 것 같습니다.

--
Passion is like genius; a miracle.

sDH8988L의 이미지

Java를 놓은 지 한참 되어서 그런 지 가끔 Community에 가도 이제는 모르는 말들을 많이 하네요...

지나가다가 이 글에 맞는 게시판 글이 있어서 Link를 겁니다...

http://javalobby.org/java/forums/t14809.html

제목은 What's your favorite improvements in JDK 5.0 입니다.

그런데, 댓글들을 읽어보면, Generics에 대해서 그다지 불평이 있는 거 같지는 않던데요... Generics에 대한 개발자들의 평은 좀 더 알아봐야 겠습니다...

stadia의 이미지

가끔 클래스를 구현 할 때
해쉬를 만들어서 그 안에 값을 다 때려 놓고
키 값으로 가져다 쓰는 일이 있는데
generics 를 사용한다면 캐스팅 문제로 귀찮은 일은 없을 것 같기도 한데요.

한 번 구현을 해봐야지 정확하게 알 것 같네요.

해밝의 이미지

다른건 잘 모르겠고, InetAddress 클래스에 isReachable 메소드가 들어있어서 참 좋던데요 ㅋㅋ

제 경우에는 JDK 1.4 이하에서 각 클래스가 가져야하는 당연한 메소드(Long.valueOf(long)와 같이)임에도 없던 것들이 추가되어있어 JDK 5.0이 반갑더군요. :wink:

mykldp의 이미지

pool007 wrote:
저도 자바 generics에 대해서 불만이 많습니다. 구체적으로는 자바 generics는
erasure로 구현되어있고, 그것때문에 실행시간에 받아온 타입정보를 알아내지 못합니다. 그것이 저의 가장 큰 불만거리입니다.

동감입니다. 강한 타입 언어(뜻이 좀 애매하지만...)를 지향하는 자바로서 제너릭은 당연한 방향입니다. 하지만 erasure로 구현된 현재 방식은 정말 맘에 안들더군요. 캐스팅을 없애준다고 하지만 이는 캐스팅 삽질을 감춰놓은 것에 불과합니다. 콜렉션 비스무리한 클래스를 직접 구현하려고 들면 내부적으로 Object 배열 등을 만들고 캐스팅을 할 수 밖에 없습니다. 물론 경고가 보기 싫으니까 @SupressWarnings 가 따라다니지요. API 에만 캐스팅이 안보일 뿐입니다. 실제로 자바 콜렉션 소스를 들여다보면 수많은 캐스팅을 볼 수 있습니다.

어노테이션은 무척 매력적인 기능입니다. 활용도가 무궁 무진 하리라고 생각합니다. 하지만 아직 실제 프로젝트에서 써본적은 없군요. 어노테이션 프로세서에 대해 좀 찾아보고 익히고 해야하는데 그러지 못하고 있네요.

concurrent utils 정말 좋지요. 하지만 5.0 이전에도 별도 프로젝트로 진행되던 라이브러리이니까 1.4 이하에서도 사용할 수는 있지요.

5.0 으로 작업한지 1년 정도 되가네요. 개발을 끝내고 설치하러 가면 막상 실제로 설치되야할 머신에 관리자들이 1.4를 깔아놓은 경우가 많더군요. 5.0 으로 바꿔달라고 하니까 대부분 "5.0 이요?" 하는 반응이더군요. 그러면서 꼭 버젼을 올려야 하냐고 묻더군요. 5.0 의 기능들을 많이 사용해서 어쩔 수 없다고 대답하면 알았다고 하면서 바꿔주기는 하는데, 주변에서 5.0 을 요구하는 경우는 없었다고 하네요.

여하튼 그럭 저럭 잘 사용하고 있고 erasure 제너릭에 대한 불만도 심각한 것은 아니어서 그냥 잘 사용하고 있습니다. 캐스팅을 없앨 수는 없지만 확실히 줄어들기는 했고, 그만큼 타입 안전성도 높아졌고 , 프로그램에 버그가 발생할 확률이 어느정도 줄어든 샘이니까요.

pool007의 이미지

Generics의 현재 구현방법을 싫어하시는 또다른 분을 만나게 되어 기쁩니다.. ㅠㅠ Generics가 가장
마음에 안드는 점은 다음에 있습니다.

http://www.langer.camelot.de/Articles/Papers/JavaGenerics/ArraysInJavaGenerics.htm

요약하면,

어떤 클래스가 다음과 같이 선언되어있을때

class Test<T> { ... }

이 안의 메소드에서 T형태의 배열을 선언하지 못합니다.

public T makeArray() { return new T[10]; }

컴파일시 이 문장은 unchecked exception이라는 예외를 발생시키고(에러는 아닙니다), 컴파일은 되지만 런타임에 완전히 예측 불허가 되버립니다. 예를들어,

Test<String> t = new Test<String>();
String []strArr = t.makeArray();

는 런타임에 실패합니다. 어처구니 없죠. 당연히 되야되는것 같은데. 근본적인 원인은
makeArray안에서 T가 무슨타입인가를 알아내지 못한다는 것입니다. 타입을
모르니까 배열도 못만들죠. 더 견디기 힘든건, 이게 컴파일시엔
멀쩡하고 런타임에 죽는다는 것입니다. (뭐 이런게 다 있는지;;)

이의 해결은 T[] 를 쓰지말고 ArrayList<T> 같은걸 쓰라는 것입니다.

또다른 문제는

public T bar() { return new T(); }

도 실패한다는 것입니다. 왜냐면 T가 뭔지 모르니까요. 역시 어처구니...
C++이라면 글자를 잘 치환했을겁니다. C#이라면 T가
무엇인지 알고 있습니다.

이 문제로 여러 사이트들을 돌아다녀봤는데, 주로는 generics가 문제인것이
아니라 object[] 가 다른 모든 배열의 부모인것이 문제라고 변명 하더군요. 언제는 object가 모든 클래스의 부모여서 템플릿같은게 필요없는
자바는 축복받은 언어이다라는 식으로 이야기하다가 이제와선 object가 잘못이랍니다;;
제 생각엔 어쨌거나 generics잘못이지만..

이 문제의 해결은 실행시간에 makeArray(String.class) 와 같이 클래스 객체를 넘기고,
generics로 선언된 클래스안에서 해당 Class 인스턴스를 사용해 클래스를
new하는 것입니다. 이것도 하다보면 String.class 넘기고 String넘기고
하면서 이중 삼중 삽질이 될뿐더러 별로 직관적이지도 않습니다..

그러나 물론 이 두가지 문제를 잘 피해다니면, 쓸만합니다.
대신 너무 창의력을 발휘하면 안되죠 ㅎㅎ 굉장히 전형적인 코드만
잘 되니까요...

--
Passion is like genius; a miracle.

pool007의 이미지

Quote:
어노테이션은 무척 매력적인 기능입니다. 활용도가 무궁 무진 하리라고 생각합니다. 하지만 아직 실제 프로젝트에서 써본적은 없군요. 어노테이션 프로세서에 대해 좀 찾아보고 익히고 해야하는데 그러지 못하고 있네요.

아마 당분간은 쓸일 없지 않을까요..

http://www.artima.com/lejava/articles/jdbc_four3.html

에 보시면 재미있는 annotation이 있습니다. JDBC 코딩에서
거의 완전히 해방되게 만들어주는 @Query, @Update 와 같은
annotation들이요.

이거하고 다음 EJB 버젼이 나오면 많이 쓰게 되지 않을까 생각합니다. 완전히 닷넷처럼
그냥 annotation만 붙이면 클래스가 세션빈, 엔티티빈으로 변신하는
형태던데요. 무척 맘에 듭니다.

--
Passion is like genius; a miracle.

creativeidler의 이미지

저도 자바 5.0이 전반적으로 많이 좋아졌고 generics 외에는 크게 문제 삼을 부분이 없다는데 동의합니다. 전 개인적으로 모니터링 API 쪽이 가장 맘에 듭니다. 서버 관리 작업들을 많이 개선할 수 있게 되었죠.

그러나, 문제는 generics의 불쾌함이 적지 않다는 것입니다. 많은 사람들이 자바 generics의 문제로 generics의 구현 방식을 들지만 전 generics 자체가 싫습니다. 사실상 이제 퇴출되어야할 패러다임이라고도 생각하고 있죠. generics의 원래 목적은 Generic Programming입니다. Generic Programming은 type independent한 자료구조와 알고리즘을 구현할 수 있도록 추상화하는 것입니다. 그런데 자바는 이미 Object를 통해 Generic Programming이 가능한 언어입니다. auto boxing/unboxing을 통해 primitive type의 처리도 가능해졌구요. 그래서 generics 문법 없이도 충분히 Generic Programming이 가능합니다. 이런 상황에서 generics가 가져다 주는 이득은 컴파일 타임 에러 체킹이 하나 더 늘었다는 것 뿐입니다.

물론 저것도 장점이라고 할 수 있겠지만 실상 JUnit과 같은 유닛 테스팅이 일반화되고 있는 요즘에는 런타임 에러 체킹에 다 포함되기 때문에 개발 과정 전체에서 보면 이득이 없습니다. 그리고 사실 코딩하는 입장에서는 어차피 변수 선언시에 타입을 명시해야 하기 때문에 타입을 미리 알고 있어야 하는 사실은 변하지 않습니다. 캐스팅하는 것과 코딩에는 아무 차이가 없는 것이죠. LoC도 별반 줄어들지 않습니다.

그런데 반해 손해는 적지 않습니다. 자바 프로그래밍에서 javadoc API 문서의 비중을 생각해본다면 API가 커지고 지저분해지는 문제는 심각한 것이죠. 그리고 자바의 컬렉션이 다양한 방법으로 확장되서 사용된다는 점을 생각한다면 그 확장이 어려워진 것은 코드의 agility를 많이 떨어뜨립니다.

결국 자바의 generics는 본래 목적인 Generic Programming에는 별반 부가적인 이득을 주지 못하면서 단점만 안고 가는 셈이 되버린 것이죠.

그러나, generics의 문제에도 불구하고 Java 5.0은 유익합니다. generics의 불쾌함이 다른 장점들을 덮을 정도까진 아니니까요. 하지만 문제는 이제까지 한 문제에 대해서는 한 가지 방법으로 해결하는 것을 지향해온 자바가 한 문제에 두 가지 방법을 갖게 되었다는 것, 이로 인해 자바 문법의 가장 큰 장점인 단순성이 무너졌다는 것입니다. 실상 1.4까지의 자바의 문법은 현존하는 메이저 OOP 언어 중 가장 단순하다고 해도 과언이 아닙니다. 쉽다는 파이썬도 다중 상속, operator overloading 등 자바보다 복잡한 문법을 많이 갖고 있습니다. 자바는 쓰임새가 낮은 문법들을 과감히 제거하면서 명료함을 얻은 것인데 이제 문법이 복잡해져서 C++이나 파이썬, 루비 등에 대해 상대적으로 가져온 장점들이 희석되어 버린 것입니다.

어쨋든 자바는 2004년 이전까지 오랫동안 지켜오던 언어 사용율 1위 자리를 다시 C에게 내줬고 계속 하향세를 걷고 있습니다(비율상으로만). 파이썬, 루비, PHP, C# 등은 지속적인 증가세를 기록하고 있구요. 다양한 원인이 있겠지만 자바 5.0이 기대만큼 호응을 받지 못한 것이 원인 중 하나가 아닐까 합니다.

mykldp의 이미지

creativeidler wrote:
이런 상황에서 generics가 가져다 주는 이득은 컴파일 타임 에러 체킹이 하나 더 늘었다는 것 뿐입니다.

물론 저것도 장점이라고 할 수 있겠지만 실상 JUnit과 같은 유닛 테스팅이 일반화되고 있는 요즘에는 런타임 에러 체킹에 다 포함되기 때문에 개발 과정 전체에서 보면 이득이 없습니다. 그리고 사실 코딩하는 입장에서는 어차피 변수 선언시에 타입을 명시해야 하기 때문에 타입을 미리 알고 있어야 하는 사실은 변하지 않습니다. 캐스팅하는 것과 코딩에는 아무 차이가 없는 것이죠.

컴파일 타임 타입 체크와 런타임 타입 체크는 불꽃 튀기는 논쟁거리지요.:D 무지하게들 싸우는 문제이기는 하지만 어느쪽이 옳다 그르다를 떠나서 자바가 지향하는 방향은 분명히 컴파일타임 타입 체크입니다. 타입 파라메터가 없는 제너릭은 컴파일타임 타입 체크 관점에서 보면 타입 시스템에 구멍이 있는 거지요. 반드시 해결해야 할 문제입니다. 런타임 타입 체크를 지향하는 언어라면 별 문제 될 것이 없지만요. 제 생각에 자바가 런타임 타입 체크쪽으로 발전하기는 어려울 듯 합니다. 언어의 근본 패러다임중 하나가 바뀌는 셈이니까요. 대신에 파이썬, 루비등 런타임 체크를 지향하는 언어를 사용하던가, 자바의 수많은 라이브러리들을 버리기가 아깝다면 JVM위에서 돌아가고 런타임 타입 체크를 방식인 groovy 같은 언어를 사용하는 것이 좋다고 생각합니다.

creativeidler wrote:
한 문제에 대해서는 한 가지 방법으로 해결하는 것을 지향해온 자바가

이건 그냥 궁금해서 그러는 건데 "한 가지 문제에 한 가지 방법" 은 파이썬의 캐치프레이즈이지 않았나요? 자바에 대해서 이런 캐치프레이즈는 어울리지 않는다는 생각도 들고 들어본적이 없어서요. :)
creativeidler의 이미지

Quote:
컴파일 타임 타입 체크와 런타임 타입 체크는 불꽃 튀기는 논쟁거리지요. 무지하게들 싸우는 문제이기는 하지만 어느쪽이 옳다 그르다를 떠나서 자바가 지향하는 방향은 분명히 컴파일타임 타입 체크입니다. 타입 파라메터가 없는 제너릭은 컴파일타임 타입 체크 관점에서 보면 타입 시스템에 구멍이 있는 거지요. 반드시 해결해야 할 문제입니다. 런타임 타입 체크를 지향하는 언어라면 별 문제 될 것이 없지만요. 제 생각에 자바가 런타임 타입 체크쪽으로 발전하기는 어려울 듯 합니다. 언어의 근본 패러다임중 하나가 바뀌는 셈이니까요. 대신에 파이썬, 루비등 런타임 체크를 지향하는 언어를 사용하던가, 자바의 수많은 라이브러리들을 버리기가 아깝다면 JVM위에서 돌아가고 런타임 타입 체크를 방식인 groovy 같은 언어를 사용하는 것이 좋다고 생각합니다.

몇몇 자바 generics 논쟁에서 이 비슷한 이야기를 많이 접했습니다만 실상 자바가 strong typing을 지향한다고 볼 수는 없을 것 같습니다. 그냥 현재 strong typing 언어일 뿐이죠. type casting 자체를 없애지 않는 이상 런타임 타입 체킹이 완전히 없앨 수는 없습니다. 결국 이건 정도의 문제죠. 어디까지를 컴파일 타임에 체크하고 어디까지를 런타임에 체크할 것인가. 그런 정도의 문제입니다.

오히려 자바가 지향하는 것은 단순성입니다. 한 가지 문제에 한 가지 방법은 파이썬의 캐치프레이즈이긴 하지만 또한 자바가 1.0부터 줄곧 주장해왔던 단순성과도 관계되는 개념입니다. 사실 자바는 파이썬보다도 더 한 가지 방법을 중시합니다. 파이썬의 경우는 다중 상속과 operator overloading이 상당히 다양한 방식을 가능하게 합니다. 예를 들어 새로운 number 클래스를 만든다면 덧셈을 add 메소드로 만들 것인지 + 연산자로 만들 것인지 고민해야하죠. 자바라면 고민할 것 없이 add 메소드입니다. 이런 단순성이 자바에게는 중요한 힘이었죠.

카二리의 이미지

creativeidler wrote:
저도 자바 5.0이 전반적으로 많이 좋아졌고 generics 외에는 크게 문제 삼을 부분이 없다는데 동의합니다. 전 개인적으로 모니터링 API 쪽이 가장 맘에 듭니다. 서버 관리 작업들을 많이 개선할 수 있게 되었죠.

그러나, 문제는 generics의 불쾌함이 적지 않다는 것입니다. 많은 사람들이 자바 generics의 문제로 generics의 구현 방식을 들지만 전 generics 자체가 싫습니다. 사실상 이제 퇴출되어야할 패러다임이라고도 생각하고 있죠. generics의 원래 목적은 Generic Programming입니다. Generic Programming은 type independent한 자료구조와 알고리즘을 구현할 수 있도록 추상화하는 것입니다. 그런데 자바는 이미 Object를 통해 Generic Programming이 가능한 언어입니다. auto boxing/unboxing을 통해 primitive type의 처리도 가능해졌구요. 그래서 generics 문법 없이도 충분히 Generic Programming이 가능합니다. 이런 상황에서 generics가 가져다 주는 이득은 컴파일 타임 에러 체킹이 하나 더 늘었다는 것 뿐입니다.

물론 저것도 장점이라고 할 수 있겠지만 실상 JUnit과 같은 유닛 테스팅이 일반화되고 있는 요즘에는 런타임 에러 체킹에 다 포함되기 때문에 개발 과정 전체에서 보면 이득이 없습니다. 그리고 사실 코딩하는 입장에서는 어차피 변수 선언시에 타입을 명시해야 하기 때문에 타입을 미리 알고 있어야 하는 사실은 변하지 않습니다. 캐스팅하는 것과 코딩에는 아무 차이가 없는 것이죠. LoC도 별반 줄어들지 않습니다.

그런데 반해 손해는 적지 않습니다. 자바 프로그래밍에서 javadoc API 문서의 비중을 생각해본다면 API가 커지고 지저분해지는 문제는 심각한 것이죠. 그리고 자바의 컬렉션이 다양한 방법으로 확장되서 사용된다는 점을 생각한다면 그 확장이 어려워진 것은 코드의 agility를 많이 떨어뜨립니다.

결국 자바의 generics는 본래 목적인 Generic Programming에는 별반 부가적인 이득을 주지 못하면서 단점만 안고 가는 셈이 되버린 것이죠.

그러나, generics의 문제에도 불구하고 Java 5.0은 유익합니다. generics의 불쾌함이 다른 장점들을 덮을 정도까진 아니니까요. 하지만 문제는 이제까지 한 문제에 대해서는 한 가지 방법으로 해결하는 것을 지향해온 자바가 한 문제에 두 가지 방법을 갖게 되었다는 것, 이로 인해 자바 문법의 가장 큰 장점인 단순성이 무너졌다는 것입니다. 실상 1.4까지의 자바의 문법은 현존하는 메이저 OOP 언어 중 가장 단순하다고 해도 과언이 아닙니다. 쉽다는 파이썬도 다중 상속, operator overloading 등 자바보다 복잡한 문법을 많이 갖고 있습니다. 자바는 쓰임새가 낮은 문법들을 과감히 제거하면서 명료함을 얻은 것인데 이제 문법이 복잡해져서 C++이나 파이썬, 루비 등에 대해 상대적으로 가져온 장점들이 희석되어 버린 것입니다.

어쨋든 자바는 2004년 이전까지 오랫동안 지켜오던 언어 사용율 1위 자리를 다시 C에게 내줬고 계속 하향세를 걷고 있습니다(비율상으로만). 파이썬, 루비, PHP, C# 등은 지속적인 증가세를 기록하고 있구요. 다양한 원인이 있겠지만 자바 5.0이 기대만큼 호응을 받지 못한 것이 원인 중 하나가 아닐까 합니다.

동감합니다. 저도 JAVA5에서 generics가 들어간것 자체가 불만인 사람 입니다.
불만인 이유 조차도 똑같군요~
하지만 다른 JAVA5에서 추가된 점은 마음에 들기 때문에 어찌 해야 할지 눈치만 보고 있는 중입니다~

현재 현업에서 generics와 함께 JAVA5를 쓰고 있는 곳이 있는지 궁금합니다.

새 생각 :)

pool007의 이미지

creativeidler wrote:
물론 저것도 장점이라고 할 수 있겠지만 실상 JUnit과 같은 유닛 테스팅이 일반화되고 있는 요즘에는 런타임 에러 체킹에 다 포함되기 때문에 개발 과정 전체에서 보면 이득이 없습니다. 그리고 사실 코딩하는 입장에서는 어차피 변수 선언시에 타입을 명시해야 하기 때문에 타입을 미리 알고 있어야 하는 사실은 변하지 않습니다. 캐스팅하는 것과 코딩에는 아무 차이가 없는 것이죠. LoC도 별반 줄어들지 않습니다.

LoC 별반 안줄던가요? 저는 캐스팅이 지겨웠는데..

저는 다만 실시간 타입정보만 넘겨주면 자바 generics도 좋은데요. 그러나 이제와서 그런건 불가능하겠죠? 에혀..

--
Passion is like genius; a miracle.

creativeidler의 이미지

저도 첨엔 LoC가 줄 줄 알았는데 막상 해보니까 보

List list = getListFromRepository();
Type obj = (Type) list.get(1);

List<Type> list = getListFromRepository();
Type obj = list.get(1);

그냥 이거더라구요. (Type)이 <Type>으로 바뀌고 위치만 바뀌어서 들어가는 것 뿐이더라는-_- 글고 5.0 시범 적용으로 몇 개의 라이브러리를 generics 지원하게 변경하고 전체 byte 수를 재봤더니 컬렉션 몇 개 확장한 것 때문에 10% 가량 코드가 늘더군요. 그 이후로 자바 5.0 도입하자고 주장하려고 했던 저는 입을 꾹 다물었답니다-_-

kenny007one의 이미지

자바는 자바개발자 사이에서도 회의적으로 가는 중입니다.

C#이 아마도 조만간 하이레벨의 언어통일을 이루지 않을까 싶군요.

델파이의 오브젝트 파스칼의 창시자인 언더스 헤즐버그가

M$의 휘광을 엎으면 아마 볼랜드에서 델파이정도의 성공이라면

윈도우즈처럼 언어통일이 가능할것으로 보입니다.

컴파일러는 이제 자취를 감취게 되는 것일지도........ 휘릭

kenny007one의 이미지

자바는 자바개발자 사이에서도 회의적으로 가는 중입니다.

C#이 아마도 조만간 하이레벨의 언어통일을 이루지 않을까 싶군요.

델파이의 오브젝트 파스칼의 창시자인 언더스 헤즐버그가

M$의 휘광을 엎으면 아마 볼랜드에서 델파이정도의 성공이라면

윈도우즈처럼 언어통일이 가능할것으로 보입니다.

컴파일러는 이제 자취를 감취게 되는 것일지도........ 휘릭

pool007의 이미지

creativeidler wrote:
저도 첨엔 LoC가 줄 줄 알았는데 막상 해보니까 보

List list = getListFromRepository();
Type obj = (Type) list.get(1);

List<Type> list = getListFromRepository();
Type obj = list.get(1);

그냥 이거더라구요. (Type)이 <Type>으로 바뀌고 위치만 바뀌어서 들어가는 것 뿐이더라는-_- 글고 5.0 시범 적용으로 몇 개의 라이브러리를 generics 지원하게 변경하고 전체 byte 수를 재봤더니 컬렉션 몇 개 확장한 것 때문에 10% 가량 코드가 늘더군요. 그 이후로 자바 5.0 도입하자고 주장하려고 했던 저는 입을 꾹 다물었답니다-_-

생각하기 나름이지만 get을 여러번한다면 코드가 짧아지죠..
그러나 그건 중요한건 아니고..

코드가 길어지는게 문제인데요.
erasure라는걸로 일단 type을 몽땅 다 Object로 바꿔버리고
캐스팅 넣고 브리지 메소드 넣고하다보면 컴파일시에
코드가 길어집니다. 그리고 문제는 잘못하면 아무데서나
캐스팅을 해버려서 오히려 성능이 느려지지 않을까하는
점인데요...

SUN의 자체 입장에 따르면, '절대 안느리다'라고 합니다.
하지만 그거야 자기 회사 제품 자화자찬이니 믿을수가;;
자바가 너무 지나치게 H/W 발전에만 기대려고 하는거 아닌가 생각이
듭니다.

--
Passion is like genius; a miracle.

atie의 이미지

저도 끼어들어보죠. 제 경우는 이클립스가 5.0을 지원하는 것을 기다려서 5.0으로 넘어가는 지체했고 지금은 막상 5.0으로 코드를 변경하여도 실행이 될 기계용으로는 5.0이 나오지 않아서 제 데탑에서만 5.0과 1.4 동거 생활을 시키는 사람이지만 위의 분들이 얘기하듯 5.0의 제너릭이 문제라고 생각하지는 않습니다.

왜나면 어차피 1.4를 쓰면서도 오브젝트로 캐스팅을 하는 것은 명시를 해서 써왔습니다. 타입 세이프 제너릭을 쓴다고 해도 명시를 하는 것은 마찬가지 입니다. 코딩상에 어느 위치에 오느냐가 다를 뿐 달라진 것이 없습니다. 하지만 1.4에서는 런타임에 발견될 것을 일정 부분 이제는 컴파일 시에 문제가 있는 코드를 미리 발견할 수 있습니다.

그리고 타이거 발표하면서 제너릭은 콜렉션의 요소들에 대한 타입 캐스팅이 런타임에 발견되는 것을 막고 컴파일 시에 이를 발견하는데 유용하다고 밝혔기에 용도대로 사용을 하면 되는 것이고 사용 또한 옵션입니다. (물론 반쪽짜리 적용이어서 c#만큼 직관적이지 못한 것은 인정합니다.)

또한 enhanced for loop에서 쓰는 제너릭과

public void newFor(Collection<String> c) {
  for(String str : c) {
    sb.append(str);
  }
}

제너릭과 autoboxing을 쓰면 코드가 간결해져서 좋다고 봅니다.

List<Integer> list = new ArrayList<Integer>();
list.add(0, 59);
int total = list.get(0);

----
I paint objects as I think them, not as I see them.
atie's minipage

vacancy의 이미지

Down-casting을 줄일 수 있다는 것 만으로도
generics가 충분히 좋다고 생각하는데요.
Down-casting이 아무렇지 않다고 생각하시는건 아니겠죠. ;;

저도 Java에서 erasure로 generics를 구현한 게 싫어서
C# specification 2.0 제대로 나오면 옮겨탈까 싶네요. -_-
C#은 C#대로 C++마냥 복잡해져가는 것 같아서 좀 그렇지만서도
( operator overloading 같은 건 정말 싫어해서. -_- )
저건 좀 아닌 것 같더라고요.

죠커의 이미지

pool007 wrote:
또 한편 C++도 있는데. C++의 경우엔 템플릿 제대로 쓰기 어렵습니다.
템플릿이 사실 그냥 매크로나 마찬가지라서 code bloat를 막기위해서 공통 코드는 부모 클래스로 빼주어야하는데,
그걸 하는데도 문법이 까다롭습니다. 어떤 클래스가 템플릿인데,
그 클래스에서 operator<< 를 오버로딩하려면 또 까다롭습니다.
솔직히는 어떻게 저딴게 언어인가 싶을때가 한두번이 아닙니다..
그러나 물론 시장에서 많이 쓰이고 있고, 당분간 시장에서 많이 쓰일게
확실하고, 성능도 좋고, 이식성도 좋고 기타 등등의 이유가 있다는 생각에
열심히 공부해보려고 하고 있습니다.

늘어나는 인스턴스의 해답이 부모 클래스일까요?

http://bbs.kldp.org/viewtopic.php?t=64660#318266

pool007의 이미지

CN wrote:
pool007 wrote:
또 한편 C++도 있는데. C++의 경우엔 템플릿 제대로 쓰기 어렵습니다.
템플릿이 사실 그냥 매크로나 마찬가지라서 code bloat를 막기위해서 공통 코드는 부모 클래스로 빼주어야하는데,
그걸 하는데도 문법이 까다롭습니다. 어떤 클래스가 템플릿인데,
그 클래스에서 operator<< 를 오버로딩하려면 또 까다롭습니다.
솔직히는 어떻게 저딴게 언어인가 싶을때가 한두번이 아닙니다..
그러나 물론 시장에서 많이 쓰이고 있고, 당분간 시장에서 많이 쓰일게
확실하고, 성능도 좋고, 이식성도 좋고 기타 등등의 이유가 있다는 생각에
열심히 공부해보려고 하고 있습니다.

늘어나는 인스턴스의 해답이 부모 클래스일까요?

http://bbs.kldp.org/viewtopic.php?t=64660#318266

저와 초점이 살짝다르신거 같은데요.
인스턴스가 아니라 같은일을 하는 코드가 타입만 다르게
여러개가 나온다는 의미입니다. 실제 semantic은 클래스는
하난데 타입만 다르다는 것이구요.

CN님은 '인스턴스'를 얘기하신걸로봐서.. 그리고 첨부한
코드를 봐서는 '공간복잡도'를 말씀하시는 것 같은데 - 사실
명시적으로 코드에 설명도 없고해서 제가 이해를 잘 못했습니다 -
그에대한 해결도 결국은 vetor<void *> 상속에 초점이
있는 것 아닌지요. 다시말해서, 저장소를 부모로 빼던가,
아니면 저장소는 자식인데 부모가 자식에 와서 저장소를
찾던가 해야한다는 거죠.. 그리고 부분이 작성하기 까다롭다는
말은 EC++ 3판의 아이템중 하나를 지칭한 것입니다..

--
Passion is like genius; a miracle.

죠커의 이미지

pool007 wrote:
저와 초점이 살짝다르신거 같은데요.
인스턴스가 아니라 같은일을 하는 코드가 타입만 다르게
여러개가 나온다는 의미입니다. 실제 semantic은 클래스는
하난데 타입만 다르다는 것이구요.

클래스가 하나의 실체를 갖추게 되는 것도 인스턴스이지만 템플릿 함수나 클래스가 하나의 실체를 갖는 것도 인스턴스입니다. 사람들은 템플릿을 이용하면 인스턴스가 많아지지 않겠느냐고 생각을 하는 분도 있지만 그 템플릿 인스턴스의 수도 조절 가능한 하나의 패러미터입니다.

pool007 wrote:
CN님은 '인스턴스'를 얘기하신걸로봐서.. 그리고 첨부한
코드를 봐서는 '공간복잡도'를 말씀하시는 것 같은데 - 사실
명시적으로 코드에 설명도 없고해서 제가 이해를 잘 못했습니다 -
그에대한 해결도 결국은 vetor<void *> 상속에 초점이
있는 것 아닌지요. 다시말해서, 저장소를 부모로 빼던가,
아니면 저장소는 자식인데 부모가 자식에 와서 저장소를
찾던가 해야한다는 거죠.. 그리고 부분이 작성하기 까다롭다는
말은 EC++ 3판의 아이템중 하나를 지칭한 것입니다..

이 코드는 vector를 상속받아 vector를 구현하고 있습니다만 이 부분을 보는 것은 숲이 아닌 나무를 보는 것입니다. 이 코드는 고리타분한 고전 객체지향의 개념이나 idiom을 따르고 있는 것이 아닙니다.

더 자세히 보셔야 할 부분은 클래스 명 뒤에 <T*>라는 형태가 있다는 것입니다. 이것은 특화를 의미합니다. vector 클래스 중 특정 상황에 대해서 (이 경우에는 포인터 형의 사용) vector<void *>의 적용을 강제화시켜버린 것입니다. 위의 코드는 사실 vector를 상속받지 않아도 얼마든지 구현가능한 코드입니다.

vector의 특화를 이용해서 인터페이스를 확장한 것입니다. vector라는 명칭이 가진 인터페이스의 내용을 확장한 것입니다. 인용된 소스의 경우에는 공간 복잡도와 상관이 있지만 확장된 인터페이스를 통해서 더 나은 일(기능의 확장, 하드웨어 종속성의 극복, 정적 다형성의 확보)을 할 수도 있습니다.

직설적으로 말하자면 스캇 마이어는 틀렸습니다. 그가 매우 훌륭한 프로그래머인 것은 사실입니다만 그는 적어도 템플릿은 현대적인 (또는 진보적인) C++ 프로그래머에 비해 취약합니다. 보다 최신의 메타 프로그래밍 서적과 문서를 참고하시는 것을 추천드립니다.

이 쓰래드에서는 제너릭 프로그래밍을 단지 형을 담는 컨테이너라는 고전적인 개념으로 이해하시는 분들이 많은 것 같습니다. 제너릭 프로그래밍은 형에 자유로운 타입과 알고리즘을 만드는 단순한 컨테이너가 아닙니다. 그것은 낡은 개념입니다. 제너릭 프로그래밍은 객체 지향의 형태와 다른 형태의 "다형성"을 찾기 위한 노력입니다.

물론 template 키워드와는 달리 generic 키워드에서는 아직까지 주목할만한 다형성을 발견하지 못하고 있습니다. 하지만 우리는 template이 가진 정적 다형성이 우연히 발견되었다는 것을 생각해 볼 필요가 있습니다. 그래서 Herb Sutter와 같은 진보적인 C++ 표준 위원들이 generics에 관심을 가지고 C++에 적용을 테스트 해보는 것입니다.

이한길의 이미지

저는 방금 갈아타기로 했습니다..
또다시 아래로 갈아탈지도 모르지만 톰캣5.5는 jdk5를 사용한 모양이더군요
그래서 그냥 갈아 탈랍니다.. ^^*

----
먼저 알게 된 것을 알려주는 것은 즐거운 일이다!
http://hangulee.springnote.com
http://hangulee.egloos.com

creativeidler의 이미지

Quote:

생각하기 나름이지만 get을 여러번한다면 코드가 짧아지죠..

하지만 모 통계에 따르면 자바 프로그램의 90% 이상이 컬렉션 엘리먼트에 대한 get 작업은 for loop에서 iterator를 통해서 일어나며 코드에는 캐스팅이 딱 한 번 들어간다고 합니다.

그리고 사실 한 Map 안에 여러 타입이 저장되는 Data Trasfer Object 같은 경우는 generics는 아무 도움이 안되죠. 사실 자바의 Object는 generics보다 더 generic한 경우가 많습니다.

enhanced loop의 경우는

	public void newFor(Collection list) {
		for(Object obj: list) {
			((StringBuffer) obj).append("abc");
		}
	}

괄호 두 개 더 들어가는 차이군요.

auto boxing/unboxing

		List list = new ArrayList();
		list.add(10);		
		int a = (Integer) list.get(0);

이 쪽이 더 짧군요.

p.s. 이런 문제는 가급적 코드로 대화했으면 하는 바램입니다.

atie의 이미지

creativeidler wrote:
...

enhanced loop의 경우는

	public void newFor(Collection list) {
		for(Object obj: list) {
			((StringBuffer) obj).append("abc");
		}
	}

괄호 두 개 더 들어가는 차이군요.

auto boxing/unboxing

		List list = new ArrayList();
		list.add(10);		
		int a = (Integer) list.get(0);

이 쪽이 더 짧군요.
...

그렇죠, 이미 위의 코드는 5.0에서 작성이 되었으니까요. 위에 제가 썼던 글을 다시 인용하죠.
atie wrote:
왜나면 어차피 1.4를 쓰면서도 오브젝트로 캐스팅을 하는 것은 명시를 해서 써왔습니다. 타입 세이프 제너릭을 쓴다고 해도 명시를 하는 것은 마찬가지 입니다. 코딩상에 어느 위치에 오느냐가 다를 뿐 달라진 것이 없습니다. 하지만 1.4에서는 런타임에 발견될 것을 일정 부분 이제는 컴파일 시에 문제가 있는 코드를 미리 발견할 수 있습니다.

----
I paint objects as I think them, not as I see them.
atie's minipage

creativeidler의 이미지

네, 저도 위에서 밝혔듯 5.0에서 generics 외의 기능들은 다 좋다고 봅니다. 딱히 atie님 글에 반론을 하기 위해서라기보다 이건 좀더 코드에 가까운 대화가 되었으면 하는 바램에서 atie님 코드를 인용한 것이구요. 어쨋든 결국 코드 상에 이점이 없다는 데는 동의하시는 분이 적지 않은 것 같군요.

vacancy의 이미지

LOC 얘기를 떠나서 -_-a ..
Generics를 쓰면 없어도 될 down-casting을
굳이 generics를 쓰지 않고 down-casting할 필요가 있나요.

Down-casting의 경우 compile-time에 거의 나몰라라;하겠다는 건데,
웬만하면 피해야할 일이라고 생각하는데요. ;;

Generics를 써서 compile-time에 type checking도 더 잘 할 수 있고요.
( 예를 들어, 함수 parameter 등으로 Collection을 넘기거나 할 때라던가; )

타이핑 얼마나 더하고 덜하고는 별 상관없는 문제라고 봅니다. -_-a

atie의 이미지

부연해서, 자바의 제너릭에 대한 반론은 위에 mykldp님이

Quote:
캐스팅을 없애준다고 하지만 이는 캐스팅 삽질을 감춰놓은 것에 불과합니다.

이렇게 쓰셨지만, 실상은 모든 것을 Object로 auto casting (삽질을 감춰놓은 거죠)을 하는 것입니다. (erasure) 즉, any type이 아니라 only Object이라는 거죠.
이게 다른 언어 (C++, python, ruby)에서의 제너릭의 의미와 자바에서의 제너릭의 의미가 다른 점이고 이것이 "자바에서의 제너릭"이구나라고 이해를 하고쓰면 된다는 것이 제 의견입니다. 물론 위의 다른 분들은 제너릭이 anything이 아닌 것이 아쉬워서 의견을 내신 것으로 이해합니다.

----
I paint objects as I think them, not as I see them.
atie's minipage

creativeidler의 이미지

Quote:
LOC 얘기를 떠나서 -_-a ..
Generics를 쓰면 없어도 될 down-casting을
굳이 generics를 쓰지 않고 down-casting할 필요가 있나요.

Down-casting의 경우 compile-time에 거의 나몰라라;하겠다는 건데,
웬만하면 피해야할 일이라고 생각하는데요. ;;

Generics를 써서 compile-time에 type checking도 더 잘 할 수 있고요.
( 예를 들어, 함수 parameter 등으로 Collection을 넘기거나 할 때라던가; )

타이핑 얼마나 더하고 덜하고는 별 상관없는 문제라고 봅니다. -_-a

타이핑 얼마나 더하고 덜하고가 얼마나 중요한지는 언어의 역사를 보면 알 수 있습니다. 코드 사이즈가 줄면 프로그래머가 작성해야하는 코드량이 줄어 빠른 시간에 작성할 수 있고 코드를 보는 사람도 적은 양만 이해해도 되죠.

그리고 10라인 룰이라는 게 있습니다. 언어의 종류와 프로그램의 전체 사이즈와 상관 없이 10라인 당 하나의 버그가 발생할 확률이 있다는 이론이죠. 10 word line, 10개의 단어로 한 줄을 구성할 경우 가장 빠르게 읽을 수 있다는 것과 비슷한 이야기로 인간의 단기 기억 단위가 7개 안팎이라는 데서 기인하는 현상이라고 합니다. 즉, 코드 사이즈가 늘면 버그 발생도 증가합니다.

그리고 한 5년 전쯤이라면 컴파일 타임 타입 검사가 아주 설득력 있는 이슈일 수도 있었을 겁니다. 하지만 지금은 많은 자바 프로젝트에서 JUnit을 통한 유닛 테스트를 필수로 하고 있고 이런 상황에서 테스트 한 번 돌려보면 타입 에러는 전부 검출이 되기 때문에 어차피 프로젝트 전체의 개발 과정에서 보면 컴파일 타임 타입 검사는 아무런 이득이 되지 못합니다.

그리고 7년 동안 void*를 써왔지만 한 번도 타입 문제로 골치 썩힌 일이 없다는 한 C++ 프로그래머의 고백처럼 자바 역시 List나 Map 쓰면서 안에 있는 타입이 뭔지 몰라서 삽질하는 경우는 극히 드뭅니다. 코드로 잠깐 예를 들어보면..

List list = getDataList();
ClassA = (ClassA) list.get(0);

여기서 두번째 라인이 컴파일 타임 에러를 발생시키지 않으면서 런타임 에러를 발생시키는 경우는 list 안에 뭐가 들어 있는지 모르는 경우 뿐입니다. 뭐가 들어 있는지도 모르는 list에서 객체를 빼내서 쓰겠다는 상황 설정 자체가 모순이죠. 그래서 컴파일 타임 타입 검사는 허구라고 주장하는 것입니다.

이야기를 조금 바꿔볼까요. dynamic language에선 아예 타입 캐스팅도 없고 generics도 없고 template도 없지만 누구도 컬렉션 안의 타입을 몰라서 삽질하는 문제를 이야기하지 않습니다. 사실 generics나 template은 Generic Programming을 위한 것이고 Generic Programming이 진짜 완성되는 것은 dynamic language를 통해서이죠. generics는 단지 발전 과정의 중간 단계에 불과합니다. 파이썬을 쓰다보면 아, 이게 진짜 Generic Programming이구나 싶을 ㅤㄸㅒㅤ가 많죠.

파이썬에서 하는 재미 있는 이야기 하나를 잠깐 옮겨 봅니다.

Quote:

Q : 파이썬에서 다음 C++ 코드처럼 상수를 사용하려면 어떻게 해야 하나요?
const int MAX = 50;

A : 다음과 같이 쓰고 MAX 값을 바꾸지 마세요.
MAX = 50


말하자면, MAX의 값을 변경하는 것을 막기 위해 const니 final이니 하는 키워드들이 언어마다 있지만 대체 어느 누가 상수인 줄 몰라서 그 값을 바꾸는 실수를 하냐, 그런 걸로 문법 하나 더 추가할 필요는 없다. 그런 얘기죠. 컴파일 타임 타입 검사도 같은 차원에서 생각할 수 있는 일이라고 봅니다.
fender의 이미지

오랜만에 답글 쓰는 군요 :)

creativeidler wrote:
타이핑 얼마나 더하고 덜하고가 얼마나 중요한지는 언어의 역사를 보면 알 수 있습니다. 코드 사이즈가 줄면 프로그래머가 작성해야하는 코드량이 줄어 빠른 시간에 작성할 수 있고 코드를 보는 사람도 적은 양만 이해해도 되죠.

일반적으로 반드시 코드량이 가독성과 반비례 한다고 생각하지 않습니다. 오히려 프로그래밍을 하면서 가독성을 위해 짧게 축약해서 쓸 수 있는 것을 좀 더 길게 늘여 쓰거나, 아니면 약간 다른 이야기가 되겠지만 한 클래스나 메소드 안에서 모두 해결할 수 있는 것을 굳이 별도의 클래스나 인터페이스, 혹은 메소드로 분리해내는 경우도 흔히 있습니다.

말씀하신 '10 줄 법칙'이라는 것도 어느 정도 'rule of thumb'으로서의 가치는 있겠지만 모든 경우, 모든 언어에 적용되는 황금율이 되긴 어렵다고 봅니다. 극단적으로는 '아희' 같은 경우도 있으니까요;

creativeidler wrote:
그리고 한 5년 전쯤이라면 컴파일 타임 타입 검사가 아주 설득력 있는 이슈일 수도 있었을 겁니다. 하지만 지금은 많은 자바 프로젝트에서 JUnit을 통한 유닛 테스트를 필수로 하고 있고 이런 상황에서 테스트 한 번 돌려보면 타입 에러는 전부 검출이 되기 때문에 어차피 프로젝트 전체의 개발 과정에서 보면 컴파일 타임 타입 검사는 아무런 이득이 되지 못합니다.

이론적으로는 개발하는 코드의 전체 부분에 대한 단위 테스트를 짜는 것이 이상적이겠고, 기술적으로도 JUnit에 덧붙여 각종 Coverage 툴을 함께 사용한다면 불가능 한 것도 아닙니다.

하지만 현업에서 복잡한 시스템을 그런 식으로 개발한다는 것 자체가 사실상 불가능하다고 생각하며, 더구나 단순히 모든 클래스와 메소드에 대해 하나씩 테스트 케이스를 작성한 다는 것과 실제 사용시 해당 메소드에 넘겨질 수 있는 모든 인자값의 경우의 수와 이에 따른 코드 패스를 일일이 다 테스트한다는 건 쉽게 가능한 일이 아닙니다.

컬렉션의 예의 경우, 말씀하신 대로 코딩을 한 개발자는 당연히 해당 컬렉션에 어떤 형이 들어있는지 알 수 있지만 실무에서 여러 명이 협업을 하거나 공통으로 사용하는 라이브러리를 제작하는 경우는 완전히 문제가 다릅니다.

예를들어 Collection getAllProducts(); 라고 인터페이스를 정의하고 굳이 주석에 'Product의 컬렉션을 반환합니다'라고 적는 것 보다는 Collection<Product> getAllProducts();라고 하는 것이 훨씬 직관적이고 안전하다고 봅니다.

실제로 오픈소스 라이브러리들을 사용하는 중에 흔히 겪는 문제로, IDE를 이용해 코딩하는 중 컬렉션을 반환하는 메소드를 사용할 때 정확한 타입을 몰라서 API를 참조하거나 로그를 찍어보고 다시 코딩하는 경우가 종종 있습니다. 이런 문제를 단 10여 글자를 더 타이핑해서 해결할 수 있다면 저는 당연히 그런 방법을 사용해야 한다고 생각합니다.

----------------------------
[서명] 그놈 한국 사용자 모임 - 그놈에 대한 모든 것! - 게시판, IRC, 위키, 갤러리 등등...

creativeidler의 이미지

Quote:

일반적으로 반드시 코드량이 가독성과 반비례 한다고 생각하지 않습니다. 오히려 프로그래밍을 하면서 가독성을 위해 짧게 축약해서 쓸 수 있는 것을 좀 더 길게 늘여 쓰거나, 아니면 약간 다른 이야기가 되겠지만 한 클래스나 메소드 안에서 모두 해결할 수 있는 것을 굳이 별도의 클래스나 인터페이스, 혹은 메소드로 분리해내는 경우도 흔히 있습니다.

말씀하신 '10 줄 법칙'이라는 것도 어느 정도 'rule of thumb'으로서의 가치는 있겠지만 모든 경우, 모든 언어에 적용되는 황금율이 되긴 어렵다고 봅니다. 극단적으로는 '아희' 같은 경우도 있으니까요;


물론 이것이 절대적인 법칙은 아닙니다. 어디까지나 경향성의 문제죠. 만약 generics 사용으로 코드 가독성이 향상된다면 코드량 좀 늘어나는 건 별 문제가 아닐 수도 있습니다. 하지만 실질적으로 generics를 쓸 때의 가독성 향상은 미미한 반면 generics를 적용해서 컬렉션을 extend할 때는 가독성이 엄청나게 떨어집니다. 난잡하다고 말해도 과언이 아니라고 봅니다. 더 심각한 것은 API 문서의 가독성마저 심각하게 떨어뜨린다는 것입니다.

여러 사람이 개발할 때도 문제가 별반 다르지 않습니다. 제시하신 예에서 Collections<Product> getAllProducts()라는 메소드를 IDE 자동 완성으로 쓸 수 있다고 해서 그 메쏘드가 무슨 일을 하는지까지 알 수 있는 것은 아니죠. 무슨 일을 하는지 알려면 어차피 API 문서를 보든가 물어보든가 소스를 보든가 해야 합니다. 그러면 그 과정에서 어차피 Product가 담겨 있다는 사실을 알 수 있습니다. 이것은 컴파일 타임 타입 검사가 어차피 런타임 타입 검사에서 다 걸린다는 것과 같은 논리죠. 어차피 하는 일에 포함되어 있기 때문에 실질적인 일을 증가시키지 않는다는 것입니다.

Quote:
이론적으로는 개발하는 코드의 전체 부분에 대한 단위 테스트를 짜는 것이 이상적이겠고, 기술적으로도 JUnit에 덧붙여 각종 Coverage 툴을 함께 사용한다면 불가능 한 것도 아닙니다.

하지만 현업에서 복잡한 시스템을 그런 식으로 개발한다는 것 자체가 사실상 불가능하다고 생각하며, 더구나 단순히 모든 클래스와 메소드에 대해 하나씩 테스트 케이스를 작성한 다는 것과 실제 사용시 해당 메소드에 넘겨질 수 있는 모든 인자값의 경우의 수와 이에 따른 코드 패스를 일일이 다 테스트한다는 건 쉽게 가능한 일이 아닙니다.


컬렉션의 타입 문제는 모든 클래스를 테스트해야할 필요도 없고 단 한 번 그 코드가 포함된 다른 테스트라도 실행되면 바로 드러납니다. 어차피 generics로 해결할 수 있는 문제라면 collection 안에 들어가는 타입이 동적으로 바뀌는 것도 아닐 것이고 그런 경우는 따로 테스트를 하지 않고 실행만 한 번 해봐도 다 걸리게 되어 있습니다. 굳이 TDD 등을 하지 않더라도 말이죠.

한 가지 더 이의를 제기한다면 그 사실상 불가능한 일이 이미 현실인 곳도 많습니다. 요즘은 "어떻게 테스트도 안 만들고 메소드를 만들지?"라고 말하는 개발자도 있답니다.

제가 generics에 제기하는 문제는 generics를 사용할 때 코드량이 늘어난다는 것이 아니라 generics를 사용할 때 코드량을 줄여주지도 못하면서 컬렉션을 extend할 때는 코드가 지저분해지고 덩달아 API 문서까지 지저분해진다는 것입니다. 즉, 코드량에 대한 것은 generics의 단점으로 지적한 것이 아니라 장점이 아니라는 의미에서 지적한 것이고 단점은 오히려 말씀하신 코드 가독성과 API 문서 가독성이 떨어진다는 것입니다.

atie의 이미지

얘기가 제너릭에서 뱅뱅도는 느낌이어서 좀 더 포괄적으로 5.0으로 갈아타야 되는 이유를 이야기한 문서들의 링크를 걸어 주제에 부합해 보도록 하겠습니다.

우선, 썬에서 나온 문서들 중에 세 가지를 뽑아보죠.
첫 번째 문서는 5.0으로 이전하는 이유
두번째 문서는 5.0 performance
세번째는 종합판 5가지 이유

다음은 generics, annotations, enumerated types, autoboxing, varargs, the for/in loop, and even static imports 외에 5가지 favorite API를 소개한 이 글

위의 링크 정도만 읽어봐도 5.0으로 갈아타는 이유는 충분합니다. 덤으로
Walmart의 5.0 이전에 대한 이 글도 읽어볼만 하고요. 이 밖에도 5.0의 XML 지원, Collection과 AWT 변화, JVM 향상 등등 이야기할 것이 많습니다.

주제를 환기하고자 해서 링크를 걸었으니 제너릭 외에 다른 건도 논의가 되었으면 합니다.

----
I paint objects as I think them, not as I see them.
atie's minipage

pool007의 이미지

썬이 JAVAONE의 자료를 공개로 제공하고 있습니다.
http://developers.sun.com/learning/javaoneonline/

기존에는 PDF만 다운로드 가능했고, 멀티미디어 자료는 일년에
대략 10만원을 좀 넘게 내고 보아야했습니다만 이제는 무료로
제공되고 있습니다.

JDK5의 내용도 많이 다뤄지고 있는 듯 하구요..

--
Passion is like genius; a miracle.

lunarboy의 이미지

ClassCastException의 문제가 그동안 과장된 측면도 있고, 그 문제를 떠들고 다니던 사람들이 이제와서 별 문제 아니다라고 시치미 떼는 측면도 있다고 봅니다.
그리고, 자바에서 Generics 사용에 들어가는 비용에 비해 얻어지는 것이 거의 Type-safe Collections 뿐이라는 것 때문에, 하나의 코드에 여러 타입을 적용할 수 있는 이른바 코드-다형성(?)을 기대하던 사람들이 많이 실망하고 있는 것 같습니다.
JCP의 입장에서는 Migration 및 하위 호환성을 위해 실시간 타입 정보를 지워버릴 수 밖에 없었다고(Erasure) 강변할 수 있고, 일리있는 주장이라 봅니다. 그렇지 않으면 기존 라이브러리들을 두가지 버전(generic 버전과 non-generic 버전)으로 관리해야 하는 끔직한 상황을 초래하게 되니까요.
표준 라이브러리야 런타임과 같이 배포되니까 그런다 치더라도 수많은 그 외 경우에는 엄청난 비용을 치러야 할 겁니다.
저도 Generic 자체를 자바에서 뺐으면 하지만, 지금 상황은 이렇게 되었고...
뭐... 일반적인(?) 제너릭을 위해서는 Class<T> 타입을 생성자의 매개변수로 Parameterize시켜서 Type-Injection을 직접 구현하거나, NextGen(http://japan.cs.rice.edu/nextgen/)같은 것을 이용하거나, 1.4 버전만 주구장창 쓰거나, 1.5 버전의 다른 매력적인 부분 때문에 generic문법의 일부 불편함을 감수하거나 이겠네요. 아니면 자바를 버리거나? 헤...

이한길의 이미지

creativeidler wrote:
파이썬에서 하는 재미 있는 이야기 하나를 잠깐 옮겨 봅니다.
Quote:

Q : 파이썬에서 다음 C++ 코드처럼 상수를 사용하려면 어떻게 해야 하나요?
const int MAX = 50;

A : 다음과 같이 쓰고 MAX 값을 바꾸지 마세요.
MAX = 50


말하자면, MAX의 값을 변경하는 것을 막기 위해 const니 final이니 하는 키워드들이 언어마다 있지만 대체 어느 누가 상수인 줄 몰라서 그 값을 바꾸는 실수를 하냐, 그런 걸로 문법 하나 더 추가할 필요는 없다. 그런 얘기죠. 컴파일 타임 타입 검사도 같은 차원에서 생각할 수 있는 일이라고 봅니다.

뭐.. 꼭 딴지걸려는 생각은 아니지만..
어느누가 상수인줄 모르고 실수할 수도 있습니다..
프로그래밍을 하루나 단기간에 뚝딱하면 모를까..
시간이 지나다보면 착각도 합니다.

위는 변수 이름이 MAX 니까.. 그래도 좀 낫겠지만...
그렇지 않은 수도 배제할 수는 없습니다.

예전에 C++와 C에 대한 토론 가운데에서도 저는 늘 주장했듯이..
컴파일러/인터프리터는 인간의 실수를 막아주려는 노력을 해야 합니다. 지금도 그 입장은 변함이 없습니다.

그런 의미에서...

자바5로 옮기고 제네릭에 대해 처음에는 불만이었지만..
꼭 그럴필요는 없다는 생각이 들었습니다.

일반적인 프로그래머가 원하던 제네릭이 아닐 뿐이었던것 같습니다.

atie님의 말씀처럼 좀더 포괄적인 토의도 계속 진행되면 좋겠네요.

----
먼저 알게 된 것을 알려주는 것은 즐거운 일이다!
http://hangulee.springnote.com
http://hangulee.egloos.com

litdream의 이미지

다른건 몰라도, 좀 빨라진것 같긴 하던데요?
( 생뚱맞나요? 헐.. )

삽질의 대마왕...

iolo의 이미지

자바5로 옮겨타야한다면 그 이유가 제네릭스만은 아니죠^^;

문법적인 측면에서 보면:
1. 오토박싱
2. 제네릭스
3. 어노테이션
4. Enum
5. 가변 인자
6. 향상된 for문
7. 스태틱 임포트

그외:
1. 성능향상(스타트업타임,런타임)
2. 뽀대향상(스윙쓸일은 별로 없긴하지만)

전 아직 자바5로 옮겨탄 상태는 아닙니다만... 1.5.2가 나오면 그때 본격적으로 옮겨타려고 생각만 하고 있습니다. 아직은 버그퍼레이드에 대기중인 버그가 너무 많아요~.~

----
the smile has left your eyes...

kenny007one의 이미지

자바 5는 곧 프레임웍에서는 C#에 밀릴 예정이고 웹에서는 PHP 5에 힘을 못쓰고 있습니다.

이미 유명 웹의 개발자들(네스케이프의 마크 안드리센)조차도 웹에서는 자바보단 PHP가 평정할거라고 예언했습니다.

그럼 다른 분야에서라도 선전해야 되는데..

C#의 기세가 만만찬습니다.

이미 공개표준으로 C#이 채택되었기때문에 SUN의 자바는 제약이 많지요.

C#으로 한번 개발해 보면 느낄겁니다.

자바랑 차원이 틀린 개발속도와 디버깅이 가능해집니다.

결국 제 예상엔 C#이 언어 천하통일을 이룩하지 않을까 합니다.

자바는 그 태생적 한계점인 VM이 발목을 잡기에 그것을 극복하고 나온 C#의 유연함은 절대 따라잡을수가 없을 겁니다.

stadia의 이미지

kenny007one wrote:
자바 5는 곧 프레임웍에서는 C#에 밀릴 예정이고 웹에서는 PHP 5에 힘을 못쓰고 있습니다.

씨샵을 기반으로 한 프레임웍이 뭐가 있나요?
닷넷프레임웍 말씀하시는건가요?

fender의 이미지

kenny007one wrote:
자바 5는 곧 프레임웍에서는 C#에 밀릴 예정이고 웹에서는 PHP 5에 힘을 못쓰고 있습니다.

언제 자바가 C#/.NET에 밀릴 '예정'인지는 모르겠습니다만 지금 현재 엔터프라이즈 시장은 자바가 장악하다 시피 한 상태고 .NET이 조금 씩 치고 올라오는 중입니다. 그리고 '프레임워크'에서 밀린다고 하셨는데 도대체 서버 쪽에 쓰이는 닷넷 프레임워크가 몇 개나 된다고 그런 말씀을 하시는 지 모르겠군요.

kenny007one wrote:
이미 유명 웹의 개발자들(네스케이프의 마크 안드리센)조차도 웹에서는 자바보단 PHP가 평정할거라고 예언했습니다.

뭐 세상에는 다양한 생각의 전문가들, 개발자들이 있습니다만 구글링 해보시면 반대로 J2EE에 비해 PHP의 단점을 지적하는 수 많은 전문적 의견들도 널려 있습니다. 굳이 마크 안드리센이 얼마나 유명한 사람이고 하는 논쟁은 사양하고 싶습니다. 이전 mysql/pgsql 처럼 무익하게 얼마나 유명한 회사가 쓰니까 좋은 제품이니 하는 이야기는 건설적인 결론을 얻기 힘드니까요.

kenny007one wrote:
이미 공개표준으로 C#이 채택되었기때문에 SUN의 자바는 제약이 많지요.

JCP라는 건 아시는지요? 또 닷넷 프레임워크 중의 핵심을 제외한 극히 일부만 ECMA에서 관리한다는 건 아십니까?

kenny007one wrote:
자바랑 차원이 틀린 개발속도와 디버깅이 가능해집니다. 결국 제 예상엔 C#이 언어 천하통일을 이룩하지 않을까 합니다.

근거를 제시하지 않은 주장은 굳이 반박하고 싶지 않지만 IDE나 툴 지원이 아닌 언어 자체 기능만 보면 C#이 자바보다 '차원이 다르게' 좋은 점이 뭐가 있던가요? 개인적으로 플랫폼이 아닌 언어로서 C#이 자바보다 발전한 부분이 있음을 알고 있습니다만 문법적 개선사항이 IDE 지원이나 방대한 라이브러리의 존재 유무보다 생산성 측면에서 '엄청나게' 중요하다고 보지 않습니다.

kenny007one wrote:
자바는 그 태생적 한계점인 VM이 발목을 잡기에 그것을 극복하고 나온 C#의 유연함은 절대 따라잡을수가 없을 겁니다.

닷넷은 VM이 아닌지요?

마지막으로 플레임을 즐기시는 건 이해하겠습니다만, 이 글타래의 주제는 '자바 5.0으로 갈아타야 하는 가'임을 다시 한 번 주지시켜 드리고 싶습니다.

----------------------------
[서명] 그놈 한국 사용자 모임 - 그놈에 대한 모든 것! - 게시판, IRC, 위키, 갤러리 등등...

anarch의 이미지

우선 마크 안드레선은 지금 젠드에 있을 겁니다... 사실 마크가 말한건
좀 마케팅적인 느낌을 지울수가 없는군요..

자바의 Spring 이나 Hibernate같은 오픈소스는 이미 닷넷버젼으로 구현되거나 하려고 합니다.. Spring.net,Nhibernate ..
근데 닷넷 프래임워크에서 자바로 컴버젼된건 뭐가 있나요?

JVM이나 .Net의 CLR이나 VM은 매한거지 일거 같은데요.:-)

kwon37xi의 이미지

kenny007one wrote:
자바 5는 곧 프레임웍에서는 C#에 밀릴 예정이고 웹에서는 PHP 5에 힘을 못쓰고 있습니다.

정확히 프레임웍의 의미가 무엇인지요?
대체 님의 말씀에서 저 말의 의미가 무엇인지 전혀 이해가 안됩니다. C#의 프레임웍은 뜨면서 웹 개발 쪽에서는 PHP가 석권한다는 건가요?

그럼 웹 쪽에서는 C#도 힘을 못쓴다는 의미인가요?

그렇다면 대체 "프레임웍"이 강한 C#은 어느 분야에서 쓰이게 될까요?
C#은 그럼 웹쪽 보다는 GUI어플리케이션과 Web Services 같은 분야에서만 쓰이게 되나요??

아니.. 그보다 먼저.. 대체 님이 말씀하신 프레임웍이 뭘까요?

말꼬리 잡지 않고, 그냥 단도직익적으로 말씀드리면, 님의 글을 보다보면 스스로 깊이 있는 이해가 있어서 글을 쓰는 것이라기 보다는 신문에서 어설픈 IT기자들이 쓴 단편적인 내용들을 제대로 이해도 못한 상태에서 사실인양 쓰고 있다는 느낌을 지울 수 없습니다.

저는 KLDP를 좋아하고, 여기서 일어나는 논쟁들을 좋아합니다. 하지만 논쟁에 잘 안끼어들고, 그냥 구경하면서 즐기는(?) 편이거든요... 아는게 없어서 끼어들 여지가 별로 없거든요..

어쨌든 가끔 보이는 건설적인 논쟁들은 정말 저를 즐겁게 하고 많은 지식을 전해줍니다.

요즘 님을 보면서, 왜 자꾸 확인도 안되고 정확히 파악도 못하고 있는 루머들을 가지고 불필요하고 소모적이고, 잘 모르는 사람들에게 정말 말도 안되는 오해를 하게 만드는 플레임성 글을 올리시는지...

논쟁을 유발하시는 건 좋지만 건설적인 방향으로 이끌고 가셨으면 좋겠습니다.

다즐링의 이미지

글쎄요...

지금 자바 개발자들 못구해서 난리인데..

(포탈쪽이라 그런가요?)

대세에서 밀릴 자바개발자들 여기 2분승차하세요.

(농담이 아니라 진짜니까 메시지로 연락주세요)

------------------------------------------------------------------------------------------------
Life is in 다즐링

ssif의 이미지

다즐링 wrote:
글쎄요...

지금 자바 개발자들 못구해서 난리인데..

(포탈쪽이라 그런가요?)

대세에서 밀릴 자바개발자들 여기 2분승차하세요.

(농담이 아니라 진짜니까 메시지로 연락주세요)

신입도 가능합니까?

봄들판에서다

다즐링의 이미지

글쎄요.. 신입은 좀 무리일꺼 같습니다.

개인적으로는 똑똑하고 패기 넘치는 신입이 좋습니다만.

회사에서는 안좋아할꺼 같군요. 2~3년차는 되어야할거 같습니다.

------------------------------------------------------------------------------------------------
Life is in 다즐링

ssif의 이미지

다즐링 wrote:
글쎄요.. 신입은 좀 무리일꺼 같습니다.

개인적으로는 똑똑하고 패기 넘치는 신입이 좋습니다만.

회사에서는 안좋아할꺼 같군요. 2~3년차는 되어야할거 같습니다.

음....역시 대새는 경력자군요.
답 글 감사합니다. :)

봄들판에서다

kenny007one의 이미지

다즐링 wrote:
글쎄요.. 신입은 좀 무리일꺼 같습니다.

개인적으로는 똑똑하고 패기 넘치는 신입이 좋습니다만.

회사에서는 안좋아할꺼 같군요. 2~3년차는 되어야할거 같습니다.

경력자만 원하는 회사들때문에 청년실업자가 늘어나고 소비의 주체인 청년들이 돈이 없으니 계속 경기가 침체되는 겁니다.

처음부터 잘하는 사람이 어디있습니까

회사들은 신입을 키워서 장기전략으로 몇년후를 보고 채용해야 합니다.

대기업은 보통 2년정도를 보고 신입을 뽑습니다.

왜 근데 벤처라는 도전정신을 가진 회사가 경력자를 뽑을까요?

벤처라면 더더욱 사람을 뽑는데 있어서 도전정신으로 그 사람의 가능성을 보고 모험을 해야 합니다.

여러분 경력자만 뽑는곳은 가지 마십시오 뻔합니다.

신입도 같이 뽑는 곳을 지원해야 그 회사의 제대로 된 마인드를 압니다.

ssif의 이미지

kenny007one wrote:
다즐링 wrote:
글쎄요.. 신입은 좀 무리일꺼 같습니다.

개인적으로는 똑똑하고 패기 넘치는 신입이 좋습니다만.

회사에서는 안좋아할꺼 같군요. 2~3년차는 되어야할거 같습니다.

경력자만 원하는 회사들때문에 청년실업자가 늘어나고 소비의 주체인 청년들이 돈이 없으니 계속 경기가 침체되는 겁니다.

처음부터 잘하는 사람이 어디있습니까

회사들은 신입을 키워서 장기전략으로 몇년후를 보고 채용해야 합니다.

대기업은 보통 2년정도를 보고 신입을 뽑습니다.

왜 근데 벤처라는 도전정신을 가진 회사가 경력자를 뽑을까요?

벤처라면 더더욱 사람을 뽑는데 있어서 도전정신으로 그 사람의 가능성을 보고 모험을 해야 합니다.

여러분 경력자만 뽑는곳은 가지 마십시오 뻔합니다.

신입도 같이 뽑는 곳을 지원해야 그 회사의 제대로 된 마인드를 압니다.

음.... 위 글에대한 논의는 다른 글을 열어서 시작해주셨으면 합니다.(이유는 처음 글과 다른 방향의 글이 오갈까봐서 그렇습니다. kenny007one 님께 제안을 드립니다.)

제가 처음 글과 관련없는 글을 올려서 전체 구성을 흐트린 점 모든분들께 사과드립니다.

봄들판에서다