new 연산자로 객체를 생성 및 선언할 수 있다.
Student
// 4. s를 통해 Student에 접근 가능 (3. 에 의해서, 생성자를 호출받음)
class Student{
int age;
int score;
String name;
}
Stuent_Test
public class Stuent_Test {
public static void main(String[] args) {
// 1. new 연산자를 통해, Heap 영역의 메모리 공간을 할당받는다. → 이 공간이 s 객체(데이터)가 저장될 공간
// s 변수가 해당 메모리 공간의 주소를 가리킨다. → "참조" 라고 한다
// 2. 생성자가 s 객체를 초기화
Student s = new Student();
// 3. new 연산자가 새로 생성된 객체의 주소인 s 변수에 저장(참조값(reference value)을 s 객체에게로 반환)
s.age = 20;
s.score = 100;
s.name = "철수";
System.out.println(s.age + " / "+ s.score + " / " + s.name);
}
}
"new 연산자가 Heap 영역의 메모리 공간을 할당받는다."
→ 즉, new 연산자가 객체를 생성할 때마다 Heap이라는 메모리 영역에 각각의 새로운 메모리 공간을 할당해준다.
→ new 연산자로 생성한 객체들의 메모리 주소가 다르게 나오는 것도 이 때문.
참고: 운영체제 (OS) - (2) 프로세스의 메모리 영역 (메모리 구조)
코드 1
public class PolyArgumentTest {
public static void main(String[] args) {
Buyer b = new Buyer();
Tv tv = new Tv();
Computer com = new Computer();
Audio audio = new Audio();
b.buy(tv);
b.buy(com);
b.buy(audio);
}
}
코드 2
public class PolyArgumentTest {
public static void main(String[] args) {
Buyer b = new Buyer();
b.buy(new Tv());
b.buy(new Computer());
b.buy(new Audio());
}
}
new 연산자를 통한 객체 생성을 보면, 결국
new 클래스()
이것 만으로도 객체를 생성할 수 있다.
따라서, 코드 1은 코드 2의 형태로도 표현가능하다고 할 수 있다.
new 연산자를 사용해서, "string" 문자열 값을 담고있는 String 객체를 생성
public class Main {
public static void main(String[] args) {
String str = new String("string");
}
}
변수는 Stack 영역에 할당 된 후, "string" 문자열 값이 Heap 영역의 메모리 공간을 할당받는다.
이 때, str 변수는 해당 메모리의 주소를 가리킨다.
만약, 동일한 문자열을 new 연산자로 또 생성한다면?
public class Main {
public static void main(String[] args) {
String str = new String("string");
String str2 = new String("string");
}
}
처음에 생성한 "string"과 별개로, Heap 메모리에 새로운 영역을 할당받아 생성한다.
public class Main {
public static void main(String[] args) {
String str = new String("string");
String str2 = new String("string");
System.out.println(System.identityHashCode(str)); //result:2008362258
System.out.println(System.identityHashCode(str2)); //result:760563749
//메모리주소는 컴퓨터마다 다르기때문에 실행결과가 다르게 나올수도 있다.
}
}
메모리 주소를 출력해보면, 서로 다르게 찍히는 것을 볼 수 있다.
반면에 리터럴의 경우, 메모리 주소가 동일하게 찍힌다.
(리터럴 : 변하지 않는 고정적인 값. 원시타입과 String 이 있다.)
public class Main {
public static void main(String[] args) {
String str = "string";
String str2 = "string";
System.out.println(System.identityHashCode(str)); //result:2008362258
System.out.println(System.identityHashCode(str2)); //result:2008362258
}
}
즉, 동일한 값을 추가적으로 생성하더라도, 이 전에 할당받은 주소로 할당받게 된다.
int a = 10;
int b = 10;
→ 이는 메모리 낭비를 줄여준다.
참고: [JAVA] 객체생성 - new 연산자
참고: [Java] New 연산자
참고: [JAVA] new 연산자란?
참고: new 연산자 와 객체생성에 대하여
참고: [Java] new 연산자란
참고: [Java] 리터럴(literal)이란?