ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [live-study] 2: 자바 데이터 타입, 변수 그리고 배열
    개발/Java 2020. 12. 24. 18:21

    백기선님이 진행하시는 live-study 2주차 과제
    2주차 과제

    목표

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

    학습할 것

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

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

    자바의 프리미티브 타입은 8가지가 있다. 그리고 이 타입을은 각각의 범위와 기본 값을 가지고 있다.

    타입 프리미티브 타입 값의 범위 기본 값 크기
    논리형 boolean true, false false 1byte
    정수형 byte 2⁸ ~ 2⁸-1 0 1byte
      short 2⁻¹⁶ ~ 2¹⁶-1 0 2byte
      int 2⁻³² ~ 2⁻³²-1 0 4byte
      long 2⁻⁶⁴  ~ 2⁻⁶⁴-1  0L 8byte
    실수형 float single-precision 32-bit  0.0F 4byte
      double double-precision 64-bit  0.0 8byte
    문자형 char \u0000 ~ \uffff (유니코드) \u0000 2byte

    정수의 범위에 오는 제곱은 비트를 의미한다고 생각하면 된다.
    byte로 예를 들면, 1바이트에 8비트이므로 바이트는 8비트로 이루어져 있다. 전체 비트중 1비트를 음수 표현을 위해 남겨놓으면(MSB라고 한다) 7비트의 숫자를 표현할 수 있다. 0111 1111은 256이므로 256개의 숫자를 담을 수 있는 것다.
    그리고 양수 최대가 2⁸ -1 로 끝나는 이유는 0도 포함해야 하기 때문에 2⁻⁸ ~ (-1)이 128개, 0부터 2⁸-1이 128개 총 256개가 되기 때문이다.

    • 자바8에서 unsigned int, unsigned long이 생겼다고 하는데 잘 사용하지 않는다고 한다.

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

    • 프리미티브 타입
      • 자바에서 정적으로 정의한 타입으로, 사용되기 전에 반드시 초기화되어야 하며 null이 올 수 없다.
    • 레퍼런스 타입
      • heap 영역에 할당되는 참조 타입으로, Object 클래스를 상속받는다.
        • Method Area에 레퍼런스 타입의 정의가 되어있고, 스택프레임에 생서된 참조변수가 레퍼런스 타입 객체의 주소를 가지고 있는다.
      • 프리미티브 타입이 아니라면 레퍼런스 타입이 되며 String, 배열 또한 레퍼런스 타입이고, 객체를 생성하는데 이용되는 사용자 정의 클래스들도 레퍼런스 타입이다.
      • 레퍼런스 타입의 변수는 객체의 주소를 저장하고 있으며, null이 올 수 있다.

    리터럴

    리터럴은 고정된 값을 직접 소스코드에 표현한 것을 말한다. 프리미티브 타입은 클래스로부터 생성되는 객체가 아니기 때문에 new키워드 없이 생성가능한 특별한 타입이다. 그래서 아래 예제처럼 바로 직접 값을 대입해주는데 이것을 리터럴 이라고 한다.

    boolean result = true;
    char capitalC = 'C';
    byte b = 100;
    short s = 10000;
    int i = 100000;
    • Integer Literals
      • long 타입으로 명시할 때 접미사로 L를 붙인다. ex. 123L
      • binary로 명시할 때 접두사로 0b를 붙인다. ex. 0b1101
      • hexadecimal로 명시할 때 접두사로 0x를 붙인다. ex. 0x1a
    • Floating-Point Literals
      • flot 타입으로 명시할 때 접미사로 f를 붙인다. ex. 0.12f
      • double 타입으로 명시할 때는 접미사로 d or D를 선택적으로 붙인다. ex. 123.12, ex.123.12d
    • String/Char Literals
      • \b (backspace) : 백스페이스
      • \t (tab) : tab을 누른 만큼 이동한다.
      • \n (line feed) : 커서 위치를 한줄 아래로 이동한다.
      • \f (form feed) : 프린트 출력시 현재 페이지를 마친다.
      • \r (carriage return) : 커서 위치를 맨 앞으로 이동한다.
      • escape 문자
        • \" (double quote)
        • \' (single quote)
        • \\ (backslash).

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

    • 프리미티브 타입

      • 위에 리터럴 설명에 나온 예시처럼 직접적으로 리터럴을 넣어서 초기화하거나, 이미 초기화된 동일 타입의 변수를 넣어 초기화 할 수 있다.

        int number = 100; // 리터럴
        int age = number; // 변수를 넣어 초기화
    • 레퍼런스 타입

      • 레퍼런스 타입은 new 키워드를 사용해서 초기화한다.

        List<Integer> numbers = new ArrayList<>(); // 비어있는 array list로 초기화
        List<Integer> numbers2 = new ArrayList<>(1, 2, 3); // 값을 미리 주고 초기화 할수도 있다.

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

    변수에는 클래스(스태틱) 변수, 로컬 변수, 객체 변수가 있다.
    클래스 변수
    - 라이프타임 : 자신이 위치한 클래스가 메모리의 Method Area영역에 올라가는 순간부터 프로그램이 종료되는 순간까지이다.
    - 스코프 : Method Area는 공유되는 영역이다. 그러므로 접근 제한자에 따라 달라지겠지만, public이라는 가정하에 모든 곳에서 접근 가능하다.

    로컬 변수
    - 라이프타임 : 선언되는 순간 스택 프레임 내부에 생성되고, 자신이 생성된 스택프레임이 사라지기 전까지 유지된다. 스택프레임이 사라지면 같이 사라진다.
    만약 메소드 내부에 있는 if문에서 생성된 변수라면, 해당 if문이 종료되는 }를 만나면 로컬 변수도 사라진다.
    - 스코프 : 자신이 위치한 스택프레임과 그 스택프레임이 포함하고 있는 내부 스택프레임에서 접근이 가능하다.

    로컬 변수는 현재 진행중엔 스택프레임에 생성된다.
    객체 변수
    - 라이프타임 : 객체가 생성되는 순간 Heap에 할당되고, 참조되지 않을 때 Garbage Collector에 의해 제거된다.
    Station station = new Station();처럼 할당 되었다가
    station = null;이 되면 생성되었던 객체를 참조하는 변수가 없어지므로 GC에 의해 제거되는 것이다.
    - 스코프 : Heap영역 역시 공유되는 영역이므로 접근제어가 public이라면 모든 곳에서 접근 가능하다.

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

    타입변환을 하는 경우에는 두가지 상황이 있다.

    1. 기존 타입을 새로운 타입으로 표현 가능한 경우

    2. 기존 타입을 새로운 타입으로 표현 불가능한 경우

      1 처럼 표현이 가능한 경우는 프로모션이라고 한다.

      • 이 경우는 float형을 double형으로 변환하는 경우처럼 새로운 타입이 표현할 수 있는 범위가 더 넓은 경우이다.

      2 처럼 표현이 불가능한 경우는 캐스팅이라고 한다.

      • 이 경우는 double형을 float형이나 int형으로 변환하는 경우처럼 새로운 타입이 표현할 수 있는 범위가 더 작은 경우이다.
      • 캐스팅을 하면 원본 데이터가 손실될 위험이 있다.

    그리고 타입 변환을 하는 방법에도 두가지가 있다.

    1. 자동 타입 변환 (프로모션)

      • 개발자가 명시하지 않아도 자동으로 타입이 변환된다.

      • 기존 타입을 새로운 타입으로 표현 가능한 경우 사용될 수 있다.

      • 이 경우는 float형을 double형으로 변환하는 경우처럼 새로운 타입이 표현할 수 있는 범위가 더 넓은 경우이다.

      • ex.
        byte byteValue = 10;
        int number = byteValue;
    2. 강제 타입 변환 (캐스팅)

      • 명시적으로 새로운 타입을 나타내는 방식이다.

      • 기존 타입을 새로운 타입으로 표현 불가능한 경우 캐스팅만 가능하고, 표현 가능한 경우도 사용 가능하다.

      • 캐스팅을 하면 원본 데이터가 손실될 위험이 있다.

      • 이 경우는 double형을 float형이나 int형으로 변환하는 경우처럼 새로운 타입이 표현할 수 있는 범위가 더 작은 경우이다.

      • ex. int number = (int) 123.12

      • ex.
        byte byteValue = 10;
        int number = (int) byteValue;

    1차 및 2차 배열 선언하기

    배열을 선언할 때 크기만 선언하는 방법과 값을 초기화하는 방법이 있다.
    다음은 두가지 방법으로 1차원 배열을 선언하는 방법이다.

    // 크기만 선언. 값은 초기화 되어 있지 않음.
    int[] arr = new int[5];
    
    // 값을 초기화. 초기화 한 값의 개수가 곧 크기이다.
    int[] arr2 = {1, 2, 3, 4, 5}

    1차원 배열 할당시 메모리

    배열은 레퍼런스 타입이다.
    스택 영역에 arr(arr2) 변수를 생성하고 힙 영역에는 int크기(4byte)의 공간을 5개 이어서 할당한다.
    그러면 스택 영역에 있는 변수가 힙 영역에 있는 int 영역의 시작주소를 참조한다. (주소를 저장한다.)

    2차원 배열은 1차원 배열의 데이터에 배열을 넣는것과 같다.

    출처 : https://www.notion.so/2-38b5d67c7f5a48238529bb8f1617ea0d

    // 크기가 2인 int형 배열을 5개 가지는 배열을 선언한 것이다.
    // 5행 2열과 같다.
    int[][] arr = new int[5][2];
    
    // 선언시 값을 초기화하는 것이다.
    int[][] arr2 = {{1,2}, {3,4}, {5,6}}

    2차원 배열 할당시 메모리
    2차원 배열도 1차원 배열과 다르지 않다. 1차원 배열을 더 큰 배열에 포함시킨 구조다.

    출처 : https://www.notion.so/2-38b5d67c7f5a48238529bb8f1617ea0d

    타입 추론, var

    타입 추론이란 코드 작성시에 타입이 명시되어 있지 않지만, 컴파일러가 타입을 유추하는 것을 말한다.
    코드 작성 시점에 어떤 타입이 와야할지 알 수 없는 경우 타입 추론을 이용해서 중복되는 코드를 사용하지 않고 해결할 수 있다.

    generic

    • 제네릭은 타입을 파라미터로 가지는 클래스와 인터페이스를 말한다. <>안에 임의의 타입명을 넣어서 <T>와 같이 이용해서 표현한다.
    • 제네릭 타입을 이용함으로써 잘못된 타입이 사용될 수 있는 문제를 컴파일 과정에서 제거할 수 있다.
    public void addObject<T>(T value) {
           List<T> list = new ArrayList<>();
           list.add(value);
     }
    
    public static void main() {
        addObject(1234);
    }
    • 컴파일 타임에 TInteger 타입으로 변환된다.

    var

    • var는 자바10부터 지원되는 방식이다.

    • 반드시 선언할 때 초기화가 이루어져야 한다.

    • 특정한 타입 대신 var 타입으로 선언하면 초기화된 값을 통해 타입을 유추한다.

    • 다음과 같이 사용한다.

      var list = new ArrayList<String>(); // 오른쪽 `<>`안에 타입을 명시하지 않을 경우 컴파일 에러가 난다.

    참고

    https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html
    https://docs.oracle.com/javase/tutorial/java/generics/why.html
    https://blog.naver.com/hsm622/222144931396
    https://www.notion.so/2-38b5d67c7f5a48238529bb8f1617ea0d
    https://velog.io/@bk_log/Java-%ED%83%80%EC%9E%85-%EC%B6%94%EB%A1%A0

    댓글

Designed by Tistory.