Java - 메모리 구조, 생성자, 접근 제어자
자바 메모리 구조
메소드 영역(데이터 영역) (클래스, static 변수)
- 메소드 영역은 자바 프로그램에서 사용되는 클래스에 대한 정보와 함께 클래스 변수(static variable)가 저장되는 영역입니다.
- JVM은 자바 프로그램에서 특정 클래스가 사용되면 해당 클래스의 클래스 파일을 읽어들여, 해당 클래스에 대한 정보를 메소드 영역에 저장합니다.
힙(heap) 영역 (객체 인스턴스)
- 힙 영역은 자바 프로그램에서 사용되는 모든 인스턴스 변수가 저장되는 영역입니다.
- JVM은 자바프로그램에서 new 키워드를 사용하여 인스턴스가 생성되면, 해당 인스턴스의 정보를 힙 영역에 저장합니다.
- 힙 영역은 메모리의 낮은 주소에서 높은 주소의 방향으로 할당됩니다.
스택(stack) 영역 (메소드, 지역 변수, 매개 변수)
- 스택 영역은 자바 프로그램에서 메소드가 호출될 때 메소드의 스택 프레임이 저장되는 영역입니다.
- JVM은 자바 프로그램에서 메소드가 호출되면, 메소드의 호출과 관계되는 지역 변수와 매개변수를 스택 영역에 저장합니다.
- 스택 영역은 메소드의 호출과 함께 할당되며, 메소드의 호출이 완료되면 소멸합니다.
- 메모리의 높은 주소에서 낮은 주소의 방향으로 할당됩니다.
생성자
생성자의 특징
- 생성자는 반환 값이 없지만, 반환 타입을 void형으로 선언하지 않습니다.
- 생성자는 초기화를 위한 데이터를 인수로 전달받을 수 있습니다.
- 객체를 초기화하는 방법이 여러 개 존재할 경우에는 하나의 클래스가 여러 개의 생성자를 가질 수 있습니다. 즉, 생성자도 하나의 메소드이므로, 메소드 오버로딩이 가능합니다.
기본 생성자
- 자바의 모든 클래스에는 하나 이상의 생성자가 정의되어 있어야 합니다.
- 하지만 특별히 생성자를 정의하지 않고도 인스턴스를 생성할 수 있습니다.
- 자바 컴파일러가 기본 생성자라는 것을 기본적으로 제공해 주기 때문입니다.
- 기본 생성자는 아무런 동작도 하지 않으므로, 인스턴스 변수를 클래스 필드에서 바로 초기화합니다.
- 만약 매개변수를 가지는 생성자를 하나라도 정의했다면, 기본 생성자는 자동으로 추가되지 않습니다.
- 따라서 매개변수를 가지는 생성자를 하나 이상 정의한 후 기본 생성자를 호출하면, 오류가 발생할 것입니다.
접근 제어자
private
- 같은 패키지 일반 클래스 (x)
- 같은 패키지 자식 클래스 (x)
- 다른 패키지 일반 클래스 (x)
- 다른 패키지 자식 클래스 (x)
public
- 같은 패키지 일반 클래스 (o)
- 같은 패키지 자식 클래스 (o)
- 다른 패키지 일반 클래스 (o)
- 다른 패키지 자식 클래스 (o)
default
- 같은 패키지 일반 클래스 (o)
- 같은 패키지 자식 클래스 (o)
- 다른 패키지 일반 클래스 (x)
- 다른 패키지 자식 클래스 (x)
protected
- 같은 패키지 일반 클래스 (o)
- 같은 패키지 자식 클래스 (o)
- 다른 패키지 일반 클래스 (x)
- 다른 패키지 자식 클래스 (o)
기타 제어자
final
- 자바에서 final 제어자는 '변경할 수 없다'는 의미로 사용됩니다.
- 즉, 필드나 지역 변수에 사용하면 값을 변경할 수 없는 상수가 됩니다.
- 클래스에 사용하면 해당 클래스는 다른 클래스가 상속받을 수 없게 됩니다.
- 메소드에 사용하면 해당 메소드는 오버라이딩을 통한 재정의를 할 수 없게 됩니다.
- 메소드 오버라이딩 : 상속받은 부모 클래스의 메소드를 재정의하여 사용하는 것
static
- 자바에서 static 제어자는 '공통적인'이라는 의미로 사용됩니다.
- 즉, static 제어자를 변수에 사용하면 해당 변수를 클래스 변수로 만들어 줍니다.
- 메소드에 사용하면 해당 메소드를 클래스 메소드로 만들어 줍니다.
static 특징
- 프로그램 시작 시 최초에 단 한 번만 생성되고 초기화됩니다.
- 인스턴스를 생성하지 않고도 바로 사용할 수 있게 됩니다.
- 해당 클래스의 모든 인스턴스가 공유합니다.
abstract
- 자바에서 abstract 제어자는 '추상적인'이라는 의미로 사용됩니다.
- 선언부만 있고 구현부가 없는 메소드를 추상 메소드라 하며, 반드시 abstact 제어자를 붙여야 합니다.
- 하나 이상의 추상 메소드가 포함하고 있는 추상 클래스도 반드시 abstract제어자를 붙여야 합니다.
사용할 수 없는 제어자의 조합
클래스에 final과 abstract는 함께 사용할 수 없습니다.
- final은 상속 불가
- abstract는 다른 클래스가 상속해서 오버라이딩 해야하므로
메소드에 static과 abstract는 함께 사용할 수 없습니다.
- abstract 메소드는 구현부가 없는 메소드
- static 메소드는 인스턴스를 생성하지 않고도 사용할 수 있어야 하므로
메소드에 private와 abstract는 함께 사용할 수 없습니다.
- abstract 메소드는 상속을 통한 오버라이딩이 필요
- 하지만 private는 자식 클래스가 부모 클래스에 접근 할 수 없도록 만듦으로
메소드에 private과 final은 함께 사용할 필요가 없습니다.
- 메소드에 사용된 final 제어자와 private 제어자는 모두 해당 메소드가 오버라이딩을 통한 재정의를 할 수 없다는 의미를 가지므로, 둘 중에 하나만 사용해도 의미가 충분히 전달될 수 있습니다.