JAVA 식별자와 예약어 및 데이터 타입

식별자와 예약어

식별자 생성 규칙

  • 첫 문자는 A-Z, a-z, _, $, 유니코드로 시작해야 함
  • 특수문자 사용불가(!, @, #, %, &, * 등)
  • 대소문자를 구별하고, 길이에 제한이 없음
  • 예약어를 포함할 수 있으나, 예약어만을 사용할 수 없음
  • 숫자를 사용할 수 있으나, 첫 문자에는 숫자 사용 불가
  • 클래스 이름은 대문자, 메서드 이름은 소문자, 변수는 소문자, 상수는 대문자로 시작

예약어

  • 시스템에서 일정 특성을 가진 언어로 등록된 것으로 데이터 타입이나 프로그램 정의를 위해 사용됨
  • 자바의 모든 예약어는 소문자로 이루어짐

자바 데이터 타입

Primitive Type(기본형)

  • 할당된 공간에 실제 value가 들어오는 경우
  • 더이상 쪼개질 수 없는 원자성의 데이터

  1. 논리형

    • boolean(1bit) : true or false(0 또는 1로 표현 불가능)
  2. 문자형

    기본 타입 메모리 용량 저장 가능 값 범위
    char 2byte(16bit) 0 ~ 2^16 - 1(0 ~ 65,535)
    • 아스키코드 표현 가능
    • 'a'와 같이 작은 따옴표 안에 포함된 문자로 표현
  3. 정수형

    기본 타입 메모리 용량 저장 가능 값 범위
    byte 1byte(8bit) -2^7 ~ 2^7 - 1(-128 ~ 127)
    short 2byte(16bit) -2^15 ~ 2^15 - 1(-32,768 ~ 32,767)
    int 4byte(32bit) -2^31 ~ 2^31 - 1(-2,147,483,648 ~ 2,147,483,647)
    long 8byte(64bit) -2^63 ~ 2^63 - 1(어마어마하게 큰 수 표현)
    • 부호형이라는 특징이 있음(0이면 양수, 1이면 음수)
    • 형을 명시하지 않을 경우 기본형인 int형으로 정의
    Java
    long i = 100000000000L;  // 정수형의 기본형인 int로 표현할 수 있는 수의 범위를 넘어가는 값을 저장하기 위해서는 long형으로 만들어줘야함
    System.out.println(i);
    
    /* 실행 결과 */
    100000000000

    정수형의 기본형은 int형이므로 long형으로 표현할 경우 값 뒤에 l 혹은 L를 붙여줘야 함

  4. 실수형

    기본 타입 메모리 용량 저장 가능 값 범위
    float 4byte(32bit) (+/-)1.4E-45 ~ (+/-)3.4028235E38
    double 8byte(64bit) 어마어마하게 큰 수 표현
    • 형을 명시하지 않을 경우 기본형인 double형으로 정의
    • IEEE 부동 소수점 방식으로 표현하기때문에 더 큰 범위까지 표현할 수 있다는 장점이 있지만,
      실수의 표현에서 오차가 존재한다는 단점이 있음
    Java
    double d = 3.14F;  // float형의 값 3.14을 double형의 변수에 저장
    System.out.println(d);
    
    /* 실행 결과 */
    3.140000104904175

    실수형의 기본형은 float형이므로 double형으로 표현할 경우 값 뒤에 f 혹은 F를 붙여줘야 함

Non-Primitive Type(참조형)

  • 할당된 공간에 실제 값을 참조할 수 있는 reference가 들어오는 경우

  1. 클래스 타입

  2. 인터페이스 타입

  3. 배열 타입

자바 데이터 타입 변환(형변환)

  • 데이터 타입의 크기순 정렬 : byte < short < int < long < float < double
  • float형의 경우 표현 범위가 long형보다 넓으므로 데이터 타입의 크기가 더 크다고 봄

  1. 묵시적 형변환(Promotion)

    • 더 작은 데이터 단위에서 더 큰 데이터 단위로 변환 -> 데이터 손실 우려 없음
    • 형변환 연산자를 사용하지 않아도 자동적으로 형변환이 이루어짐
    Java
    long j = 100000000000L;
    float f = j;  // 묵시적 형변환(float = long) : float > long이므로 가능
    System.out.println(f);
    
    /* 실행 결과 */
    9.9999998E10  // 단, 실수형의 경우 부동소수점 표기법에 의해 오차 발생 가능
  2. 명시적 형변환(Demotion)

    • 더 큰 데이터 단위에서 더 작은 데이터 단위로 변환 -> 데이터 손실 우려
    • 반드시 형변환 연산자를 사용하여 변환하고자 하는 데이터 타입을 명시해야 함
    Java
    double d = 3.14F;
    int d2 = (int)d;  // 명시적 형변환(int = double) : int < double이므로 명시 필수
    System.out.println(d2);
    
    /* 실행 결과 */ 
    3  // 명시적 형변환은 값의 손실이 있을 수 있음

    🧐 연산 과정에서 overflow가 발생하지 않는가?

    Java
    int price = 50000000;
    int amout = 100;
    
    /* 문제의 코드 */
    long totalPrice = price * amout;
    
    /* 해결 코드 */
    long totalPrice = (long)price * amout;
    
    System.out.println(totalPrice);
    
    /* 실행 결과 */ 
    5000000000
    • 문제의 코드 : int*int=int 인데 5000000000이 int로 표현할 수 있는 범위를 넘어가므로 totalPrice에는 잘린 값이 저장되는 문제가 생김
    • 해결 코드 : 서로 다른 타입간의 연산더 큰 타입을 따라가므로 long*long=long이 됨.
      따라서 값이 잘리거나 변하지 않게하려면 연산시에 형변환 해주기!
    Java
    int[] score = {100, 92, 91};
    double avg = 0.0;
    int sum = 0;
    
    for (s : score) {
        sum += s
    }
    
    /* 문제의 코드 */
    avg = sum / score.length;
    
    /* 해결 코드 */
    avg = (double)sum / score.length;
    
    System.out.println(avg);
    
    /* 실행 결과 */ 
    94.33333333333333
    • 문제의 코드 : int/int=int 이므로 소수점 이하 값을 잃는 문제가 생김
    • 해결 코드 : double/double=double 이 되어 소수점 이하의 값을 유지한 double 형의 값이 저장됨

값 복사와 주소 복사

기본형 변수와 참조형 변수

기본형 변수(값 복사)

Java
int score = 80;  // score 변수에 80을 저장
int copyScore = score;  // score 변수에 저장된 값을 copyScore 변수에 할당
  • 메모리 상 다른 위치에 존재하는 두 개의 변수가 동일한 값을 가지게 됨
  • 특정 변수의 값을 수정해도 다른 변수에는 영향을 미치지 않음

참조형 변수(주소 복사)

Java
int[] list = {10, 20, 30};  // list 변수에 일차원 배열 객체의 주소 값이 저장됨
int[] copyList = list;  // list 변수에 저장된 주소 값을 copyList 변수에 할당
  • 하나의 배열 변수를 두 개의 참조 변수가 참조하며 데이터를 공유함
  • 특정 변수로 배열의 값을 수정하면, 동일한 객체를 참조하는 다른 변수도 수정된 값을 인식

기본형 : 값에 의한 호출(Call by Value)

Java
public class CallByValue {
    public static void main(String[] args) {
        int score = 10;
        System.out.println("변경 전 :" + score);

        changeScore(score);

        System.out.prinln("변경 후 : " + score);
    }
    private static int changeScore(int score) {
        score = 100;

        System.out.println("변경된 score :" + score);

        return score;
    }
}

-> 실행 결과

변경 전 : 10
변경된 score : 100
변경 후 : 10  // 원래 score 변수 값이 변하지 않음

참조형 : 주소에 의한 호출(Call by Reference)

Java
public class CallByReference {
    public static void main(String[] args) {
        int[] scoreList = {10, 20, 30};
        System.out.println("변경 전 :" + scoreList[0]);

        changeScore(scoreList);

        System.out.prinln("변경 후 : " + scoreList[0]);
    }
    private static int[] changeScore(int[] scoreList) {
        scoreList[0] = 100;

        System.out.println("변경된 score :" + scoreList[0]);

        return scoreList;
    }
}

-> 실행 결과

변경 전 : 10
변경된 score : 100
변경 후 : 100  // 동일한 배열의 메모리 주소를 공유하기 때문에, 원래 scoreList[0] 변수 값이 변함

매개변수로 객체 넘기기

  • 객체가 다른 메서드를 호출할 때 단순히 값만 넘기고자 하는 경우 : 매개변수를 기본형으로 선언
  • 메서드를 수행 이후에도 수행 결과를 유지하고자 하는 경우 : 매개변수를 참조형으로 선언