변수 — 타입을 먼저 쓴다
Article
값을 하나 기억해두고 싶다. 이름을 붙여서 나중에 다시 꺼내 쓰려는 것이다.
public class Main {
public static void main(String[] args) {
age = 20;
System.out.println(age);
}
}
읽기에는 아무 문제가 없어 보인다. 그런데 컴파일이 안 된다.
- Main.java:3: error: cannot find symbol
- age = 20;
- ^
- symbol: variable age
- location: class Main
age 라는 이름을 못 찾겠다고 한다. 우리는 방금 만들었는데.
자바에서 이름을 만들려면 그 이름이 어떤 종류의 값을 담을지 먼저 밝혀야 한다. 이걸 안 했으니 컴파일러 입장에서는 age 라는 이름이 세상에 존재한 적이 없다.
int age = 20;
앞에 int 한 단어가 붙었다. 이게 이번 강의의 전부다. 다만 이 한 단어가 자바라는 언어의 성격을 거의 다 설명한다.
이름 앞에 종류를 적는다
int 는 정수(integer)를 뜻한다. "age 라는 이름에는 정수만 담겠다"는 선언이다.
int age = 20;
double height = 175.5;
boolean isStudent = true;
읽는 순서는 이렇다.
- int어떤 종류를 담을 상자인가
- age상자에 붙일 이름
- =오른쪽 값을 왼쪽에 넣는다
- 20넣을 값
= 는 "같다"가 아니라 "넣는다" 이다. 수학의 등호와 다르다. 이 기호를 대입 연산자라고 부른다.
한 번 선언한 뒤에는 타입을 다시 적지 않는다.
int age = 20;
age = 21; // 값만 바꾼다
int age = 22; // 에러 — 같은 이름을 또 선언할 수 없다
int age = 20; 을 실행한 직후
- age
- 20
선언과 초기화는 나눌 수 있다
이름만 먼저 만들어두고, 값은 나중에 넣어도 된다.
int age; // 선언
age = 20; // 초기화
다만 값을 넣기 전에 꺼내 쓰면 컴파일러가 막는다.
int age;
System.out.println(age);
- Main.java:3: error: variable age might not have been initialized
"초기화가 안 됐을 수도 있다"고 한다. 빈 상자를 열어보려는 것을 컴파일러가 미리 알아챈 것이다.
이게 자바가 타입을 적으라고 시키는 대가다. 귀찮은 대신, 실행하기도 전에 실수를 잡아준다.
종류가 안 맞으면 못 넣는다
정수를 담겠다고 선언한 상자에 글자를 넣어보자.
int age = "스무살";
- Main.java:3: error: incompatible types: String cannot be converted to int
- int age = "스무살";
- ^
String 을 int 로 바꿀 수 없다고 한다. 화살표까지 문제 지점을 정확히 가리킨다.
이 에러는 프로그램을 실행해서 만난 게 아니다. 아직 한 줄도 실행되지 않았다. javac 가 코드를 읽다가 발견한 것이다.
이름 짓는 규칙
자바가 강제하는 규칙과, 사람들이 지키는 관례가 따로 있다.
| 구분 | 내용 | 예 |
|---|---|---|
| 필수 | 숫자로 시작할 수 없다 | 2age ✕ · age2 ○ |
| 필수 | 키워드는 쓸 수 없다 | int ✕ · class ✕ |
| 필수 | 공백과 기호를 넣을 수 없다 | my age ✕ · my-age ✕ |
| 관례 | 소문자로 시작한다 | age ○ · Age △ |
| 관례 | 단어가 겹치면 뒤 단어를 대문자로 | myAge · userName |
| 관례 | 줄임말보다 풀어 쓴다 | n △ · count ○ |
관례를 어겨도 컴파일은 된다. 다만 자바를 쓰는 사람들은 거의 예외 없이 이렇게 쓴다. myAge 처럼 낙타 등 모양으로 오르내린다고 해서 카멜 케이스라고 부른다.
2강에서 클래스 이름은 대문자로 시작한다고 했다. 변수는 소문자로 시작한다. 이 차이 덕분에 코드를 보다가 Hello 와 hello 만 봐도 클래스인지 변수인지 짐작할 수 있다.
var — 타입을 안 적어도 되는 경우
자바 10 부터는 var 를 쓸 수 있다.
var age = 20; // int 로 정해진다
var height = 175.5; // double 로 정해진다
var name = "김자바"; // String 으로 정해진다
편해 보이지만, 오해하기 딱 좋은 문법이다.
증거는 간단하다.
var age = 20;
age = "스무살";
- Main.java:4: error: incompatible types: String cannot be converted to int
int 라고 적은 적이 없는데 int 라고 혼난다. 컴파일러가 이미 정해뒀기 때문이다.
또 var 는 값을 같이 주지 않으면 못 쓴다. 추측할 근거가 없어서다.
var age; // error: cannot infer type for local variable age
이 시리즈에서는 당분간 타입을 손으로 적는다. 타입이 눈에 보여야 배우기 좋기 때문이다.
정리하면
자바에서는 변수를 만들 때 담을 값의 종류를 먼저 적고, 컴파일러가 그 약속을 실행 전에 검사한다.
- 01
타입을 이름 앞에 적는다
적지 않으면 컴파일러는 그 이름을 모른다.
int age = 20; - 02
=는 넣는다는 뜻이다오른쪽 값을 왼쪽 상자에 넣는다. 같다는 뜻이 아니다.
- 03
빈 상자를 열면 막힌다
값을 넣기 전에 꺼내 쓰면 컴파일 에러다.
- 04
종류가 다르면 못 넣는다
실행 전에 잡힌다. 이게 타입을 적는 대가이자 보상이다.
int age = "스무살"; // 컴파일 에러 - 05
var는 타입을 없애지 않는다컴파일러가 대신 정할 뿐, 한 번 정해지면 못 바꾼다.
그런데 int 말고 또 무엇이 있을까? 이름 앞에 적을 수 있는 단어의 목록이 있을 텐데.
다음 강의에서 그 목록을 본다. 목록은 딱 여덟 개다. 그리고 그 여덟 개에 속하지 않는 나머지 전부가 또 하나의 무리를 이룬다. 이 시리즈에서 가장 자주 되돌아올 구분이 거기서 생긴다.