자바의 신을 읽으며 기초 개념을 다시 한번 짚고 넘어가는 시간을 보냈다.
마음 같아서는 1권에 나와있는 1장부터 18장까지 후루룩 읽고 싶은데 4장에서 잘 이해되지 않는 부분이 있어 이 부분은 특별히 포스팅해서 뇌리에 깊게 남기려고 한다.
4가지 존재하는 건 알겠는데 "변수"가 뭔데요?
영어로는 variable. (베리어블이라고 읽더라)
담아두는 것을 변수라고 한다. 그리고, 담아두는 것에는 항상 이름을 정해주어야 한다.
String name = "Liz";
name이라는 변수에 Liz라는 이름을 담아주었다.
그럼 그 4가지 변수가 뭔지 알아보자
위 변수들이 어떻게 쓰이는지 보여주기 위해 예제를 준비했다.
public Class School{
public static void main(String [] args){
School highSchool = new School();
int age = 18;
String name = "suzy";
}
}
위 코드에서 지역변수는 어떤 것일까?
바로, highSchool, age, name이 해당한다.
매개변수는 args이다.
public Class Concert{
int volume;
int visitPeople;
String musicTitle;
}
인스턴스 변수는 volume, visitPeople, musicTitle이다.
클래스 변수는 인스턴스 변수처럼 메소드 밖에, 클래스 안에 선언된 변수 중에서 타입 선언 앞에 static이라는 예약어가 있는 변수이다.
전체적인 예시 코드로 보자면
public Class Concert{
int 인스턴스_변수;
static int 클래스_변수;
public void method(int 매개_변수){
int 지역_변수;
}
}
위와 같다.
둘의 차이점은?
new를 사용해서 초기화하는 것을 참조 자료형, 그렇지 않고 바로 초기화가 가능한 것을 기본 자료형이라고 한다.
단, String은 참조 자료형이지만 new를 사용해서 객체를 생성하지 않아도 되는 유일한 타입이다.
byte: -128 ~ 127
short: -32,768 ~ 32,767
int: -2,147,483,648 ~ 2,147,483,647
long: -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807
char: 0('\u0000') ~ 65,535('uffff')
사실, 위 범위 외우는 거 오바 아닌가.
byte는 외우겠는데 나머지는 원주율 파이 외우듯이 외우고 다닐 수 없지 않을까.
혹시 바이너리라고 들어봤는가.
2진법이라고 컴퓨터에서 숫자를 표현할 때 가장 적절하다.
그래서, 모든 자바의 숫자 타입들은 2의 배수로 범위가 정해진다.
byte: -2⁷ ~ 2⁷-1
short: -2¹⁵ ~ 2¹⁵ - 1
int: -2³¹ ~ 2³¹ - 1
long: -2⁶³ ~ 2⁶³ -1
char: 0 ~ 2¹⁶ - 1
외우려거든 위처럼 2진수로 외우는 게 쉬울 것이다.
1 byte = 8 bit
byte는 8비트의 부호가 있는 타입이다.
컴퓨터는 0과 1밖에 모른다. 8비트라는 것은 0과 1로 표현할 수 있는 공간이 8개가 있다는 말이다.
이해하기 쉽게 그림으로 봐보자.
0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
---|
총 8 개 공간에 1과 0이 값에 따라 채워진다.
모든 공간이 0으로 채워지면 이 값은 0이다.
위 그림과같이 가장 오른쪽 값이 1이면 그 값은 얼마일까?
2⁷ | 2⁶ | 2⁵ | 2⁴ | 2³ | 2² | 2¹ | 2⁰ |
---|---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
모든 수의 0 제곱은 1이기 때문에 1X1을 하여 2⁰은 1이다.
그럼 오른쪽에서 두 번째값만 1인 경우는?
2⁷ | 2⁶ | 2⁵ | 2⁴ | 2³ | 2² | 2¹ | 2⁰ |
---|---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
2¹X1 = 2다
그럼 모두 1로 채워진다면?
2⁷ | 2⁶ | 2⁵ | 2⁴ | 2³ | 2² | 2¹ | 2⁰ |
---|---|---|---|---|---|---|---|
1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
2⁷x1 + 2⁶x1 +2⁵x1 + 2⁴x1 + 2³x1 + 2²x1 + 2⁰x1 = 255
이상하다. 분명 byte의 범위는 -128 ~ 127이랬는데
왜 127이 아닌 255가 나오지??
위 표에서 첫번째 칸을 다시 보자.
자바의 기본 자료형에 포함된 숫자들은 모두 부호가 있는 signed 타입들이다.
그런데 byte의 공간은 8개인데, 음수와 양수를 표현하려면 어떻게 해야 할까?
바로바로, 맨 앞에 있는 값이 0이면 양수, 1이면 음수로 정하기로 하였다.
그렇기에 2⁷ 칸은 음수와 양수를 구분하기 위한 공간이다.
그래서 양수의 최대값은 127이다.
2⁶x1 +2⁵x1 + 2⁴x1 + 2³x1 + 2²x1 + 2⁰x1 = 127
그렇다면 음수는 왜 -128일까?
2⁶ | 2⁵ | 2⁴ | 2³ | 2² | 2¹ | 2⁰ | |
---|---|---|---|---|---|---|---|
1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
맨 앞 칸은 부호를 담당한다고 했는데, 저렇게 되면 -0 아닌가?
아니다. -128이다.
byte, short, int, long 타입의 가장 앞의 값만 1인 것은 해당 타입의 최소값이고, 두번째 값부터 1로 채워져 있는 건 해당 타입의 최대값이다.
부호 | 2⁶ | 2⁵ | 2⁴ | 2³ | 2² | 2¹ | 2⁰ |
---|---|---|---|---|---|---|---|
0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
---- | --- | --- | --- | --- | --- | --- | --- |
1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
그리고 절대값만으로 따지면 최소값의 절대값이 최대값의 절대값보다 딱 1이 더 크다.
그럼 심화해서 들어가보자
byte byteMin = -128;
byte byteMax = 127;
byteMin = (byte)(byteMin-1);
이렇게 할 경우 byteMin 값은 몇일까?
-128에 -1이니까 -129? 라고 생각했겠지만 아니다.
2⁶ | 2⁵ | 2⁴ | 2³ | 2² | 2¹ | 2⁰ | ||
---|---|---|---|---|---|---|---|---|
byteMin | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
byteMax | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
위에 표를 보면 byteMin 값을 2진수로 표현하면 1000_0000인 값에서 1을 빼면 0111_1111이 된다. byteMax는 그럼 몇일까? 0111_1111인 값에서 1을 더하면 1000_0000이 된다.
즉, byte 최소갑에서 1을 빼면 최대값이, byte 최대값에서 1을 더하면 최소값이 나온다.
이건 수학적인 부분이라 2진수를 공부하든지 아니면 그냥 외우자.
동영상을 저장하거나 이미지를 저장할 때, 저장 데이터가 모두 int 타입일 경우 단순한 숫자 하나를 표현하기 위해 32개의 0과 1을 표시하기 위한 공간이 필요하다. 즉, byte 대비 4배의 저장 공간이 필요한 것이다. 그래서 데이터를 저장할 때 byte값들을 조합해서 사용한다. 그래야 적은 공간에 보다 많은 내용을 저장할 수 있다.
실제로 개발할 때 byte, short보다 int, long 사용하는 비율이 훨씬 많다.
왜냐하면 데이터를 저장할 목적이 아닌 계산하기 위한 목적으로 byte나 short를 사용하면 위에서 본 것처럼 원하지 않는 계산이 될 수도 있기 때문이다.
기본적으로 자바에서는 숫자를 명시하면 int로 생각한다.
그래서 long 타입 숫자를 명시적으로 지정해줄 때에는 반드시 숫자 가장 뒤에 L을 붙여주어야 한다!
long longMax = 91239812398129L;
소수점을 처리하기 위해 사용되는 것에는 float, double이 있다.
float은 32비트이고 double은 64비트이다.
※ 주의 ※
돈 계산처럼 중요한 부분에서는 이 타입들을 사용해서 안 된다.
왜냐하면, float과 double은 제공 가능한 범위를 넘어서면 값의 정확성을 보장하지 못하기 때문이다.
소수점 처리를 할 때 일반적으로 double을 많이 사용한다.
그리고 대량으로 소수점 자리수가 적은 데이터를 저장하려고 할 경우에는 float을 사용하면 된다.
float: 부호(1자리) + 지수(8자리) + 가수(23자리) = 32비트
double: 부호(1자리) + 지수(11자리) + 가수(52자리) = 64비트
char는 캐릭터라고 읽는다. char는 보통 문자열과 관련된 부분에서 사용한다.
그리고 정의할 때 홑따옴표를 사용한다.
public void checkChar(){
char charMin ='\u0000';
char charMax ='\uff ff';
System.out.println("charMin = ["+charMin+"]");
System.out.println("charMin = ["+charMax+"]");
}
수행 결과는 다음과 같다.
charMin=[ ]
charMax=[?]
charMin은 공백이 출력되었다.
int intValue = 'a';
System.out.println("intValue = ["+intValue+"]");
결과값은
intValue=[97]
이라고 찍힌다.
이유는 아스키코드 97의 값이 a이기 때문이다.
*아스키코드란?
옛날에 1byte 단위의 문자들을 만들었다. 여기에는 알파벳도 있고, 숫자도 있고, 기호도 있고, 각종 여러가지 값들이 있다. 각 문자마다 고정되어 있는 번호가 할당되어 있다. 방금 본 a라는 문자의 ASCII(아스키코드)값은 어떤 컴퓨터, 어떤 언어, 어떤 OS를 사용하더라도 97이다.
자바에서는 유니코드라는 2byte를 사용하기 때문에 ASCII가 할당된 값들이 먼저 나오고, 그 다음에 미리 정해져 있는 유니코드들이 존재한다. 더 자세한 사항은 구글에서 ASCII나 Unicode로 검색해보길 바란다.
char 값을 지정하는 방법
지역 변수로 기본자료형을 사용할 때는 기본값이 자동 적용되지 않기 때문에 반드시 값을 지정해야만 한다. 즉, 지역 변수를 만들어 놓고 사용하지 않을 때에는 초기화를 하지 않아도 되지만, 사용할 때에는 반드시 초기화를 해야 한다.
변수를 초기화하지 않고 컴파일하면 오류는 발생하지 않는다. 변수를 정의만 하고 사용하지 않을 경우에만 해당한다. 변수를 정의 후 사용할 경우 변수값을 초기화하지 않은 상태라면 바로 컴파일 에러가 발생한다.
즉, 지역 변수를 만들어 놓고 사용하지 않을 때에는 초기화를 안 해도 되지만, 사용할 때는 반드시 초기화해야 한다.
자꾸 지역변수 지역변수 하는데 클래스 인스턴스 변수 초기화 안 해주면 어떻게 되는데??
클래스 인스턴스 변수는 정의만하고 값을 할당하지 않을 경우 기본값을 자동으로 할당해주고 있다.
네가지 종류의 변수는 어떻게 구분할 수 있나요?
-> 변수의 종류는 변수를 선언한 위치와 static 선언 여부에 따라 달라진다.
변수의 이름을 지을 때 대문자로 시작해도 되나요?
-> 일반적인 변수의 이름은 소문자로 시작해야 하며, 두개 이상의 단어를 나열할 경우에는 두번째단어의 첫 문자를 대문자로 시작한다.
자료형에는 기본 자료형과 어떤 자료형이 있나요?
-> 자바의 타입은 "기본 자료형"과 "참조 자료형"이 존재한다.
기본 자료형에는 몇 가지가 있나요?
-> 기본 자료형은 byte, short, int, long, float, double, boolean, char의 8가지만 존재한다.
기본 자료형 중 정수형에는 어떤 것들이 있나요?
-> 기본 자료형 중 정수형은 byte, short, int, long, char로 총 5가지이다.
byte는 몇 비트(bit)로 되어 있나요?
-> 1 byte = 8 bit 이다.
byte는 왜 만들었을까요?
-> byte 타입은 적은 공간에 보다 많은 내용을 저장할 수 있도록 하기 위해서 만들어졌다.
int와 long 중 어떤 타입이 더 큰 숫자를 처리할 수 있나요?
-> 정수형 타입의 공간은 byte, short, int, long 순이며, 공간이 넓을 수록 더 큰 숫자를 표현할 수 있다.
소수점을 처리하는 타입은 어떤 것이 있나요?
-> 소수점은 float과 double로 처리할 수 있다.
char는 정수형인가요?
-> char도 정수형이다.
a라는 것을 char로 정의할 때 어떤 기호로 감싸주어야 하나요?
-> 소수점은 ' 로 감싸야 한다. 여기서 '는 "가 있는 키의 기호이며 키보드의 1 옆에 있는 키가 아니다.
true와 false 두 개의 값만을 가지는 타입은 어떤 것인가요?
-> boolean 타입은 true와 false만이 존재한다.