본문 바로가기

Java

[JAVA / 자바] 형변환

1. 형변환(casting)이란?:

- 서로 다른 타입간 연산 수행을 위해서는 연산 전 연산하고자 하는 값들의 타입을 일치시키는 것이 원칙
- 형변환: 변수나 리터럴(상수)의 타입을 다른 타입으로 변환하는 것

(타입) 피연산자
() : 캐스트연산자, 형변환 연산자

2.  형변환의 종류

 

 

1) 자동 형변환 (promotion)
- 화살표 순방향의 경우 컴파일러 자동 형변환 (화살표 역순의 경우 강제형변환 필요)

https://s3.ap-northeast-2.amazonaws.com/opentutorials-user-file/module/516/1822.gif

                    

 

2. 강제 형변환(force casting) :자동형변환이 이루어지지 않을 경우 진행
  - 큰타입 => 작은타입으로 변환

 - 프로그래머 책임 하에, (캐스팅연산자)를 통해 진행, 형변환 명시

    ===> 값 손실 발생가능. 신중하게
    

ex) byte b = 10000; (에러)
- 좁은그릇-> 넓은그릇 : O (값 손실 없음, 자동형변환)
* 기본값을 최대한 보존할 수 있는 타입으로 자동형변환됨

 

3. 산술변환:
1) 이항연산자는 두 피연산자의 타입이 일치해야 연산 가능함
2) 피연산자 타입이 다를시 형변환 연산자를 통해 타입 일치시켜야함
===> 컴파일러가 자동으로 형변환하는 것을 "산술변환", "일반산술변환"이라 함
* 산술변환 규칙
(1) 더 큰 그릇 타입으로 일치
*(2) 피연산자 타입이 int보다 작을 시 int로 변환

      기본형끼리 산술연산시, short+byte 등 int보다 범위가 작은 변수끼리 연산하게 되면 오버플로우가 발생할 가능성이 높으므로 컴파일러가 자동으로 피연산자들을 int형으로 변환하여 계산함
( char, short의 경우 표현범위가 좁아서 오버플로우 발생 가능성이 높음)
*(3) 정수 + 실수 형변환시, 실수로 변환

      마찬가지로 정수+실수로 형변환시 반환받는 값은 실수가되어야하므로 컴파일러가 자동으로 반환타입을 실수로 반환
( 8byte 정수 (long) 보다 4byte 실수(float)형이 더 범위가 큼)

long + int -> long + long -> long
float + int -> float + float -> float
double + float -> double + double -> double
byte + short -> int + int -> int
char + short -> int + int -> int
char + char -> int + int ->int // char형이 int로 변할때에는 대응되는 아스키코드 값으로 변환됨
long + float -> float + float ->float

 

// 자동형변환: 작->큰
	 public void autoCasting() {
	// 1. int(4byte, 정수) -> double(8byte, 실수)
	    int i1 =10;
		System.out.println(i1);
		double d1 = /*double*/i1;
		System.out.println(d1);
		// 자동형변환 완료 (int -> double 타입으로) 
		// int형을 더 큰 그릇인 double형 변수에 담으면 자동으로 double로 변환되어 담긴다
        // d1 =10->10.0
		
	  // 2. int(4byte, 정수)-> long (8byte, 실수)
          int i2 = 1200000;
          long l3 =i2;
         System.out.println(l3);    // 1200000
         
      // 특이케이스 1. long (8byte, 정수) -> float(4byte)
      // 정수 -> 실수 변환시, 큰 정수가 작은 실수에 대입 가능
      // => 4byte float 형이 8byte long형보다 담을 수 있는 값의 범위가 더 크기 때문
         
        long l4 = 1000000L;
        float f5 = l4;
        System.out.println("f5출력: " +f5); //  f5출력: 1000000.0  	
      // long형이 float형 변수에 담기면 자동으로 float형으로 컴파일되며,
      // 출력시 float형식에 맞춰 "~ .0"을 달고 출력됨
         
         
       // 특이케이스 2. char(2Byte) <-> int (4Byte) 
       // 아스키코드표 
         char ch = 98; // 아스키코드, 숫자 - 알파벳 대응
         char ch2 = 'b';
         System.out.println(ch+"는"+ch2+"?"); // b는b? 
         //char + string + char ==> String + String +String으로 인식

         
         int num = ch; // int<->char 간의 형변환
         System.out.println(num);
         
         System.out.println('b');  //b 
         System.out.println((int) 'b'); // ->98
         System.out.println('b'+2);//  -> char + int => int ( 98+2 =100)
         System.out.println('b'+(char)'2'); //-> 100 
         System.out.println((char)2); //
         
         
         
         System.out.println((char)2+(char)'2'); 
         // char형 '2'를 int형으로 변환시,이에 대응되는 아스키값인 50이 출력됨
         // 작은 자료형, 큰 자료형 연산시 작은 자료형을 큰 자료형으로 변환하여 연산, 위의 경우 모두 int 형으로 변환,int50 + int2 이 되어 int 52가됨 (502아님)

 

// 특이케이스 5. byte, short간의 연산
         // -128~127
         byte b1 = 126;
         byte b2 = 2;       
         System.out.println(b1+b2);
         // 결과값이 int 형 => cpu가 값을 처리하는 기본크기가 int형의 크기 (4byte)         
         // byte b3 = (byte)128;  // byte 범위를 넘는 값을 byte에 넣었음, 오버플로우 발생
         System.out.println(b3);
         
         // 강제형변환 : 큰 바이트 -> 작은바이트
	 }
         public void forceCasting() {              //여기 오류 다시보기 
        	 // 명시적 형변환이라고도 함 
        	 // (바꿀자료형) 값
        	 // 1. double (8byte) -> float(4byte)
        	 
        	 double d2= 8.0;
        	 float f1 = (float)d2;
        	 
        	 System.out.println(f1);
    
         
         double d3= 10.123123;
         int i4 = (int)d3;
         System.out.println(i4);
          // 0.123123소수점 뒷부분 절삭 -> 데이터 손실 
         
         int iNum=10;
         double dNum=1.56;
         double dNum2 = 0.57;
         
         // BigDecimal
         
         System.out.println(iNum+dNum); // 11.56
         System.out.println(dNum+dNum2);//2.13
         System.out.println((int)(dNum+dNum2));//2
         
         
         
         char ch = 98; // 아스키코드, 숫자 - 알파벳 대응
         char ch2 = 'b';
         System.out.println(ch+"는"+ch2+"?");
         
         int num = ch; // int<->char 간의 형변환
         System.out.println(num);
         
         System.out.println('b');
         System.out.println((int) 'b'); // ->98
         System.out.println('b'+2);//  -> 100
         System.out.println('b'+(char)2); //-> 문자+문자는 자바가 컴파일 할 수 없는 코드임
                                          //-> 자바가 강제로 int+int로 변환함
         
         System.out.println((char)2); // 숫자를 문자형에 넣으면 인식이 불가!
         System.out.println((char)2+(char)'2'); 
         // char형 + char형 = int형 
         // char형 '2'를 int형으로 변환시,이에 대응되는 아스키값인 50이 출력됨
         // 작은 자료형, 큰 자료형 연산시 작은 자료형을 큰 자료형으로 변환하여 연산, 위의 경우 모두 int 형으로 변환,int50 + int2 이 되어 int 52가됨 (502아님)
         
      
         }



 

'Java' 카테고리의 다른 글

[JAVA / 자바] API - Math클래스  (0) 2023.02.20
Properties 객체  (0) 2022.11.10
[JAVA / 자바] 조건문과 반복문  (1) 2022.10.15
[JAVA / 자바] 연산자  (0) 2022.10.15
[JAVA / 자바] 변수  (1) 2022.10.11