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