Wanna be Brilliant Full-Stack Developer

2/16 JAVA 커스텀 자료형(heap) 개념 잡기! 본문

Some Memos/Java

2/16 JAVA 커스텀 자료형(heap) 개념 잡기!

Flashpacker 2022. 2. 16. 20:46


목표 

클래스 자료형에대해 배울것인데 이번에는 Heap 에다가 저장하는법을 배울것이다! 

package ch01;

// MyVar은 클래스 자료형이다. 클래스 자료형은 개발자가 만드는 커스텀 자료형! 
// 여러가지 데이터를 가지고 있는 클래스를 Beans 라고 부름.
class MyVar {
	static int n1 = 10;
	static char c1 = 'A';
}


public class VarEx03 {

	static int num = 500;
	
	public static void main(String[] args) {
		System.out.println(MyVar.n1);
		System.out.println(MyVar.c1);
		System.out.println(VarEx03.num);

	}

}

지난 코드에 MyVar 커스텀 자료형 클래스는 안에 있는 데이터말고 저장할수 있는게 없다.

MyVar은 10과 A를 저장할수는 있지만 다른값을 저장하기위해 값을 바꾸기 위해서는 값을 바꿔야한다. 

 

하나더 저장하고 싶으면 하나더 만들수도있다. 하지만 클래스의 이름을 변경하여야한다 

package ch01;

// MyVar은 클래스 자료형이다. 클래스 자료형은 개발자가 만드는 커스텀 자료형! 
// 여러가지 데이터를 가지고 있는 클래스를 Beans 라고 부름.
class MyVar {
	static int n1 = 10;
	static char c1 = 'A';
}

class MyVar2 {
	static int n1 = 20;
	static char c1 = 'B';
}

public class VarEx03 {

	static int num = 500;
	
	public static void main(String[] args) {
		System.out.println(MyVar.n1);
		System.out.println(MyVar.c1);
		System.out.println(VarEx03.num);
		System.out.println(MyVar2.n1);
		System.out.println(MyVar2.c1);

	}

}

이식의 문제점이 두가지가 있는데!  첫번째는?!

MyVar의 값을 static으로 저장한다? 

그러면 프로그램 시작전부터 프로그램 종료될때까지 메모리에 계속 존재하는 단점이 있고

두번쨰 단점은 MyVar을 내가 더 많은 데이터를 저장하고 싶으면 클래스 자료형을 여러개 만들어야 한다.

 

class Note {
int num = 1;
int time = 1015;
int price = 3000;
} 이렇게하면 메모리에 또 안뜨니까 앞에 static을 다 붙인다 

class Note {
static int num = 1;
static int time = 1015;
static int price = 3000;
} 이렇게되면 메인이 시작하기도전에 static은 메모리에 다뜬다. 

package ch01;

class Note {
	static int num = 1;
	static int time = 1015;
	static int price = 3000;
}
class Note2 {
	static int num = 2;
	static int time = 1020;
	static int price = 1000;
}
// 노트 100개가 필요하면? - 클래스 자료형을 100개를 만들어야한다? 이런 단점이 있다.

public class VarEx04 {

	public static void main(String[] args) {
		System.out.println(Note.num);
		System.out.println(Note.time);
		System.out.println(Note.price);
	}
}

다이소 같은 노트를 구매하는 프로그램을 만들건데 

다이소 안에 직원이 있고 손님이 있다.  손님이 가서 직원한테 " 노트 하나 주세요" 라고 말하면 "알겠어" 하고 처음으로 줄수 있는 노트가 Note1 번!  그리고 나서 Note2번도 만들어놨으니 다른손님도 "노트 주세요" 하면 Note2를 주게된다 

이런방식으로 돌려주는 프로그램이 있을떄 

또다른 손님이와서 노트를 달라고하면 노트 3번은 못준다!  

그러면 또 static에 띄어주면 되는거 아니냐고 물어볼 수 있지만 실행 도중에 노트를 넣을수 있는 방법은 없다.

Static은 자바 프로그램이 시작전에 메모리에 떴다가 프로그램이 종료되면 메모리에서 사라진다.

중간에 내가 이 노트를 생산할 수 있는 방법은 없다.

그럼 static 노트를 미리 1000개정도 만들면 안될까? 

그러면 static 공간에 노트가 1000개가 들어 있을거야 손님이 1000명까지는 서비스를 할수 있지만 1001명떄는 안된다. 

그러면 우리 10만개 미리 만들면 안될까? 

그러면 클래스를 10만개 만들면 static 공간에 10만개의 자리가 들어가있으니 메모리 공간도 부족할것이다. 

만약에 손님이 10명밖에 안오면 나머지 9만 9천 9백 90 개는 사용이 안되고 낭비밖에 안된다.

이렇게는 프로그램을 짤수가 없다. 

 

그러면 Static은 정적이란것을 이해 해야한다. 

정적이라는것은 정해져있다는거다. 내 프로그램이 시작전에 띄어놓고 나서 사용하는것이다. 프로그램이 시작된후에는 어떻게 관리를 할 수가 없다.

 

프로그램이 시작하기전에 미리 (노트의 갯수) 정해놔야하는것이 정적이라는 것이다! 


그러면 정적이 아니라 동적인 방법을 찾아야한다! 

package ch01;

//VarEx05 -> main

//Note -> X

class Note {
	int price = 2000;
}

public class VarEx05 {
	
	public static void main(String[] args) {
		new Note(); // heap 공간에 Note 클래스가 가지고 있는 모든 데이터를 할당해! (대신 static은 제외하고) 
	}
}

static int price = 2000;으로 note를 한권만 사용할 수는 없으니 , int price = 2000;으로 하면 메모리에 뜨지 않으니이때 heap이라는 공간을 사용해야하는데 이건 동적저장공간이다. VarEX05에는 main이 메모리에 떠있고 Note는 아무것도 떠있지 않는다.

이상태에서 자바는 메인을 찾아서 메인에 Stack이 열리고

new Note();는 머냐면  static이라고 적혀있지 않는것들을

heap공간에 Note 클래스가 가지고 있는 모든 데이터를 static이라고 적혀있는것을 제외하고 할당라는 것이다! 

 

크게 두공간으로 나뉘어져 있는데 NOTE와 VarEx05쪽이 있다.

Static 안에 Note라는 공간과 VarEx05라는 공간이 있는데 이 클래스마다 Static 공간을 가지고 있는데

VarEx05는 메인이라고 떠있고 Note에는 아무것도 없다.

JVM은 main을 찾아서 실행시키면 13-15번 라인이 실행되는데

그 실행되는 순간 main이라는 친구의 stack이 열리고 

그리고 14번라인이 실행될떄 Stack이 열리고 main 내부가 실행되는것이 자바이다.

14번 실행될때 new라는 키워드가 적혀져있으면 Note가 들고 있는 데이터들중  static이 아닌것들만 heap공간에 띄운다! 

heap이라는 공간은 좀 다르게 생겼다.

heap이라는 공간에 new Note()했으니까 남는 공간을 차지하게 되는데

여기는 더블, 인트 ,char영역도 아닌 Note라는 영역이 생긴다

14번라인일때 Note라는 영역안에는 price = 2000이라는것이 있다. 

15번라인이 되니 main의 stack영역이 종료되고 자바프로그램이 종료되니 static과 heap이 다사라진다. 

15번라인에서 프로그램은 종료가 되니 heap공간도 사라진다.

우리가 하려는것은 여러개를 만들고싶은데 

14,15,16번 다 heap공간에 note 타입에 커스텀 자료형이 각각 다 만들어진다. 

똑같이 price=2000이 들어가있다. Static이 아니고 new라는 연산자 를 쓰면 좋은점은

프로그램 실행후에 시간이 흐를떄 이렇게 동적으로 띄울수있다.

밑에 int age = 25; 를 하면 Stack영역에 메모리 메모리안에 만들어진다.

Note 안에 price을 찾는 방법이 무엇인가? 지금은 없다 

package ch01;

//VarEx05 -> main

//Note -> X

class Note {
	int price = 2000;
}

public class VarEx05 {
	
	public static void main(String[] args) {
		Note note1 =	new Note(); // heap 공간에 Note 클래스가 가지고 있는 모든 데이터를 할당해! (대신 static은 제외하고) 
		Note note2 = 	new Note();
		Note note3 =	new Note(); // heap 공간 
		int age = 25; // main stack 공간
		System.out.println(age);
		System.out.println(note1.price);
		System.out.println(note2.price);
		System.out.println(note3.price); //가격을 3만원으로 바꾸고싶으면?
		
		note3.price = 30000;
		System.out.println(note1.price);
		System.out.println(note2.price);
		System.out.println(note3.price); 
	}
}

new Note();이것이 값이니까 int age = 25; 에서 25을 값으로 생각한다면 앞에 그 값의 타입과 변수를 적어주면된다.

Note는 커스텀자료형 내가 만든것이다. Note타입이라고 하여 Note(클래스자료형) note1(변수) = new Note(); 

이렇게 heap으로 할당하면 장점이 무엇이냐면 static이 아니니까

내가 원하는 시점에 동적으로 만들수 있고

동적으로 만들수있다는것은 손님이 올떄마다 만들어내면 new로 만들어내면 된다는것이다.

클래스를 여러번 만들필요 없이 한번만 만들어놓고 new해서 할당시키면된다! 

값을 변경하려면 변수.price 만 초기화 해주면된다. 

 

Heap은 이렇게 공간을 따로 쓰고 있다. 

Static은 공간을 어떻게 쓰냐면 같은공간을 쓰고 있기 떄문에 static은 클래스를 여러개 만들었다면

Heap은 하나의 클래스로 new라는 키워드를 이용하여 메모리를 계속 할당하고 다른 공간을 만들수 있다!