상수
한 번만 저장할 수 있는 공간으로 초기화 이후 다른 데이터(값)을 대입할 수 없다.
상수선언
final int AGE; // 상수선언시 변수명은 반드시 대문자로
오버플로우
127 + 1 을 하면 범위를 초과한 128이 되고 허용된 범위 이상의 비트를 침범하게 되는데
이를 오버플로우라고 한다.
127(범위의 최대 값)에 +1을 하면 범위의 최소 값으로 돌아와야 한다.
ex) 127 + 1 = -128
127 + 3 = -126
-> 0111111 (127) + 1
0000000 (carry 1 발생) // carry가 발생하면 부호 비트가 바뀐다.
1000000
형변환
같은 자료형 끼리만 대입(계산) 가능
계산의 결과도 같은 종류의 값이 나와야 함
=> 원칙이 지켜지지 않은 경우에 형변환이 필요하다.
자동형변환 (묵시적 형변환)
- 값이 작은 곳(int) -> 큰 곳(long)으로 이동할 때
- 정수형 -> 실수형으로 형변환 할 때
- byte -> short -> int -> float -> double
- char -> short 로는 자동형변환 하지 못 한다. (범위가 달라서)
- char -> int로 자동형변환이 일어난다.
- byte _ int = int
- short + int = int
- byte + byte = int // 예외적인 상황
- short + short = int // int 미만의 것들은 어떤 연산을 하더라도 결과 값은 항상 int형이 된다.
- byte + short = int // 참고) E 오버플로우테스트 class의 bnum = (byte)(bnum+1); 구문
- boolean은 형변환에서 제외된다.
강제형변환 (명시적 형변환)
- casting 연산자 -> (자료형)(값)
- 값이 long(큰 곳) -> int(작은 곳)으로 이동할 때 데이터 손실 발생
- 데이터 손실이 발생하지 않을 수도 있다.
- 10 <- 10.0 (데이터 손실 X)
- 10 <- 10.5 (0.5만큼의 데이터 손실 발생)
- 데이터 손실이 발생하지 않을 수도 있다.
예제
D_상수테스트
package com.kh.variable;
public class D_상수테스트 {
public void testFinal() {
//상수 테스트
int age;
final int AGE; //AGE라는 상수를 선언
age = 20;
AGE = 20;
System.out.println("age : " + age);
System.out.println("AGE : " + AGE);
age = 30; //AGE = 30; / 에러발생 -> 상수값 변경 불가
System.out.println("age : " + age);
System.out.println("AGE : " + AGE);
System.out.println("Math.PI : " + Math.PI);
}
public static void main(String[] args) {
/*D_상수테스트 test = new D_상수테스트();
test.testFinal();*/
new D_상수테스트().testFinal(); //같은의미
}
}
E_오버플로우 테스트
package com.kh.variable;
public class E_오버플로우테스트 {
public void printVarSize() {
//기본 자료형의 사이즈 테스트
//눈으로만 확인하는 용도임
System.out.println("byte의 크기 : " + Byte.BYTES + "byte"); //.BYTES(상수) 자료형 사이즈를 출력할 수 있다.
System.out.println("short의 크기 : " + Short.BYTES + "byte");
System.out.println("int의 크기 : " + Integer.BYTES + "byte");
System.out.println("long의 크기 : " + Long.BYTES + "byte");
System.out.println("float의 크기 : " + Float.BYTES + "byte");
System.out.println("double의 크기 : " + Double.BYTES + "byte");
System.out.println("char의 크기 : " + Character.BYTES +
"byte");
//boolean은 클래스를 제공하지 않아 사이즈 출력할 수 있다
//paring - Integer : int에 관한 내용들이 담겨있다
}
public void testOverFlow() {
//byte bnum = 128;
//에러, 범위를 벗어났음 / 127이 넘어가는 수는 byte 리터럴이 될 수 없다.
byte bnum = 127;
bnum = (byte)(bnum + 1); //byte + int로 인식 -> 결과값은 무조건 int(형변환필요) / 서로 형태가 같아야 대입이 되기 때문에 형변환을 해준다.(byte 자료형으로 바꿈)
System.out.println("bnum : " + bnum);
}
public void calc() {
int num1 = 1000000;
int num2 = 700000;
//에러가 발생하지는 않지만 예상되는 결과값이 나오지 않기 때문에 주의
/*int multi = num1 * num2;
System.out.println("계산결과 : " + multi); //범위가 21억을 넘어 오버플로우 발생*/
//해결방법
//=> 오버플로우를 고려하여 더 큰 자료형을 사용한다.
//int -> long으로 바꾸어도 되지만 num1,num2를 int로 정의한다고 가정
long multi = (long)num1 * (long)num2; //이미 계산한 결과(오버플로우)가 multi에 대입되기 때문에 형변환을 해준다 (한쪽만 형변환을 해주어도 다른쪽도 강제 형변환이 된다)
System.out.println("계산결과 : " + multi);
}
public static void main(String[] args) {
E_오버플로우테스트 test = new E_오버플로우테스트(); //new E_오버플로우테스트().printVarSize();
//test.printVarSize();
//test.testOverFlow();
test.calc();
}
}
F_형변환 테스트
package com.kh.variable;
public class F_형변환테스트 {
//(바꿀자료형)값 또는 (바꿀자료형)변수 // casting연산자는 값에서만 이루어진다 (등호의 오른쪽)
//casting연산자 : 값의 자료형을 바꿀 때 사용한다.
//형변황 : 자동(묵시적)형변환, 강제(명시적)형변환이 있다.
//컴퓨터에서의 값 처리 규칙
//1. 같은 자료형 끼리만 대입이 가능하다. 다른 자료형의 값을 대입할 시 형변환 필요
//2. 같은 자료형 끼리만 계산할 수 있으며, 계산의 결과도 같은 자료형이다.
//3. 기본적으로 정수형은 실수형으로 자동 형변환이 가능하지만,
// 실수형은 정수형으로 강제 형변환을 해야 한다.
// 10 -> 10.0 자동형변환 가능, 10.5 -> 10 강제형변환 필요
public void rule1() {
boolean flag = true;
//boolean 자료형은 무조건 true, false만 들어간다(형변환 예외)
//flag = (boolean)1;
//자료형이 다르더라도 작은 크기의 변수 타입은 큰 변수 타입으로 저장할 수 있다.
//=> 자동형변환
//하지만 큰 변수 타입은 작은 변수 타입으로 자동 변환되지 않기 때문에 형변환을 명시해 주어야 한다.
//=> 강제형변환
//변경할 값 앞에 (변경할타입)을 지정해 주면 된다.
//자동 형변환이 일어남 char -> int
int num = 'A';
System.out.println("num : " + num);
char ch = 97; //ch에 97이 저장이 되면서 a라는 char타입이 된다.
System.out.println("ch : " + ch); //ch는 char이기 때문에 문자로 출력
//char ch2 = -97; //문자는 음수를 저장할 수 없다.
//int 자료형 변수의 값은 char 자료형에 대입하기 위해 강제 형변환을 해야 한다.
char ch2 = (char)num; //데이터 손실이 일어날 수도 있지만
System.out.println("ch2 : " + ch2);
//음수를 저장한 변수를 char로 강제 형변환을 하게 되면
//char는 부호비트가 없기 때문에 문자로 인식하지 못한다.
//물음표는 문자의 의미가 아닌 없는 문자라는 뜻이다.
int num2 = -97;
char ch3 = (char)num2; //강제형변환을 하면 int타입의 음수값을 넣을 순 있다.
System.out.println("ch3 : " + ch3); // 출력 : ?
}
public void rule2() {
//다른 자료형끼리의 연산은 큰 자료형으로 자동 형변환 후 연산처리 된다.
int inum = 10;
long lnum = 100;
//방법 1. 수행 결과를 int로 강제 형변환 한다.
int isum = (int)(inum + lnum); //long + long = long 이기 때문에 int에 담지 못함 -> 강제형변환 필요
System.out.println("isum : " + isum);
//방법 2. long형 값을 int로 강제 형변환 한다.
int isum2 = inum + (int)lnum;
System.out.println("isum : " + isum2);
//방법 3. long형 자료형으로 받는다.
long sum = inum + lnum;
System.out.println("sum : " + sum);
//하지만 예외적으로 byte와 short의 연산 결과는 무조건 int가 된다.
byte bnum = 1;
short snum = 2;
//강제 형변환을 적용한 경우
short sum2 = (short)(bnum + snum); //연산 결과가 int로 나오기 때문에 short로 형변환
//혹은 실행 결과를 int형으로 저장해야 한다.
int sum3 = bnum + snum;
}
public void rule3() {
//정수는 실수로 자동 형변환이 된다.
long lnum = 100; //8byte
float fnum = lnum; //4byte
System.out.println("fnum : " + fnum);
//실수는 정수로 형변환 할 때 강제 형변환을 해 주어야 한다.
double dnum = 10.5;
//실수가 정수로 바뀔 때 소수점 이하를 절삭하기 때문에 데이터 손실이 일어난다.
int inum = (int)dnum;
System.out.println("inum : " + inum);
}
public void testDataloss() {
//데이터 손실 테스트
int inum = 290;
System.out.println("inum : " + inum);
byte bnum = (byte)inum;
System.out.println("bnum : " + bnum);
}
public static void main(String[] args) {
F_형변환테스트 test = new F_형변환테스트();
//test.rule1();
//test.rule2();
//test.rule3();
test.testDataloss();
}
}
'JAVA > 이론 정리 및 예제' 카테고리의 다른 글
[JAVA/자바] #3_0 제어문 / beforeTest (0) | 2021.09.05 |
---|---|
[JAVA/자바] #2_2 연산자 실습 문제 (0) | 2021.09.03 |
[JAVA/자바] #2_1 연산자 / 예제 (0) | 2021.09.03 |
[JAVA/자바] #1_3 변수, 형변환 실습 문제 (0) | 2021.09.03 |
[JAVA/자바] #1_1 변수 - 정의와 자료형 / 예제 (0) | 2021.07.06 |