Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- Graph
- C programming
- Serialization
- coding test
- list 컬렉션
- 윤성우 열혈자료구조
- Algorithm
- stream
- 윤성우의 열혈 자료구조
- buffer
- 이스케이프 문자
- C 언어 코딩 도장
- s
- 메모리구조
- insertion sort
- 알기쉬운 알고리즘
- 이것이 자바다
- JSON
- Selection Sorting
- Stack
- 혼자 공부하는 C언어
- datastructure
- R
Archives
- Today
- Total
Engineering Note
[Java] 변수의 종류 본문
- 변수의 정의
- 변수의 종류
- 기본형 변수, 참조형 변수
- 클래스 변수, 인스턴스 변수, 지역 변수
변수
- 값을 저장할 수 있는 메모리 공간
변수의 선언과 초기화
int age;
int num = 1; //선언과 동시에 초기화
- 변수를 선언하면, 메모리의 빈 공간에 ‘변수타입’에 알맞은 크기의 저장공간이 확보되고, 앞으로 이 저장공간은 ‘변수이름’을 통해 사용할 수 있게 된다.
- 예를 들어, int, 정수 타입의 변수를 선언 했다면 int 타입 사이즈에 해당하는 4byte(32bit)의 메모리 공간이 확보된다. 우리가 인터넷에서 특정 페이지를 찾아갈 때 ip주소 대신 도메인명으로 naver를 찾아 가는 것처럼 변수명으로 메모리를 찾아 간다고 이해하면 된다.
변수타입
- 변수에 저장될 값이 어떤 ‘type’인지를 지정하는 것이다.
변수의 종류 - 실제 값 저장 vs 주소 값 저장, 선언 위치
실제 값 저장 여부로 구분
primitive type variable(기본형), reference type variable(참조형)
기본형 변수 - 실제 값 저장
- 논리형(boolean), 문자형(char), 정수형(byte, short, int, long), 실수형(float, double)
참조형 변수 - 주소 값 저장(객체의 주소)
참조형 변수는 8개의 기본형을 제외한 나머지 타입
인스턴스는 참조변수를 통해서만 다룰 수 있으며, 참조변수의 타입은 인스턴스의 타입과 일치해야 한다. (상속을 통한 다형성은 예외지만 기본적으로 참조변수의 타입과 일치하는 객체 인스턴스만 저장이 가능하다.)
ex) Person 인스턴스를 다루려면, Person 타입의 참조변수가 필요하다.
cf) Class의 정의
- 객체지향 관점 - 설계도
- 프로그래밍 관점 - 사용자 정의 타입(구조체의 발전된 형태), 참조형 타입
#include <stdio.h> typedef struct _Point{ int x; int y; }Point; int main(){ int x = 10; int y = 20; Point p1; p1.x = 10; p1.y = 20; return 0; }
클래스이름 변수이름; // 변수의 타입이 기본형이 아닌 것들은 모두 참조변수이다.
class Person (){ String name; void walk(){ System.out.println("걷는다"); } } class Main(){ public static void main(String[] args){ /** Person 인스턴스 생성으로 이해할 수도 있지만 Person 타입 p 변수(참조 변수) 선언, Person 인스턴스 할당으로 이해 가능 Person 타입 p 변수는 참조변수이면서 지역변수 Person 타입 p 변수에 Person 타입 인스턴스 할당 */ int num = 1; Person p; p = new Person(); Person p2; p2 = p; //Person p = new Person(); } }
참조변수 사용 이유 - 인스턴스는 주소를 통해 다루는 이유
- 참조변수를 사용하는 이유는 메모리 낭비를 막기 위해서 이다. 기본형 변수처럼 인스턴스도 변수에 인스턴스 값들을 직접 할당한다면 메서드 내의 지역변수마다 인스턴스를 위한 메모리 공간을 확보해야 한다. 예를 들면, 함수의 매개변수로 인스턴스를 전달할 경우 매서드 내의 스택프레임 공간에 인스턴스 크기 만큼의 메모리 공간을 또 확보해야 한다.
매개변수에서 기본형과 참조형 살펴보기 - call by value, call by reference
- 기본형 매개변수는 변수의 값을 읽기만 할 수 있지만 참조형 매개변수는 변수의 값을 읽고 변경할 수 있다.
package variable;
public class Data {
int x;
}
package variable;
public class PrimitiveParamEx {
public static void main(String[] args) {
//1.
Data d = new Data();
d.x = 10;
System.out.println("main() : x = " + d.x);
//2.
change(d.x);
//4.
System.out.println("------------------");
System.out.println("After change(d.x)");
System.out.println("------------------");
System.out.println("main() : x = " + d.x);
}
static void change(int x){
//3.
x = 1000;
System.out.println("change() : x = " + x);
}
}
출력 결과
메모리 상태
package variable;
public class ReferenceParamEx {
public static void main(String[] args) {
//1.
Data d = new Data();
d.x = 10;
System.out.println("main() : x = " + d.x);
//2.
change(d);
//4.
System.out.println("------------------");
System.out.println("After change(d)");;
System.out.println("------------------");
System.out.println("main() : x = " + d.x);
}
static void change(Data d){
//3.
d.x = 1000;
System.out.println("change() : x = " + d.x);
}
}
출력 결과
메모리 상태
참조 변수 반환
- 매개변수뿐만 아니라 반환타입도 참조형이 될 수 있다.
- 반환타입이 참조형이라는 것은 반환하는 값의 타입이 참조형이라는 얘긴데, 모든 참조형 타입의 값은 ‘객체의 주소’이므로 그저 정수값이 반환되는 것일 뿐 특별할 것은 없다.
package variable;
public class ReferenceREturnEx {
public static void main(String[] args) {
//1.
Data d = new Data();
d.x = 10;
//2.
Data d2 = copy(d);
//5.
System.out.println("d.x = " + d.x);
System.out.println("d2.x = " + d2.x);
}
static Data copy(Data d){
//3.
Data tmp = new Data();
tmp.x = d.x;
//4.
return tmp;
}
}
- main 메서드에서 d 참조변수에 Data인스턴스를 할당한다.
- copy메서드를 호출하면서 참조변수 d의 값이 매개변수 d에 복사된다.
- copy메서드 내부에서 tmp 참조변수에 새로운 Data 인스턴스를 할당한다.
- 새로운 객체를 생성한 다음, d.x에 저장된 값을 tmp.x에 복사한다.
- copy 메서ㅓ드가 반환한 tmp의 값은 참조변수 d2에 저장된다.
- copy 메서드가 종료되어 tmp가 사라졌지만, d2로 새로운 객체를 다룰 수 있다.
선언 위치에 따른 구분
- 멤버변수 - 클래스의 필드, 속성, 자원
- instance variable(인스턴스 변수)
- class variable(클래스 변수), static variable(정적 변수)
- local variable(지역 변수)
class Variables{
//클래스 영역
int instanceValue; //인스턴스 변수
static int classValue; //클래스 변수(static변수, 공유변수)
void method(){
//메소드 영역
int localValue = 0; //지역 변수
while(True){
int flag = 0;
}
}
}
변수의 종류 | 선언 위치 | 생성시기 |
---|---|---|
class variable | 클래스 영역 | 클래스가 메모리에 올라갈 때 |
instance variable | 클래스 영역 | 인스턴스가 생성되었을 때 |
local variable | 클래스 영역 이외의 영역(메서드, 생성자 블럭 내부) | 변수 선언문이 수행되었을 때 |
instance variable
- 인스턴스 변수
- 클래스 영역에 선언되며, 클래스의 인스턴스를 생성할 때 만들어진다. 그렇기 때문에 인스턴스 변수의 값을 읽어 오거나 저장하기 위해서는 먼저 인스턴스를 생성해야 한다.
- 인스턴스는 독립적인 저장공간을 가지므로 서로 다른 값을 가질 수 있다. 인스턴스마다 고유한 상태를 유지해야하는 속성의 경우, 인스턴스변수로 선언한다.
class variable
- 클래스 변수(static 변수)
- public을 앞에 붙이면 같은 프로그램 내에서 어디서나 접근할 수 있는 ‘전역변수(global variable)’의 성격을 갖는다.
- 클래스 변수를 선언하는 방법은 인스턴스변수 앞에 static을 붙이기만 하면 된다. 인스턴스마다 독립적인 저장공간을 갖는 인스턴스변수와는 달리, 클래스변수는 모든 인스턴스가 공통된 저장공간(변수)을 공유하게 된다. 한 클래스의 모든 인스턴스들이 공통적인 값을 유지해야하는 속성의 경우, 클래스변수로 선언해야 한다.
- 클래스 변수는 인스턴스변수와 달리 인스턴스를 생성하지 않고도 언제라도 바로 사용할 수 있다는 특징이 있으며, ‘클래스이름.클래스변수’와 같은 형식으로 사용한다. 예를 들면, Variables클래스의 클래스변수 classValue를 사용하려면 ‘Variables.classValue’와 같이 하면 된다.
- 클래스가 메모리에 로딩될 때 생성
instance variable, class variable 차이
- 인스턴스 변수는 인스턴스가 생성될 때마다 생성되므로 인스턴스마다 각기 다른 값을 유지할 수
있지만, 클래스 변수는 모든 인스턴스가 하나의 저장공간을 공유하므로, 항상 공통된 값을 갖는다.
instance variable, class variable 실습
- Card를 Class화 하여 인스턴스변수와 클래스 변수 실습
package variable;
public class Card {
//인스턴스 변수
String kind;
int number;
//클래스 변수
static int width = 100;
static int height = 250;
}
package variable;
public class CardTest {
public static void main(String[] args) {
System.out.println("Card.width = " + Card.width); //클래스 변수(static 변수)는 객체 생성없이 클래스명.클래스변수로 사용 가능
System.out.println("Card.height = " + Card.height);
System.out.println("--------------------------------");
Card c1 = new Card();
c1.kind = "Heart";
c1.number = 7;
Card c2 = new Card();
c2.kind = "Spade";
c2.number = 4;
System.out.println("c1은 " + c1.kind + ", " + c1.number + "이며, 카드의 크기는 (" + c1.width + ", " + c1.height + ")");
System.out.println("c2은 " + c2.kind + ", " + c2.number + "이며, 카드의 크기는 (" + c2.width + ", " + c2.height + ")");
System.out.println("--------------------------------");
System.out.println("c1의 width와 height를 각각 50, 80으로 변경합니다.");
System.out.println("--------------------------------");
c1.width = 50; //클래스 변수를 인스턴스 참조변수로 접근하여 변경
c1.height = 80;
System.out.println("c1은 " + c1.kind + ", " + c1.number + "이며, 카드의 크기는 (" + c1.width + ", " + c1.height + ")");
System.out.println("c2은 " + c2.kind + ", " + c2.number + "이며, 카드의 크기는 (" + c2.width + ", " + c2.height + ")");
System.out.println("--------------------------------");
}
}
- 각 Card 인스턴스는 자신만의 무늬(kind)와 숫자( number)를 유지하고 있어야 하므로 이들을 인스턴스 변수로 선언하였고, 각 카드의 폭(width)과 높이(height)는 모든 인스턴스가 공통적으로 같은 값을 유지해야하므로 클래스변수로 선언하였다.
- 이렇게 할 경우 카드의 폭을 변경해야 할 필요가 있을 경우, 모든 인스턴스 카드의 width값을 변경하지 않고 한 카드 인스턴스 참조변수를 통해 접근한 width값만 변경해도 모든 카드의 width 값이 변경되는 셈이다.
- 주의할 점은, 인스턴스 참조변수로 클래스변수의 값을 변경하더라도 클래스 변수는 저장공간을 공유하므로 모든 인스턴스의 값이 변경된다.
local variable
- 지역 변수
- 메서드 내에 선언되어 메서드 내에서만 사용 가능하며, 메서드가 종료되면 소멸되어 사용할 수 없게 된다.
- 메서드 내에서도 더 좁은 범위에서 사용하기 위한 변수를 선언할 수 도 있는데, 예를 들면 for문 또는 while문의 블럭 내에 선언된 변수는 해당 블럭 내에서만 사용 가능한 지역 변수다.
참고자료
- 자바의 정석(저자 남궁성)
'Programming Language > Java' 카테고리의 다른 글
이스케이프 문자 (0) | 2025.03.29 |
---|---|
[Java] Polymorphism (1) | 2022.09.22 |
[Java] Inheritance (0) | 2022.09.09 |
[Java] Access Modifier, Encapsulation (0) | 2022.09.09 |
[Java] Object Oriented Programming (0) | 2022.09.09 |
Comments