[STUDY HALLE] 2주차 과제: 자바 데이터 타입

3 minute read

/* 실제로는 2021-01-05에 작성된 게시물입니다. */

학습 목표

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

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

Deadline: ~2020/11/23 15:00

프리미티브 타입

Primitive Type이란 기본자료형 혹은 원시자료형이라고 불리며, 변수의 주소값에 값이 그 자체로 저장되는 데이터 타입이다. Java의 Primitive Type은 총 8가지 종류로, 정리된 이미지를 첨부한다.

1byte = 8bit인 것을 생각하면 표현범위는 쉽게 생각할 수 있다. 개인적인 경험으로는, int형은 +21억 까지라는 사실은 외워둘만 한 것 같다. 알고리즘 문제를 풀면서 int형과 long형 중 어떤 것을 써야할지 판단 내리기에 아주 유용했다.
그리고 Boolean형은 값이 2가지 이므로 2bit면 충분할텐데 왜 1byte를 할당하는 낭비를 하는지 궁금했는데, Java가 데이터를 다루는 최소 범위가 1byte라고 한다.

레퍼런스 타입

위의 타입과 비교하는 데는 “기본형 vs 참조형”으로 표현하는 것이 이해하기 더 쉽다. 기본형은 말 그대로 Java에서 기본적으로 제공해주는 데이터 타입으로, 고정된 크기로 스택 영역에 저장한다. 반면 참조형 타입은 실제 객체는 힙영역에 생성하고, 그 객체(인스턴스)를 가리키는 주소를 스택 영역에 저장한다. 참조형 타입을 사용한다는 것은 클래스를 정의하여 사용한다는 것인데, 클래스는 Java.lang.Object라는 최상위 클래스를 상속받는다.

리터럴

리터럴은 저장되는 데이터 그 자체를 의미한다.

int year = 2021;

‘year’이라는 변수명을 이용해서 ‘2021’이라는 int형 자료형을 선언했다. 이때 ‘2021’이 리터럴이 된다. 사실 일반적인 용어로는 2021을 ‘상수’라고 명명해야 마땅하지만, 프로그래밍에서는 상수를 ‘값을 한번 저장하면 변경할 수 없는 공간’ 으로 정의했기 때문에 이와 구분되는 리터럴이라는 용어를 사용한다. 만약 정의한 클래스가 불변성(immutable)을 갖는다면 객체 리터럴이 될 수 있다. 예를 들어 Java.lang.String 같은 경우, 변경이 요구되는 경우 아예 새로운 객체를 생성해버리기 때문에 내용의 불변성을 보장하는 객체 리터럴이다. String 타입의 특수성을 조금 더 설명하자면,

String greeting1 = "Hello 2021!";
String greeting2 = "Hello 2021!";

“Hello 2021!”라는 리터럴은 힙 안에 String constant pool 라는 특수한 영역에 저장된다. 이후 같은 문자열을 사용하는 경우, 기존에 존재하는 값을 참조하게 된다. 결과적으로 위에서 서로 다른 두 String변수는 같은 주소값을 참조하고 있다.

변수 선언 및 초기화

int year = 2021;

위에서 사용한 예제를 다시 보자. 처음 프로그래밍을 접하는 경우 대다수 변수 선언을 위와 같은 방식으로 할 것이라 생각한다. int로 자료형을 명시해주어서 저장공간을 확보하고, 그 공간에 year이라는 이름을 붙여준 뒤, 2021이라는 값을 넣어주는 과정이다. 이것을 명시적 초기화 라 하고, 가장 많이 사용되는 방법이다.

변수의 스코프 및 라이프타임

(1) 인스턴스 변수(instance variable)
:클래스 영역에 선언되며, 클래스의 인스턴스를 생성할 때 만들어지고, 객체가 메모리에서 사라질 때 함께 없어진다.

(2) 클래스 변수(class variable)
:멤버변수에 static 키워드를 붙힐 경우 클래스 변수가 되며 한 클래스의 모든 인스턴스가 값을 공유한다. 클래스가 메모리에 올라갔을때 선언되기 때문에 인스턴스에서는 언제든 바로 접근해서 사용할 수 있으므로, 전역변수(global variable)의 성격을 가진다.

(3) 지역 변수(local variable)
:메소드 내에 선언되어 메소드 내에서만 사용 가능하며 메소드 종료와 함께 소멸된다. for문이나 while문같은 반복문도 동일하게 블럭내에서 선언된 지역변수는, 블럭을 벗어나면 소멸된다.

타입 변환

서로 다른 타입끼리 연산을 수행해야하는 경우, 타입을 일치시켜주는 것을 타입 변환이라고 한다.
(1) 타입 캐스팅
크기가 더 작은 자료형으로 변환하는 것을 말한다.

long a = 10;
int b = (int)a;

크기가 더 작기 때문에, 경우에 따라 데이터가 손실될 수 있음에 주의해야한다. long형은 8byte이고, int형은 4byte이므로 앞의 4byte가 사라지게되지만, 예시에서는 앞의 4byte가 의미가 없으므로 상관이 없다.

(2) 타입 프로모션
반대로 크기가 더 큰 자료형으로 변환하는 것을 말한다.

int a = 10;
// long b = (long)a;
long b = a;

캐스팅과는 달리 형변환을 생략하여도 컴파일러가 자동으로 형변환을 해준다.

배열

배열이란 연속된 공간에 순서대로 자료를 저장하기 위한 구조이다.

// 배열 선언
int [] arr1; 
int arr2 []; 

// 크기가 3인 배열 선언 및 할당
int[] array1 = new int[3];
int[] array2 = {0, 1, 2};

배열 선언은 위와 같이 할 수 있고, 크기만 할당하거나 직접 원소를 나열하여 할당할 수 있다. 2차원 배열 또한 별반 다르지 않다.

// 2차원 배열 선언
int [][] arr1; 
int arr2 [][]; 

// 크기가 4x3 인 배열 선언 및 할당
int[][] array1 = new int[4][3];
int[][] array2 = [{0, 1, 2},{3,4,5},{6,7,8},{9,10,11}];

타입 추론

타입 추론이란 데이터 타입을 소스코드에 명시하지 않아도, 컴파일러가 타입을 유추해 정해주는 것이다. 자바 10부터 var라는 키워드가 추가되어 다음과 같은 코드가 가능해졌다.

var a = "hello";	// String a = "hello";
var b = 10;		// int b = 10;

하지만 이렇게 작성할 경우, 컴파일러는 상관 없겠지만 소스 코드를 읽는 개발자에게는 타입 추론이 어려워질 수 있다는 점에 유의하여 사용해야할 것이다.
제네릭에 대해서도 기술하려고 했지만, 스터디 계획에 제네릭이라는 주제가 따로 빠져있는 것을 발견했기 때문에 나중에 정리하도록 하겠다.

참고문헌

https://velog.io/@jaden_94/2%EC%A3%BC%EC%B0%A8-%ED%95%AD%ED%95%B4%EC%9D%BC%EC%A7%80 https://catsbi.oopy.io/6541026f-1e19-4117-8fef-aea145e4fc1b

Leave a comment