목표

자바의 프리미티브 타입, 변수 그리고 배열을 사용하는 방법을 익힙니다.

학습할 것

  • 프리미티브 타입 종류와 값의 범위 그리고 기본 값
  • 프리미티브 타입과 레퍼런스 타입
  • 리터럴
  • 변수 선언 및 초기화하는 방법
  • 변수의 스코프와 라이프타임
  • 타입 변환, 캐스팅 그리고 타입 프로모션
  • 1차 및 2차 배열 선언하기, 타입 추론, var

공부 내용

1. 프리미티브 타입 종류, 값의 범위, 기본값

  타입 할당 메모리 데이터 범위  기본값
논리형 boolean 1 byte true, false false
정수형 byte 1 byte -128 ~ 127 0
short 2 bytes -32768 ~ 32767 0
int 4 bytes

 -2147483648 ~ 2147483647

0
long 8 bytes

-2^63 ~2^63-1
(여기서 ^는 지수를 의미)

0L
실수형 float 4 bytes

 (3.4 X 10^-38) ~ (3.4 X 10^38) 의 근사값

0.0f
double 8 bytes  (1.7 X 10^-308) ~ (1.7 X 10^308) 의 근사값 0.0
문자형 char 2 bytes
(유니코드)

 0 ~ 65535

 '\u0000'
(0을 의미)

2. 프리미티브 타입과 레퍼런스 타입

위의 프리미티브 타입을 제외한 타입이 레퍼런스 타입이라고 한다.

레퍼런스 타입은 아래와 같다.

타입 할당메모리 기본값
배열 (Array) 4 bytes (객체의 주소값) Null
열거 (Enumeration)
클래스 (Class)
인터페이스 (Interface)

 

레퍼런스 타입의 특성은 주소를 저장하는 포인터의 개념으로 동작, 기본값은 Null 이므로 아무런 값을 할당하지 않았을 때 런타임 시NullPointException이 발생할 수 있기 때문에 Null 체크 또는 값 할당이 매우 중요하다.

프리미티브 타입과 레퍼런스 타입의 이해를 쉽게 하기 위해서 간단한 그림으로 보자.

그림1. 프리미티브와 레퍼런스 타입 설명

코드 영역에서는 순서대로 코드가 작성된다. 1, 2은 프리미티브 타입이고 3,4,5는 레퍼런스 타입인데 해당 부분은 Stack과 Heap이라는 메모리 영역으로 구분해서 보면 좀 더 명확하게 볼 수 있다.

프리미티브 타입은 Stack이라고 불리는 메모리 영역에 값과 같이 저장된다. 하지만 레퍼런스타입은 값이 Heap 영역에 저장되고 Stack에 있는 부분은 해당 데이터의 주소값을 가지고 참조하는 형태로 저장되는 타입을 말한다. 

예를들어 위의 그림의 3번은 int[] c = {1,2,3,4} 라는 형태로 배열을 선언했다. 해당 배열은 Heap에 생성되고 Stack에 있는 c는 해당 배열의 주소값을 가지고 가는 것이다.

3. 리터럴

리터럴은 프로그램에서 직접 표현한 값을 의미한다. 종류는 정수, 실수, 문자, 논리, 문자열 로 나눠 볼 수 있다.
위 그림1. 프리미티브와 레퍼런스 타입 설명에서는 1, 2번이 정수 리터럴, 5번이 문자열 리터럴로 볼 수 있다.

// 정수 리터럴 (15가 리터럴)
int a = 15;

// 실수 리터럴 (0.2345 값자체가 리터럴)
double f = 0.1234;

// 문자 리터럴 (아래에서 L이 리터럴)
char a = 'L';

// 문자열 리터럴 (hello가 리터럴)
String lter = "hello";

// 논리타입 리터럴 (true가 리터럴)
boolean a = true;

4. 변수 선언 및 초기화 방법

변수 선언은 아래와 같이 구성할 수 있다.

int i;
double d;
char c1, c2;

초기화 방법은 명시적 초기화, 생성자, 초기화 블럭 3가지로 나뉜다.

 

4-1. 명시적 초기화

명시적 초기화란 선언과 동시에 초기화 하는 것을 말함

class Car {
	int Oil = 12; //프리미티브 변수의 초기화
    Engine e = new Engine(); // 참조형 변수의 초기화
    // 생략
}

 

4-2. 생성자

class Car {
	int oil;
	Engine e = new Engine();

	// 생성자
	Car(int oil) {
    	this.oil = oil;
    }
}

public class Test {
    public static void main(String[] args) {
		Car car = new Car(12); //new Car(12)에서 12로 입력하는게 초기화 입력
    }
}

 

4-3. 초기화 블럭
초기화 블럭은 초기화 작업이 복잡할 때 사용한다.
초기화 블럭 내에 명시적 초기화에서는 쓸 수 없는 조건문, 반복문, 배열, 예외처리 등의 명령문을 통해 복잡한 초기화가 가능하다.

public class Square {
	int x;
	int y;
	
	// 초기화 블럭
	{
		x = Math.abs(-10);
		x += 10;
		y = 7;
	}
}

public class Test {
    public static void main(String[] args) {
		Square s = new Square();
    }
}

 위 그림과 같이 초기화 블럭을 선언하면 생성자보다 먼저 수행된다.

5. 변수의 스코프와 라이프타임

프로그램 상에서 사용되는 변수들은 사용가능한 범위가 존재한다. (스파게티 코드를 피하기 위함이 아닐까)
해당 범위가 끝나게 되면 메모리에서 해당 변수가 제거 되는 것이 변수의 라이프사이클이라고 할 수 있다.

변수는 2가지 타입으로 나뉠 수 있다.

5-1. 전역변수
전역변수는 함수 밖에 선언되어 클래스 전체에서 사용가능한 변수를 말한다.

public class Test {
	int var = 100; //전역변수
    
	public static void main(String[] args) {
		System.out.println(var); // 전역변수 출력
    }
}

 

5-2. 지역변수
지역변수는 함수 속에 선언하여 해당 함수 속에서만 사용가능한 변수를 말한다.
좀 더 쉽게 말하면 블럭 {} 안에서 유효한 변수를 말한다.

그럼 같은 이름으로 전역과 지역변수가 수행되면 어떻게 될까?

public class Test {
	int var = 100; //전역변수
    
	public static void main(String[] args) {
		System.out.println(var); // 1번
		
        {
		int var = 200;
		System.out.println(var); // 2번
        }
    }
}

1번은 전역변수로 설정된 값인 100이 출력되고 2번에서는 위에서 선언한 200이 출력된다.
int var = 200 으로 선언한 변수는 블럭내에서 유효하며, 해당 블럭내에서는 전역변수보다 우선하는 특징이 있다.

6. 타입 변환(캐스팅) 그리고 타입 프로모션

타입변환은 변수 또는 리터럴의 타입을 다른 타입으로 변환하는 것이다.

타입변환 방법은 아래와 같다.

(타입이름)피연산자
// 아래는 수도코드이다.
main(){
	double d = 100.0;
    int i = 100;
    int result = (int)d; // 타입변환이 여기서 일어남
    
    System.out.println(result);
}

프리미티브 타입에서 boolean을 제외한 나머지 7개의 타입은 서로 형변환이 가능하다.
다만,  변수의 바이트가 큰 자료형에서 작은 자료형으로 타입변환을 할때는 데이터의 손실이 발생할 수 있기 때문에 프로그래머가 명시적으로 타입 변환을 수행해야 한다.
값의 범위가 작은 타입에서 큰타입으로의 변환은 생략가능하다. (이것이 타입 프로모션임)

7. 1차 및 2차 배열 선언하기, 타입 추론, var

배열 선언은 간단하다. 아래와 같이 선언할 수 있다.

public class Test {
    
	public static void main(String[] args) {
		
        // 1차원 배열 생성
        int[] arr1 = {1,2,3,4,5};
        
        // 또다른 1차원 배열 생성 (값 입력 안됨)
        int[] arr1 = new int[5];
        
        // 2차원 배열 생성
        int[][] arr2 = {{1,1,1,1,1},{2,2,2,2,2}};
    	
        // 2차원 배열 생성 (값 입력 안됨)
        int[][] arr2 = new int[2][5];
    }
}

1차원 배열은 int[] arr1 = 변수값 형태로 입력하거나, int[] arr1 = new int[5] 형태로 선언할 수 있다.
2차원 배열도 마찬가지다. 2차원 배열은 [행][열] 로 표현된다.

접근하기 위해서는 인덱스로 접근하는데 첫번째 인자에 접근하기 위해서는 arr1[0]과 같이 접근하면 된다.

자바 10부터 타입 추론을 지원하는 var 키워드가 추가되었다.
이 키워드는 지역변수 이면서 초기화를 동시에 해줘야 한다.

// Java 9 이하
String message = "데이터 타입을 지정해줘야 함";

// Java 10 이상
var message = "이렇게 초기화 하면 String으로 초기화가 됩니다."

 

주의할 부분은 <> 와 같은 다이아몬드 연산자를 사용하면 컴파일 에러가 발생한다.

var messages = new ArrayList<>(); // 컴파일러가 타입 유추할 정보가 없음

 

+ Recent posts