목차
- 변수 명명 규칙
1-1. 컴파일 에러를 발생시키는 규칙
1-2. 개발자간 암묵적 사용 규칙 - 상수
2-1. 상수 선언
2-2. 상수 초기화
2-3. 상수 명명 규칙 - 변수 사용 시 유의점
3-1. 오버플로우와 언더플로우
3-2. 형변환
1. 변수 명명 규칙
1-1. 컴파일 에러를 발생시키는 규칙
- 컴파일 에러(compile error)란 문법적으로 올바르지 않은 문법적 오류를 뜻한다. 이클립스 작업 환경에서 빨간 줄이 가는 것을 말한다.
- 개발자가 프로그래밍 언어를 사용해 .java 파일을 만들면 compile 통해 JVM이 .class파일의 byte code를 읽어가 운영체제 위에서 작동한다. 이 compile 과정에서 발생한 오류가 바로 컴파일 에러이다.
컴파일 에러A.
같은 범위 안에서는 동일한 변수명을 가질 수 없다.
- 같은 메인클래스에서 동일한 이름의 변수 year를 사용할 수 없는 예시이다.
package com.reminder.variable;
public class variable03 {
public static void main(String[] args) {
int year = 2021;
// int year = 2021;
}
}
에러 메시지 : Duplicate local variable year
컴파일 에러B.
예약어는 사용할 수 없다.
- 예약어란 int, double 등의 자료형 이름이나 true, false와 같이 프로그래밍 언어의 구문에 사용되는 단어들을 말한다.
abstract | default | if | package | this |
assert | do | goto | private | throw |
boolean | double | implements | protected | throws |
break | else | import | public | transient |
byte | enum | instanceof | return | true |
case | extends | int | short | try |
catch | false | interface | static | void |
char | final | long | strictfp | volatile |
class | finally | native | super | while |
const | float | new | switch | |
continue | for | null | synchronized |
▲ 표1-1. 자바에서 사용되는 주요 예약어
컴파일 에러C.
대소문자를 구분한다.
- 대소문자를 구분하기에 True는 사용 가능하지만 예약어인 true는 사용할 수 없다.
boolean True = true;
// boolean true = true;
// int int = 5;
에러 메시지 : Duplicate local variable $missing$
컴파일 에러D.
숫자로 시작할 수 없다.
- 처음 시작만 숫자로 하지 않으면 변수명에 숫자 사용이 가능하다.
int year1 = 2015;
// int 1year = 2015;
에러 메시지 : Syntax error on token "1", delete this token
컴파일 에러 E.
특수기호는 '_'와 '$'만 사용 가능하다.
- _와 $는 변수명의 시작, 중간, 끝 어디에도 쓰일 수 있다.
- _와 $ 외 다른 특수문자는 사용이 불가하다.
// int ye@ar = 2021;
int year_ = 2021;
int $harp = 20;
✅ 변수 명명 시 컴파일 에러가 발생하는 사례들을 설명할 수 있다.
1-2. 암묵적 사용 규칙
- 컴파일 에러에는 해당하지 않지만 개발자간 암묵적 사용 규칙들이다. 처음 습관을 들일 때 이렇게 잡아가면 좋다.
암묵적 규칙A.
변수명은 적당한 길이를 사용한다.
- 변수명의 길이 제한은 없다. 하지만 적당한 길이를 고수하는 것이 좋다.
int abcdefghijklmnopqrsehkdsnddsjhasjsadsaeurrklejrjkhdsd;
암묵적 규칙B.
합성어 사용 시 Camel-Case 적용한다.
- 변수에는 의미를 부여하므로 합성어가 될 경우가 있다. 이처럼 단어와 단어간 결합이 일어나면 첫 단어는 소문자, 두 번째 단어는 그 시작을 대문자로 쓴다. 단어 사이 구분을 위해 사용하는 camel-case이다. 단어간에 연결된 모양새가 낙타 등처럼 생겼다하여 이렇게 이름 지어졌다.
int maxHeight = 200;
int minHeight = 130;
암묵적 규칙C.
언더스코어를 사용하지 않는다.
- 띄어쓰기는 사용할 수 없으며, 단어 사이를 구분하기 위해 언더스코어(_)를 사용하는 일도 없다.
- 대신에 camel-case를 적용할 수 있다.
String user_mail;
String userMail;
암묵적 규칙D.
한글 변수명은 권장되지 않는다.
- 한글로도 쓰일 수는 있으나 통용되기 어려운 환경을 고려하여 권장되지는 않는다.
int 자음;
int 모음;
암묵적 규칙E.
값의 의미를 명확히 표현하도록 한다.
- int a, int b와 같이 간략히 적어 쓰일 수는 있으나 그 뜻을 알 수가 없다. 변수에 든 값의 의미를 보다 분명히 표현할 수 있도록 하는 것이 좋다.
String s;
String userName;
암묵적 규칙F.
전형적인 변수명이 있다면 가급적 사용한다.
- 작성자만 알아볼 수 있는 독창적인 변수명보다는 누구나 변수의 의미를 이해할 수 있게끔 작성한다.
int sum = 0;
int max = 10;
int min = 0;
int count = 10;
암묵적 규칙G.
명사형으로 작성한다.
- 동사보다는 명사를 사용하는 것이 권장된다.
String eat;
String menu;
암묵적 규칙H.
boolean형은 가급적 긍정형으로 네이밍한다.
- true 혹은 false 중 하나로 답을 내는 boolean형의 경우 같은 상태를 나타내더라도 긍정형으로 묻는 질문과 부정형으로 묻는 질문에서 뉘앙스의 차이가 생기게 마련이다.
boolean isOn = true;
boolean isOff = false;
✅ 변수 명명 규칙을 이해하고 있다.
✅ 개발자간 암묵적으로 사용되는 변수 명명 규칙들을 이해하고 있다.
2. 상수(constant)
- 프로그램 실행되는 동안 값이 고정되어 변경할 수 없는 메모리 공간을 말한다.
2-1. 상수 선언
- 선언 방법은 아래와 같다. 변수와 달리 final을 쓴다는 것이 특징이다.
final double PI;
2-2. 상수 초기화
- 선언과 동시에 초기화 또는 선언 후 초기화 모두 가능하다.
- 초기화 이후에는 다른 데이터를 대입할 수 없다!
PI = 3.141592;
// PI = 3.14;
에러 메시지 : The final local variable PI may already have been assigned
2-3. 상수 명명 규칙
- 변수와 기본 규칙은 동일하나, 아래와 같은 암묵적 규칙의 차이가 있다.
- 영문 대문자 또는 숫자를 사용한다. 소문자를 사용하더라도 컴파일 에러 대상은 아니다. 다만 변수와의 구분을 위해 대문자 사용이 권장될 뿐이다.
final int YEAR1 = 2021;
final int YEAR2 = 2022;
final int year3 = 2023; // 컴파일 에러 대상은 아니다. 변수와의 구분을 위해 대문자 사용된다.
- 단어 사이 연결은 언더스코어(_)를 사용한다. camel case 사용 가능하나, 변수와의 구분을 위해 언더스코어 사용된다.
final int MAX_WIDTH = 2000;
final int MIN_WIDTH = 1300;
final int minWidth = 1300; // camel case 사용 가능하나, 변수와의 구분을 위해 언더스코어 사용된다.
✅ 상수를 이해하고 선언할 수 있다.
✅ 상수 명명 시 특징들을 설명할 수 있다.
3. 변수 사용시 유의점
3-1. 오버플로우와 언더플로우
- byte형을 예로 들 때 최대 저장 범위인 127에 +1을 하면 사인 비트(sign bit, 음수와 양수를 뜻하는 +/-부호)를 침범해 반전시키게 되는데 이를 오버플로우(overflow)라고 한다.
- 00~59까지 표현하는 전자시계에서 23:59:59였던 시간이 1초 지나면 00:00:00 되듯이 나타낼 수 있는 값이 초과하면 발생하는 현상이다.
byte num1 = 127;
System.out.println("byte의 최대 저장 범위 = " + num1);
num1++;
System.out.println("byte의 최대 저장 범위 + 1 = " + num1);
byte의 최대 저장 범위 = 127
byte의 최대 저장 범위 + 1 = -128
- 언더플로우(underflow)는 오버플로우의 반대를 말하는 것으로, 최소 범위보다 작은 값을 출력시켰을 때 발생한다.
byte num2 = -128;
System.out.println("byte의 최소 저장 범위 = " + num2);
num2--;
System.out.println("byte의 최소 저장 범위 - 1 = " + num2);
byte의 최소 저장 범위 = -128
byte의 최소 저장 범위 - 1 = 127
- 이를 논리적 에러라고 한다. 오버플로우, 언더플로우 발생 시 별도의 컴파일 에러나 런타임 에러가 발생하지 않아 미리 예측하고 더 큰 자료형에 결과값을 받아 처리해야 한다.
int num3 = 100_000_000;
int num4 = 30_000_000;
int intMulti = num3 * num4;
System.out.println("intMulti = " + intMulti); // 논리적 에러의 예.
// long longMulti = (long)(num3 * num4); // int 값끼리 먼저 연산이 일어나므로 값은 여전히 -296517632
long longMulti = (long)num3 * num4; // 정상 출력된 예.
System.out.println("longMulti = " + longMulti);
intMulti = -296517632
longMulti = 3000000000000000
✅ 오버플로우와 언더플로우를 이해하고 있다.
✅ 논리적에러의 경우 미리 예측하고 더 큰 자료형에 결과값을 받아 처리하는 것이 해결 방법임을 이해하고 있다.
3-2. 형변환(type casting)
- 형변환이란 데이터의 자료형을 바꾸는 것으로 여기서 형은 자료형(type)을 말한다.
- 형변환 적용 대상에서 boolean형은 제외된다. 논리형은 형변환 할 수 없다.
자동A. 정수끼리의 자동 형변환
- 작은 자료형에서 더 큰 자료형으로 옮겨가는 경우 데이터 손실이 없어 자동 형변환 처리된다.
byte bnum = 10;
short snum = bnum;
int inum = snum;
long lnum = inum;
System.out.println("lnum = " + lnum);
lnum = 10
- 더 큰 자료형에 맞춰 연산된다. 아래 예시에서는 long형에 맞춰 연산됐기 때문에 int형에 담을 수 없는 것이다.
int num1 = 50;
long num2 = 60L;
// int sum = num1 + num2;
long sum = num1 + num2;
System.out.println("num1 + num2 = " + sum);
자동B. 실수끼리의 자동 형변환
- float(4 byte) → double(8 byte)로 옮겨가는 것이므로 자동 형변환된다.
float fnum = 4.0f;
double dnum = fnum;
System.out.println("dnum = " + dnum);
dnum = 4.0
- 정수와 실수간 연산은 실수로 반환된다.
- 모든 정수는 모든 실수로 자동 형변환 될 수 있다.
❗ long(8 byte) → float(4 byte) 자동 형변환 가능
실수형 저장 방법이 지수부, 가수부로 나누어져 있어 long형보다 float형의 저장 범위가 더 넓기 때문이다.
long num3 = 4L;
float num4 = num3;
float result = num3 + num4;
System.out.println("num4 = " + num4);
System.out.println("result = " + result);
num4 = 4.0
result = 8.0
자동C. 문자형의 자동 형변환
- 문자형은 int형으로 자동 형변환된다.
char ch1 = 'A';
int charNumber = ch1;
System.out.println("'A'의 유니코드 = " + charNumber);
char ch2 = 97;
System.out.println("97 to char = " + ch2);
'A'의 유니코드 = 65
97 to char = a
필요에 따라 강제 형변환 역시 가능하다. 강제 형변환 시에는 데이터 손실에 유의하여 사용하도록 한다.
논리형 boolean은 강제 형변환도 할 수 없다.
강제A. 정수간 강제 형변환
long lnum = 8L;
int inum = (int)lnum;
short snum = (short)inum;
byte bnum = (byte)snum;
강제B. 실수간 강제 형변환
double dnum = 8.0;
float fnum = (float)dnum;
강제C. 실수에서 정수로 변경 시 강제 형변환
- 소수점자리 탈락이 발생한다.
float width1 = 234.56f;
int width2 = (int)width1;
강제D. 문자형을 byte / short로 강제 형변환
- 문자형이 int보다 작은 크기의 자료형인 byte, short에 저장될 때 강제 형변환 한다.
❗ char(2 byte) → short(2 byte) 강제 형변환 필요!
char(2 byte)와 short(2 byte)는 byte 크기는 같지만, 표현하는 값의 범위가 다르다. 정수형 short형은 부호를 가지기에 -32,768~32,767까지 해당하고, 문자형 char형은 0~65,535 값의 크기만 표현한다. 따라서 short형은 char가 가지는 일부 범위를 표현하지 못한다.
char형은 int, long형으로 형변환 가능하며 byte, short형으로는 강제 형변환이 필요하다.
✅ 형변환이 필요한 이유에 대해 설명할 수 있다.
✅ 자동 형변환이 되는 조건에 대해 설명할 수 있다.
✅ 강제 형변환이 필요한 경우에 대해 설명할 수 있다.
'Java' 카테고리의 다른 글
[JAVA] 3-1. 메소드, 패키지, 임포트 (0) | 2021.12.22 |
---|---|
[JAVA] 2. 연산자 (0) | 2021.12.21 |
[자바의 정석] Ch 2. 변수 예제 응용 학습 (0) | 2021.12.19 |
[자바의 정석] Ch 2. 변수 연습문제 풀이 (0) | 2021.12.18 |
[JAVA] 1-1. 리터럴과 변수 (0) | 2021.12.17 |