[자바 스터디] 2주차 : 자바 데이터 타입, 변수 그리고 배열

2023. 1. 22. 00:15·스터디/자바

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

프리미티브 타입 (Primitive Type)

  • 실제 값 자체를 Stack에 저장
  • byte, short, int, long, char 등

레퍼런스 타입 (Reference Type)

  • class, interface, enum, array, String
  • 값에 대한 참조(주소값)을 Stack에 저장
    • 실제 값은 Heap에 저장

Example

Stack Heap
int a = 10;
char b = 'C';
MyClass myClass = 100번지; 100번지 = myClass 인스턴스

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

이름 크기 값 범위 기본 값 비고
byte 1 byte -128 ~ 127 0
short 2 bytes -32,768 ~ 32,767 0
signed int 4 bytes $-2^{31}$ ~ $2^{31}-1$ 0
unsigned int 4 bytes 0 ~ $2^{32}-1$ 0 java 8 이상부터 가능
signed long 8 bytes $-2^{63}$ ~ $2^{63}-1$ 0L
unsigned long 8 bytes $0$ ~ $2^{64}-1$ 0L java 8 이상부터 가능
float 4 bytes single-precision 32-bit 0.0f
double 8 bytes double-precision 64-bit 0.0d
boolean 1 bit true / false false
char 2 bytes '\u0000' ~ '\uffff' '\u0000'
  • unsigned -> 부호가 없으므로 signed에 비해 약 2배 더 많은 값을 저장할 수 있음
  • \u는 Unicode escape 문자로, 뒤의 0000, ffff가 유니코드

int 값의 범위와 값이 정해지는 원리

  • int는 4byte 이다
    • 1byte == 8bit 이다
    • 1bit는 2가지의 비트를 저장할 수 있다
  • 따라서, 4byte에는 총 $2^{32}$ 개의 값을 저장할 수 있다
    • 이때, signed의 경우 맨 앞자리를 부호로 사용하므로 음수, 양수 각각 $2^{31}$ 개의 수를 저장할 수 있게 된다
    • 마지막으로 양수는 0을 포함하므로 양수에서 1을 빼어 signed int의 범위가 $-2^{31}$ ~ $2^{31} - 1$ 로 정해지는 것이다

부동 소수점

  • 현재 대부분의 언어 / 시스템은 IEEE 754 표준을 따름

float (32bit)의 경우

double (64bit)의 경우

특징 및 주의점

  • 부동 소수점 방식은 항상 오차가 존재할 수 밖에 없음
    • 따라서, 실수를 다룰 땐 정확한 값이 아닌 근사치를 표현하고 있을 뿐임을 기억해야 한다
  • 아래 예제에서 볼 수 있듯 0.1을 1000번 더했음에도 sum은 100이 아닌 99.9999... 가 된다
    • 마찬가지 이유로 double과 float과의 비교 연산 시 같은 수를 저장하고 있다고 해도 (실제로는 저장하는 비트의 개수가 달라서) 같다고 나오지 않는다. (ex. 10.1F != 10.1D)
    double sum = 0.0;
    for (int i = 0 ; i < 1000 ; i++) {
        sum += 0.1;
    }
    System.out.println(sum); // 99.9999999999986
  • 자바에서 실수 정확하게 계산하는 방법
    • BigDecimal 사용하기
      BigDecimal bigNumber1 = new BigDecimal("1000.0");
      BigDecimal bigNumber2 = new BigDecimal("999.9");

    BigDecimal result = bigNumber1.subtract(bigNumber2); // 0.1 (정확한 값이 나옴)

리터럴

  • 코드 상에서 직접 표현한 값을 의미함

Integer Literals

  • 숫자 값은 int
    • int는 1000000 == 1_000_000 로도 가능 (다른 표기법)
  • long 타입은 L이나 l로 끝나는 값
    • 근데 인텔리제이에서 lower case로 쓰면 upper로 쓰라고 권유하던데 왠진 모르겠다
  • 2진수는 0b로 시작
  • 16진수는 0x로 시작
  • 8진수는 0으로 시작

Floating-Point (실수) Literals

  • float 타입은 F나 f로 끝나는 값
    • float f = 10.5 는 오류 발생. float f = 10.5f 라고 해야 함
  • 그 외 나머지는 double (D or d를 적을 수도 있음)

Character & String Literals

  • 기본적으로 Unicode Character 가능
  • escape character
    • \b : 백스페이스
    • \t : 탭
    • \n : 개행
    • \f : form feed (used to indicate to a printer that it should start a new page)
    • \r : 캐리지 리턴 (CRLF에서의 개행 -> \r\n)
    • \" , \' : double, single quote
    • \\ : 역슬래시

String Pool

  • String을 리터럴로 초기화하게 되면, Heap 내의 String Pool에 저장되고 재활용 됨
    • 반면 new 키워드를 통해 초기화하면, Heap 내에 다른 객체와 동일하게 저장되고 재활용되지 않음


[출처 : Baeldung - Where Does Java’s String Constant Pool Live, the Heap or the Stack?]

Boolean Literals

  • true or false

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

선언 시 초기화

    int a = 10;
    char c = 'C';
    String s = "abc";
    MyClass myClass = new MyClass();

선언 후 초기화

    int a;
    char c;
    String s;
    MyClass myClass;

    a = 10;
    c = 'C';
    s = "abc";
    myClass = new MyClass();

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

클래스 변수 (static)

  • 클래스 전체
    • 인스턴스가 없어도 접근 가능
    • static 요소는 JVM에 클래스가 로딩될 때 생성됨
  • 클래스이름.변수명, 인스턴스.변수명 모두로 접근 가능
    • 다만, 인스턴스의 레퍼런스를 통해 static 변수 / 메서드에 접근하는 것은 좋지 않다 (인텔리제이에서도 클래스를 통해 참조하라고 권고함)
  • static 변수는 GC의 대상에서 제외 (애플리케이션 로딩 시점부터 종료 시점까지 생존)

인스턴스 변수 (non-static)

  • static이 아닌 클래스 전체에서 접근 가능
  • 인스턴스가 생성되어야만 접근 가능
    • 즉, 인스턴스.변수명으로만 접근 가능

블록 {} 내에서 선언된 변수

  • 기본적으로 해당 변수가 선언된 블록 내에서만 사용 가능

변수의 초기화

  • 클래스 변수 / 인스턴스 변수
    • 선언 후 초기화 하지 않아도 기본 값 (0, null 등) 이 들어가서 바로 사용할 수 있음 (권장되진 않지만 컴파일 오류는 발생 X)
  • 지역 변수
    • 선언 후 초기화하지 않고 사용하면 컴파일 오류 발생

접근제어자

  • public, protected : 상속받은 클래스에서도 사용 가능
  • private : 자기 클래스에서만 사용 가능

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

타입 프로모션 (묵시적 형 변환)

  • 타입 프로모션은 자동으로(묵시적으로) 발생하는 형 변환을 말함
  • 아래와 같은 상황에서 1, 2라는 int 값이 자동으로 double로 변환됨
    public double sum(double a, double b) {}

    public static void main(String[] args) {
        sum(1, 2);  // int -> double 묵시적 형 변환 발생
    }

`

  • 타입 프로모션은 작은 크기의 타입에서 큰 크기의 타입으로만 가능
    • 큰 크기의 타입 -> 작은 크기의 타입은 명시적으로 캐스팅해주어야 함

      [출처 : geeksforgeeks]

타입 캐스팅 (명시적 형 변환)

Upcasting

  • subclass -> superclass
    • subclass는 항상 superclass 전체를 포함하므로 안전한 캐스팅 가능
     public static class Parent {
          public void message() {
              System.out.println("Parent");
          }
      }

      public static class Child extends Parent{
          @Override
          public void message() {
              System.out.println("Child");
          }
          public String name = "childA";
      }

      public static void main (String[] args) {
          Child child = new Child();
          Parent parent = (Parent) child;
          parent.message(); // Child
  //        System.out.println(parent.name); // 컴파일 에러 발생 (안전)
      }

Downcasting

  • superclass -> subclass
    • superclass는 subclass의 일부를 포함하지 않을 수 있으므로 오류 발생 가능
    public static class Parent {
          public void message() {
              System.out.println("Parent");
          }
      }

      public static class Child extends Parent{
          @Override
          public void message() {
              System.out.println("Child");
          }
          public String name = "childA";
      }

      public static void main (String[] args) {
          Child child = new Child();
          Parent parent = (Parent) child; // 런타임 에러 발생 (위험)
          // 아래 두 코드모두 컴파일 타임에는 오류 발생 X
          parent.message();
          System.out.println(parent.name);
      }
  • 원시타입의 경우 Downcasting을 하게 되면 값의 손실이 발생할 수 있음

1차 및 2차 배열 선언하기

선언

    // 1차 배열
    int[] oneDimensionArrayOne = {1, 2, 3};

    int[] oneDimensionArrayTwo = new int[3];
    oneDimensionArrayTwo[0] = 1;
    ...

    // 2차 배열
    int [][] twoDimensionArrayOne = {{1, 2}, {3, 4}};
    int [][] twoDimensionArrayTwo = new int[2][2];
    twoDimensionArrayTwo[0][0] = 1;
    ...
  • 배열에 대한 주소(참조)는 JVM Runtime Data Area의 Java Stack 내부에 생성되며, 실제 배열 값들은 Heap 영역에 저장됨
  • 1차원 배열

  • 2차원 배열

타입 추론, var

  • 자바 10부터 지원하는 가능
  • 명시적으로 변수의 타입을 적어주지 않아도 컴파일러가 알아서 변수의 타입을 입력한 리터럴을 통해 추론하는 것을 말함
    • var number = 10;과 같이 사용가능

제약 사항, 특징

  • var은 반드시 선언과 동시에 초기화가 이루어져야 함
  • var에는 null이 들어갈 수 없음
  • var은 지역변수로만 사용 가능함
  • var은 키워드가 아니므로 변수명으로 사용할 수 있음
  • 파이썬 등과 다르게 자바의 var은 런타입에 타입이 변경될 순 없음

피드백

  1. 각 프리미티브 타입의 범위가 왜 그렇게 정해지는지 원리 이해하기 (byte) + 부동소수점 이 갖는 문제점/특징 이해
  2. unsigned는 자바 8부터 가능한데, 프리미티브 타입으로 직접 지원하진 않고 Integer.parseUnsignedInt(), Integer.toUnsignedString()으로 사용가능 (사용 권장 X)
  3. 변수가 선언될 때 바이트코드 상에서는 두 줄로 나누어 이뤄지기 때문에 동시성 문제가 발생할 수 있다..

질문

1. BigInteger과 Long의 차이

  • int와 long의 범위
int long
-2,147,483,648 ~ 2,147,483,647 -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807
  • BigInteger
    • BigInteger은 숫자를 문자열로 취급하기 때문에 무한하게 숫자를 저장할 수 있음
    • valueOf()로 BigInteger 객체 생성 가능
    • 연산 시 add, subtract 등 메서드 사용해야 함
    • intValue(), longValue() 등으로 값을 빼낼 수 있음

레퍼런스

  • https://www.notion.so/2-38b5d67c7f5a48238529bb8f1617ea0d
  • https://catch-me-java.tistory.com/19
  • http://www.tcpschool.com/java/java_datatype_floatingPointNumber
  • https://inpa.tistory.com/entry/JAVA-%E2%98%95-%EC%8B%A4%EC%88%98-%ED%91%9C%ED%98%84%EB%B6%80%EB%8F%99-%EC%86%8C%EC%88%98%EC%A0%90-%EC%9B%90%EB%A6%AC-%ED%95%9C%EB%88%88%EC%97%90-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0#%EB%B6%80%EB%8F%99_%EC%86%8C%EC%88%98%EC%A0%90_%EA%B3%84%EC%82%B0_%EB%B0%A9%EB%B2%95

'스터디 > 자바' 카테고리의 다른 글

[자바 스터디] 7주차 : 패키지  (0) 2023.01.30
[자바 스터디] 6주차 : 상속  (0) 2023.01.23
[자바 스터디] 5주차 : 클래스  (0) 2023.01.23
[자바 스터디] 3, 4주차 : 연산자, 제어문  (0) 2023.01.22
[자바 스터디] 1주차 : JVM은 무엇이며 자바 코드는 어떻게 실행하는 것인가.  (0) 2023.01.21
'스터디/자바' 카테고리의 다른 글
  • [자바 스터디] 6주차 : 상속
  • [자바 스터디] 5주차 : 클래스
  • [자바 스터디] 3, 4주차 : 연산자, 제어문
  • [자바 스터디] 1주차 : JVM은 무엇이며 자바 코드는 어떻게 실행하는 것인가.
gmelon
gmelon
백엔드 개발을 공부하고 있습니다.
  • gmelon
    gmelon's greenhouse
    gmelon
  • 전체
    오늘
    어제
    • 분류 전체보기 (91)
      • 개발 공부 (28)
        • Java (6)
        • Spring (10)
        • 알고리즘 (11)
        • 기타 (1)
      • 프로젝트 (12)
        • [앱] 플랭고 (4)
        • 졸업 프로젝트 (8)
      • 스터디 (0)
        • 자바 (30)
      • 기록 (15)
        • 후기, 회고 (9)
        • SSAFYcial (5)
        • 이것저것 (1)
      • etc. (6)
        • 모각코 (6)
  • 블로그 메뉴

    • 홈
    • 방명록
    • github
    • 스크랩
  • 인기 글

  • 태그

    AWS 프리티어 종료
    프리티어 종료
    groupingBy()
    Java Collector
    groupingBy mapping
    졸업프로젝트
    2024 회고
    자바 Collector
    자바
    태초마을이야
    2024 상반기 회고
    Collector groupingBy()
    java
    싸피 회고
    한글프로그래밍언어
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
gmelon
[자바 스터디] 2주차 : 자바 데이터 타입, 변수 그리고 배열
상단으로

티스토리툴바