← Java 강의 목록으로
기초
기초 · 선수: 이전 단원

02. 변수와 타입

변수는 데이터를 담는 "이름표가 붙은 상자" 입니다. Java 는 **정적 타입(static type)** 언어라서 변수마다 어떤 타입의 값을 담을지 선언 시점에 미리 정해야 합니다. 이 단원에서는 Java 의 기본(primitive) 8가지와 형변환, JDK 10+ 의 `var` 키워드를 살펴봅니다.

JavaJDK기초변수와 타입
소요 시간
약 1~1.5시간
난이도
📊 초급
선수 조건
🎯 이전 단원 또는 동등 지식
결과물
변수는 데이터를 담는 "이름표가 붙은 상자" 입니다. Java 는 **정적 타입(static type)** 언어라서 변수마다 어떤 타입의 값을 담을지 선언 시점에 미리 정해야 합니다. 이 단원에서는 Java 의 기본(primitive) 8가지와 형변환, JDK 10+ 의 `var` 키워드를 살펴봅니다.

이 강의에서 배우는 것

  • 18가지 primitive 타입의 크기와 기본값을 안다
  • 2형변환(암묵적·명시적) 이 언제 일어나는지 이해한다
  • 3`var` 가 사용 가능한 위치와 그렇지 않은 위치를 구분한다
  • 4`String` 리터럴과 `new String()` 의 차이를 안다

소개

변수는 데이터를 담는 "이름표가 붙은 상자" 입니다. Java 는 **정적 타입(static type)** 언어라서 변수마다 어떤 타입의 값을 담을지 선언 시점에 미리 정해야 합니다. 이 단원에서는 Java 의 기본(primitive) 8가지와 형변환, JDK 10+ 의 `var` 키워드를 살펴봅니다.

핵심 개념

1) Primitive 8종

타입크기기본값범위
`byte`1 byte0-128 ~ 127
`short`2 byte0-32,768 ~ 32,767
`int`4 byte0약 ±21억
`long`8 byte0L약 ±9 × 10^18
`float`4 byte0.0fIEEE 754 단정도
`double`8 byte0.0dIEEE 754 배정도
`boolean`JVM 의존`false``true` / `false`
`char`2 byte''UTF-16 코드 단위
java
int age = 21;
long population = 50_000_000L;   // long 리터럴은 끝에 L
double pi = 3.14159;
boolean done = false;
char grade = 'A';

2) 형변환

java
int i = 100;
double d = i;          // int → double : 암묵적 (값 보존)
int back = (int) d;    // double → int : 명시적 (소수점 절삭)

작은 타입 → 큰 타입은 자동으로 변환되지만, 그 반대는 데이터 손실 가능성 때문에 반드시 **명시적 캐스팅** 이 필요합니다.

3) `var` 키워드 (JDK 10+)

java
var name = "지수";    // String 으로 추론
var nums = new int[]{1, 2, 3};
  • **지역 변수에서만** 사용 가능 (필드·메서드 시그니처 불가)
  • 초기값으로부터 타입을 추론하므로 **선언과 동시에 값** 이 있어야 함
  • 가독성에 도움이 될 때만 쓰는 것을 권장

4) `String` 리터럴 vs `new String()`

java
String a = "hello";
String b = "hello";
String c = new String("hello");
System.out.println(a == b);          // true  (문자열 풀 공유)
System.out.println(a == c);          // false (다른 객체)
System.out.println(a.equals(c));     // true  (내용 비교)

핵심 예제

예제 1 — `Primitives.java` : 8가지 primitive 출력

java
public class Primitives {
    public static void main(String[] args) {
        byte b = 10;
        short s = 200;
        int i = 100_000;
        long l = 9_999_999_999L;
        float f = 3.14f;
        double d = 3.141592653589793;
        boolean t = true;
        char c = 'A';
        System.out.printf("byte=%d, short=%d, int=%d, long=%d%n", b, s, i, l);
        System.out.printf("float=%.2f, double=%.6f%n", f, d);
        System.out.printf("boolean=%b, char=%c(%d)%n", t, c, (int) c);
    }
}

**실행 결과**

text
byte=10, short=200, int=100000, long=9999999999
float=3.14, double=3.141593
boolean=true, char=A(65)

**메모:** 큰 숫자는 `_` 로 자리 표시할 수 있습니다 (`100_000`).

예제 2 — `Conversion.java` : 형변환 함정

java
public class Conversion {
    public static void main(String[] args) {
        int i = 100;
        double d = i;
        System.out.println("int -> double: " + d);

        double pi = 3.99;
        int truncated = (int) pi;
        System.out.println("double -> int (절삭): " + truncated);

        int big = 1_000;
        byte overflow = (byte) big;
        System.out.println("byte 오버플로: " + overflow);
    }
}

**실행 결과**

text
int -> double: 100.0
double -> int (절삭): 3
byte 오버플로: -24

**메모:** `byte` 범위(-128~127) 를 벗어나면 비트가 잘려 예측 못할 값이 나옵니다.

예제 3 — `VarKeyword.java` : `var` 사용 가능/불가능 케이스

java
import java.util.ArrayList;
import java.util.List;

public class VarKeyword {
    public static void main(String[] args) {
        var name = "지수";
        var list = new ArrayList<String>();
        list.add("Java");
        list.add("Spring");

        for (var s : list) {
            System.out.println(s);
        }

        // var x;          // 컴파일 에러: 초기값 필요
        // var n = null;   // 컴파일 에러: 타입 추론 불가
        List<Integer> nums = List.of(1, 2, 3);
        System.out.println("이름: " + name);
        System.out.println("타입은: " + nums.getClass().getSimpleName());
    }
}

**실행 결과**

text
Java
Spring
이름: 지수
타입은: ListN

**메모:** 필드/매개변수/반환형엔 `var` 를 못 씁니다. 어디까지나 **지역 변수** 한정입니다.

예제 4 — `StringBasics.java` : 문자열 리터럴 vs `new String()`

java
public class StringBasics {
    public static void main(String[] args) {
        String a = "hello";
        String b = "hello";
        String c = new String("hello");
        System.out.println("a == b : " + (a == b));
        System.out.println("a == c : " + (a == c));
        System.out.println("a.equals(c) : " + a.equals(c));
        System.out.println("length : " + a.length());
        System.out.println("upper  : " + a.toUpperCase());
    }
}

**실행 결과**

text
a == b : true
a == c : false
a.equals(c) : true
length : 5
upper  : HELLO

**메모:** Java 에서 문자열 **내용 비교는 항상 `.equals()`** 를 사용하세요. `==` 는 참조(주소) 비교입니다.

전체 예제 코드 (src/)

src/Conversion.java

java
public class Conversion {
    public static void main(String[] args) {
        int i = 100;
        double d = i;
        System.out.println("int -> double: " + d);

        double pi = 3.99;
        int truncated = (int) pi;
        System.out.println("double -> int (절삭): " + truncated);

        int big = 1_000;
        byte overflow = (byte) big;
        System.out.println("byte 오버플로: " + overflow);
    }
}

src/Primitives.java

java
public class Primitives {
    public static void main(String[] args) {
        byte b = 10;
        short s = 200;
        int i = 100_000;
        long l = 9_999_999_999L;
        float f = 3.14f;
        double d = 3.141592653589793;
        boolean t = true;
        char c = 'A';
        System.out.printf("byte=%d, short=%d, int=%d, long=%d%n", b, s, i, l);
        System.out.printf("float=%.2f, double=%.6f%n", f, d);
        System.out.printf("boolean=%b, char=%c(%d)%n", t, c, (int) c);
    }
}

src/StringBasics.java

java
public class StringBasics {
    public static void main(String[] args) {
        String a = "hello";
        String b = "hello";
        String c = new String("hello");
        System.out.println("a == b : " + (a == b));
        System.out.println("a == c : " + (a == c));
        System.out.println("a.equals(c) : " + a.equals(c));
        System.out.println("length : " + a.length());
        System.out.println("upper  : " + a.toUpperCase());
    }
}

src/VarKeyword.java

java
import java.util.ArrayList;
import java.util.List;

public class VarKeyword {
    public static void main(String[] args) {
        var name = "지수";
        var list = new ArrayList<String>();
        list.add("Java");
        list.add("Spring");

        for (var s : list) {
            System.out.println(s);
        }

        List<Integer> nums = List.of(1, 2, 3);
        System.out.println("이름: " + name);
        System.out.println("타입은: " + nums.getClass().getSimpleName());
    }
}

자주 하는 실수

  1. `long` 리터럴에 `L` 빼먹기 → `int` 로 해석되어 오버플로
  2. `float` 리터럴에 `f` 빼먹기 → 기본은 `double`, 캐스팅 필요
  3. `int / int` 가 정수 나눗셈이라는 점을 잊고 `1 / 2 == 0` 에 당황
  4. `char` 가 작은 정수(0~65535)와 호환된다는 사실 모름
  5. 문자열 비교에 `==` 사용

정리

  • Java 의 8 primitive 와 각자 기본값을 외워 두면 디버깅이 편합니다
  • 형변환은 작은 → 큰 자동, 큰 → 작은 명시적 캐스팅이 원칙
  • `var` 는 가독성 도구일 뿐, 만능 키워드가 아닙니다
  • 문자열 내용은 `.equals()`, 참조는 `==`

과제

# 과제 - 02. 변수와 타입

## 문제 1 — 나의 프로필 변수

  • 파일명: `Homework01.java`
  • 핵심 개념: primitive 타입 선언, `printf`

요구사항

  • 이름(String), 나이(int), 키(double), 학생 여부(boolean), 등급(char) 변수를 선언합니다.
  • `printf` 로 한 줄에 모두 출력합니다.

예상 출력

text
이름=홍길동, 나이=21, 키=175.30, 학생=true, 등급=A

힌트

  • `printf` 포맷: `%s %d %.2f %b %c`

## 문제 2 — 사칙연산

  • 파일명: `Homework02.java`
  • 핵심 개념: 변수, 정수/실수 연산, 명시적 형변환

요구사항

  • 두 정수 `a = 17`, `b = 5` 를 선언합니다.
  • 합·차·곱·몫(정수 나눗셈)·나머지·실수 나눗셈을 출력합니다.

예상 출력

text
17 + 5 = 22
17 - 5 = 12
17 * 5 = 85
17 / 5 = 3
17 % 5 = 2
17 / 5 (실수) = 3.40

힌트

  • 마지막 줄은 `(double) a / b` 처럼 한 쪽만 캐스팅하면 됩니다.

## 정답 확인 직접 풀어 본 후 [`answer/`](./answer/) 폴더의 정답과 비교해 보세요.

정답 코드 (homework/answer/)

answer/Homework01.java

java
/** 프로필 변수 출력. */
public class Homework01 {
    public static void main(String[] args) {
        String name = "홍길동";
        int age = 21;
        double height = 175.30;
        boolean student = true;
        char grade = 'A';
        System.out.printf("이름=%s, 나이=%d, 키=%.2f, 학생=%b, 등급=%c%n",
                name, age, height, student, grade);
    }
}

answer/Homework02.java

java
/** 두 정수의 사칙연산. */
public class Homework02 {
    public static void main(String[] args) {
        int a = 17;
        int b = 5;
        System.out.printf("%d + %d = %d%n", a, b, a + b);
        System.out.printf("%d - %d = %d%n", a, b, a - b);
        System.out.printf("%d * %d = %d%n", a, b, a * b);
        System.out.printf("%d / %d = %d%n", a, b, a / b);
        System.out.printf("%d %% %d = %d%n", a, b, a % b);
        System.out.printf("%d / %d (실수) = %.2f%n", a, b, (double) a / b);
    }
}

직접 해 보기

bash
cd 01_기초/02_변수와_타입/src
javac Primitives.java
java Primitives

다음 단원

[03_연산자와_표현식](../03_연산자와_표현식/) — 산술·비교·논리·비트 연산자와 `==` vs `.equals()` 를 배웁니다.

예제 코드 / 강의 자료

전체 강의 자료와 예제 코드는 GitHub에서 자유롭게 받아볼 수 있습니다.

GitHub에서 보기 ↗