JAVA

new를 언제? 왜 붙여야하는가? (2)

싸블양 2025. 6. 18. 19:16

자바는 왜 배열을 생성할 때 항상 new를 통해 메모리에 배열 객체를 생성해야 할까요?

 

자바에서 new는 클래스의 객체를 생성하는 데 사용되는 단항 연산자입니다. 다음과 같이 표현식에서 new를 사용하면:

Dog scooby = new Dog();

Dog scooby = new Dog(); 라는 문장은 Dog 클래스의 객체를 생성하고, 그 참조를 scooby에 저장합니다.

 

  • new Dog() → 힙 메모리에 Dog 객체가 생성됨.
  • 그 객체가 저장된 주소값(예: 0x1234) 이 만들어짐.
  • scooby에는 그 주소값이 저장됨.
  • scooby → 그 객체의 주소값을 저장하는 참조 변수(Reference Variable) 
  • 즉, scooby는 Dog 객체 자체가 아니라 그 객체가 있는 주소를 가리키는 포인터 같은 역할입니다.

객체에는 그 안에 변수를 가질 수 있습니다. 즉, 객체의 인스턴스 변수(Instance Variable) 입니다. new 연산자는 객체를 생성할 때 이 인스턴스 변수를 객체 내부에 배치합니다.

 

인스턴스 변수(Instance Variable)란

class Dog {
    String name;// 인스턴스 변수 (== 필드)
    static int count;// 클래스 변수 (== 필드)int age;
}
  • 위 클래스는 name, age라는 인스턴스 변수(멤버 변수)를 가집니다.
  • new Dog()를 호출하면 이 변수들도 함께 메모리 안에 공간이 잡히게됩니다

 

실행되는 순서대로 정리하자면

  1. new가 실행되어 힙(Heap)에 Dog 객체를 위한 메모리 공간 생성
  2. 그 객체의 주소값을 생성
  3. 그 주소값을 생성자 Dog()에 전달
  4. 생성자 Dog()는 그 주소에 해당하는 객체의 초기화 작업 수행
  5. new Dog() 전체 표현식이 주소값을 반환
  6. 그 주소값을 scooby라는 참조 변수에 저장

 

자바에서 new 연산자는 언제, 왜 써야 할까?

 1. 객체를 생성할 때

자바에서 대부분의 클래스 타입 변수(밑에서는 p) 는 단순한 참조 변수입니다. 실제 데이터를 갖고 있는 객체(인스턴스)를 생성하려면 new가 필요합니다.

Person p = new Person();// new가 없으면 객체가 생성되지 않음
  • Person() → 생성자 호출
  • new Person() → 객체 생성 + 생성자 호출
  • p → 그 객체의 주소를 참조

 

 2. 배열을 생성할 때

사실 배열도 객체입니다! 따라서 배열을 선언하고 실제로 메모리에 생성하려면 new를 사용해야 합니다.

int[] numbers = new int[3];// 크기를 지정하여 생성
int[] scores = new 
int[] {90, 80, 70};// 초기화와 함께 생성


단, 배열 선언과 동시에 초기화하는 경우는 예외로 new 생략 가능합니다.

 

int[] arr = {1, 2, 3};// OK (컴파일러가 new int[] 자동으로 붙여줌)

 

 

특별히 허용된 배열 초기화 리터럴

int[] arr = {1, 2, 3};// ✅ OK — new 생략 가능

이건 자바 문법상 특별히 허용된 “배열 초기화 리터럴” 문법입니다
컴파일러가 내부적으로 다음과 같이 바꿔줍니다:

int[] arr = new int[] {1, 2, 3};

왜 허용하느냐?

  • 배열은 자바에 내장된 특별한 구조
  • {} 문법은 C언어 스타일과 호환성 때문에 자바에서 예외적으로 허용된 특수 문법

 

그런데 객체에서는?

Dog d = { "초코", 3 };// ❌ 문법 오류!

→ 자바는 객체를 리터럴로 초기화하는 문법을 전혀 허용하지 않습니다.

 

이유는?

 

1. 클래스는 사용자가 정의한 구조이기 때문

  • 배열은 고정된 형식(int[ ], String[ ] 등)이므로 자바가 예측할 수 있음
int[] nums = {1, 2, 3};// int형 배열
String[] names = {"Tom", "Amy"};// String 객체 배열
char[] letters = {'h', 'e', 'l', 'l', 'o'};// char 배열
  • 객체는 개발자가 원하는 만큼 필드나 생성자를 커스터마이즈할 수 있으므로
    컴파일러가 자동으로 추론할 수 없음

 

 2. { ... } 문법은 배열 전용 리터럴

  • 자바에서 { }는 배열 리터럴 전용입니다.
int[] arr = {1, 2, 3};// ✅ 가능 (배열 리터럴)
char[] c = {'a', 'b', 'c'};// ✅ 가능
String[] s = {"hi", "hey"};// ✅ 가능
  • 자바에서는 배열만 예외적으로 {} 리터럴 문법을 지원하고,
    일반적인 객체(new 클래스명())는 반드시 생성자를 통해 생성해야 합니다.

'JAVA' 카테고리의 다른 글

new를 언제? 왜 붙여야하는가? (final)  (0) 2025.06.19
new를 언제? 왜 붙여야하는가? (3)  (0) 2025.06.19
new를 언제? 왜 붙여야하는가? (1)  (1) 2025.06.14
Java 메서드 구조 분석  (0) 2025.06.14
클래스와 오브젝트  (0) 2025.06.13