<div><br></div><a target="_blank" href="http://www.todayhumor.co.kr/board/view.php?table=programmer&no=9129" target="_blank">http://www.todayhumor.co.kr/board/view.php?table=programmer&no=9129</a> <div><br></div> <div>오래간만입니다.</div> <div>링크에 재미난 글이 올라왔습니다.</div> <div><br></div> <div>뭐 인사 생략하고 좀 반박해보죠.</div> <div><br></div> <div> <div style="font-family:gulim;line-height:21.6000003814697px;">> 1. String 논리연산시 == 를 쓰지말고 equals() 를 사용하라</div> <div style="font-family:gulim;line-height:21.6000003814697px;">> java의 특징중 하나는 if 연산시 String type의 경우 data 연산이 아니라 type 연산을 하게 됩니다.</div> <div style="font-family:gulim;line-height:21.6000003814697px;"><br></div> <div style="font-family:gulim;line-height:21.6000003814697px;">틀렸어요.</div> <div style="font-family:gulim;line-height:21.6000003814697px;">==는 reference equality고</div> <div style="font-family:gulim;line-height:21.6000003814697px;">.equals()가 value equality입니다.</div> <div style="font-family:gulim;line-height:21.6000003814697px;">그리고 이거 중요한건데, string literal은 <b>그대로 스택에 저장되어 재사용이 됩니다. </b>Java String은 immutable이기 때문입니다.</div> <div style="font-family:gulim;line-height:21.6000003814697px;"><br></div> <div style="font-family:gulim;line-height:21.6000003814697px;">예를 들어보죠.</div></div> <div style="font-family:gulim;line-height:21.6000003814697px;">String a = "1";</div> <div style="font-family:gulim;line-height:21.6000003814697px;">String b = "2";</div> <div style="font-family:gulim;line-height:21.6000003814697px;">String c = "1";</div> <div style="font-family:gulim;line-height:21.6000003814697px;">String d = Integer.toString(1);</div> <div style="font-family:gulim;line-height:21.6000003814697px;"><br></div> <div style="font-family:gulim;line-height:21.6000003814697px;">a == b: FALSE</div> <div style="font-family:gulim;line-height:21.6000003814697px;">a == c: TRUE</div> <div style="font-family:gulim;line-height:21.6000003814697px;">a == d: FALSE</div> <div style="font-family:gulim;line-height:21.6000003814697px;"><br></div> <div style="font-family:gulim;line-height:21.6000003814697px;">a == c가 참이 뜨는 이유는 a와 c가 <strike>스택 안의 </strike>같은 장소를 가리키고 있기 때문입니다.</div> <div style="font-family:gulim;line-height:21.6000003814697px;"><br></div> <div style="font-family:gulim;line-height:21.6000003814697px;">EDIT: 정확한 지적을 받아 수정합니다.</div> <div style="font-family:gulim;line-height:21.6000003814697px;">a, b, c의 string literal은 스택 안이 아니라 이 부분은 data segment에 들어가는 게 맞습니다.</div> <div style="font-family:gulim;line-height:21.6000003814697px;">정적으로 먼저 정의가 되어진 거라 컴파일할때 즉각 집어넣는 게 가능하죠.</div> <div style="font-family:gulim;line-height:21.6000003814697px;">좀더 정확한 정보는 위키피디아(<a target="_blank" href="http://en.wikipedia.org/wiki/Data_segment">http://en.wikipedia.org/wiki/Data_segment</a>)나 스택오버플로우 답(<a target="_blank" href="http://stackoverflow.com/questions/8700491/what-is-stored-on-heap-and-what-is-stored-on-stack/8701010#8701010">http://stackoverflow.com/questions/8700491/what-is-stored-on-heap-and-what-is-stored-on-stack/8701010#8701010</a>)에서 볼 수 있습니다.</div> <div style="font-family:gulim;line-height:21.6000003814697px;"><br></div> <div style="font-family:gulim;line-height:21.6000003814697px;"><span style="line-height:21.6000003814697px;">c는 string literal이니 컴파일할때 알아서 a와 같은 놈으로 연산이 가능하기 때문이죠.</span></div> <div style="font-family:gulim;line-height:21.6000003814697px;">a ==d가 참이 안 뜨는 이유는, d는 스택이 아닌 힙에 들어가기 때문입니다.</div> <div style="font-family:gulim;line-height:21.6000003814697px;">d는 dynamically managed object이기 때문에, 런타임에서 생긴 놈이죠.</div> <div style="font-family:gulim;line-height:21.6000003814697px;"><br></div> <div style="font-family:gulim;line-height:21.6000003814697px;">자바는 printf에서 "%p"를 못하기 때문에, <b>그나마 </b>비슷한 놈으로 해보면.</div> <div style="font-family:gulim;line-height:21.6000003814697px;">System.identifyHashCode(a)</div> <div style="font-family:gulim;line-height:21.6000003814697px;"><span style="line-height:21.6000003814697px;">System.identifyHashCode(b)</span></div> <div style="font-family:gulim;line-height:21.6000003814697px;"><span style="line-height:21.6000003814697px;">System.identifyHashCode(c)</span></div> <div style="font-family:gulim;line-height:21.6000003814697px;"><span style="line-height:21.6000003814697px;">System.identifyHashCode(d)</span></div> <div style="font-family:gulim;line-height:21.6000003814697px;"><br></div> <div style="font-family:gulim;line-height:21.6000003814697px;">숙제입니다.</div> <div style="font-family:gulim;line-height:21.6000003814697px;">1. identifyHashCode가 뭐하는 놈인지 찾아보길</div> <div style="font-family:gulim;line-height:21.6000003814697px;">(<a target="_blank" href="http://www.nomachetejuggling.com/2008/06/04/getting-a-java-objects-reference-id/" target="_blank">http://www.nomachetejuggling.com/2008/06/04/getting-a-java-objects-reference-id/</a>)</div> <div style="font-family:gulim;line-height:21.6000003814697px;">(<b>그나마</b> %p와 비슷한 놈입니다.)</div> <div style="font-family:gulim;line-height:21.6000003814697px;">2. 저것들을 비교해보길</div> <div style="font-family:gulim;line-height:21.6000003814697px;">(a하고 c는 같되 b와 d는 다릅니다)</div> <div style="font-family:gulim;line-height:21.6000003814697px;"><br></div> <div style="font-family:gulim;line-height:21.6000003814697px;"><br></div> <div style="font-family:gulim;line-height:21.6000003814697px;"><br></div> <div style="font-family:gulim;line-height:21.6000003814697px;"><span style="line-height:21.6000003814697px;">> 2. if문 연산 시 존재하지 않을수도 있는 데이터는 먼저 연산하지 말라</span> <div style="line-height:21.6000003814697px;"><span style="line-height:21.6000003814697px;font-size:9pt;">> String a =null;</span></div> <div style="line-height:21.6000003814697px;"><span style="font-size:9pt;line-height:1.5;">> if(a.equals("")) // 1번</span></div> <div style="line-height:21.6000003814697px;"><span style="font-size:9pt;line-height:1.5;">> 와</span></div> <div style="line-height:21.6000003814697px;"><span style="font-size:9pt;line-height:1.5;">> if("".equals(a)) // 2번</span></div> <div style="line-height:21.6000003814697px;"><br></div> <div style="line-height:21.6000003814697px;">그냥 (a == null && a.isEmpty())를 써요. 뭐 굳이 ""를 먼저 붙여봤자 보기에만 안 좋은데.</div> <div style="line-height:21.6000003814697px;"><span style="line-height:21.6000003814697px;font-size:9pt;">애초에 a.isEmpty()가 "".equals(a)보다 빠릅니다.</span></div> <div style="line-height:21.6000003814697px;"><span style="line-height:21.6000003814697px;font-size:9pt;">""는 String 오브젝트를 하나 새로 생성해서 equality 체크를 하는 반면,</span></div> <div style="line-height:21.6000003814697px;">isEmpty는 그냥 오브젝트 a에 가서 a.length == 0을 리턴하거든요.</div> <div style="line-height:21.6000003814697px;"><br></div> <div style="line-height:21.6000003814697px;">그리고 ""도 다를 수가 있어요.</div> <div style="line-height:21.6000003814697px;">final String a = "";</div> <div style="line-height:21.6000003814697px;"><span style="line-height:21.6000003814697px;font-size:9pt;">String b = "";</span></div> <div style="line-height:21.6000003814697px;"><span style="line-height:21.6000003814697px;font-size:9pt;">char[] arr = new arr[0];</span></div> <div style="line-height:21.6000003814697px;">String c = String.copyValueOf(arr);</div> <div style="line-height:21.6000003814697px;"><br></div> <div style="line-height:21.6000003814697px;">a ==b입니다만</div> <div style="line-height:21.6000003814697px;">a != c입니다.</div> <div style="line-height:21.6000003814697px;"><br></div> <div style="line-height:21.6000003814697px;">언어의 idiom은 다 이유가 있어서 생기는 거에요.</div> <div style="line-height:21.6000003814697px;">애초에 "".equals(a) Java 6 이전버전에 퍼진 idiom인데요. 요즘 자바 5 이하를 쓰나요? 그러면 프로그래밍 이전 관리문제에 가깝습니다.</div> <div style="line-height:21.6000003814697px;"><span style="line-height:21.6000003814697px;font-size:9pt;"><br></span></div> <div style="line-height:21.6000003814697px;"><span style="line-height:21.6000003814697px;font-size:9pt;">> 3. 반복문 에서의 변수선언은 하지마라</span></div> <div style="line-height:21.6000003814697px;"> <div style="line-height:21.6000003814697px;">> 학생때 배웠던 책 중 일부분의 경우</div> <div style="line-height:21.6000003814697px;"><span style="line-height:21.6000003814697px;font-size:9pt;">> for(i==0; i<=10; i++) {</span></div> <div style="line-height:21.6000003814697px;">> int a;</div> <div style="line-height:21.6000003814697px;">> a += i;</div> <div style="line-height:21.6000003814697px;">> System.out.println(a);</div> <div style="line-height:21.6000003814697px;">> }</div> <div style="line-height:21.6000003814697px;"><br></div> <div style="line-height:21.6000003814697px;">> 이런식으로 사용되는 예제가 간혹 있었습니다.</div> <div style="line-height:21.6000003814697px;">> 이렇게 생성된 a 변수는 for문 안에서만 사용 가능할 뿐더러</div> <div style="line-height:21.6000003814697px;">> 선언될 때 마다 메모리 주소를 새로 잡기 때문에 성능적으로도 좋지 않습니다.</div> <div style="line-height:21.6000003814697px;"><br></div> <div style="line-height:21.6000003814697px;">그냥 이런 거로 최적화를 하고 있다면 정말 한가한 사람이거나 잘못된 데서 최적화를 하고 있는 겁니다.</div> <div style="line-height:21.6000003814697px;">기본적으로 variable scope는 가능한 한 가까운 로컬에 넣는 게 좋습니다. 어차피 O(1)이니까요.</div> <div style="line-height:21.6000003814697px;">그게 아니라면 int a를 루프 바깥에 둬서 scope를 오염시킬 셈입니까?</div> <div style="line-height:21.6000003814697px;">어차피 스택에 두는 variable이에요. 깔끔하게 쓰는 게 더 낫습니다.</div> <div style="line-height:21.6000003814697px;">행간을 읽는 식으로 보면, int a가 루프 바깥에 있다는 이유만으로 a를 루프 바깥에서도 써야 한다는 메세지를 줄 수 있습니다.</div> <div style="line-height:21.6000003814697px;"><br></div> <div style="line-height:21.6000003814697px;">물론 int가 아니라 String이라면 이야기가 다르죠. O(N)까지 가니까요.</div> <div style="line-height:21.6000003814697px;">이럴 땐 StringBuilder를 써야 합니다.</div> <div style="line-height:21.6000003814697px;"><br></div> <div style="line-height:21.6000003814697px;"><br></div> <div style="line-height:21.6000003814697px;">결론을 말하자면 <span style="line-height:21.6000003814697px;font-size:9pt;">의도는 좋았습니다만 좀 더 리서치를 하고 팁을 줍시다.</span></div> <div style="line-height:21.6000003814697px;"><span style="line-height:21.6000003814697px;font-size:9pt;">자꾸 말하지만 다 애정이 있어서 까는 거에요.</span></div> <div style="line-height:21.6000003814697px;">애정이 없었으면 자꾸 말하는 것처럼 그냥 무시하고 넘어가죠.</div> <div style="line-height:21.6000003814697px;"><br></div> <div style="line-height:21.6000003814697px;">이상.</div></div></div>