* 참조 타입과 참조 변수
💡 참조 타입 : 객체의 번지를 참조하는 타입: 배열,열거,클래스,인터페이스 💡 기본 타입 : 정수,실수,문자,논리 리터럴 저장
1) 스택 (Runtime Stack)
- 바이트 코드(컴파일된 목적 코드)를 불러들여서(load) 지역 변수(local variable)을 할당.
- 블록 영역을 벗어나면 소멸. 반드시 초기화 작업 선행되어야 함. 자동으로 초기화 되지 않음.
2) 힙 (Heap : The garbage-collected Heap, dummy memory)
- 배열이나 클래스 객체(인스턴스)가 할당됨. GC(Garbage Collector)가 관리함.
- 이 영역은 특별한 초기화 없이도 사용가능하다. 참고로 인스턴스(instance)들의 초기값은 null이다.
3) 상수 영역 (literal pool)와 메소드 영역(method area)
- 실질적으로 바이트 코드(목적 코드)가 위치한 영역.
- 고정(static) 값을 가지는 상수(constant), 추상 메소드(abstract method)가 위치하는 영역. 실행(runtime)시 호출(call)을 위해서 주소 위치를 갖게 됨.
- 특히, 외부에서는 호출되는 메모리의 주소(위치)를 파악할 수 없어서 해킹이 어려움(보안).
- 참고로 native method area는 다른 언어(C, C++ 등) 언어의 메소드 사용시 그 메소드들이 불러들여지는 영역임.
4) 레지스터 영역 (process register area)
- JVM 실행시 호출할 메모리 주소를 기억해두는 곳.
- 실행 프로세서들이 작동될 때 이곳에 등록(registration)된 내용을 기초로 실행됨.
5) Registers
- 일종의 임시 기억장소(메모리)로써 32비트 주소 지정 방식(addressing)으로 JVM이 관리하며 구체적으로는 주로 스택(stack)을 관리하는 역할을 함.
- 5-1) optop register (operand-top register)
- 연산자(oprand)의 마지막 주소를 가지고(혹은 가리키고) 있다(보관).
- The top of the operand stack is pointed to by the optop register.
- 5-2) PC register (program counter register)
- 메소드 영역의 몇 바이트를 가리키고 있으며 바이트 코드가 실행되면서 한 명령이 실행된 후 다음 명령이 실행될 메모리 주소값을 가지고(fetch) 있음. 쓰레드(thread)의 실행 진행 상황을 주시(감시)하는 역할도 함.
- 5-3) vars register
- 실행중인 메소드의 요소들(지역 변수, 반환 값(return value) 등)의 주소값을 가지고(가리키고) 있음.
- 5-4) frame register (stack frame register : Execution Environment Area(Sector))
- 스택(operand stack) 자체의 연산을 수행 및 관리하는 역할을 함.
- 물론 언급한 바와 같이 JVM은 바이트 모드에 대한 모든 연산을 이 스택(stack)에서 실행하게 됨.
- 연산시 인자들(parameter, 매개변수) 및 명령 및 결과들을 연산하기 위해 임시적으로 보관함.
- 실행 환경(Execution Environment) 변수들에 대한 주소를 가지고(가리키고) 있음.
* 배열
- 낱개의 변수 -> 배열 : 같은 자료형이 여러개 있는것
1.배열변수 선언방법 : 바로 선언 X , 값을 할당해 줘야 한다
- new : 동적 변수 할당(allocation) 연산자 => heap(자유 메모리 공간)에 할당
- Ex)
// 배열변수 선언 방법 // new : 동적 변수 할당(allocation) 연산자 => heap(자유 메모리 공간)에 할당 int arr[]; = new int[10]; // 1) int [] arr = new int[10]; // 2) int arr[]; // 3) arr = new int [10]; arr = new int [5]; // 재할당 System.out.println("arr 배열 변수의 크기 : " + arr.length); // 5 출력(재할당 됐기 때문에)' arr[0] = 10; // arr배열의 인덱스 0자리에 10 입력 arr[4] = 20; // arr배열의 인덱스 4자리에 20 입력 // 배열 전체 요소들을 나열 for(int i=0; i<arr.length; i++) { System.out.print(arr[i] + " "); // 10 0 0 0 20 출력 } // 향상된 for문(enhanced for loop, foreach) // 인덱스 사용(X), 다음(next) 요소 검색 방식(iterator(반복자)패턴 방식) for(int n : arr) { System.out.print(n + " "); // 10 0 0 0 20 출력 } // 배열의 수동 초기화 int arr[] = {1,2,3,4,5}; // (O) // int arr[5] = {1,2,3,4,5}; // (X) int arr[] = new int[] {1,2,3,4,5}; // (O) // int arr[] = new int[5] {1,2,3,4,5}; // (X) arr[0] = 10; for(int n : arr) { System.out.print(n + " "); // 10 2 3 4 5 출력 }
* 다차원 배열
-
Ex)
// 다차원 배열(array) // 선언 방법 int arr[][]; // 1) int []arr[]; // 2) int [][]arr; // 3) arr = new int [3][2]; arr[0][0] = 1; arr[0][1] = 2; arr[1][0] = 3; arr[1][1] = 4; arr[2][0] = 5; arr[2][1] = 6; System.out.println("2차원 배열의 크기(행의크기) : " + arr.length); // 3 출력 System.out.println("2차원 배열의 요소의 갯수 : " + arr.length * arr[0].length); // 6 출력 // 전체 요소 나열 (중첩 for문) for(int i=0; i<arr.length; i++) { for( int j =0; j<arr[i].length; j++) { System.out.print(arr[i][j] + " "); // 1 2 } // 3 4 System.out.println(); // 5 6 => 출력된 형태 } // foreach for(int[] arr2 : arr) { for(int n : arr2) { System.out.print(n + " "); // 1 2 } // 3 4 System.out.println(); // 5 6 => 출력된 형태 } // 2차원 배열의 초기화 int [][]arr = { {1,2},{3,4},{5,6}}; // (O) int [][]arr = new int{ {1,2},{3,4},{5,6}}; // (O) // int [][]arr; // (X) // arr = { {1,2},{3,4},{5,6}}; // (X) // int [][]arr = new int[3][2]{ {1,2},{3,4},{5,6}}; // (X) // 2차원 배열의 가변 할당 int [][]arr = new int[3][]; // (O) // int [][]arr = new int[][]; // (X) // int [][]arr = new int[][3]; // (X) arr[0] = new int[5]; // arr[1] = {1,2,3}; // (X) arr[1] = new int[3]; arr[2] = new int[7]; for(int[] arr2 : arr) { for(int n : arr2) { System.out.print(n + " "); // 0 0 0 0 0 } // 0 0 0 System.out.println(); // 0 0 0 0 0 0 0 => 출력된 형태 }
* 열거 타입
** 열거타입 : 클래스 처럼 생긴 상수 => 열거형 상수를 사용한다면 원래 있던 소스코드를 다시 컴파일하지 않아도 된다는 장점이 있다
-
Ex1) : eunm 사용
package com.javateam.jse; public enum Season { // SPRING,SUMMER,FALL,WINTER; SPRING("봄",1),SUMMER("여름",2),FALL("가을",3),WINTER("겨울",4); private String name; private int num; Season(String name,int num){ this.name = name; // 멤버 필드 <= 인자 this.num = num; } public String getName() { return name; } public int getNum() { return num; } public static void main(String[] args) { Season season = Season.SPRING; System.out.println(Season.SPRING); // System.out.println(Season.valueOf("SPRING")); // System.out.println(season); System.out.println(Season.SPRING); // SPRING 출력 System.out.println(Season.SPRING.name); // 봄 출력 System.out.println(Season.SPRING.num); // 1 출력 } }
-
Ex2) : class 사용
package com.javateam.jse; public class Season2 { // class 이용시 final(값이 변하지 않는다) 사용 public static final int SPRING = 0; public static final int SUMMER = 1; public static final int FALL = 2; public static final int WINTER = 3; public static void main(String[] args) { System.out.println(Season2.SPRING); } }