자바는 왜 배열을 생성할 때 항상 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()를 호출하면 이 변수들도 함께 메모리 안에 공간이 잡히게됩니다
실행되는 순서대로 정리하자면
- new가 실행되어 힙(Heap)에 Dog 객체를 위한 메모리 공간 생성
- 그 객체의 주소값을 생성
- 그 주소값을 생성자 Dog()에 전달
- 생성자 Dog()는 그 주소에 해당하는 객체의 초기화 작업 수행
- new Dog() 전체 표현식이 주소값을 반환
- 그 주소값을 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 |