변수를 선언한 후에는 타입을 변경할 수 없다.
자바가 제공하는 기본타입은 총 8개
구분 | 저장되는 값에 따른 분류 | 타입의 종류 |
---|---|---|
기본타입 | 정수타입 | byte,char,short,int,long |
기본타입 | 실수타입 | float,double |
기본타입 | 논리값 | boolean |
메모리 사용 크기와 저장되는 값의 범위가 서로 다르다.
타입 | 메모리 사용 크기 | 저장되는 값의 허용 범위 | |
---|---|---|---|
byte | 1byte(=8bit) | -2^7 ~ (2^7 -1) | -128 ~ 127 |
char | 2byte | 0~(2^16 -1) | 0~65535(유니코드) |
short | 2byte | -2^15 ~ (2^15 -1) | |
int | 4byte | -2^31 ~ (2^31 -1) | -2,147,483,648 ~ 2,147,483,647 |
long | 8byte | -2^63 ~ (2^63 -1) |
각 타입에 저장되는 값의 범위를 외울 필요는 없지만, 메모리 사용 크키 정도는 알고 있는것이 좋다.
char타입은 음수 값을 가질 수 없으며, 나머지 정수 타입이 저장할 수 있는 값의 범위는 -2^(n-1) ~ (2^(n-1) -1)이다. 여기서 n은 메모리 bit수이다.
정수타입으로 선언된 변수에는 정수 리터럴을 대입해 정수를 저장할 수 있다.
정수 리터럴
소스코드에서 프로그래머에 의해 직접 입력된 값을 리터럴이라고 한다.
입력된 리터럴 중 자바가 정수로 인식하는 경우는 다음과 같다.
- 2진수 : 0b 혹은 0B로 시작하고 0과 1로 구성된다.
0b1011 : 1*2^3 + 0*2^2 + 1*2^1 + 1*2^0 = 11
- 8진수 : 0으로 시작하고 0~7숫자로 구성된다.
013 : 1*8^1 + 3*8^0 = 11
- 10진수 : 소수점이 없는 0~9숫자로 구성된다.
12
- 16진수 : 0x 또는 0X로 시작하고 0~9 숫자와 A,B,C,D,E,F 또는 a,b,c,d,e,f로 구성된다.
0xB3 : 11*16^1 + 3*16^0 = 179
다음은 int타입 변수에 다양한 진수의 값을 저장하고, 10진수로 출력하는 예제이다.
int var1 = 0b1011;
int var2 = 0206;
int var3 = 365;
int var4 = 0xB3;
Systen.out.println(var1); // 11
Systen.out.println(var2); //134
Systen.out.println(var3); //365
Systen.out.println(var4); //179
다음 예제는 byte타입 변수에 허용 범위를 초과한 값을 대입한 경우 컴파일 에러가 발생하는것을 볼 수 있다.
byte var = 128; // 컴파일 에러 발생 ( Type mismatch : cannot convert from int to byte)
기본적으로 컴파일러는 정수 리터럴을 int타입으로 간주한다.
따라서 정수 리터럴이 int허용범위를 초과할 경우, long타입임을 컴파일러에게 알려주어야한다.
-> 방법 : 정수 리터럴 뒤에 소문자 l 이나 대문자 L을 붙인다.(일반적으로 숫자 1과 혼동하지않기위해 대문자 사용)
long var = 30000000000; //컴파일에러
long var = 30000000000L;
long타입 변수에 정수리터럴 저장할 때 반드시 L을 붙여야 하는건 아니다!
정수 리터럴이 int허용 범위 이내라면 L을 붙이지 않아도 된다.
하나의 문자를 작은 따옴표(')로 감싼 것 = 문자 리터럴
문자리터럴은 유니코드로 변환되어 변수에 저장된다.
유니코드는 세계 각국의 문자를 2byte로 표현할 수 있는 숫자(0~65535)로 매핑한 국제 표준 규약
ex) 'A' = 65
'B' = 66
'가' = 44032
유니코드는 정수이므로 char도 정수 타입에 속한다.
그래서 char변수에 작은 따옴표(')로 감싼 문자가아니라 10진수 또는 16진수 형태로 유니코드를 저장할 수 있다.
char c = 65; //10진수, 'A'의미
char c = 0x0041 //16진수, 'A'의미
❓의문점
왜 10, 16진수만 되는거지?
문자 리터럴을 int타입에 저장할 경우
작은 따옴표(')로 감싼 문자 리터럴은 유니코드로 변환되기 때문에 int타입 변수에도 저장할 수 있다.
char 타입 변수에 저장하면 자동으로 문자로 매핑되어 출력되지만, int타입 변수에 저장하면 유니코드 자체가 출력된다.
char var1 = 'A';
int var2 = 'A';
Systen.out.println(var1); //A
Systen.out.println(var2); //65
- 유니코드 표현
자바의 유니코드 표현은 \u 다음 4자리의 16진수를 사용해 문자를 나타내는 표기 방법이다.
char c3 = '\u0041'
-> 16진수로 저장
System.out.println(c3); //A
System.out.println('\u0041'); //A
System.out.println('\u0061'); //a
❓ 의문점
여기서 말하는 유니코드 표현은 16진수앞에
\u
가 붙고,''
안에 이것들을 넣는데, 앞에서 '10진수 또는 16진수 형태로 유니코드를 저장할 수 있다'고 이야기할 때 예시를 보면char c = 0x0041
로 표현을 한다. 이 차이는 뭘까? 그리고 유니코드 표현은 꼭 작은따옴표안에 넣어야하는건가?
->
이렇게 코드를 직접 돌려보니, 아래의 결과가 나왔다. (f는 지우고 실행)
- 우선 둘이 다른건지 뭔지 이해가 잘안되고 궁금했는데, 코드를 보고 생각해보니 말 그대로 표현의 차이다.
16진수로 표현하기위해서0x
를 앞에쓰고 숫자를 적는것이다. (물론 c의 예시0x0041
을0x41
로 쓰고 값을줘도 결과가 동일하다)
그리고 이렇게 따옴표없이 앞에0x
를 작성하면 자바에서 이를 정수 리터럴로 인식하며, 인식한 값을 char 형태의 변수에 넣기위해 자동으로 문자로 매핑되는것이다.
다음으로''
안에\u
로 시작하며 뒤에 4자리 16진수를 사용하는 표기법은 말 그대로 유니코드의 정해진 표현법인것이다!
작은따옴표 (')로 감싼 문자는 char 타입 변수에 저장되어 유니코드로 저장되지만, 큰 따옴표(")로 감싼 문자 또는 여러개의 문자들은 유니코드로 변환되지 않는다.
이렇게 큰 따옴표로 감싼 문자들을 문자열이라고 한다.
작은 따옴표와 큰 따옴표는 컴파일러가 문자 리터럴과 문자열 리터럴을 구별하는 기호로 사용된다.
String 타입은 기본 타입이 아니고, 클래스 타입이다.
[이스케이프 문자]
문자열 내부에 역슬래시(\)가 붙은 문자를 사용할 수 있는데, 이것을 이스케이프 문자라고 한다.
이스케이프 문자를 사용하면 문자열 내부에 특정 문자를 포함시킬 수 있다.
ex) 문자열 식별기호가 아닌, 데이터로써 큰 따옴표를 사용하고싶다면 \"
이렇게 사용한다.
String str = "나는 \"자바\"를 좋아한다.";
System.out.println(str);
//나는 "자바"를 좋아한다.
또한 이스케이프 문자를 사용하면 출력을 제어할 수 있다.
ex) 탭만큼 띄우기(\t), 개행(\n)
String str = "나는\t자바\t를 좋아한다.";
System.out.println(str);
//나는 자바 를 좋아한다.
String str = "홍길동\n자바";
System.out.println(str);
//홍길동
//자바
이스케이프 문자 | 용도 |
---|---|
\t | 탭만큼 띄움 |
\n | 줄바꿈 |
\r | 캐리지리턴(커서를 행 맨 앞 위치로 복귀시키는 것) |
\" | "출력 |
\' | '출력 |
\\ | \출력 |
\u16진수 | 16진수 유니코드에 해당하는 문자 출력 |
소수점이 있는 실수 리터럴을 저장할 수 있는 타입
타입 | 메모리 사용 크기 | 저장되는 값의 범위(양수 기준) | 정밀도(소수점 이하 자리) |
---|---|---|---|
float | 4byte | 1.4*10^(-45) ~ 3.4*10^38 | 7자리 |
double | 8byte | 4.9*10^(-324) ~ 1.8*10^308 | 15~16자리 |
double의 정밀도가 float의 정밀도보다 2배 정도 높기때문에 더 정확한 데이터 저장이 가능하다.
(유효자릿수가 뜻하는 것은 정밀도를 뜻한다. 즉, 몇자리 까지 오차없이 표현할 수 있는가이다.)
소스코드에서 소수점이 있는 숫자 리터럴은 10진수로 인식한다.
0.25 -3.14
또한 알파벳 소문자 e 또는 대문자 E가 포함되어있는 숫자 리터럴은 지수와 가수로 표현된 소수점이있는 10진수 실수로 인식한다.
5e2 -> 5.0*10^2 = 500.0
0.12E-2 -> 0.12*10^(-2) = 0.0012
자바는 실수 리터럴을 기본적으로 double타입으로 해석하기때문에 double 타입 변수에 저장해야한다. float 타입 변수에 저장하면 컴파일에러가 발생한다.
실수를 float타입에 저장하고싶으면 리터럴 뒤에 소문자 f나 대문자 F를 붙여 컴파일러가 float타입임을 알 수 있도록 해야한다.
public static void main (String[] args) throws java.lang.Exception
{
float var4 = 0.1234567890123456789f;
double var5 = 0.1234567890123456789;
System.out.println(var4);
System.out.println(var5);
}
-> float형은 7자리가 유효자리수이기때문에, 소수점이하 8자리까지 나타나고 이후는 잘리는데 소수점이하 9자리에서 반올림하였다.
-> double형은 16자리가 유효자리수이기때문에, 소수점이하 17자리까지 나타나고 이후는 잘리는데 소수점이하 18자리에서 반올림하였다.
자바는 참과 거짓을 의미하는 논리 리터럴로 true false를 사용한다.
boolean의 크기는 1byte이다.
이 타입은 주로 두 가지 상태값에 따라 조건문과 제어문의 실행 흐름을 변경하는데 사용한다.
출처
혼자 공부하는 자바