Java 스터디 2일차

프로그래밍/Java

2018. 10. 14. 12:45

반응형

※이 글은 2018/08/05 ~ 2018/08/27일까지 했던 자바 스터디 노트를 올려놓은 겁니다. ※

02-4 상수와 리터럴
 
상수 선언하기
상수는 항상 변하지 않는  (constant)입니다.
이때까지 배웠던 변수랑은 정반대의 의미를 가지고 있네요.
 
자바에서는 상수를 final 예약어를 사용해 선언한다고 합니다.
아래 코드는 예시입니다.

final double PI = 3.14; final int MAX_NUM = 100;

상수 이름은 대문자를 주로 사용하고, 여러 단어를 연결하는 경우에는,
 _ 기호를 사용해주면 보기 좋습니다.
 
가끔은 선언만 하고 사용하기 전에 값을 지정하기도 한답니다.
 

상수 사용하기

package chapter2; public class chapter2 { public static void main(String[] args) { final int MAX_NUM = 100; final int MIN_NUM; MIN_NUM = 0; System.out.println(MAX_NUM); System.out.println(MIN_NUM); //MAX_NUM = 1000; } }

6 코드가 선언과 동시에 초기화해주는 부분이다.
9 코드는 사용하기 전에 초기화를 시켜주고 (안 해주면 오류 발생)
14 코드는 오류 발생 부분이어서 주석 처리를 해주었다. (상수는 변하지 않는다.
  코드는 상수를 변경하려 했으니 오류 발생!)
 
상수를 사용하면 편리한 이유
프로그램 내부에서 반복적으로 사용되고, 변하지 않아야 하는 값을 상수로
선언하여 사용하면 좋습니다.
 
예를 들면 어떤 학급의 학생 수가 최대 30명이라는 코드를 작성하는 경우.

값을 코드에 직접 사용한다면

if(count == 30) { ... } // 값이 30이라면 while(i < 30) { ... } // 30보다 작은

상수로 선언한다면

final int MAX_STUDENT_NUM = 35; // 값이 MAX_STUDENT_NUM이라면 if(count == MAX_STUDENT_NUM) { ... } // MAX_STUDENT_NUM보다 작은 동안 while(i < MAX_STUDENT_NUM) { ... }

(저는 솔직히 상수로 선언하는 게  길어 보여서  불편할  같습니다.)
하지만, 값을 코드에 직접 사용할 경우 30명에서 35명으로 늘어날 때,
엄청난 삽질을 요구해서 실질적으로 상수로 선언하는 게  편합니다 :)
 

리터럴
리터럴 이란 프로그램에서 사용하는 모든 숫자, 문자, 논리값을 일컫는 말입니다.

char ch = 'A'; int num = 10; final double PI = 3.14;

위에서 사용한 'A', 10, 3.14 같은 문자와 숫자를
'리터럴' 혹은 '리터럴 상수'라고 합니다.
 
리터럴은 변수나 상수값으로 대입할  있습니다.
그리고, 프로그램이 시작할  시스템에 같이 로딩되어 특정 메모리 공간인
상수 (constant pool) 놓입니다.
 
예를 들어 int num = 3;
코드에서  3 메모리 공간 어딘가에 존재해야 num 변수에  값을
복사할  있습니다.  숫자가 변수에 대입되는  과정은 일단 숫자 값이 어딘가 메모리에
쓰여있고,  값이 다시 변수 메모리에 복사되는 것입니다.
 
자바에서 정수를 표현하는 메모리의 기본 크기는 4바이트라는 
1일차에 공부하였습니다.
 
이는 상수 풀에서도 마찬가지로 적용됩니다.
 
예를 들어 리터럴 10, 'a', 3.14등은 int형으로 처리됩니다.
그런데 long num = 12,345,678,900; 4바이트 크기에 들어갈  없기 때문에 long,
 8바이트로 처리하라고 컴파일러에 알려 주어야 합니다.
 
따라서 ' 리터럴은 long형으로 저장되어야 한다'라는 의미로
리터럴 뒤에 식별자 l이나 L  주는 것입니다.
 
실수도 마찬가지입니다.
(실수는 float이니 f F 사용해야 합니다.)
 
 
02-5  변환
 
 변환이란?
정수와 실수는 컴퓨터 내부에서 표현되는 방식이 전혀 다릅니다.
따라서 정수와 실수를 더한다고   그대로 연산을 수행할  없고 하나의
자료형으로 통일한  연산을 해야 합니다.
이를  변환이라고 합니다.

int n = 10; // int형 변수 n에 정수 값 10을 대입 double dnum = n; // int형 변수 n의 값을 double형 변수 dnum에

 코드처럼  변환이란 이렇게  변수의 자료형이 다를 
자료형을 같게 바꾸는 것을 말합니다.
 
 변환은 크게 묵시적  변환(자동) 명시적  변환(강제) 두 가지로 구별해서
생각할  있습니다.  변환의 기본 원칙은 밑과 같습니다.
 
바이트 크기가 작은 자료형에서  자료형으로  변환은 자동으로 이루어진다.
 정밀한 자료형에서  정밀한 자료형으로  변환은 자동으로 이루어진다.
 

 두 가지 원칙에 기반하여 묵시적  변환이 이루어지는 관계는 아래와 같습니다.

 그림에서 화살표 방향과 반대로  변환을 하려면 강제로 변환해야 합니다.
여기서! long형은 8바이트이고, float형은 4바이트인데  변환이 되는 이유는
실수가 정수보다 표현 범위가  넓고 정밀하기 때문입니다.
 
 화살표 방향으로  변환이  때는 자료 손실이 없지만,
 반대의 경우에는 자료 손실이 발생할  있습니다. 
 
묵시적  변환
바이트 크기가 작은 자료형에서  자료형으로 대입하는 경우

byte bNum = 10; int iNum = bNum; // byte형 변수 bNum 값을 int형 변수 iNum

 경우는 자료 손실 없이 bNum 들어있는 값이 모두 iNum 저장됩니다.
남은 3바이트는 0으로 채워집니다.
 

 정밀한 자료형에서  정밀한 자료형으로 대입하는 경우

int iNum2 = 20; float fNum = iNum2;

 4 코드에서 두 번의  변환이 일어납니다.
fNum + iNum;  부분에서 float형으로 먼저 변환되어주고
dNum =  부분에서 double형으로 변환이 됩니다.
 
바이트 작은 크기 ->  크기
 정밀 -> 정밀
 
한 번 더 복습!!
 
묵시적  변환

package chapter2; public class chapter2 { public static void main(String[] args) { byte bNum = 10; int iNum = bNum; // byte형 값이 int형 변수로 대입됩 System.out.println(bNum); System.out.println(iNum); int iNum2 = 20; float fNum = iNum2; // int형 값이 float형 변수로 대입됨 System.out.println(iNum); System.out.println(fNum); double dNum; dNum = fNum + iNum; System.out.println(dNum); } }

(코드를 천천히 읽어보며 해석해보면 바보  터지는 소리가 절로 납니다. )
 
명시적  변환
묵시적  변환과 반대의 경우로 생각할  있습니다.
 

바이트 크기가  자료형에서 작은 자료형으로 대입하는 경우

int iNum = 10; byte bNum = (byte)iNum; // 강제로 형을 바꾸려면 바꿀 형을 괄호를 써서 명시해야함

byte형은 int 형보다 크기가 작기 때문에 자료 손실이 발생할  있습니다.
따라서, 프로그래머가 변환할 자료형을 명시적으로  주어야 하며 이를 강제  변환이라고 합니다.

 경우에는 대입된  10 1바이트 안에 표현할  있으므로 자료 손실이 없습니다.

int iNum = 1000; byte bNum = (byte)iNum;

 경우에는  1000 byte 범위를 넘기 때문에 자료 손실이 발생해
대입된 값이 -24 출력이 됩니다.
 
 정밀한 자료형에서  정밀한 자료형으로 대입한 경우
실수형에서 정수형으로 변환될 때도  변환을 명시적으로 해주어야 합니다.

double dNum = 3.14; int iNum2 = (int)dNum;

 경우에는 실수의 소수점 부분이 생략되고 정수 부분만 대입됩니다.

연산
   변환

package chapter2; public class chapter2 { public static void main(String[] args) { double dNum1 = 1.2; float fNum2 = 0.9F; int iNum3 = (int)dNum1 + (int)fNum2; //두 실수가 각각 int형 변환되어 더해짐 int iNum4 = (int)(dNum1 + fNum2); //두 실수의 합이 먼저 계산되고 형 변환됨 System.out.println(iNum3); System.out.println(iNum4); } }

이처럼 같은 연산이라도  변환이 언제 이루어졌는지에 따라 값이 다르게 나타날  있습니다.


반응형

'프로그래밍 > Java' 카테고리의 다른 글

Java 스터디 6일차  (0) 2018.10.21
Java 스터디 5일차  (0) 2018.10.19
Java 스터디 4일차  (0) 2018.10.17
Java 스터디 3일차  (0) 2018.10.17
Java 스터디 1일차  (0) 2018.10.14