자바 스터디 2주차 : 데이터 타입, 변수 and 배열

hwanse·2021년 2월 1일
0

Java

목록 보기
2/14
post-thumbnail

이 글은 백기선님의 라이브 스터디 참여 및 학습 내용 정리용으로 작성한 글입니다.


학습 목표

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


자료형(Type)이란

해당 데이터가 메모리에 어떻게 저장되는지, 해당 데이터가 프로그램에서 어떻게 처리 되어야 하는지를 명시적으로 정의하는 것이다. 자바에서 타입은 크게 기본형(Primitive Type) 타입참조형(Reference Type) 타입으로 분류된다.

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

자료형키워드크기기본값값의 범위
논리형boolean1 Bytefalsetrue or false(0과 1이 아님)
문자형char2 Byte\u00000 ~ 65,535
정수형byte1 Byte0-128 ~ 127
short2 Byte0-32,768 ~ 32,767
int4 Byte0-2,147,483,648 ~ 2,147,483,647
long8 Byte0-9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807
실수형float4 Byte0.0-3.4E38 ~ +3.4E38
double8 Byte0.0-1.7E308 ~ +1.7E308



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

프리미티브 타입

  • 기본형 타입 또는 원시 타입이라고도 부른다
  • 총 8가지의 기본 자료형을 미리 정의하여 제공
  • 기본형 타입에는 Null을 넣을 수 없다
  • 실제 값을 저장하는 공간으로 JVM의 스택 메모리에 저장됨
  • 컴파일 시점에서 데이터가 해당 자료형의 range 범위를 벗어나는 값일 때, 컴파일 에러가 발생한다.

레퍼런스 타입

  • 참조형 타입이라고도 부른다
  • 기본값은 Null이다
  • 값이 저장되어 있는 주소값을 저장하므로 JVM의 Heap 메모리에 저장됨
  • 문법상으로 에러가 나타나지는 않지만 런타임 시 에러가 발생할 수 있다. 예로 참조형 타입 변수의 값이 Null일 경우에 해당 객체의 메소드를 사용할 경우 NPE가 발생하게된다



리터럴

소스 코드 내에 직접 입력된 값(데이터)를 의미한다.(즉, 변수의 초기화 값)

상수와의 비교

상수는 값을 한 번 저장하면 변경할 수 없는 변수를 뜻하므로 둘은 비슷해 보여도 의미하는 대상이 다르다.

리터럴의 예

정수 리터럴
정수 형태의 값으로 byte, char, short, int ,long의 정수 타입 기본 데이터 타입이 저장될 수 있다. 정수 리터럴은 기본적으로 int 형이며, long 타입을 표현하기 위해서 정수형 리터럴 값 마지막에 L을 붙여준다.

// 정수형 숫자 33을 리터럴로 표현해보자
int decimal     = 33;       // 10진법
int octal       = 041;      // 8진법 (앞에 0을 붙여서 8진법이라는 것을 표현)
int hexadecimal = 0x21;     // 16진법 (앞에 0x를 붙여 16진법임을 표현)
int binary      = 0b100001; // 2진법 (앞에 0b를 붙여 2진법임을 표현)

실수 리터럴
실수형 리터럴은 기본적으로 double 타입이며, float 타입으로 표현하기 위해서는 실수 리터럴 값 마지막에f를 붙여준다.

double a = 1.0;   // 1.0
double b = 5E-1;  // 0.5
float c = 0.7f;   // float 타입의 0.7

문자 리터럴
문자는 작은 따옴표(') 안에 문자 값을 표현할 수 있다

char c = 'c';   // 문자 c



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

변수를 선언한다는 것은 어떤 자료형(타입)으로 특정한 값을 저장할 공간을 만드는 것이다.
초기화를 한다는 것은 해당 변수의 특정 값을 넣어주는 것을 의미한다. 이 변수 초기화를 하지 않는다면 해당 변수에는 쓰레기 값이 들어가게되는데 자바에서는 자료형의 default 값으로 들어가게된다.

int test = 10000;  // 정수형 타입의 변수를 선언하였고 10000 이라는 값으로 초기화

위와 같이 변수의 선언과 동시에 값의 초기화를 코드 한 줄로 나타낸 것이다.


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

스코프란 사전적 의미로 '범위'를 뜻한다. 여기서 변수의 스코프란 무엇일까?
말 그대로 풀이하면 변수의 범위(영역), 변수는 범위(영역)을 가지고 있구나 라는것을 추측해 볼 수 있다. 자바에서는 변수에 접근할 수 있는 범위(영역)를 변수의 스코프라고 부른다.
변수의 스코프의 종류로는 Instance Variables, Class Variables, Local Variables 세 가지가 있다.

Instance Variables

  • 의미: 클래스 내부 필드로 선언된 변수 및 선언된 메소드
  • Scope: 정적 메소드를 제외한 클래스 안 전체에서 접근 가능

Class Variables

  • 의미: 클래스에서 static으로 선언된 변수 및 메소드
  • Scope: 클래스 전체 접근 가능

Local Variables

  • 정의: 인스턴스 및 클래스 멤버들을 제외한 블록 내부에서 선언된 변수
  • Scope: 선언된 블록 내부에서만 유효함

public class Test {

    int instanceVar;        // Instance Variables
    static int classVar;    // Class Variables
    
    // Instance Method
    public void testFunction() {	
    	int localVar = 0;   // Local Variables
    }
    
    // Class Method
    public staic printFunction() {	
    	// System.out.println(instanceVar); <- 컴파일 에러 발생
    	System.out.println(classVar);
    }

}

위 코드를 보며 Instance 와 Class 를 JVM과 연관지어 생각을 해보자.
먼저, 클래스 변수는 JVM의 클래스 로더를 통해 클래스 파일의 정보를 읽고 메모리의 Method영역에 올라가게된다. 이때 클래스 변수의 정보가 담긴 Method영역은 전체 공유가 가능한 영역이기 때문에 해당 클래스 내부에서 어느 영역에서든 사용이 가능한 것이다.
인스턴스 변수는 클래스의 생성자를 통해서 생성된 인스턴스들이 Heap영역에 저장된다. 따라서 생성자를 통해 Heap메모리에 할당되기 때문에 클래스 메소드에서 인스턴스 변수를 사용하려고 코딩을 하면 컴파일 에러가 발생하게 된다. 컴파일러는 해당 인스턴스 변수가 언제 메모리에 올라가게되는지 모르기 때문이다.

라이프 타임

라이프 타임은 변수 데이터가 메모리에 올라가고 소멸되는 과정이라고 볼 수 있고, 더 이상 사용되지 않는 변수들은 JVM의 GC(Garbage Collector)에 의해서 메모리에서 정리된다. 위 변수의 스코프와 연관성이 있는데 변수의 스코프 종류별로 각각 생명주기가 다르다.

  • Local Variables 는 선언된 블록 내에서만 유효하며 블록의 과정이 끝나면 소멸된다
  • Instance Variables 는 객체가 생성될 때 메모리에 올라가고, 해당 객체가 더 이상 참조되는 코드가 없으면 소멸된다.
  • Class Variables 는 클래스 로더에 읽히고 Method영역 메모리에 올라가고 부터 자바 프로그램이 종료될 때 소멸된다.


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

타입 변환

타입 변환이란 변수의 타입을 다른 타입으로 변환하는 것이다.

Type Casting (명시적 형변환)
자료형의 크기가 더 큰 타입에서 작은 크기의 자료형으로 타입을 바꾸는 과정을 말한다.

Type Promotion (묵시적 형변환)
자료형의 크기가 더 작은 타입에서 큰 타입의 자료형으로 대입을 할 때 자동으로 작은 타입의 자료형이 큰 타입으로 변환하는 과정을 말한다.

int a = 10;
short s = 1;
long m = 30L;

a = s;          // 타입 프로모션
a = (int) m;    // 타입 캐스팅



1차 및 2차 배열 선언하기

자바에서 1차, 2차 배열을 선언하는 방법은 다음과 같다

int size = 5;

// 1차 배열 선언 case
int[] arr1 = new int[];           // 크기 할당 없이 배열 참조변수만 선언
int[] arr2 = new int[size];       // 배열의 크기를 선언
int[] arr3 = new int[] {1, 2, 3}; // 배열의 크기 선언 및 값 초기화
int[] arr4 = {1, 5, 2, 3};        // 위와 동일하지만 다른 방식으로 선언


// 2차 배열 선언 case
int[][] arr10 = new int[size][size]  // 2차원 배열의 각 크기 선언
// 배열의 크기 선언 및 값 초기화
int[][] arr11 = new int[][] {
    {1, 3, 5},
    {2, 0, 7}
};



타입추론 var

먼저, 타입 추론이란 변수 선언시 타입이 선언되어 있지 않아도, 컴파일러가 해당 데이터의 타입을 유추하는 것을 말함. var키워드 같이 보이지만 키워드가 아니다. 예로 변수 선언시 var로 네이밍이 가능하다. 이것이 가능한 이유는 컴파일러가 변수에 대입된 리터럴 값을 통해 추론을 하기 때문에 가능하다. 마지막으로 var은 런타임 오버헤드가 없다. 이것이 무슨 이야기인가 하면 타입 추론은 컴파일 시점에서 변수의 리터럴 값을 보고 바이트코드로 변환 시 타입을 명시하고 해당 변수를 읽을 때 마다 타입을 알아내기 위한 연산을 하지 않는다. 따라서 var 변수는 코드 중간에 타입이 절대 변경되지 않는다.

Java 10 later 지원
자바 10버전 부터 var를 통해 변수 선언을 하면 타입 추론이 가능해졌다. 단, 타입추론은 지역 변수이면서 선언과 동시에 초기화가 필수적이다.

타입추론의 특징을 정리해보자

  • 지연변수, 변수 선언 및 초기화가 필수적
  • var 타입 변수에는 컴파일러가 리터럴 값으로 추론하기 때문에 Null 값이 들어갈 수 없다
  • var 타입 변수는 중간에 타입이 변경될 수 없다
//var a;  <- 컴파일 에러 발생, 반드시 초기화가 필요하다
//var b = null; <- null 값 또한 올 수 없다  

var test = 10;	  // 정수형
var test2 = new String[] {"A", "B"};  // 문자열 배열
//var test3 = {"A", "B"};  <- 컴파일 에러, 초기화를 해주긴 했으나 배열은 위와 같이 타입 명시가 필요




참고

profile
만사가 귀찮은 ISFP가 쓰는 학습 블로그

0개의 댓글