본문 바로가기

2022 여름방학 자바 스터디

[이것이 자바다] Ch02. 변수와 타입

2.1. 변수

2.1.1. 변수란?

- 하나의 값을 저장할 수 있는 메모리 공간

2.1.2. 변수의 선언

- 변수 선언 시 타입과 이름을 설정해야 한다.

int age;
double value;

int x, y, z;
📍변수의 작성 규칙
- 첫 번째 글자는 문자이거나 $, _ 이어야 하고, 숫자로 시작할 수 없음
- 영어 대소문자 구분
- 첫 문자는 영어 소문자로 시작하되, 다른 단어가 붙을 경우 첫 문자를 대문자로 ex) firstName
- 문자 길이의 제한은 없음
- 자바 예약어 사용 불가

2.1.3. 변수의 사용

- 변수 값을 저장할 때는 대입 연산자(=)를 사용함.

int score; // 변수 선언
score = 90; // 값 저장

int score = 90; // 변수를 선언함과 동시에 초기화

 

- 리터럴? 소스 코드 내에서 직접 입력된 값

 

🔖 정수 리터럴 |  byte, char, short, int, long

  • 소수 점이 없는 정수 리터럴은 10진수로 간주
  • 0으로 시작되는 리터럴은 8진수로 간주
  • 0x 또는 0X로 시작하고 0~9 숫자나 A, B, C, D, E, F로 구성된 리터럴은 16진수로 간주

🔖 실수 리터럴 |  float, double

  • 소수 점이 있는 리터럴은 10진수 실수로 간주
  • 대문자 E 또는 소문자 e가 있는 리터럴은 10진수 지수와 가수로 간주 ex) 5E7 = 5 * 10^7

🔖 문자 리터럴 |  char

  • 작은 따옴표로 묶은 텍스트는 하나의 문자 리터럴로 간주
  • 역슬래쉬가 붙은 문자 리터럴은 이스케이프 문자
이스케이프 문자 용도 유니코드
\t 수평 탭 0x0009
\n 줄 바꿈 0x000a
\r 리턴 0x000d
\" " 0x0022
\' ' 0x0027
\\ \ 0x005c
\u16진수 16진수에 해당하는 유니코드 0x0000 ~ 0xffff

 

🔖 문자열 리터럴 |  String

  •  큰 따옴표로 묶은 텍스트는 문자열 리터럴로 간주
  • 큰 따옴표 안에 텍스트가 없어도 문자열 리터럴로 간주됨
  • 문자열 리터럴 내부에서도 이스케이프 문자를 사용할 수 있음
"탭 만큼 이동 \t 합니다."
"한줄 내려 쓰기 \n 합니다."

 

🔖 논리 리터럴 | boolean

  • true/false는 논리 리터럴로 간주

 

2.1.4. 변수의 사용 범위

- 메소드 블록 내에서 선언된 변수? '로컬 변수'

- 로컬 변수는 메소드 실행이 끝나면 메모리에서 자동으로 없어짐

- 변수는 메소드 블록 내 어디든 선언 가능

- 하지만, 변수 사용은 제한: 변수는 선언된 블록 내에서만 사용이 가능

 

2.2. 데이터 타입

2.2.1. 기본 타입

값의 종류 기본 타입 메모리 사용 크기
정수 byte 1 byte 8 bit
char 2 byte 16 bit
short 2 byte 16 bit
int 4 byte 32 bit
long 8 byte 64 bit
실수 float 4 byte 32 bit
double 8 byte 64 bit
논리 boolean 1 byte 8bit

byte는 -128부터 127까지만 저장 가능

 

2.2.2. 정수타입

📍 byte

- GarbageValueExample :

byte 변수는 127을 넘어가는 순간 최솟값인 -128부터 다시 저장되고,

int 타입의 변수는 정상적으로 1 증가된 값을 계속 저장하는 것을 볼 수 있는 예제

public class GarbageValueExample {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		byte v1 = 125;
		int v2 = 125;
		
		for(int i=0; i<5; i++) {
			v1++;
			v2++;
			System.out.println("v1: " + v1 + "\t" + "v2: " + v2);
		}

	}

 

📍 char

- char 타입 변수에 작은 따옴표로 감싼 문자를 대입하면 해당 문자의 유니코드가 저장됨

- char 타입에는 음수를 저장할 수 없음 (0 ~ 65535까지 가능)

char var1 = 'A'  // 유니코드 0x0041
char var2 = 'B'  // 유니코드 0x0042
char var3 = '가'  // 유니코드 0xAC00
char var4 = '나'  // 유니코드 0xAC01

- 변수 안에 작은 따옴표로 감싼 문자가 아닌, 직접 유니코드 정수값을 저장할 수도 있음

char c = 65;
char c = '\u0041'

- char 변수에 저장된 유니코드를 알고 싶다면 char 타입 변수를 int 타입 변수에 저장하면 됨

char c = 'A';
int uniCode = c;

 

✅ String

- char 타입은 단 하나의 문자만 저장함

- 만약 문자열을 저장하고 싶다면, String 타입을 사용

- 큰 따옴표로 감싸야 함

String name = "김우리";

- String은 기본 타입이 아닌, 클래스 타입으로, String 변수는 참조 변수임

- 문자열을 String 변수에 대입하면 문자열이 변수에 직접 저장되는 것이 아니라,

  String 객체가 생성되고 String 변수는 String 객체의 번지를 참조하게 되는 것

- char 타입의 변수에 빈 문자를 대입하면 컴파일 에러가 발생하지만, String은 빈 문자 가능

- char 타입에서 공백으로 초기화하는 것은 가능

char c = ''; // 컴파일 에러
char c = ' '; // 가능

String str = ""; // 가능

 

📍 short

- C언어와의 호환을 위해 사용되며, 비교적 자바에서는 잘 사용되지 않는 타입

 

 

📍 int

- 정수값을 직접 코드에 입력할 경우 8진수, 10진수, 16진수 표현 가능

 

📍 long

- 수치가 큰 데이터를 다루는 프로그램에서 필수적으로 사용됨

- long 타입의 변수를 초기화할 때는 정수값 뒤에 소문자 l이나 대문자 L을 붙일 수 있음

- int 타입의 저장 범위를 넘어서는 큰 정수는 반드시 l이나 L을 붙여 표시해야 함

- 일반적으로 소문자 l은 1과 비슷해 혼돈하기 쉬워, 대문자 L 사용

 

2.2.3. 실수 타입

- 정수 타입과는 다른 저장 방식 때문에 정수 타입보다 훨씬 큰 범위의 값 저장 가능

- 부동 소수점 방식으로 저장

- float보다 double이 더 정밀한 값 저장 가능

- 자바는 실수 리터럴의 기본 타입을 double로 간주

- float 타입 변수를 저장할 때는 리터럴 뒤에 소문자 f나 대문자 F를 붙여야 함

double var1 = 3.14;
float var2 = 3.14; // 컴파일 에러 
float var3 = 3.14f;

- 만약 정수 리터럴에 10의 지수를 나타내는 E를 포함하고 있다면 실수 타입 변수에 저장해야 함

int var6 = 300000;
double var7 = 3e6;
float var8 = 3e6f;
double var9 = 2e-3; // 0.002

 

2.2.4. 논리타입

- boolean 타입은 두 가지 상태값을 저장할 필요성이 있을 경우에 사용

- 조건문과 제어문의 실행 흐름을 변경하는 데 주로 이용

 

2.3. 타입변환

- 데이터 타입을 다른 데이터 타입으로 변환하는 것

- 자동(묵시적) 타입 변환과 강제(명시적) 타입 변환

2.3.1. 자동 타입 변환

- 프로그램 실행 도중에 자동적으로 일어나는 것

- 작은 크기를 가지는 타입이 큰 크기를 가지는 타입에 저장될 때 발생 (기준은 메모리 크기)

🌟 크기 별 타입 정리
byte(1) < short(2) < int(4) < long(8) < float(4) < double(8)

- 자동 타입 변환이 발생되면 변환 이전의 값과 변환 이후의 값은 동일함 (손실 없이 그대로 보존)

- 정수  실수 타입으로 변환하는 것은 무조건 자동 타입 변환이 됨

- 실수 타입으로 변환된 이후에는 .0이 붙은 실수값이 됨

 

예외! (주의)

- char의 범위는 0 ~ 65535이므로 음수가 저장될 수 없음

- 따라서, 음수가 저장될 수 있는 byte 타입을 char 타입으로 자동 변환시킬 수 없음

byte byteValue = 65;
char charValue = byteValue; // 컴파일 에러

char charData = (char)byteData; // 강제 타입 변환

 

2.3.2. 강제 타입 변환

- 강제적으로 큰 데이터 타입을 작은 데이터 타입으로 쪼개어 저장하는 것

- 캐스팅 연산자() 사용

 

 

✅ 주의1

- 사용자로부터 입력받은 값을 변환할 때 값의 손실이 발생하면 안 됨

- 강제 타입 변환을 하기 전에 우선 안전하게 값이 보존될 수 있는지 검사하는 것이 좋음 (Byte.MAX_VALUE 사용)

public class CheckValueBeforeCasting {

	public static void main(String[] args) {
		int i = 128;
		
		if(i < Byte.MIN_VALUE || i > Byte.MAX_VALUE) {
			System.out.println("byte 타입으로 변환할 수 없습니다.");
			System.out.println("값을 다시 확인해주세요.");
		} else {
			byte b = (byte)i;
			System.out.println(b);
		}
	}

}

 

✅ 주의2

- 정수 타입을 실수 타입으로 변환할 때 정밀도 손실을 피해야 함

public class FromIntToFloat {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int num1 = 123456780;
		int num2 = 123456780;
		
		float num3 = num2;
		num2 = (int)num3;
		
		int res = num1 - num2;
		System.out.println(res);
	}

}

/*
예상된 값은 0인데 결과값은 -4가 나옴
*/

- 해결책은 double 타입을 사용하는 것

public class FromIntToDouble {

	public static void main(String[] args) {
		int num1 = 123456780;
		int num2 = 123456780;
		
		double num3 = num2;
		num2 = (int)num3;
		
		int res = num1 - num2;
		System.out.println(res);
	}

}

 

2.3.3. 연산식에서의 자동 타입 변환

- 서로 다른 타입의 피연산자가 있을 경우 두 피연산자 중 크기가 큰 타입으로 변환된 후 연산을 수행

int intValue = 10;
double doubleValue = 5.5;

double res = intValue + doubleValue; // res에 15.5가 저장

 

- 만약 int 타입으로 꼭 연산을 해야 한다면 double 타입을 int 타입으로 강제 변환하고 연산 수행

int intValue = 10;
double doubleValue = 5.5;

double res = intValue + (int)doubleValue; // res에 15가 저장

 

- 자바는 정수 연산인 경우 int 타입을 기본으로 함

- 예를 들어, char 타입의 연산 결과는 int 타입으로 산출되므로, int 타입 변수에 결과를 저장해야 함

- 연산의 결과를 문자로 출력하거나 저장하기 위해서는 int 결과값을 char 타입으로 강제 변환해야 함

char ai = 'A';
int res = ai + 1;

char na = (char)res; // 'A'보다 유니코드가 1 큰 'B'가 저장됨.