자바 기본 복습 2. 기본형과 참조형

장난·2021년 5월 5일
0

자바 기본

목록 보기
2/15
post-thumbnail

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


📜 시작에 앞서

  • 백기선 님의 라이브 스터디(2020년 11월부터 2021년 3월까지) 커리큘럼을 따라 진행한 학습입니다
  • 뒤늦게 알게 되어 스터디 참여는 못했지만 남아있는 스터디 깃허브 주소유튜브 영상을 참고했습니다

📌 목표

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

📌 학습할 것

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

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

  • 프리미티브 타입은 자바 라이브러리에서 기본적으로 제공
  • 저장할 리터럴 타입, 메모리 크기, 범위, 기본값 등이 정해져 있다
    • 적절한 리터럴 타입이 아니거나, 범위를 벗어나는 값을 담으려 하면 컴파일 에러 발생
TypeDefaultSizeRange
booleanfalse1bytefalse, true
char\u00002byte\u0000 ~ \uffff
byte01byte-27~27-1 (-128~127)
short02byte-215~215-1 (-32768~32767 )
int04byte-231~231-1 (약 +- 20억)
long0L8byte-2 63 ~ 2 63 -1
float0.0f4byte1.4*10-45 ~ 3.4*1038
double0.08byte4.9*10-324 ~ 1.8*10308
  • boolean 타입은 true, false 두 가지 값 중 하나를 가지므로 1bit의 정보를 나타내지만, 메모리 사용 크기는 가상 머신의 구현에 따라 다름

    • 보통 1byte로 가정
  • char은 자바에서 유니코드를 사용하므로 2byte

  • 정수 자료형을 나타내는 경우 맨 앞자리 비트를 부호 비트로 사용하고, 남는 비트로 수를 표현

  • 실수 자료형을 나타내는 경우 무한한 실수를 모두 표현 할 수 없기 때문에 부동 소수점 방식으로 표현

    • 부동 소수점 방식: 가수 부분과 지수 부분을 나눠서 실수를 표현하는 방식

    • 부동 소수점 방식을 통해 같은 메모리 크기라도 더 넓은 범위 표현

    • 부동 수소수점 방식 이용시 지수로 표현되는 값이 0을 나타낼 수 없으므로 약간의 오차 발생

    • 정확한 실수 계산 필요할 때는 BigDecimal 사용

    import java.math.BigDecimal;
    
    public class FloatingPoint {
        public static void main(String[] args) {
    
            double doubleNum = 0.1;
            for (int i = 1; i < 10; i++) {
                doubleNum += 0.1;
            }
            System.out.println(doubleNum);
    
            BigDecimal bigDecimalNum = new BigDecimal("0.1");
            for (int i = 1; i < 10; i++) {
                bigDecimalNum = bigDecimalNum.add(new BigDecimal("0.1"));
            }
            System.out.println(bigDecimalNum);
        }
        
        /*
        결과
        doubleNum: 0.9999999999999999
    	bigDecimalNum: 1.0
        */
    }

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

  • 자료형은 크게 기본형(Primitive Type)참조형(Reference Type)으로 분류

프리미티브 타입

  • 프리미티브 타입은 자바 라이브러리에서 기본적으로 제공
  • 논리형 boolean, 문자형 char, 정수형 byte short int long, 실수형 float double로 총 8 종류
  • 변수에 실제 값을 저장

레퍼런스 타입

  • 기본형 8개를 제외한 나머지 타입
  • String, Integer처럼 JDK에서 제공하는 것도 존재
  • 변수에 특정 값이 저장되 있는 메모리 주소를 저장
  • 이때 참조되는 객체는 힙에 저장
public class ReferenceType {
    public static void main(String[] args) {

        class Member {
            private int id;
            private String name;

            public Member(int id, String name) {
                this.id = id;
                this.name = name;
            }
        }

        int num = 10;
        String string = "Reference Type";
        int[] arr = { 0, 1, 2, 3, 4 };
        Member member = new Member(1, "Kim a");

        System.out.println("string: " + Integer.toHexString(string.hashCode()));
        System.out.println("arr: " + arr);
        System.out.println("member: " + member);
        
        /*
        결과(개별적)
        string: 4f81572f
        arr: [I@69222c14
        member: week2.ReferenceType$1Member@606d8acf
        */
    }
}

Reference-Type


📑 리터럴

  • 변수나 상수에 저장되는 값 자체
종류리터럴 예
논리형true, false
문자형'A', '1', 111, '\n' '\u0099', ' '
문자열"string", "new line\n"
정수형100, 0b0011, 077, 0x0F, 100L, 100_000_000L
실수형1.02, 1.03d, 1.04f

논리형

  • true, false 둘 중 하나

문자형

  • 작은따옴표 사이에 표시
  • 작은따옴표 안에 반드시 하나의 문자 필요
  • 유니코드를 나타내는 다른 방식으로도 가능

문자열

  • 큰따옴표 사이에 표시
  • 빈 문자열 가능

정수형

  • 접두사 사용해 2, 8, 16진수 표현 가능
    • '0b' 2진수 / '0' 8진수 / '0x' 16진수
  • 접미사 'L', 'l' 사용해 long 타입 표현
    • 접미사 없을시 int 타입
  • 정수형 리터럴 중간에 구분자 '_' 사용 가능

실수형

  • 접미사 'F', 'f' 사용해 float 타입 표현
  • 접미사 'D', 'd' 사용해 double 타입 표현
    • 접미사 없을 시 double 타입

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

변수 선언

//<변수 타입> <변수 이름>
int i;
  • 변수 선언은 구분되는 알맞은 크기의 저장공간을 확보는 것
    • 변수 이름을 통해 구분하고, 변수 타입을 통해 알맞은 크기 확보
    • 예시의 int의 경우 4byte 공간 확보
    • 레퍼런스 타입인 경우 메모리 주소를 저장하기 위한 공간 확보

변수 초기화

  • 대입 연산자 = 사용해, 우측의 값을 좌측의 변수에 저장
  • 위 예시에 이어 i = 5;

변수 선언과 초기화 특징

  • 변수 선언과 동시에 초기화 가능
public class Var {
    public static void main(String[] args) {
        int var1 = 1;
        int var2 = 2;
    }
}

javap -c로 확인해보면 선언과 초기화가 각각 진행되는 모습

...
public static void main(java.lang.String[]);
  Code:
     0: iconst_1
     1: istore_1
     2: iconst_2
     3: istore_2
     4: return
  • 멤버 변수(클래스 변수, 인스턴스 변수)는 선언 후 초기화 생략시 자동으로 기본 값으로 초기화
  • 지역 변수는 선언 후 자동으로 초기화 되지 않으므로 사용 전 반드시 초기화

초기화 블럭

public class Initlock{
    
    static String classVar; 		// 클래스 변수
    static int[] arr = new int[10]	// 클래스 변수
    String instanceVar;     		// 인스턴스 변수
    

    static {				// 클래스 초기화 블럭
        classVar = "static { }";
        for(intt i=0; i<arr.length; i++){
            arr[i] = (int)(Math.random()*10);
        }
    }

    {					// 인스턴스 초기화 블럭
        instanceVar = "{ }";
    }
}
  • 초기화에 조건문이나 반복문 가능 (생성자에서도 가능하지만..)

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

  • 변수는 클래스 변수, 인스턴스 변수, 지역변수로 나뉘는데 각 종류마다 스코프와 라이프타임에 차이 존재

public class Var {
    static int classVar;	// 클래스 변수
    int instanceVar;		// 인스턴스 변수, 필드, 전역 변수

    void foo(int paramVar) {// 매개 변수
        int localVar = 1;	// 지역 변수

        classVar++;
        instanceVar++;
    }

    static void staticFoo(){
        classVar++;
        //instanceVar++;
        //error: non-static variable df cannot be referenced from a static context
        //인스턴스 변수와 스테틱 메서드의 생성시기 차이때문
    }
}

변수의 종류선언위치생성시기스코프해제시기메모리
클래스 변수클래스 영역클래스가 메모리에 올라갈 때클래스 전역 (접근제어자에 따라 다른 클래스에서 사용 가능)애플리캐이션 종료할 때힙 영역 or 메타 영역 (자바8 이후)
인스턴스 변수클래스 영역인스턴스가 생성되었을 때각 인스턴스 내부 (접근제어자에 따라 다른 클래스에서 사용 가능)GC가 메모리 수거할 때힙 영역
지역변수클래스 영역 이외의 영역(메서드, 생성자, 초기화 블럭 내부)변수 선언문이 수행되었을 때해당 블럭 내부해당 블럭 종료할 때스택 영역

클래스 변수

  • 클래스 로더가 힙 영역 or 메타 영역 (자바8 이후)에 클래스 수준의 정보를 저장할 때 저장

  • 한 공간에 저장하고 모든 인스턴스가 공유

  • 인스턴스 생성하지 않고 사용 가능 클래스이름.클래스 변수

  • 접근제어자에 따라 클래스이름.클래스 변수로 다른 클래스에서 사용 가능

  • 애플리캐이션이 종료될 때 메모리 해제


인스턴스 변수

  • 인스턴스를 생성할 때 해당 인스턴스가 힙 메모리에 올라가며 생성
  • 생성시점으로 인해 static 메서드에서 사용 불가
  • 해당 인스턴스가 참조되지 않으면 GC에 의해 메모리 해제
  • 접근제어자에 따라 참조 변수로 다른 클래스에서 사용 가능

지역변수

  • 예로 함수를 호출하면 스택 영역에 해당 함수 스택 프레임 내부에 생성
  • 함수가 종료될때 해당 스택이 내려오며 메모리 해제

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

  • 자바의 타입 변환은 크게 명시적 형변환(Casting)자동 형변환(Promotion)으로 구분

캐스팅

  • 큰 타입을 작은 타입으로 변환
  • 캐스트 연산자 사용
  • 데이터 손실이나 변형 생길 수 있다
double a = 1000.5;
int b = (int) a;

Animal dog = new Dog();
if(dog instanceof Dog){		//dog의 인스턴스 자료형이 Dog라면
    Dog dog = (Dog) dog;
}

프로모션

  • 작은 타입을 큰 타입으로 변환
  • 케스트 연산자가 없어도 컴파일러가 형변환 추가
byte a = 5;
short b = a;
int c = b;
float d = c;
double e = d;

//Dog는 Animal을 상속
Animal var = new Dog();

[프리미티브 타입 변환]

ConvertConvert To:
From:booleanbyteshortcharintlongfloatdouble
boolean-NNNNNNN
byteN-YCYYYY
shortNC-CYYYY
charNCC-YYYY
intNCCC-YY*Y
longNCCCC-Y*Y*
floatNCCCCC-Y
doubleNCCCCCC-

출저: JAVA in A NUTSHELL: Table 2-4. Java Primitive Type Conversions

  • N: 형변환 불가
  • C: 명시적 형변환
  • Y: 자동 형변환
  • Y*: 자동 형변환이지만 최하위 자릿수 일부 손실 가능

📑 1차 및 2차 배열 선언하기


배열

  • 같은 타입의 데이터연속된 공간에 저장하는 자료구조

1차 배열 선언

int[] arr;		//선언(배열을 다루기 위한 참조변수 선언)
arr = new int[3];	//생성(실제 저장공간 생성)

int[] arr2 = new int[3];	//선언과 생성

//원하는 배열의 인덱스에 값 입력
arr[0] = 0;
arr[1] = 1;
arr[2] = 2;

//생성과 동시에 기본값으로 초기화
int[] arr3 = new int[]{0, 1, 2};
int[] arr4 = {0, 1, 2};

출저: programcreek


2차 배열 선언

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

출저: programcreek


📑 타입 추론, var

  • 변수의 타입을 var로 입력시 컴파일러가 초기화 데이터를 통해 타입 추론
  • 자바 10부터 추가된 기능
  • 지역변수에서만 사용 가능
  • 컴파일러가 타입 추론할 수 있게 선언과 함께 초기화
  • 한번 추론된 타입은 다른 타입으로 변경 불가
Map<Integer, String> map1 = new HashMap<>();
var map2 = new HashMap<Integer, String>();

0개의 댓글