프로그래밍백엔드 개발자

자바에서 new 연산자는 어떻게 작동하며 객체 생성 시 실제로 어떤 일이 발생하고 여기에 존재하는 잠재적인 문제는 무엇입니까?

Hintsage AI 어시스턴트로 면접 통과

답변.

자바에서 new 연산자는 새로운 객체 인스턴스를 생성하는 데 사용됩니다. 객체 생성 프로세스에는 메모리 할당, 필드 초기화 및 생성자 호출이 포함됩니다.

질문의 역사

고전 프로그래밍 언어에서는 메모리 할당과 객체 초기화가 별도로 발생할 수 있었습니다. 자바에서는 이 둘이 결합되어 가상 머신(JVM)에 의해 제어되므로 오류 및 메모리 누수가 줄어듭니다.

문제

객체 생성 시 발생하는 프로세스를 잘 이해하지 못하면 잘못된 초기화, 메모리 누수 또는 예기치 않은 동작을 초래할 수 있습니다.

해결책

new 연산자를 사용할 때:

  1. JVM은 힙(heap)에서 객체를 위해 메모리를 할당합니다.
  2. 필드는 첫 단계에서 null, 0, false와 같은 기본값으로 채워집니다.
  3. 초기화기(initializers)가 실행되며, 필드 초기화도 포함됩니다.
  4. 객체 생성자가 호출됩니다.
  5. 변수는 생성된 객체에 대한 참조를 받습니다.

코드 예시:

Person p = new Person("Ivan", 20);

이후 메모리에는 독립적인 Person 객체가 생성되어 사용할 수 있게 됩니다.

주요 특징:

  • 생성 후 객체의 무결성과 정확성이 보장됩니다.
  • 메모리를 수동으로 해제할 필요가 없습니다(가비지 컬렉터가 작동합니다).
  • new 호출은 독립적인 객체를 생성합니다(싱글턴 패턴 제외).

함정 질문.

객체를 생성할 때 new 연산자를 사용하지 않을 수 있습니까?

네. 예를 들어 클론(clone()), 역직렬화(deserialization), 리플렉션(reflection)(Class.newInstance())를 사용할 수 있지만, 각자 고유한 뉘앙스와 제약이 있습니다.

new는 문자열 풀에서 새로운 문자열 객체를 생성합니까?

아니요. new String("abc")와 같이 문자열을 생성하면 힙에 새로운 객체가 생성되지만, 문자열 풀이 이미 존재하는 경우입니다. 문자열 리터럴을 사용하는 것이 더 좋습니다.

new의 배열 작동 방식이 다릅니까?

네. 배열의 경우 new 연산자는 배열의 모든 요소에 대한 메모리를 할당하고 기본값으로 초기화하지만, 원시 타입이 아닌 경우 요소의 생성자는 호출되지 않습니다.

String[] arr = new String[5]; // 모든 요소는 null입니다

전형적인 오류 및 안티 패턴

  • 문자열을 생성할 때 new를 사용하는 것(리터럴 대신)은 불필요한 객체를 초래합니다.
  • 초기화 및 생성자 호출 순서와 관련된 오류, 특히 상속할 때.
  • 가비지 수집에 대한 무시 — 수동으로 메모리를 해제하려는 시도.

실제 사례

부정적인 사례

개발자가 작성했습니다:

String s1 = new String("hi"); String s2 = new String("hi"); System.out.println(s1 == s2); // false

장점:

  • 각 문자열은 보장된 독립적인 객체입니다.

단점:

  • 메모리에 불필요한 부담이 있습니다.
  • ==를 통한 비교가 작동하지 않습니다(다른 객체).

긍정적인 사례

개발자가 작성했습니다:

String s1 = "hi"; String s2 = "hi"; System.out.println(s1 == s2); // true

장점:

  • 문자열이 문자열 풀을 통해 최적화됩니다.
  • 메모리를 절약하고 비교가 더 빠릅니다.

단점:

  • ==를 통한 비교는 리터럴에 대해서만 정확하며 모든 경우에 해당하지 않습니다.