JAVA 식별자와 예약어 및 데이터 타입
식별자와 예약어
식별자 생성 규칙
- 첫 문자는 A-Z, a-z, _, $, 유니코드로 시작해야 함
- 특수문자 사용불가(!, @, #, %, &, * 등)
- 대소문자를 구별하고, 길이에 제한이 없음
- 예약어를 포함할 수 있으나, 예약어만을 사용할 수 없음
- 숫자를 사용할 수 있으나, 첫 문자에는 숫자 사용 불가
- 클래스 이름은 대문자, 메서드 이름은 소문자, 변수는 소문자, 상수는 대문자로 시작
예약어
- 시스템에서 일정 특성을 가진 언어로 등록된 것으로 데이터 타입이나 프로그램 정의를 위해 사용됨
- 자바의 모든 예약어는 소문자로 이루어짐
자바 데이터 타입
Primitive Type(기본형)
- 할당된 공간에 실제 value가 들어오는 경우
- 더이상 쪼개질 수 없는 원자성의 데이터
-
논리형
- boolean(1bit) : true or false(0 또는 1로 표현 불가능)
-
문자형
기본 타입 메모리 용량 저장 가능 값 범위 char 2byte(16bit) 0 ~ 2^16 - 1(0 ~ 65,535) - 아스키코드 표현 가능
'a'
와 같이 작은 따옴표 안에 포함된 문자로 표현
-
정수형
기본 타입 메모리 용량 저장 가능 값 범위 byte 1byte(8bit) -2^7 ~ 2^7 - 1(-128 ~ 127) short 2byte(16bit) -2^15 ~ 2^15 - 1(-32,768 ~ 32,767) int 4byte(32bit) -2^31 ~ 2^31 - 1(-2,147,483,648 ~ 2,147,483,647) long 8byte(64bit) -2^63 ~ 2^63 - 1(어마어마하게 큰 수 표현) - 부호형이라는 특징이 있음(0이면 양수, 1이면 음수)
- 형을 명시하지 않을 경우 기본형인 int형으로 정의
Javalong i = 100000000000L; // 정수형의 기본형인 int로 표현할 수 있는 수의 범위를 넘어가는 값을 저장하기 위해서는 long형으로 만들어줘야함 System.out.println(i); /* 실행 결과 */ 100000000000
정수형의 기본형은 int형이므로 long형으로 표현할 경우 값 뒤에
l
혹은L
를 붙여줘야 함 -
실수형
기본 타입 메모리 용량 저장 가능 값 범위 float 4byte(32bit) (+/-)1.4E-45 ~ (+/-)3.4028235E38 double 8byte(64bit) 어마어마하게 큰 수 표현 - 형을 명시하지 않을 경우 기본형인 double형으로 정의
- IEEE 부동 소수점 방식으로 표현하기때문에 더 큰 범위까지 표현할 수 있다는 장점이 있지만,
실수의 표현에서 오차가 존재한다는 단점이 있음
Javadouble d = 3.14F; // float형의 값 3.14을 double형의 변수에 저장 System.out.println(d); /* 실행 결과 */ 3.140000104904175
실수형의 기본형은 float형이므로 double형으로 표현할 경우 값 뒤에
f
혹은F
를 붙여줘야 함
Non-Primitive Type(참조형)
- 할당된 공간에 실제 값을 참조할 수 있는 reference가 들어오는 경우
-
클래스 타입
-
인터페이스 타입
-
배열 타입
자바 데이터 타입 변환(형변환)
- 데이터 타입의 크기순 정렬 :
byte < short < int < long < float < double
- float형의 경우 표현 범위가 long형보다 넓으므로 데이터 타입의 크기가 더 크다고 봄
-
묵시적 형변환(Promotion)
- 더 작은 데이터 단위에서 더 큰 데이터 단위로 변환 -> 데이터 손실 우려 없음
- 형변환 연산자를 사용하지 않아도 자동적으로 형변환이 이루어짐
Javalong j = 100000000000L; float f = j; // 묵시적 형변환(float = long) : float > long이므로 가능 System.out.println(f); /* 실행 결과 */ 9.9999998E10 // 단, 실수형의 경우 부동소수점 표기법에 의해 오차 발생 가능
-
명시적 형변환(Demotion)
- 더 큰 데이터 단위에서 더 작은 데이터 단위로 변환 -> 데이터 손실 우려
- 반드시 형변환 연산자를 사용하여 변환하고자 하는 데이터 타입을 명시해야 함
Javadouble d = 3.14F; int d2 = (int)d; // 명시적 형변환(int = double) : int < double이므로 명시 필수 System.out.println(d2); /* 실행 결과 */ 3 // 명시적 형변환은 값의 손실이 있을 수 있음
🧐 연산 과정에서 overflow가 발생하지 않는가?
Javaint price = 50000000; int amout = 100; /* 문제의 코드 */ long totalPrice = price * amout; /* 해결 코드 */ long totalPrice = (long)price * amout; System.out.println(totalPrice); /* 실행 결과 */ 5000000000
- 문제의 코드 : int*int=int 인데 5000000000이 int로 표현할 수 있는 범위를 넘어가므로 totalPrice에는 잘린 값이 저장되는 문제가 생김
- 해결 코드 : 서로 다른 타입간의 연산은 더 큰 타입을 따라가므로 long*long=long이 됨.
따라서 값이 잘리거나 변하지 않게하려면 연산시에 형변환 해주기!
Javaint[] score = {100, 92, 91}; double avg = 0.0; int sum = 0; for (s : score) { sum += s } /* 문제의 코드 */ avg = sum / score.length; /* 해결 코드 */ avg = (double)sum / score.length; System.out.println(avg); /* 실행 결과 */ 94.33333333333333
- 문제의 코드 : int/int=int 이므로 소수점 이하 값을 잃는 문제가 생김
- 해결 코드 : double/double=double 이 되어 소수점 이하의 값을 유지한 double 형의 값이 저장됨
값 복사와 주소 복사
기본형 변수와 참조형 변수
기본형 변수(값 복사)
Java
int score = 80; // score 변수에 80을 저장
int copyScore = score; // score 변수에 저장된 값을 copyScore 변수에 할당
- 메모리 상 다른 위치에 존재하는 두 개의 변수가 동일한 값을 가지게 됨
- 특정 변수의 값을 수정해도 다른 변수에는 영향을 미치지 않음
참조형 변수(주소 복사)
Java
int[] list = {10, 20, 30}; // list 변수에 일차원 배열 객체의 주소 값이 저장됨
int[] copyList = list; // list 변수에 저장된 주소 값을 copyList 변수에 할당
- 하나의 배열 변수를 두 개의 참조 변수가 참조하며 데이터를 공유함
- 특정 변수로 배열의 값을 수정하면, 동일한 객체를 참조하는 다른 변수도 수정된 값을 인식
기본형 : 값에 의한 호출(Call by Value)
Java
public class CallByValue {
public static void main(String[] args) {
int score = 10;
System.out.println("변경 전 :" + score);
changeScore(score);
System.out.prinln("변경 후 : " + score);
}
private static int changeScore(int score) {
score = 100;
System.out.println("변경된 score :" + score);
return score;
}
}
-> 실행 결과
변경 전 : 10
변경된 score : 100
변경 후 : 10 // 원래 score 변수 값이 변하지 않음
참조형 : 주소에 의한 호출(Call by Reference)
Java
public class CallByReference {
public static void main(String[] args) {
int[] scoreList = {10, 20, 30};
System.out.println("변경 전 :" + scoreList[0]);
changeScore(scoreList);
System.out.prinln("변경 후 : " + scoreList[0]);
}
private static int[] changeScore(int[] scoreList) {
scoreList[0] = 100;
System.out.println("변경된 score :" + scoreList[0]);
return scoreList;
}
}
-> 실행 결과
변경 전 : 10
변경된 score : 100
변경 후 : 100 // 동일한 배열의 메모리 주소를 공유하기 때문에, 원래 scoreList[0] 변수 값이 변함
매개변수로 객체 넘기기
- 객체가 다른 메서드를 호출할 때 단순히 값만 넘기고자 하는 경우 : 매개변수를 기본형으로 선언
- 메서드를 수행 이후에도 수행 결과를 유지하고자 하는 경우 : 매개변수를 참조형으로 선언