3. 상수와 형 변환

Isaiah IM·2023년 1월 5일
0

java basic

목록 보기
4/38
post-thumbnail

1. 상수(Constant Number)

상수(Constant Number)란 변하지 않는 수로, java 내부에서 값이 한번 저장되면 그 값이 변하지 않는 변수를 의미한다.

예를 들어 SIZE라는 이름의 변수에 3이 저장됬다 가정하면, 추후에 SIZE=4; 와 같이 SIZE라는 변수에 값을 수정하는 것이 불가능 하다.


2. 상수의 선언

java에서는 상수를 final 키워드를 이용해 선언할 수 있으며, 다음과 같이 선언한다.

final 자료형 이름;
final 자료형 이름2=값;

첫번째의 경우는 상수에 값이 아직 할당되지 않은 경우로, 이후에 초기값을 한번만 저장할 수 있으며, 두번째의 경우에는 이미 값이 저장되 있기 때문에 값을 추가로 저장하거나 수정할 수 없다.
또한, 대부분 상수의 경우 이름을 알파벳 대문자만을 이용하는 것이 일반적이다.

상수에 대해 직접 코드로 확인하면 다음과 같다.
code1:

public class constant {
	public static void main(String[] args) {
		final int SIZE1=3;// SIZE1에 3 저장
		final int SIZE2;// SIZE2 선언(아직 저장 안함)
		
		SIZE2=5;//SIZE2에 5 저장
		
        /*값 출력*/
		System.out.println("SIZE1: "+SIZE1);
		System.out.println("SIZE2: "+SIZE2);
	}
}

output:

SIZE1: 3
SIZE2: 5

code2:

public class constant {
	public static void main(String[] args) {
		final int SIZE1=3;// SIZE1에 3 저장
		final int SIZE2;// SIZE2 선언(아직 저장 안함)
		
        SIZE1=10;// 오류!
		SIZE2=5;//SIZE2에 5 저장
		
        /*값 출력*/
		System.out.println("SIZE1: "+SIZE1);
		System.out.println("SIZE2: "+SIZE2);
	}
}

output:

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
	The final local variable SIZE1 cannot be assigned. It must be blank and not using a compound assignment

code1의 경우 정상적으로 동작함을 확인할 수 있으나, code2의 경우에는 오류가 출력됨을 알 수 있다.

오류의 내용을 확인하면 다음과 같다.
The final local variable SIZE1 cannot be assigned. It must be blank and not using a compound assignment
오류를 보면 SIZE1이 final local variable(상수) 이라서 값이 assign(할당)이 불가능 하다는 내용이다.
즉, SIZE1의 경우 상수로 선언되 있기 때문에 추가적으로 값을 수정할 수 없다는 내용이다.

이러한 상수의 경우, 프로그램이 실행되고, 변하지 않는 IP주소, 기본 환경설정등의 정보를 저장할 때 사용이 된다.


3. 리터럴(Literals) 상수

리터럴(Literals) 상수란 우리가 흔히 알고있는 변수에 대입하는 값을 의미한다.
예를 들어보자.

int a=10;

이라는 코드가 있다고 가정하면, 리터럴 상수의 경우 a에 대입한 값인 10이 된다.

리터럴을 통해서 값의 자료형을 표현할 수 있다.

  • 정수형

정수형 리터럴 상수를 표현할 때 만약 숫자만 적은 경우에는 int형으로 표현이 된다.
예를 들어 보자.

int num=10000;

위의 코드를 해석하면 다음과 같다.

10000 이라는 int형 정수가 num에 대입됬다.

다음 코드를 보자.

long num=10000;

위의 코드 역시 해석하면 다음과 같다.

10000 이라는 int형 정수가 num에 대입됬다.

이를 int형 정수 범위를 초과하는 큰 값을 대입하는 방식으로 직접 코드로 확인을 해 보자.

public class literal {
	public static void main(String[] args) {
		long num=9999999999;
		
		System.out.println(num);
	}
}

output:

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
	The literal 9999999999 of type int is out of range 

보면 9999999999라는 값이 "int is out of range "라는 이유로 오류가 발생함을 알 수 있다. 이를 해석하면 9999999999라는 큰 값은 int자료형의 범위를 벗어나는 큰 수라는 것을 의미한다.
즉, 우리는 long자료형을 선언해서 long 자료형에 맞는 값을 대입하려 했으나, 실제로는 long 자료형 안에 int형 값이 대입되는 것이다.
이를 예방하기 위해서는 알파벳 L을 숫자 뒤에 붙여주는 방식으로 long자료형의 값이라는 것을 표시할 수 있다. 물론, 소문자 l을 사용해도 무관하나, 숫자 1과 혼동할 수 있기 때문에 가급적이면 대문자 L을 사용하도록 하자.

이를 코드로 확인하면 다음과 같다.

public class literal {
	public static void main(String[] args) {
		long num=9999999999L;
		
		System.out.println(num);
	}
}

output:

9999999999

또한, 정수에서 _라는 표기를 지원하기 때문에 123_456_789와 같이 표시를 하면 123,456,789와 같이 쉼표처럼 직관적으로 큰 숫자를 구분할 수 있다.

또한, 정수의 경우에는 2진수, 8진수, 16진수의 표기 역시 지원한다.
2진수의 표기는 숫자 앞에 0B를 붙이며, 8진수의 경우 앞에 숫자0을, 16진수의 경우에는 숫자 앞에 0x를 붙이는 방식으로 표기한다.
이를 코드로 나타내면 다음과 같다.

public class literal {
	public static void main(String[] args) {
		long num=1_234_567_890L;// 1,234,567,890
		int bin=0B0101;// 2진수
		int octa=023;// 8진수
		int hex=0xf2;// 16진수
		
		/*값 출력*/
		System.out.println(num);
		System.out.println(bin);
		System.out.println(octa);
		System.out.println(hex);
	}
	
}

output:

1234567890
5
19
242
  • 실수형

실수형의 경우, 숫자 뒤에 아무것도 붙지 않았을 경우에는 double형 실수로 인식을 한다.
만약 double형임을 명시하고 싶은 경우에는 숫자 뒤에 알파벳 d 혹은 알파벳 D를 붙임으로서 명시할 수 있다.

float형의 실수를 표현하고 싶은 경우에는 숫자 뒤에 알파벳 f 혹은 알파벳 F를 붙이는 형식으로 표현을 할 수 있다.

이를 코드로 확인하면 다음과 같다.

public class literal {
	public static void main(String[] args) {
		float data=0.123f;
		float data2=0.456;// 오류
		double data3=1.2345d;
		
		/*값 출력*/
		System.out.println(data);
		System.out.println(data2);
		System.out.println(data3);
	}
}

output:

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
	Type mismatch: cannot convert from double to float

위의 코드의 실행 결과를 보면 cannot convert from double to float라는 오류가 발생함을 알 수 있다. 이를 해석하면 double형의 값을 float자료형에 대입할 수 없다는 뜻으로, data2에서 숫자 뒤에 f가 없어 0.456의 숫자가 double형태임에도 불구하고 float로 선언된 변수에 대입하려 하면서 발생하는 문제이다. 이를 수정하면 다음과 같다.

public class literal {
	public static void main(String[] args) {
		float data=0.123f;
		float data2=0.456f;
		double data3=1.2345d;
		
		/*값 출력*/
		System.out.println(data);
		System.out.println(data2);
		System.out.println(data3);
	}
}

output:

0.123
0.456
1.2345

또한, 0.5와 같이 앞자리의 숫자가 0인 경우에는 .5f 혹은 .5와 같이 0을 생략할 수 있으며, 1.0과 같은 숫자 역시 뒤의 0을 생략하여 1.f 혹은 1.와 같이 표현할 수 있다.
이들을 코드로 확인하면 다음과 같다.

public class literal {
	public static void main(String[] args) {
		float data=.123f;
		float data2=2.f;
		double data3=1.;
		
		/*값 출력*/
		System.out.println(data);
		System.out.println(data2);
		System.out.println(data3);
	}
}

output:

0.123
2.0
1.0

0.00000001과 같이 소숫점이 길어질 경우에는 e를 붙여 1.0e-8과 같이 사용할 수 있으며, 이는 1.0*10^-8을 의미한다.

이들을 코드로 확인하면 다음과 같다.

public class literal {
	public static void main(String[] args) {
		float data=1.2e-10f;// 0.00000000012
		float data2=2.e-5f;// 0.00002
		double data3=1.e-6;// 0.000001
		
		/*값 출력*/
		System.out.println(data);
		System.out.println(data2);
		System.out.println(data3);
	}
}

output:

1.2E-10
2.0E-5
1.0E-6

4. 형 변환

형 변환이란 자료형이 변환되는 것으로 자동으로 자료형이 변환되는 묵시적 형 변환(Implicit Conversion)과 사용자가 직접 자료형을 변환하는 명시적 형 변환(Explicit Conversion)이 있다.

  • 묵시적 형 변환(Implicit Conversion)

묵시적 형 변환(Implicit Conversion)이란 자료형이 서로 다를때 컴파일러에서 자동으로 자료형을 변환해 주는 형 변환 이다.

예를 들어 보자.
다음 코드에서의 연산 결과의 자료형은 무엇인가?

public class Conversion {
	public static void main(String[] args) {
		int data1=1234567;
		long data2=1234567890L;

		System.out.println(data1+data2);
	}
}

output:

1235802457

코드를 보면 int자료형과 long자료형이 서로 충돌됬음을 알 수 있다. 이때, 컴파일러에서는 데이터의 손실이 적은 방향으로 자동으로 형 변환(up casting)을 진행한다.
위의 예제에서는 계산결과가 int형보다 큰 값을 가질 경우, 데이터의 손실이 발생할 수 있으므로, long형으로 변환이 된다.

  • 명시적 형 변환(Explicit Conversion)

명시적 형 변환(Explicit Conversion)이란 사용자가 임의로 형변환을 하는 것으로, (자료형)변수명 형태로 사용한다.

예를 들어보자.

public class Conversion {
	public static void main(String[] args) {
		float data1=123.4567;
        
		System.out.println(data1);
	}
}

output:
123.4567

위의 코드에서 data1의 자료형을 int자료형으로 변환하기 위한 코드는 다음과 같다.

public class Conversion {
	public static void main(String[] args) {
		float data1=123.4567;
        
		System.out.println( (int)data1);// 형변환
	}
}

output:
123

위의 코드를 보면 강제적으로 int형으로 형변환을 하므로서 소숫점을 제거할 수 있다.


5. 실습

  • Q1

    10+3.14159을 계산한 결과값 중에서 정수부분만을 저장해서 출력하시오.

  • Q2

    0x34+5.12의 계산한 값을 출력하시오.

  • Q3

    다음 코드에서 data1+data2의 자료형은 무엇인가?

public class Q3 {
	public static void main(String[] args) {
		int data1=123;
        float data2=0.123f;
        
		System.out.println(data1+data2);
	}
}

  • A1

public class Q1 {
	public static void main(String[] args){
		int num=10;
		float pi=3.14159f;
		int result;
		
		result=num+(int)pi;
		
		System.out.println(result);
	}
}

result:

13
  • A2

public class Q2 {
	public static void main(String[] args){
		int hexData=0x34;
		float floatData=5.12f;
		float result;
		
		result=hexData+floatData;
		
		System.out.println(result);
	}
}

result:

57.12
  • A3

intfloat의 계산결과는 float자료형이 된다. 그 이유는 int자료형의 경우, 정수만을 저장할 수 있기 때문에 계산결과가 int자료형에 저장이 될 경우 소숫점 데이터의 손실될 수 있기 때문이다. 또한, float의 경우 int자료형의 범위를 포함하고 있기 때문에 데이터가 손실이 안되는 방향인 float자료형으로 변환된다.

다음은 java에서의 자료형 변환 순서이다.

앞으로 학습시 참고하도록 하자.

위 주소에서 code를 다운로드 받아 eclipse로 직접 정답 확인이 가능하다.
https://github.com/isaiahIM/java_basic/tree/main/constant%20and%20casting

profile
나는 생각한다. 고로 나는 코딩한다.

0개의 댓글