부족한 부분은 알려주시면 감사하겠습니다.
먼저, 형변환에 관한 내용이 아닙니다.
스레드 관련하여 메서드 내에서 객체 타입들이 호출 될 때 동기화 처리 안 된 메서드들의 로직을 확인하다가 적게 됐습니다.
스레드 관련한 내용은 간단히 정리하면,
int는 primitive, Integer 는 Wrapper 클래스로 객체 입니다.
자동 형변환도 되고 크게 신경쓰면서 쓸 일이 없지만,
스레드 입장에서는 차이가 있을 수 있습니다.
메서드 내에서 생성하여 사용시 primitive type은 스택 한정이지만,
Wrapper 클래스의 객체(참조형으로만 보면)는 외부 반환시 스택 한정이 깨집니다.
멀티스레스 환경에서 공유변수는 여러 이유로 thread-safe 하지 않습니다.
객체 타입을 공유변수일 때 thread-safe 하기 위해서 타입 별 지원하는 방법이나 스레드 별 등 여러 방법이 있을 수 있는데요. 여기서는 다른 내용이 될 거 같고, 어려운 내용 인 것 같습니다. ㅎㅎ
자바에서 불변객체로 String, Integer 등 있고,
저는 불변객체들이 어떻게 서로 상호작용하는지 소스를 보러 갔습니다.
저는 가볍게 접근할 수 있는 String 와 Integer로 생각하다가 기능가진 메서드를 String.valudOf( int 타입 ) 과 Integer.toString( int 타입 ) 을 봤습니다.
public static String valueOf(int i) {
return Integer.toString(i);
}
내부적으로 Integer.toString() 호출을 하고 있고, 들어가니 생각보다... 숫자에 쌍따옴표 붙이지 않아요. ㅋㅋㅋ
new String 반환으로 매개변수에 대해 순수해졌어요.
toString() 은 오버라이딩 되는 메서드로 외부 공개되기 때문에 객체 내에서 사용시 thread-safe 하지 않을 수 있는데, static 메서드로 새 객체를 반환하고 있습니다.
public static String toString(int i) {
int size = stringSize(i);
if (COMPACT_STRINGS) {
byte[] buf = new byte[size];
getChars(i, size, buf);
return new String(buf, LATIN1);
} else {
byte[] buf = new byte[size * 2];
StringUTF16.getChars(i, size, buf);
return new String(buf, UTF16);
}
}
그냥 바라본 로직은 좀 복잡하네요.
버퍼 따라가면 속도위해 썼고, COMPACT_STRINGS 은 String 문자열에서 온 상수이고, defualt true 인데 .. 복잡해서 좀더 간편하게 따라가보고자 제 방식대로 테스트 예시로 이럴 수 있겠구나 하고 넘어가 보겠습니다. (답이 아닙니다. )
숫자에 쌍따옴표 붙이지 않아요.
다음의 테스트를 실행해 봤습니다. 로직이 왜 복잡할지, Integer 와 String 이 불변객체로 서로 상호작용하면서 어떻게 구현됐는지가 재미있었습니다.
int addtion = 1 + '+' + 2;
System.out.println('+');
System.out.println(addtion);
System.out.println(1 + '+' + 2 +"="+3);
System.out.println(number + '+' + 2 +"="+3);
System.out.println(number.toString() + '+' + 2 +"="+3);
System.out.println(1 + "+" + 2 +"="+3);
+
46
46=3
46=3
1+2=3
1+2=3
간단하게 개발자가 "+" 과 '+' 을 혼동한다면 그 결과차이는 크게 날 거 같아요.
(답은 아닙니다. 내부적으로 +가 어떻게 되는지(연산자 우선순위, 컴파일), Integer.toString()(자바의 인코딩, java9) 이 변환시키는지 등...몰라요.)
String.valueOf() 는 내부에 불변객체로 반환해주는 Integer.toString() 을 통해 syschronized 없이 동작한다고 생각했습니다.
또 String.valueOf() 와 Integer.toString() 차이는 String.valudOf() 가 오버로딩 되어 있지만, 혹시나 매개변수로 null 이 들어올 경우 Object 타입을 받는 메서드 호출로 NPE 발생하지 않습니다.
사용자 입장에서는 문자열로 변환하고자 할 때, String 을 더 생각하기 쉬울 거 같아요.
파라미터로 넘어온 여러 타입별로 오버로딩 통한 메서드들이 String에 마련되어서
Object 를 받으면서 NPE 까지 방어 하고, 각각 타입 별 형변환은 위임하고 있습니다.
그리고 불변객체로 public 한 메서드 임에도 thread-safe 하다고 봤습니다.
GOOD