brunch

You can make anything
by writing

C.S.Lewis

by 이재린 Feb 13. 2021

자바 데이터 타입, 변수
그리고 배열

백기선 스터디 2주 차

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


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

- 프리미티브 타입(Primitive Type, 원시 타입)

  Java 에서 제공하는 기본타입으로써, 타입별로 default 값이 존재 하며 크기가 고정 되어 있다.

  메모리의 Stack 영역에 생성 된다.

  컴파일 시점에 타입의 크기와 형태가 결정 되므로, 타입의 크기에 벗어나면 빌드 오류를 야기 시킬 수 있으며 컬렉션의 원소 타입으로 설정할 수 없다.(원시 타입을 컬렉션의 원소로 사용하기 위해서는 Wrapper Class 사용)


- 래퍼런스 타입(Reference Type, 참조 타입)

  위의 Primitive Type을 제외한 모든 자료형은 Reference Type으로 분류 된다.

  실제로 변수의 값이 저장된 Heap 메모리 영역의 주소를 저장하고 있고,

  변수에 null을 대입할 수 있다.


리터럴

- 리터럴(Literal)은 변수에 저장되어 있는 상수 값(Constant)을 의미 한다. 별도의 연산 없이 표현 된다.

ex) 

int a = 10; // 10은 Literal, 상수 이다.

char b = 'b'; // b는 Literal



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

Java에서 변수의 초기화는 아래와 같은 문법을 사용 한다.

데이터타입 변수명 = 값; 


// boolean 타입 변수의 선언
boolean b;

// boolean 타입 변수의 초기화
b = true;


// char 타입 변수의 선언
char c;

// char 타입 변수의 초기화
c = 'c';


// byte 타입 변수의 선언
byte by;

// byte 타입 변수의 초기화
by = 0x1;


// short 타입 변수의 선언
short s;

// short 타입 변수의 초기화
s = 32767;


// int 타입 변수의 선언
int i;

// int 타입 변수의 초기화
i = 2147483647;


// long 타입 변수의 선언
long l;

// long 타입 변수의 초기화
l = 9223372036854775807L;


// float 타입 변수의 선언
float f;

// float 타입 변수의 초기화
f = 3.4028235E38f;


// double 타입 변수의 선언
double d;

// double 타입 변수의 초기화
d = 1.7976931348623157E308;


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

- 변수 스코프 : 변수를 사용할 수 있는 범위. 크게 아래 세가지로 분류 한다. 

1. 인스턴스 변수

2. 클래스 변수

3. 로컬 변수로 구분 된다.


- 라이프 타임 : 생명주기로써, 선언된 변수가 메모리에서 해제 되지 않고 정상적으로 읽기/쓰기 가능한 상태로 유지되는 주기.

1. 인스턴스 변수의 라이프 타임 : 객체 생성 후 부터, 객체가 메모리에서 해제 될 때까지

2. 클래스 변수의 라이프 타임 : 클래스 초기화 시점 부터, 프로그램이 종료 될 때까지

3. 로컬 변수의 라이프 타임 : 코드 블럭({, }) 시작 시점 부터, 블럭을 벗어나는 시점 까지


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

- 타입 변환 이란? 컴퓨터 에서 연산을 수행하려면 같은 타입의 데이터에 대해서만 연산이 가능하다. 따라서, 다른 형태의 자료형을 연산의 수행에 앞서 같은 타입으로 만드는 동작을 형변환 이라 칭한다.


- 타입 변환(Casting) 과 타입 프로모션(Promotion)?

  1. Casting(수동/명시적 타입 변환) : 작은 크기의 데이터 타입에서 큰 데이터 타입으로 타입 변환. 

- 사용자(프로그래머)에 의해서 명시(강제)적으로 타입 변환을 실행하는 것을 말하며, 아래와 같이 사용 한다.


// long 타입의 변수 b 선언
long b = 10L;

// long 타입의 값을 더 작은 타입인 int 타입 변수 a에 명시적 형변환 수행
int a = (int)b;


- 위의 경우 b에 담긴 값이 int 의 범위를 넘어 가는 경우에도 수행은 되지만, over/under flow 가 발생하게 되어 예상하지 못한 연산 결과를 얻게 될 수 도 있으니 주의 한다.


ex)
long b : 9223372036854775807L

long -> int 로 Casting

int a : -1


  2. Promotion(자동/묵시적 타입 변환) : 큰 크기의 데이터 타입에서 작은 데이터 타입으로 타입 변환


- 자바 컴파일러에 의해서 자동으로 타입 변환을 실행하는 것을 말하며, 연산을 하려는 값이 타입끼리 서로 호환성이 있으면 자동으로 변환을 실행 한다.

이때, 묵시적 형변환이 발생하는 조건은 더 작은 타입에서 더 큰 타입인 경우에만 수행 된다.

ex) 

// int 타입의 변수 a 선언
int a = 11111;


// int 타입의 값을 더 큰 타입인 long 타입 변수 b에 묵시적 형변환 수행
long b = a;


1차 및 2차 배열 선언하기

- 배열(Array)이란? 동일한 데이터 타입으로 선언된 데이터를 연속된 공간에 저장 하기 위한 자료 구조 이다.


- 1차원 배열의 선언

아래와 같은 문법으로 선언이 가능하며, 보통 가장 위의 형태를 사용하는 것이 권장 된다.

int intArray[];
int []intArray2;
int[] intArray3;


- 1차원 배열의 초기화

배열은 일반 객체들과 마찬가지로 선언 후에 new 키워드를 통한 할당을 필요로 한다.

 1. 배열 크기 우선 할당 후, 값 할당

// new 키워드를 통한 메모리 공간 할당, 총 10개의 int 공간 확보
int intArray[] = new int[10];

// 10개의 공간 중에 가장 첫번째 위치(0)에 1이라는 값을 할당
intArray[0] = 1;

// 10개의 공간 중에 다섯번째 위치(4)에 100이라는 값을 할당
intArray[4] = 100;


 2. 값 할당을 통한 배열크기 자동 할당

// 배열의 선언과 동시에 1~10까지의 값을 직접 입력 함으로써, 10만큼의 크기를 가진 배열 생성
int intArray[] = new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};


- 2차원 배열의 선언

아래와 같은 문법으로 선언이 가능하며, 보통 가장 위의 형태를 사용하는 것이 권장 된다.

int[][] intArray;
int [][]intArray2;
int intArray3[][];


- 2차원 배열의 초기화

 1. 배열 크기 우선 할당 후, 값 할당

// new 키워드를 통한 메모리 공간 할당, 총 10X10개의 int 공간 확보
int[][] intArray = new int[10][10];

// 100개의 공간 중에서 가장 첫번째 위치(0, 0)에 1이라는 값을 할당
intArray[0][0] = 1;

// 100개의 공간 중에서 가장 마지막 위치(9, 9)에 100이라는 값을 할당
intArray[9][9] = 100;


 2. 값 할당을 통한 배열크기 자동 할당

// 배열의 선언과 동시에 1~9까지의 값을 직접 입력 함으로써, 9(3*3)만큼의 크기를 가진 배열 생성
int[][] intArray = new int[][] {
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9}
};


타입 추론, var

- 타입추론(Type Declaration)은 주변의 변수 혹은 컴파일 시점에 확정된 변수의 타입을 추론하여 형을 확정하는 것으로 컴파일 시점에 적용 된다.


1. Java 5 Generic Method

- 선언된 제네릭의 타입을 참조하여 타입을 추론한다.

    AS-IS 

    List<String> list = Collections.<String>emptyList();


    TO-BE

    List<String> list = Collections.emptyList();


2. Java 7 Diamond Operator

- 선언된 제네릭의 타입을 참조하여, 할당시의 제네릭 매개변수를 생략할 수 있다.

    AS-IS

    Map<String, List<String>> map = new HashMap<String,List<String>>();


    TO-BE

    Map<String, List<String>> map = new HashMap<>();


3. Java 8 Lambda Expression

- 람다 표현식에서 인자 타입을 생략할 수 있다.

   AS-IS

    Predicate<String> isNotEmpty = (String x) -> x.length() > 0;


    TO-BE

    Predicate<String> isNotEmpty = x -> x.length() > 0;


4. Java 9 local Variable Type Declaration

- 로컬 변수의 경우 var 타입을 통해 타입 추론이 가능 하다.

    AS-IS

    String message = "hello world";

    TO-BE

    var message = "hello world";


- 타입 추론은 쉽게 말하자면 "컴파일 시점의 타입을 추측 하여 고정" 하는 동작으로 이해하면 편하다.

따라서, 컴파일 시점에 사용된 타입으로 고정 되기 때문에, Java 의 객체를 사용하는 경우에는 대표적 특징인 다형성을 적용하기에는 상당한 제약사항이 생긴다.

예를 들어 Animal 클래스가 있고 이를 상속 받은 Dog, Cat 클래스가 존재 하는 경우,

var animal = new Dog();

위와 같이 선언/컴파일 된 경우 animal 변수의 타입은 Animal이 아닌, Dog 클래스 타입으로 고정 된다.(Dog animal = new Dog();)

따라서, 이후에 animal = new Cat(); 을 하는 경우에는 타입 불일치로 인한 컴파일 오류가 발생하게 된다.


위와 같은 타입 추론의 특성을 잘 파악하여 편한 콛의 작성 보다는, 가독성을 높이기 위한 측면에서의 사용을 지향 해야한다.

작가의 이전글 JVM은 무엇이며 자바 코드는 어떻게 실행하는 것인가
브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari