프로그램에서 항상 변하는 값을 변수라고 하고 메모리 주소에 붙여진 이름을 뜻합니다. 이 메모리 주소에 접근하여 값을 저장하거나 읽습니다.
C나 C++ 그리고 Java 등 이 변수라는 것을 사용하는 데, 이를 사용하는 이유는 표현 하려는 자료가 숫자, 문자, 문자열 등 다양할 수 있습니다. 그래서 그에 맞는 자료형을 사용해야 하기 때문에 사용합니다.
Java에서 패키지 이름이 소문자로 시작해야 하고, 클래스 이름도 첫 문자는 대문자로 시작해야 한다는 규칙(약속)이 존재하는데 변수의 이름을 정하는데에도 규칙(약속)이 존재합니다.
그 규칙은 다음과 같습니다.
변수 이름의 시작은 숫자로 시작할 수 없습니다.
ex) 3sum, 1str 등등 모두 사용할 수 없습니다.
Java에서 사용하고 있는 예약어를 이름으로 사용할 수 없습니다.
ex) new, switch, break 등등 Java에서 지정한 단어는 사용할 수 없습니다.
영문자, 숫자, 특수문자 사용가능. 단, 특수문자 $, _ 만 사용 가능합니다.
ex) $sum, _sum은 가능하지만, #sum, sum!은 사용할 수 없습니다.
이 변수 이름을 지정하는 데, 너무 대충지으면 안됩니다. 개인적으로 개발할 때에는 자기만 알아볼 수 있게 변수 이름을 지정해도 상관없겠지만 다른 사람이 자신의 코드를 확인할 때나 팀원 간의 협력할 때에는 변수 이름을 보고 어떤 코드인지 추측하기 어려울 수 있습니다.
그래서 변수 이름 자체의 의미와 용도에 맞게 사용하면 전체적으로 프로그램의 가독성이 증가하게 됩니다.
예를 들어, 학생들의 수를 나타내는 변수 이름으로numberOfStudents
로 표현할 수 있습니다. 여기서 중요한 점은 낙타 등 모양을 뜻하는 카멜표기법으로 작성하셔야 합니다. 첫 문자는 소문자로 시작, 다른 단어가 붙으면 첫 문자는 대문자로 작성하는 규칙이 존재합니다.
자료형(Data Type)이란 말 그대로입니다.
자료(데이터)가 갖는 형식
으로 자료형의 구조 및 개념, 가질 수 있는 값, 그 자료형에서 행할 수 있는 연산 등을 정의한 것을 말합니다.
그냥 데이터를 표현하는 방법? 정도로 이해하면 됩니다.
자료형은 크게 2가지로 분류할 수 있습니다.
기본형은 간단하게 숫자형, 문자형, 논리형이 존재하며, 참조형은 객체를 가리키는 형으로 기본형을 제외한 모든 것을 뜻합니다.
자료형 중에서 참조형은 이번에 살펴보지 않고 기본형을 먼저 알아보겠습니다.
이 기본형에는 숫자형(Numeric Type), 문자형(Character Type), 논리형(Boolean Type)이 존재합니다.
이 숫자형에는 다시 정수형과 실수형으로 구분됩니다.
정수형
정수형에는 byte, short, int, long 형이 존재합니다.
이 정수형 각각의 크기는 다음과 같습니다.
자료형 | 크기 | 범위 |
---|---|---|
byte | 1 byte | -128 ~ 127 |
short | 2 byte | -32,786 ~ 32,767 |
int | 4 byte | -2,147,483,648 ~ 2,147,483,647 |
long | 8 byte | -2^63 ~ 2^63-1 |
byte와 short형의 값은 항상 연산되기 전에 int형을 반환되기 때문에 byte와 short형은 결코 연산을 위한 형이 아니고 저장을 위한 형입니다. 그리고 프로그램에서 기본적으로 모든 숫자형은 int 형으로 저장됩니다. 만약 4 byte(32 bit)를 초과하는 숫자는 long 형으로 변환합니다.
int i = 1000000;
System.out.println(i*i);
long l = i;
System.out.println(l*l);
여기서 위의 코드와 같이 int 자료형을 갖는 변수가 범위를 벗어나게 되면 어떻게 될까?
-727379968
1000000000000
int형의 범위를 벗어나기 때문에 상위 비트가 넘치면서 오버플로우가 발생하여 부호 비트가 1로 되어 음수 값이 되었습니다. long 형은 범위 내에 있기 때문에 정상적으로 출력이 됩니다.
실수형
실수형은 정밀도에 따라 float(4 byte)와 double(8 byte) 형이 존재합니다. 두 개의 float를 연산한 결과는 float 형이지만 어느 하나라도 double 형이면 결과는 double형이 됩니다.
그리고 주의해야 할 점이 있습니다.
float f = 3.14; // 오류 발생
double d = 3.14; // 정상 작동
위의 코드와 같이 float 형에 3.14를 작성하면 오류가 발생합니다. 왜냐하면 float 형은 4 byte인데, 저장할 값은 8 byte이기 때문에 float 형에 담기에는 너무 큽니다. 따라서 아래와 같이 float 형 type으로 저장시켜라는 의미
의 뒤에 f 또는 F를 붙여줘야 합니다.
float f = 3.14F; // 정상 작동
double d = 3.14; // 정상 작동
초기에 컴퓨터에서 문자를 표현하는 방식에 대해서 8 bit 아스키(ASCII) 코드가 나왔습니다. 이 ASCII 코드는 8 bit이기 때문에 2의 8승, 256개의 문자를 표현할 수 있었는데, 점점 각 나라에 맞는 문자 세트가 등장함에 따라 서로 다르기 때문에 호환이 안되는 문제가 발생하게 됩니다. 그래서 모든 나라의 문자들을 어떤 하나의 코드표로 표준화시킨 유니코드(UNICODE)가 나오게 되었습니다.
바로 위에서 설명한 전세계 표준인 유니코드가 자바에서 문자를 나타내기 위해 사용됩니다. UTF-16 인코딩을 사용하며, 이는 모든 문자를 2 byte로 표시합니다.
여기서 문자와 문자열에 대해 미리 짧게 말하자면 표현하는 방법이 다릅니다. 문자는 기본형인 char 형으로 싱글쿼터(' ')
로 표현하고 참조형인 문자열은 더블쿼터(" ")
으로 표현합니다.
아래와 같은 코드를 작성하면 결과가 어떤 식으로 나올까?
char ch1 = 'A';
System.out.println(ch1);
System.out.println((int)ch1);
char ch2 = 68;
System.out.println(ch2);
System.out.println((char)ch2);
결과
A
65
D
D
유니코드의 코드 값이 문자에 해당하는 값이 되며, 수식에서 문자형은 int 형으로 변환되어 계산됩니다. 그래서 유니코드의 값이 65면 A를 뜻하고 68은 D를 뜻하기 때문에 위와 같은 결과가 출력됩니다.
논리형은 1 byte 크기로 true와 false 중 하나의 값만을 가지는 자료형입니다. 논리형으로 선언된 변수는 다른 자료형으로 변환되지 않습니다.
예를 들어, 논리형은 다음과 같이 표현할 수 있습니다.
boolean isPrime = true;
System.out.print(isPrime);
// 결과
true
지금까지 자료형 중에서 기본형을 살펴봤습니다.
여기서 추가적으로 자바 10부터 var 키워드로 변수의 자료형을 선언할 수 있습니다.
원래는 정수나 문자를 표현할 때는 자료형을 명시적으로 선언해야 하는데, 이 var는 컴파일러가 자료형을 추론하기 때문에 자료형을 생략할 수 있습니다.
표현하는 방법은 아래와 같습니다.
var i = 10;
var j = 10.0;
var str = "hello";
System.out.println(i);
System.out.println(j);
System.out.println(str);
// 결과
10
10.0
hello
하지만 여기서 var를 통해 문자열로 추론된 상태에서 다시 정수로 바꿀 수 없습니다.
var str = "hello";
System.out.println(str);
str = 3; // 에러 발생
주의할 점은 { }
블록 안에 있는 변수를 나타내는 지역 변수에서만 사용가능하며, 클래스의 멤버 변수를 선언할 때는 사용할 수 없습니다. 또한 초기화가 필요하며, null로 초기화할 수 없다는 점입니다. 또한 배열, 람다에서도 사용이 불가합니다.