처음 자바를 배울 때 int와 String을 가장 먼저 배운다. 사실 int 보다 String을 먼저 배운다. 왜냐하면 System.out.println("Hello, World!"); 를 출력해야 하니까. 그래서 String을 int와 같은 것으로 이해하곤 한다. 그러나 int와 String은 전혀 다른 타입의 데이터이다.
int의 경우 그것이 main thread에서 선언되면, 변수와 값이 stack에 저장된다. 변수에 해당 값이 저장된다. 그러나 String의 변수(참조변수)는 스택에 값은 heap에 저장된다. String의 참조변수는 문자열이 저장된 heap 객체의 주소만 있다.
만약 아래와 같이 선언했다면 그 값은 다음 표처럼 결과가 나올 것이다.
int a = 3;
String b = "java";
스택 | 힙 | ||
변수 | 값 | 주소 | 값 |
int a | 3 | ||
String b | heap 30번지 | heap30번지 | "java" |
그러나 String은 보통의 데이타타입과 차이를 가진다. String의 객체를 두 개 만드는데 만약 해당 문자열이 값이 완전히 같은 경우 String은 같은 객체를 가르키는 변수 두 개를 만든다. 그러므로 두 개의 값(주소의 값)은 같다.
만약 두 변수를 다르게 하고 싶으면 new 연산자를 추가하여 다른 힙 영역에 저장한다.
String a = "java";
String b = "java";
System.out.println(a==b); // 값 : true
int[] c = {1,2,3};
int[] d = {1,2,3};
System.out.println(c==d); // 값 : false
String aa = new String("spring");
String bb = new String("spring");
System.out.println(aa==bb);
String의 변수들이 가리키는 객체가 같을 수는 있으나 그것의 사용은 배열과 차이를 가지지 않는다. subString(), indexOf(), length, charAt() 등 index에 따른 배열로서의 사용할 수 있는 매서드가 존재한다.
한편, 자바는 변수를 선언함에 있어서 값을 지정하지 않으면 컴파일 오류가 발생한다. 하지만 배열로서 객체를 선언 할 때 배열 각각의 값을 선언하지 않아도 된다. 이때 각각의 배열이 가지고 있는 값을 보면 그 값은, int의 경우 0이며 String의 경우 null이다. 이때 0과 null의 의미는 다른데, 0은 숫자 그대로의 의미이나, null은 참조할 객체가 없다는 의미이다.
String[] strs = new String[3];
System.out.println(strs); // 값 : Ljava.lang.String;@3b6eb2ec
for (String str : strs) {
System.out.println(str); // 값 : null / null / null
}
int[] ints = new int[3];
System.out.println(ints); // 값 : [I@1e643faf
for (int i : ints) {
System.out.println(i); // 값 : 0 / 0 / 0
}
마지막으로 Array의 경우 함수처럼 만들 수 있다. 배열의 배열로서 2차원 배열을 생성할 수 있다. 그것은 아래의 코드와 같다. 아래의 코드를 보면 부모 배열을 선언하고 자식 배열을 다시 한 번 선언하는 것을 확인할 수 있다. 이 의미는 부모의 배열은 자식 3개의 주소를 가진 배열이란 의미이며 자식 3개는 각각의 배열의 객체의 주소를 가졌음을 의미한다.
int a[][]= new int[3][];
a[0] = new int[] {1,2};
a[1] = new int[] {1,2,3,4,5};
a[2] = new int[] {1,2,3};
for(int i=0; i<a.length; i++){
for(int j=0; j<a[i].length; j++){
System.out.print(a[i][j]+" ");
}
System.out.println();
}
// 값 :
1 2
1 2 3 4 5
1 2 3
System.out.println(a);
for (int[] child : a) {
System.out.println(child);
}
// 값 :
[[I@22f71333
[I@13969fbe
[I@6aaa5eb0
[I@3498ed