[Java] 변수의 종류

윤여준·2023년 8월 4일
0

자바[Java]

목록 보기
3/4
post-thumbnail

변수의 종류

자바의 변수는 크게 클래스 변수, 인스턴스 변수, 지역 변수, 매개변수, 배열 요소(Array components)로 나눌 수 있다. (참고 : https://docs.oracle.com/javase/specs/jls/se20/html/jls-4.html#jls-4.12.3)

클래스 변수(class variable)

A class variable is a field declared using the keyword static within a class declaration, or with or without the keyword static within an interface declaration.
[클래스 변수는 클래스 선언(class declaration) 내에서 static 키워드를 사용하거나 인터페이스 선언(interface declaration) 내에서 static 키워드를 사용하거나 사용하지 않고 선언된 필드이다.]
출처 : https://docs.oracle.com/javase/specs/jls/se20/html/jls-4.html#jls-4.12.3

클래스 변수는 클래스나 인터페이스의 선언(declaration) 내에 존재한다.

클래스 선언 내에서 클래스 변수를 선언하려면 static 키워드를 사용해야 하고, 인터페이스 선언 내에서는 static 키워드를 사용해도 되고 사용하지 않아도 된다.

클래스 변수는 모든 인스턴스가 공통된 저장공간을 공유한다. 모든 인스턴스들이 공유해야 하는 공통적인 값은 static 키워드를 사용해서 클래스 변수에 저장해야 한다.

클래스 변수는 인스턴스를 생성하지 않고도 바로 사용할 수 있다. ‘클래스이름.클래스변수’와 같은 형식으로 사용할 수 있다. 예를 들어, Variables 클래스의 클래스 변수 cv를 사용하려면 ‘Variables.cv’와 같이 하면 된다.

클래스 변수는 클래스나 인터페이스가 메모리에 로딩(loading)될 때 생성되고, unloading될 때 제거된다.

클래스나 인터페이스의 unloading과 관련된 내용은 이 링크를 참고하자. https://docs.oracle.com/javase/specs/jls/se20/html/jls-12.html#jls-12.7

인스턴스 변수(instance variable)

An instance variable is a field declared within a class declaration without using the keyword static.
[인스턴스 변수는 static 키워드를 사용하지 않고 클래스 선언 내에서 선언된 필드이다.]
출처 : https://docs.oracle.com/javase/specs/jls/se20/html/jls-4.html#jls-4.12.3

인스턴스 변수가 클래스 선언(declaration) 내에 선언된다는 점은 클래스 변수와 동일하다. 차이점은 인스턴스 변수에서는 static 키워드를 사용하지 않는다는 점이다.

인스턴스 변수는 클래스의 인스턴스를 생성할 때 만들어진다. 그래서 인스턴스 변수에 접근하려면 먼저 인스턴스를 생성해야한다.

만약 인스턴스가 더 이상 참조되지 않으면 인스턴스 변수는 사실상 제거된 것으로 볼 수 있다.

인스턴스는 클래스 변수와 달리 인스턴스마다 독립적인 저장공간을 갖는다. 그렇기 때문에 인스턴스마다 서로 다른 값을 가질 수 있다. 그렇기에 인스턴스마다 고유한 상태를 유지해야하는 속성의 경우, 인스턴스 변수로 선언한다.

지역 변수(local variable)

지역 변수에 대한 내용은 자바의 정석을 참고해서 작성하겠다.

지역 변수는 메서드 내에 선언되어 메서드 내에서만 사용 가능하다. 메서드가 종료되면 소멸되어 사용할 수 없다.

for문 또는 while문의 블럭 내에 선언된 지역 변수는, 지역 변수가 선언된 블럭{} 내에서만 사용 가능하며, 블럭{}을 벗어나면 소멸되어 사용할 수 없게 된다.

매개 변수(parameter)

자바 spec 문서에 의하면 매개 변수에는 method parameter, constructor parameter, lambda parameter, exception parameter가 있다.

메서드나 생성자 등에 매개 변수로 어떤 값을 전달하면 내부에서는 매개 변수를 이용해서 원하는 작업을 진행한다.

기본형 매개 변수와 참조형 매개 변수

매개 변수는 다시 기본형 매개 변수와 참조형 매개 변수로 나눌 수 있다.

자바에서는 매개 변수에 넘겨줄 값을 매개 변수에 복사해서 넘겨준다.

이때 매개 변수의 타입이 기본형(primitive type)인 경우에는 기본형 값이 복사되지만, 참조형(reference type)인 경우에는 인스턴스의 주소가 복사된다.

그렇기 때문에 매개 변수가 참조형인 경우에는 인스턴스의 주소를 알고 있기 때문에 값을 읽는 것 뿐만 아니라 값을 수정할 수도 있다.

반면 매개 변수가 기본형인 경우에는 값을 읽어올 수만 있다.

배열 요소(array component)

Array components are unnamed variables that are created and initialized to default values whenever a new object that is an array is created. The array components effectively cease to exist when the array is no longer referenced.
[배열 요소(array component)는 배열인 새 객체가 생성될 때마다 생성되고 기본값으로 초기화되는 이름 없는 변수이다. 배열이 더 이상 참조되지 않으면 배열 요소는 더 이상 존재하지 않는다.]
출처 : https://docs.oracle.com/javase/specs/jls/se20/html/jls-4.html#jls-4.12.3

배열 요소(array component)는 이름이 없는 변수이다.

배열 요소는 배열 객체가 생성될 때마다 생성되고 기본 값으로 초기화된다.

배열이 더 이상 참조되지 않으면, 그 배열의 배열 요소들은 더 이상 존재하지 않는다.

JVM의 메모리 구조와 변수

이 항목에 대한 내용은 자바의 정석을 참고해서 작성하였다.

프로그램이 실행되면 JVM은 시스템으로부터 프로그램을 실행하는데 필요한 메모리를 할당받고 JVM은 이 메모리를 용도에 따라 여러 영역으로 나누어 관리한다.

그 중 변수와 관련된 3가지 주요 영역 method area, heap, call stack에 대해서 알아보자.

메서드 영역(method area)

JVM은 모든 JVM 스레드 간에 공유되는 메서드 영역을 갖는다. 이 메서드 영역은 JVM이 시작될 때 생성된다.

메서드 영역은 고정된 크기일 수도 있고 계산에 필요한 만큼 확장될 수도 있으며 더 큰 메서드 영역이 불필요해지면 축소될 수도 있다. 메서드 영역을 위한 메모리는 연속적일 필요가 없다.

프로그램 실행 중 어떤 클래스가 사용되면 JVM은 해당 클래스의 클래스파일(*.class)을 읽어서 분석 후 클래스에 대한 정보를 메서드 영역에 저장한다. 이 때, 그 클래스의 클래스 변수(class variable)도 이 영역에 함께 생성된다.

힙(heap)

JVM의 힙은 모든 클래스 인스턴스 및 배열에 대한 메모리가 할당되는 곳이다. 즉, 인스턴스 변수(instance variable)와 배열 요소(array component)가 생성되는 공간이다.

JVM의 힙도 메서드 영역과 마찬가지로 모든 JVM 스레드가 공유한다.

JVM이 생성될 때 힙이 생성되며, 객체에 대한 힙 저장소는 가비지 컬렉터에 의해 회수된다. 객체는 명시적으로 할당 해제되지 않는다.

힙은 고정된 크기이거나 계산에 필요한 만큼 확장될 수 있으며 더 큰 힙이 불필요해지면 축소될 수 있다.

힙을 위한 메모리는 연속적일 필요가 없다.

호출 스택(call stack 또는 execution stack)

호출 스택을 JVM spec 문서에서는 Java Virtual Machine Stack이라고 부르고 있다. 호출 스택이라는 용어가 공식적인 용어는 아닌 것으로 보인다. 하지만 자바의 정석에서는 호출 스택이라는 단어를 사용하기 때문에 혼용하도록 하겠다.

JVM 스택 또는 호출 스택에는 메서드 작업에 필요한 것들이 저장된다.

메서드가 호출되면, 호출 스택에 호출된 메서드를 위한 메모리가 할당되며, 이 메모리는 메서드가 작업을 수행하는 동안 지역변수(매개변수 포함)들과 연산의 중간 결과 등을 저장하는데 사용한다. 그리고 메서드가 작업을 마치면 할당되었던 메모리 공간은 비워진다.

참고자료

profile
Junior Backend Engineer

1개의 댓글

comment-user-thumbnail
2023년 8월 4일

정보에 감사드립니다.

답글 달기