자바의 데이터 타입

Hyun·2023년 8월 25일
0

공부한거 정리

목록 보기
13/20

자바의 데이터 타입

  • 백기선님의 자바스터디 2주차 과제인, 자바의 데이터 타입을 공부하고 정리하였다.

프리미티브 타입

  • int, byte, short, long, float, double, boolean, char 로 8가지가 있다.

  • 객체로 간주되지 않는다.

  • 선언된 값이 스택에 바로 저장된다.


overflow, underflow

  • primitive 데이터 타입은 크기의 제한이 있다.

  • 제한을 넘어서는 값을 담게되면 발생한다.

  • integer overflow, underflow

    • 정수 순환 발생
    public static void main(String[] args) {
        System.out.println(Integer.MAX_VALUE);

        System.out.println(Integer.MAX_VALUE + 1);		// overflow

        System.out.println(Integer.MIN_VALUE);

        System.out.println(Integer.MIN_VALUE - 1);		// underflow

} 


  • floating point overflow, underflow

    • 부동 소수점 방식의 경우 1을 더하는 방식으로는 overflow 가 발생하지 않는다.

      • 유효 비트에 영향을 주지 못한다.
    • 비트를 변경하여 발생을 확인할 수 있다.


    public static void main(String[] args) {

        System.out.println(Double.MAX_VALUE);

        System.out.println(Double.MAX_VALUE * 2);         	// overflow 

        System.out.println(Double.MIN_VALUE);

        System.out.println(Double.MIN_VALUE / 2);			// underflow
}


Autoboxing

  • primitive 데이터 타입을 Wrapper Class 로 변환해야 할 때가 있다.

  • 이를 자동으로 변환해주는 것을 Autoboxing 이라 한다.

Character c = 'c';

Integer i = 1;

부동 소수점 (floating point)

  • 263.3 을 2진수로 표현해보자

    • 263 = 100000111

    • 		0.3 = 0.3 x 2 = 0.6 ... 0
      			  0.6 x 2 = 1.2 ... 1
                    0.2 x 2 = 0.4 ... 0
                    0.4 x 2 = 0.8 ... 0
                    0.8 x 2 = 1.6 ... 1
                    ...
               
    • 소수점이 계속 존재

    • 무한히 반복된다.

    • 0.3 = 0.01001100110011...

    • 가장 근사치의 값을 저장해야 한다.

  • 저장하는 방식은 2가지가 있다.

    • 고정 소수점

      • 정수를 표현하는 bit 수와 소수를 표현하는 bit 수를 미리 정해놓고 표현

      • 만약 부호 1bit, 정수 16bit, 소수 15bit 인 시스템이라면,
        263.3 = (0)0000000100000111.010011001100110

      • 정수 bit 이 커지면 큰 숫자로 표현할 수 있지만, 정밀한 숫자 표현 X

      • 소수 bit 이 커지면 정밀한 숫자를 표현할 수 있지만, 큰 숫자 표현 X

    • 부동 소수점

      • 지수 8bit 과 가수 23bit 으로 나누어 표현

      • 263.3 = 1.00000111010011001100110 * 2^8 으로 표현

      • 2^8 ➔ 지수부

        • bias 127 이 있으므로, 2^8 을 표현하려면 127 + 지수

        • 10000111 (127 + 8)

      • 00000111010011001100110 ➔ 가수부

        • 23bit 까지 표현

float 자료형


double 자료형

  • float 대비 2배의 byte를 사용하여 정밀도를 더욱 높였다.

부동 소수점의 특징

  • 0을 표현하는 방법

    • 모두 0인 경우, 0으로 한다.


  • 가장 작은 수 표현

    • 지수 bit 가 모두 0이어도, 가수 bit가 모두 0이 아니면,

    • 유효 bit 을 0.xx... 로 설정하고

      • 일반적인 유효 bit 은 1.xx... 로, 1로 시작한다.
    • 지수값을 -126으로 설정한다.


  • 무한수 표현

    • 모든 지수 bit, 가수 bit 이 1인 경우, inf 를 나타낸다.

  • 최대값 표현

    • 모든 지수 bit 이 1인 경우를 제외한, 가장 큰 수로 지수값 설정 (127)


  • 부동 소수점의 오차

    • 작은 bit 로 큰 수를 표현할 순 있지만 값이 커지면 정확성이 떨어진다.

      • float 자료형의 가수 bit 크기는 23bit 로 정수값 자리수가 23을 넘어가면 작은 자릿수들을 표현할 수 없다.

        • 작은 자릿수들은 0으로 패딩된다.

레퍼런스 타입

  • 8가지 primitive type 을 제외한 나머지 타입

  • 클래스, 배열, 인터페이스, 열거 타입등이 모두 reference type 이다.

  • 실제 값이 저장되지 않고, 자료가 저장된 Heap 의 주소값을 스택에 저장

    • 주소를 참조하여 값을 가져온다.
  • 스택에 할당되는 메모리크기는 주소값을 저장하기 위한 4byte 이다.


리터럴

  • 코드에서 상수로 지정하는 모든 값

    • 직접 표현한 값
  • integer, float, double, long, String, char, boolean, null 등 직접 표현하는 모든 값들이 리터럴이 될 수 있다.

  • 작은 리터럴을 큰 자료형에 담을 수 있지만, 큰 리터럴을 작은 자료형에 담을 순 없다.

        double d = 123.456;			// 123.456
        double d2 = 123.456f;			// 123.45600128173828

        long l = 123;
        long l2 = 123L;

        int i = (short) 1;
        int i2 = (byte) 1;	

상대적으로 작은 리터럴을 큰 자료형에 담을 수 있다.


        float f = 123.456;
        float f2 = 123.456d;

        int i = 123L;
        int i2 = 1234567890123;

        short s = 32768;
        byte b = 128;

       // 모두 컴파일 에러 발생

상대적으로 큰 리터럴을 작은 자료형에 담을 수 없다.


문자열 리터럴

  • 문자열 리터럴은 String Constant Pool 영역에 할당된다.

    • 문자열 리터럴의 경우 내부적으로 String 클래스의 intern() 메서드를 호출한다.

    • 만약 String Constant Pool 에 이미 문자열 리터럴이 존재하는 경우, 존재하는 객체의 주솟값을 반환한다.

    • 만약 String Constant Pool 에 문자열 리터럴이 존재하지 않는 경우, 새로 객체를 String Constant Pool 에 생성한 후 해당 객체의 주솟값을 반환한다.

  • new 연산자로 생성한 경우엔, 일반 객체들처럼 메모리의 Heap 영역에 할당된다.

public void string() {
    String name = "lxxjn0";
    String name1 = "lxxjn0";			// String 클래스의 intern() 메서드 동작
    String name2 = new String("lxxjn0");
    String name3 = new String("lxxjn0");
}

name, name1은 같은 객체를, name2, name3 는 다른 객체를 가리킨다.


  • 문자열 비교 연산
        String s1 = "hi";
        String s2 = new String("hi");

        System.out.println(s1.equals(s2));					// true
        System.out.println(s1 == s2);						// false

        System.out.println("s1 addr = " + System.identityHashCode(s1));		// s1 addr = 2144838275
        System.out.println("s2 addr = " + System.identityHashCode(s2));		// s2 addr = 596470015

        String intern = s2.intern();

        System.out.println("s2 addr = " + System.identityHashCode(intern));
  • 문자열 리터럴과 new 로 만든 문자열은 다른 객체를 가리키므로 == 비교에서 false 를 반환한다.
  • intern() 메서드 호출 시, String Constant Pool 에 있는 문자열 객체 (문자열 리터럴) 의 주소값을 반환한다.

문자열 리터럴은 불변이기 때문에 이와같이 여러 레퍼런스가 같은 문자열 리터럴을 참조하여도 thread-safe 하다.

출처

자바 primitive, reference 자료형 그림과 표 (인파 님)
https://inpa.tistory.com/entry/JAVA-%E2%98%95-%EB%B3%80%EC%88%98%EC%9D%98-%EA%B8%B0%EB%B3%B8%ED%98%95-%EC%B0%B8%EC%A1%B0%ED%98%95-%ED%83%80%EC%9E%85


자바 primitive (Baeldung)
https://www.baeldung.com/java-primitives


부동 소수점의 유래 (modolee 님)
https://steemit.com/kr/@modolee/floating-point


부동 소수점의 이해 (콘파냐 님)
https://thrillfighter.tistory.com/349


자바 overflow, underflow (그날그날메모 님)
https://memo-the-day.tistory.com/121


IEEE Standard 754 Floating Point Numbers (GeeksforGeeks)
https://www.geeksforgeeks.org/ieee-standard-754-floating-point-numbers/


자바의 literal (Baeldung)
https://www.baeldung.com/java-literals


자바의 문자열 리터럴 (테코블 스티치 님)
https://tecoble.techcourse.co.kr/post/2020-09-07-dive-into-java-string/

0개의 댓글