5.1 데이터 타입 분류

 

기본 타입은 정수, 실수, 문자, 논리 리터럴을 저장하는 타입 

          정수타입 : byte, char, short, int, long

        실수타입: float, double

        논리타입: boolean

참조 타입은 배열, 열거, 클래스. 인터페이스 타입

*String은 클래스 타입이다.

변수가 스택 영역에 생성되고 객체는 힙 영역에 생성된다.

변수 스택 / 객체 힙에 생성

[기본 타입 변수]
int age = 25;
double price = 100.5;

[참조 타입 변수]
String name = "신용권";
String name = "독서";

int와 double 변수인 age와 price는 직접 값을 저장하고 있지만, String 클래스 변수인 name과 hobby는 힙 영역의 String 객체 주소 값을 가지고 있다. 주소를 통해 객체를 참조한다는 뜻에서 String 클래스 변수를 참조 타입 변수라고 한다.

5.2 메모리 사용 영역

Heap(힙) 영역

힙 영역은 객체와 배열이 생성되는 영역이다.

힙 영역에 생성된 객체와 배열을 JVM 스택 영역의 변수나 다른 객체의 필드에서 참조한다.

JVM Stack(스택) 영역

JVM 스택 영역은 각 스레드마다 하나씩 존재하며 스레드가 시작될 때 할당된다. 

자바 프로그램에서 추가적으로 스레드를 생성하지 않았다면 main 스레드만 존재하므로 JVM 스택도 하나이다.

JVM스택은 메소드를 호출할 때마다 프레임(Frame)을 추가(Push)하고 메소드가 종료되면 해당 프레임을 제거(Pop)하는 동작을 수행한다.

예외 발생 시 printStackTrace() 메소드로 보여주는 Stack Trace의 각 라인은 하나의 프레임을 표현한다.

프레임 내부에는 로컬 변수 스택이 있는데, 기본 타입 변수와 참조 타입 변수가 추가(push)되거나 제거(pop)된다.변수가 이 영역에 생성되는 시점은 초기화 될 때, 즉 최초로 변수에 값이 저장될때이다.변수는 선언된 블록 안에서만 스택에 존재하고 블록을 벗어나면 스택에서 제거된다.

//예시코드

char v1 = 'A';

if (v1=='A') {
int v2 = 100;
double v3 = 3.14;
}

boolean v4 = true;

//v2와 v3은 if 블록 내부가 실행되고 있을 때만 스택 영역에 존재하고 실행 흐름이 if 블록을 빠져나가면 소멸된다.

 

기본 타입 변수는 스택 영역에 직접 값을 가지고 있지만, 참조 타입 변수는 값이 아니라 힙 영역이나 메소드 영역의 객체 주소를 가진다.

 

5.3 참조 변수의 ==,!= 연산

5.4 null과 NullPointerException

5.5 String 타입

문자열은 직접 변수에 저장되는 것이 아니라, 문자열은 String 객체로 생성되고 변수는 String 객체를 참조한다.

(하지만 일반적으로 String 변수에 저장한다는 표현을 사용한다.)

String name;
name = "신용권";
String hobby = "자바";

name 변수와 hobby 변수는 스택 영역에 생성되고 , 문자열 리터럴인 "신용권"과 "자바"는 힙 영역에 String 객체로 생성된다. 그리고 name 변수와 hobby 변수에는 String 객체의 주소 값이 저장된다.

<new, 객체 생성 연산자>

일반적으로 변수에 문자열을 저장할 경우에는 문자열 리터럴을 사용하지만, new 연산자를 사용해서 직접 String 객체를 생성시킬 수도 있다. new 연산자는 힙 영역에 새로운 객체를 만들 때 사용하는 연산자로 객체 생성 연산자라고 한다.

**자바는 문자열 리터럴이 동일하다면 String 객체를 공유하도록 되어 있다. 다음과 같이 name1과 name2 변수가 동일한 문자열 리터럴인 "신용권"을 참조할 경우 name1과 name2는 동일한 String 객체를 참조하게 된다.

String name1 = "신용권";
String name2 = "신용권";
String name1 = new String("신용권");
String name2 = new String("신용권");

이 경우 name1과 name2는 서로 다른 String 객체를 참조한다.

변수에 저장된 객체 번지가 달라졌다.

문자열만을 비교하고 싶을 경우 아래와 같이 해야한다. String 객체의 equals() 메소드

boolean result = str1.equals(str2);

5.6 배열 타입

배열은 같은 타입의 데이터를 연속된 공간에 나열시키고, 각 데이터에 인덱스(index)를 부여해 놓은 자료구조이다.

배열도 객체이므로 힙 영역에 생성되고 배열 변수는 힙 영역의 배열 객체를 참조하게 된다.참조할 배열 객체가 없다면 배열 변수는 null 값으로 초기화될 수 있다.다만 배열 변수가 null 값을 가진 상태에서 변수[인덱스]로 값을 읽거나 저장하게 되면 NullPointerException이 발생한다.배열 변수는 배열을 생성하고 참조하는 상태에서 값을 저장하거나 읽어야 한다. 

 

배열 변수 선언

타입[] 변수;
int[] intArray;
double[] doubleArray;
String[] strArray;

또는


타입 변수[];
int intArray[];
double doubleArray[];
String strArray[];

배열이 생성되고 나서 새로운 값을 저장하려면 대입 연산자를 사용하면 된다.

변수[인덱스] = 값;

int[] scores = new int[3];
scores[0] = 83;
scores[1] = 90;
scores[2] = 75;

다차원 배열

2(행)x3(열) 행렬을 만들기 위해 다음과 같은 코드를 사용한다.

int[][] scores = new int[2][3];

scores.length //2(배열 A의 길이)
scores[0].length //3(배열 B의 길이)
scores[1].length //3(배열 C의 길이)

 

int[][] scores = new int[2][];
scores[0] = new int[2]; //01
scores[1] = new int[3]; //012


//배열 항목의 수
scores.length  //2(배열 A의 길이)
scores[0].length //2(배열 B의 길이)
scores[1].length //3(배열 C의 길이)

배열 복사

src 매개값은 원본 배열이고, srcPos는 원본 배열에서 복사할 항목의 시작 인덱스이다. dest 매개값은 새 배열이고, destPos는 새 배열에서 붙여넣을 시작 인덱스이다. 마지막으로 length는 복사할 개수이다. 예를 들어 원본 배열이 arr1이고 새 배열이 arr2일 경우 arr1의 모든 항목을 arr2에 복사하려면 다음과 같이 System.arraycopy()메소드를 호출하면 된다.

System.arraycopy(Object src, int srcPos, Object dest, int destPos, int length);

System.arraycopy(arr1, 0, arr2, 0, arr1.length);

향상된 for 문

int[] scores = { 95, 71, 84, 93, 87 };

int sum = 0;

for(int score : scores) {

	sum = sum + score;
	}
	
    System.out.println("점수 총합 = " + sum);
    
    double avg = (double)sum / scores.length;
    System.out.println("점수 평균 = " + avg);

5.7 열거 타입

 

+ Recent posts