선언 위치에 따른 변수의 종류
변수는 클래스변수, 인스턴스변수, 지역변수가 있다.
변수의 종류를 결정짓는 중요한 요소는 '변수가 선언된 위치'이다.
멤버변수를 제외한 나머지 변수들은 모두 지역변수이고, 멤버변수 중 static 이 붙은 것은 클래스변수, 붙지 않은 것은 인스턴스 변수이다.
class Variables
{
int iv; // 인스턴스 변수
static int cv; // 클래스 변수 (static 변수, 공유 변수) --> 클래스 영역 (전체)
void method() {
{
int lv = 0; // 지역 변수 --> 메서드 영역
}
}
1.인스턴스 변수
- 클래스 영역에 선언되며, 클래스의 인스턴스를 생성할 때 만들어진다.
그렇기 때문에 인스턴스 변수의 값을 읽어 오거나 저장하기 위해서는 먼저 인스턴스를 생성해야한다.
인스턴스는 독립적인 저장공간을 가지므로 서로 다른 값을 가질 수 있다.
인스턴스마다 고유한 상태를 유지해야하는 속성의 경우, 인스턴스변수로 선언한다.
2. 클래스 변수
클래스 변수를 선언하는 방법은 인스턴스 변수에 static만 붙이면 된다.
클래스 변수는 모든 인스턴스가 공통된 저장공간을 공유한다.
한 클래스의 모든 인스턴스들이 공통적인 값을 유지해야하는 속성의 경우, 클래스 변수로 선언한다.
클래스변수는 인스턴스 변수와 달리 인스턴스를 생성하지 않고도 언제라도 바로 사용할 수 있다.
'클래스이름.클래스변수'와 같은 형식으로 사용하며 클래스가 메모리에 로딩될때 생성되어 프로그램이 종료될 때 까지 유지된다.
public을 앞에 붙이면 같은 프로그램내에 어디서나 접근할 수 있는 전역변수의 성격을 갖는다.
3. 지역 변수
메서드 내에 선언되어 메서드 내에서만 사용 가능하며, 메서드가 종료되면 소멸되어 사용하지 못한다.
클래스 변수와 인스턴스 변수의 차이를 이해하기 위한 예) 카드게임
public class Thisisjava {
public static void main(String[] args) {
System.out.println("Card.width : " + Card.width);
System.out.println("Card.height : " + Card.height);
Card c1 = new Card();
c1.kind = "Heart";
c1.number = 7;
Card c2 = new Card();
c2.kind = "spade";
c2.number = 4;
System.out.println(c1.kind + " " + c1.number + " " + c1.width + " " + c1.height);
System.out.println(c2.kind + " " + c2.number + " " + c2.width + " " + c2.height);
c1.width = 50;
c1.height = 100;
System.out.println(c1.kind + " " + c1.number + " " + c1.width + " " + c1.height);
System.out.println(c2.kind + " " + c2.number + " " + c2.width + " " + c2.height);
}
}
class Card{
String kind;
int number;
static int width = 100;
static int height = 250;
}
card 인스턴스인 c1와 c2는 클래스 변수인 width 와 height를 공유하기 때문에 c1의 width, height 값을 변경하면 c2의 width, heigth 값도 변한다.
메서드 선언과 구현
메서드는 크게 '선언부'와 '구현부'로 이루어졌다.
반환타입 메서드이름 (타입 변수명, 타입 변수명, ...) // 선언부
{
// 메서드 호출시 수행될 코드 // 구현부
}
int add (int a, int b)
{
int result = a + b;
return result; //호출한 메서드로 결과 반환
}
return 문
- 현재 실행중인 메서드를 종료하고 호출한 메서드로 되돌아간다.
반환값의 유무에 관계없이 모든 메서드에는 적어도 하나의 return 문이 있어야하지만,
반환타입이 void 인 경우 return 문 없이도 문제가 없는데, 이는 컴파일러가 메서드의 마지막에 return; 을 자동적으로 추가하기 때문이다.
매개변수의 유효성 검사
메서드의 구현부{}를 작성할 때, 제일 먼저 하는 일이 매개변수의 값이 적절한 값인지 확인하는 것이다.
타입만 맞으면 아무 값이나 매개변수를 통해 넘어올 수 있기 때문에, 가능한 모든 경우의 수에 대해 고민하고 그에 대한 코드를 작성해야 한다.
예를 들어 숫자를 나누는 메서드를 작성할 때, 분모의 값이 0이면 안되기 때문에 분모의 매개변수가 0 이면 메서드를 종료한다는 조건을 걸어줘야 한다.
JVM의 메모리 구조
JVM은 시스템으로부터 프로그램을 수행하는데 필요한 메모리를 할당받고 JVM 은 이 메모리를 용도에 따라 열 영역으로 나눠 관리한다.
그 중 3가지 중요 영역 (method area, call stack, heap) 이 있다.
1. 메서드 영역 : 프로그램 실행 중 어떤 클래스가 사용되면, JVM 은 해당 클래스의 클래스파일을 읽어서 분석하여 클래스에 대한 정보를 이곳에 저장한다. 이때 클래스의 클래스변수도 이 영역에 함께 생성된다.
2. 힙 : 인스턴스가 생성되는 공간, 프로그램 실행 중 생성되는 인스턴스는 모두 이곳에 생성된다. 인스턴스 변수들이 생성되는 공간
3. 호출스택 : 메서드의 작업에 필요한 메모리 공간을 제공한다. 메서드가 호출되면 호출스택에 호출된 메서드를 위한 메모리가 할당되며, 메서드가 작업을 수행하는 동안 사용된다.
각 메서드를 위한 메모리상의 작업공간은 서로 구별되며, 첫 번째로 호출된 메서드를 위한 작업공간이 호출스택의 맨 밑의 마련되고, 첫 번째 메서드 수행 중에 다른 메서드를 호출하면 첫 번째 메서드의 바로 위에 두 번째로 호출된 메서드를 위한 공간이 마련된다.
호출스택의 제일 상위에 위치하는 메서드가 현재 실행중인 메서드이며 나머지는 대기상태에 있게 된다.
따라서 호출스택을 조사해보면 메서드 간의 호출관계와 현재 수행중인 메서드가 어느 것인지 알 수 있다.
호출스택의 특징
- 메서드가 호출되면 수행이 필요한 만큼의 메모리를 스택에 할당받는다.
- 메서드가 수행을 마치고나면 사용했던 메모리를 반환하고 스택에서 제거된다.
- 호출스택의 제일 위에 있는 메서드가 현재 실행 중인 메서드이다.
- 아래에 있는 메서드가 바로 위의 메서드를 호출한 메서드이다.
'자바' 카테고리의 다른 글
[JAVA] 상속 (0) | 2023.09.15 |
---|---|
[JAVA] 변수와 메서드 2 (0) | 2023.09.12 |
[JAVA] 클래스와 객체 (0) | 2023.09.12 |
[JAVA] 약수 구하기 알고리즘 (0) | 2023.09.06 |
[자바] 인텔리제이 단축키 (0) | 2023.07.31 |