본문 바로가기
JAVA

2주차. 자바 데이터 타입, 변수 그리고 배열

by AndoneKwon 2022. 9. 2.

2주차 Java Study

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

Java에서 primitive type이란 자바에서 쓰이는 기본형 타입이다. 이와 대비되는 것으로는 Reference Type이 존재한다.

그 종류와 범위는 다음 표와 같다.

 타입메모리 크기Default Value데이터의 범위

논리형 boolean 1byte false true, false
정수형 byte 1byte 0 -128~127(2^7)
정수형 short 2byte 0 -32,768 ~ 32,676(2^16)
정수형 int 4byte 0 -2147483648 ~ 2147483647(2^32)
정수형 long 8byte 0 -9223372036854775808 ~ 922372036854775807(2^64)
실수형 float 4byte 0.0F -3.4x10^38 ~ 3.4x10^38
실수형 double 8byte 0.0 -1.7x10^308 ~ 1.7x10^308
문자형 char 2byte '\u0000' 0~65,535

기본 타입들은 stack 영역에 저장되며 해당 scope를 벗어나면 메모리 할당이 해제되게 된다.(static으로 선언된 변수 제외)

범위를 넘어간 값이 들어가면 overflow가 발생하여 원하지 않는 값이 들어가지 않을 수 있다.

null 값을 저장할 수 없다.

바로 계산이 가능하다. 레퍼런스 타입과는 다르게 방식, 언박싱 과정이 필요하지 않다.

2. 레퍼런스 타입

기본형 타입을 제외한 모든 타입들을 의미한다.(문자열, 배열, 열거, 클래스, 인터페이스, Wrapper type)

즉, heap영역에 저장되는 타입들이다.

이 객체들은 힙영역에 저장되며 참조 타입 변수는 stack영역에 주소만을 저장해서 사용할때 불러오는 식으로 사용하게 된다.

(참고로 코틀린에서는 프리미티브 타입이 존재하지 않으며 컴파일 과정에서 알아서 최적화를 시켜준다.)

2 - 1. Wrapper Class

원시타입을 레퍼런스 타입으로 만든것이며 모두 Number Class의 자식 클래스이며 당연하게도 Number Class는 Object의 자식 클래스이다.

Object이기 때문에 null값을 가질 수 있으며 모든 원시타입에 해당되는 타입을 가진다.

사용되야 하는 경우가 있다.

  1. 매개변수로 객체가 요구되는 경우
  2. 기본형 값이 아닌 객체로 저장되어야 하는 경우
  3. 객체간의 비교가 필요 할 때
  4. 등등..

Wrapper class를 실제로 열어보면 다음과 같다.

public final class Integer extends Number implements Comparable {

      ...

      private int value;

      ...

 } 



출처: https://jusungpark.tistory.com/17 [정리정리정리]

모두 equals를 오버라이드 하고 있기 때문에 비교를 하여도 객체지만 주소값이 아닌 객체의 값을 비교하게 된다. (toString 또한 오버라이드 되어 있다.)

그리고 Wrapper Class의 경우 JDK 1.5버전 부터 Auto Baxing과 Unboxing이 지원되며 이것들은 많이 반복되면 속도에 영향을 끼치기 때문에 해당 사항을 생각하며 개발 해야한다.

3. 리터럴

3 - 1. 정수 리터럴

리터럴은 변수나 상수에 저장되는 값 그 자체를 의미한다.

정수 리터럴은 10진수, 8진수, 2진수 리터럴로 있으며 소수점이 없는 정수 리터럴은 10진수로 간주한다.

0으로 시작하는 리터럴은 8진수로 간주한다.

0x 또는 0X로 시작하는 리터럴이면 16진수로 간주하며 A,B,C,D,E,F로 시작되는 리터럴도 16진수로 간주된다.

3 - 2. 실수 리터럴

소수점이 있는 리터럴은 10진수 실수로 간주한다.(ex) 0.25, -3.14)

대문자 E 또는 소문자 e가 있는 리터럴은 10진수 지수와 가수로 간주한다.

5E7 -> 5 x 10^7

0.12E-5 -> 0.12 x 10^-5

실수의 리터럴을 저장할 수 있는 타입은 float, double형이 있다.

3 - 3. 문자 리터럴

작은 따옴표로 묶어놓은 텍스트 하나의 문자열은 리터럴로 간주한다.

'A', 'B', 'C' ...

또한, \(역슬래시)로 시작되는 리터럴은 이스케이프 문자라고 하는데 특수한 용도로 사용된다.

이스케이프 문자용도유니코드

\t 수평 탭 0x0009
\n 줄 바꿈 0x000a
\r 리턴 0x000d
\" 큰따옴표 0x0022
\' 작은따옴표 0x0027
\\ \ 0x005c
\u16진수 16진수에 해당되는 유니코드 0x0000 ~ 0xffff

문자 리터럴을 저장할 수 있는 타입은 char 뿐이다.

3 - 4. 문자열 리터럴

큰 따옴표로 묶은 리터럴은 문자열로 인식한다.

"안녕하세요, Andone 입니다."

문자열은 이스케이프 문자를 사용할 수 있다.

3 - 5. 논리 리터럴

true와 false는 논리 리터럴로 인식한다.

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

변수를 선언하는 방법은 다음과 같다. 우선 변수가 저장될 공간을 확보한다.

int a;

그 후 저장된 공간에 리터럴을 저장한다.

int a = 10;

위와 같이 한줄에 넣을 수도 있지만 따로 분리해서 넣을 수도 있다.

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

스코프란 변수가 살아있을 수 있는 범위를 의미한다. 라이프 타임은 메모리위에 변수가 언제까지 살아있는지를 의미한다.

변수는 중괄호인 {} 안에 선언되고 사용된다. 메서드 블록과 클래스 블록 두가지로 나눌 수 있다.

다만 static으로 선언된 변수의 경우 해당 프로그램이 실행되는 동안 메서드 영역에 변수가 존재하게 되며 사용은 역시나 같은 블록 내에서만 사용이 가능하다. 따라서, 일반적인 지역변수의 스코프는 중괄호 내이며 라이프 타임 역시 중괄호 내이며, static 변수는 스코프는 해당 블록 안에서 가능하며 라이프 타임은 인스턴스가 존재하는 동안 살아있다.

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

6 - 1. Type Casting

타입 캐스팅이란 크기가 더 큰 자료형을 더 작은 자료형에 집어 넣는 것을 의미한다. 예를들어 int형 변수를 byte 타입에 집어 넣으려고 하면 값이 잘려 데이터 손실이 올 수 있다. 집어 넣을때는 다음과 같이 넣으며 반드시 타입을 명시해줘야 한다.

int a = 10;
byte b;
b = (byte)a;//이상테에서는 

6 - 2. Type Promotion

타입 프로모션은 더 작은 자료형을 큰 자료형에 집어 넣는것이다. 이 경우에는 자료형을 명시해주지 않아도 가능하다.

byte a = 10;
int b = a;

위 두가지 방식은 레퍼런스 타입에서도 가능하다. Wrapper Class는 프리미티브 타입과 같고 다른 Class들도 가능하나 이 부분에서 Upcasting과 Downcasting이라는 개념이 등장하지만 나중에 상속 파트에서 추가적으로 다루도록 하겠다.

7. 1차 및 2차 배열 선언하기

우선 배열이 뭔지부터 이야기 해보자. 배열이란 같은 타입의 자료를 연속된 공간에 저장하는 자료구조이다.

말그대로 같은 연속된 공간에 같은 타입의 자료를 저장하기 때문에 해당 공간에 접근하는 시간은 O(1)이 소요된다.

배열을 선언하기 위해서는 []를 이용한다.

int[] arr;
int arr2[];

두가지 방식으로 배열을 저장할 시작 점을 메모리 공간에 선언한다.(다만 보통 첫번째 방식을 Java에서는 선호한다.)

그 후 배열 공간을 할당해준다. 방법은 다음과 같은 방식들이 있다.

int[] arr = new int[5];
int arr2[] = new int[5];
int[] arr3 = {1,2,3};

그리고 할당 된 공간에 값을 넣어 줄수도 있다.

arr[1] = 0;
arr[2] = 2;
...

2차원 배열은 다음과 같이 선언한다.

int[][] arr = new int[5][5];

공간에 값을 넣는 방식은 1차 배열과 같다.

배열의 첫번제 인덱스는 배열 주소의 시작 값이며 배열의 나머지 주소들은 연속되어 할당된다는 점을 잊지 않아야 한다.

8. 타입 추론, var

자바 10에서 var 키워드가 추가되었다. 이 키워드는 JEP 286 : Local- Variable Type Inferece(지역 변수 추론)에 따라 만들어 졌다.

var은 키워드가 아니라 타입의 이름이다. 키워드가 아니기 때문에 변수명으로 선언이 가능하다.

var var = 1;

이게 가능하다.

Java 8이 등장하며 람다에서 타입 추론(type inference)을 할 수 있다.

Map<String, Integer> map = new HashMap<>();
map.computeIfPresent("abc", (a,b)-> b++);

위 map에서 사용된 람다식을 확인해보면 b가 람다식만을 보고서는 명시적으로 정수형임을 알 수 없지만 타입을 컴파일러가 추론하여 계산한다.

var 키워드는 특징이 존재한다.

  1. var 키워드는 지역 변수 타입 추론을 허용한다.
  2. 형식 변수 선언 및 메서드의 반환 유형, 멤버 변수 또는 필드 선언, 생성자 형식 변수 또는 다른 종류의 변수에서는 사용할 수 없다.
  3. var 키워드 적용 이후로도 Java는 여전히 정적언어이며 지역 변수 타입 추론하기에 충분한 정보가 있어야하며 그렇지 않으면 컴파일러에서 오류를 발생시킨다.
  4. Java 11에서는 람다 표현식에 var를 사용할 수 있다. 즉 var 타입을 지정함으로 인해 어노테이션을 추가할 수 있다.

 


 

 

본 글은 백기선님의 자바스터디 커리큘럼을 따라 정리한 내용입니다.

https://github.com/whiteship/live-study/issues/2

 

'JAVA' 카테고리의 다른 글

5주차. 클래스  (0) 2022.09.15
3주차. 연산자  (0) 2022.09.02
1주차. JAVA Study JVM은 무엇이며 자바 코드는 어떻게 실행하는 것인가.  (0) 2022.09.01