JAVA 타입 변환

금송·2024년 9월 2일
0

이론

목록 보기
10/17
post-thumbnail
  • 8/30 퀴즈 정답
    // 2번
    
    public class Question {
        public static void main(String args[]) {
            // 다음 문장들의 출력 결과를 확인해보세요.
            System.out.println("10" + "04");
            // 숫자로 합쳐지는 것이 아닌 문자열로 합쳐져 1004
            System.out.println("" + false);
            // 문자열 + 논리형타입 = 문자열로 치환 -> false
            System.out.println('a' + 100);
            // char타입 + 정수형타입 = 10진수로 변환된 char타입으로 계산 -> 197
        }
    }
    
    // 3번
    
    public class Question {
        public static void main(String args[]) {
            // 에러가 발생하는 부분을 고쳐보세요. 값을 수정하던지 타입을 변경하던지
            byte a = 999;
            // int a = 999; / byte a = 127;
            char b = 'abc';
            // String b = "abc"; 문자열 타입은 기본 타입이 아니라 참조형 타입, 문자열 타입엔 무조건 쌍 따옴표 사용 / char b = 'a';
            float c = 1.23d;
            // double c = 1.23; / float c = 1.23F;
        }
    }
    
    // 5번
    2byte , 0~65535 , 16bit , 216// 6번
    2. char b = ' ';
    3. String c = "Hello";  / char c = 'H';
    4. int d = 12345; / (byte -128 ~ 127)
    
    // 9번
    // 하나의 변수를 만들어서 값을 넣어두고 나머지 값들을 할당해준다음 마지막 값에 변수값을 넣어준다.
    // 변수를 만들지 않고 값을 넣어주면 값 하나가 사라진다.
    

    JAVA 타입 변환

타입 변환

데이터 타입을 다른 데이터 타입으로 변환하는 것을 말함.
두 가지 종류가 있는데 자동 변환 타입(묵시적 타입 변환), 강제 타입 변환(명시적 타입 변환)이 있다.
이때 강제 타입 변환에선 데이터 손실이 있을 수 있다.

자동 타입 변환

작은 크기의 타입을 큰 크기의 타입으로 자동 타입 변환 하는 것

public static void main(String[] args) {
		byte byteValue = 10;
		int intValue = byteValue;        // 타입 변환 (byte -> int)
		System.out.println(intValue);

		char charValue = '가';
		intValue = charValue;
		System.out.println("'가'의 유니코드= " + intValue);

		intValue = 500;
		long longValue = intValue;        // 타입 변환 (int -> long)
		System.out.println(longValue);

		intValue = 200;
		double doubleValue = intValue;    // 타입 변환 (int -> double)
		System.out.println(doubleValue);
}

유니코드

전세계의 모든 문자를 컴퓨터에서 일관되게 표현하고 다룰 수 있도록 설계된 표준
인코딩 포맷 - utf-8(한글까지 지원해서 사용), ISO 등등

강제 타입 변환

큰 크기의 타입을 작은 크기의 타입으로 강제적으로 변환.
큰 그릇을 쪼개어 작은 그릇에 넣는다 > 캐스팅 해준다

long longValue = 300;
int intValue = (int) longValue;  // intValue는 300이 그대로 저장

연산식에서의 자동 타입 변환

표현식이 다른 두 가지 타입을 연산할 때 범위가 더 큰 값을 따라서 연산해줌.

int intValue = 10;
double doubleValue = 5.5;

double result = intValue + doubleValue;    // result에 15.5가 저장

//이때 소숫점 없이 버림으로 저장하고 싶다면 캐스팅 해주면 됨.
int result = intValue + (int)doubleValue;   // result에 15가 저장

1. 자동 타입 변환에 대한 코드 중 컴파일 에러가 발생하는 것은 무엇입니까?

byte byteValue = 10;
char charValue = 'A';

(1) int intValue = byteValue;

(2) int intValue = charValue; // charValue가 유니코드로 변환됨.

(3) short shortValue = charValue; // short - 2byte, 표현되는 크기는 같지만 변환은 불가능함

(4) double doubleValue = byteValue;

2. 강제 타입 변환(Casting)에 대한 코드 중 컴파일 에러가 발생하는 것은 무엇입니까?

int intValue = 10;
char charValue = 'A';
double doubleValue = 5.7;
String stringValue = "A";

(1) double var = (double) intValue; // 묵시적으로도 가능, 자동 타입 변환 가능하지만 명시적으로 넣어줘도 되긴 함.
(2) byte var = (byte) intValue;

(3) int var = (int) doubleValue;
(4) char var = (char) stringValue; // 문자열 값은 char 값으로 변환을 할 수가 없다. String에서 제공해주는 메서드를 이용하면 가능하지만 아니면 할 수 없다. → charAt(index) 라는 메서드를 사용해야 함.

컴파일 오류

컴파일 오류가 나면 코드를 수정 해줘야 한다.
프로그램이 실행될 수 없는 상태 → 클래스 파일이 생성되지도 않은 상태.

기본 자료형과 참조 자료형

기본 타입 변수 vs 참조 변수 차이점

저장 형태

저장 영역 : stack
기본 타입 변수
- 리터럴 값을 실제로 저장. stack에 직접 저장

참조 변수
- 직접 저장되지 않고 객체에서 참조하여 사용. 실제값을 가지고 있지 않고 주소값을 가지고 있는데 해당 주소값이 heap영역을 가르키고 있어서 그 값을 찾아서 값을 가져오는 것.
참조 변수의 객체 메모리 영역 : heap
참조 변수의 메모리 공간 차지가 더 크다.

초기화

// 기본 타입 변수의 초기화 예시
int age = 10;
// 참조 변수의 초기화 예시
Calculator calculator = new Calculator();

참조 자료형의 단 하나의 예외

문자열을 다루는 String
알아두기 : 초기화 해줄 때 null값은 넣지 말고 ""을 넣되 실제 값을 넣어 주는 걸 더 권장.

// String , 참조 자료형 : new 예약어를 사용해서 변수를 초기화.
// 실제값(리터럴값)을 그대로 선언해서 사용할 수 있음. 예외!
// String str = "" // 초기화
String str = "실제값";         
String str2 = new String("실제값");

// String str = null; // null을 선언할 수 있지만 잘 하지않음. 주소값이 없는 상태를 뜻함
// str.length(); // NullpointerException. 해당 오류는 run을 돌려야 확인할 수 있어서 치명적일 수 있다.
  • String과 string의 차이
    string은 JAVA에 존재하지 않음.
  • new String 과 “”의 차이
		
  // String , 참조 자료형 : new 예약어를 사용해서 변수를 초기화.
	// 실제값(리터럴값)을 그대로 선언해서 사용할 수 있음. 예외!
	// String str = "" // 초기화
	String str = "실제값";
	String str2 = new String("실제값");
	String str3 = new String("실제값");
	String str4 = new String("실제값");
	String str5 = "실제값";
	
	// false
	System.out.println(str == str2);
	System.out.println("str2 == str3 결과 : " + (str2 == str3));
	System.out.println("str2 == str4 결과 : " + (str2 == str4));
	System.out.println("str3 == str4 결과 : " + (str3 == str4));
	System.out.println("str == str5 결과 : " + str == str5); //"str == str5 결과 : " + str 와 str5가 비교가 되서 false가 나옴. 연산자 우선순위..!
	//true
	System.out.println("str == str5 결과 : " + (str == str5));
	System.out.println(str.equals(str2));
	
	// String str = null; // null을 선언할 수 있지만 잘 하지않음. 주소값이 없는 상태를 뜻함
	// str.length(); // NullpointerException. 해당 오류는 run을 돌려야 확인할 수 있어서 치명적일 수 있다.

값은 똑같은데 결과는 false
== 은 주소값 비교. 리터럴 값과 참조 주소값이 달라서 false가 나옴. String한정!

int a = 10;
int b = 10;
System.out.println(a == b); // tryue

오토박싱 & 언박싱, 문자열과 숫자형 변환

박싱

기본형 타입을 특정 래퍼 클래스 타입으로 변환.
이때 래퍼 클래스는 참조형 타입이다.
해당 박싱을 하는 이유는 래퍼 클래스에서 사용할 수 있는 메서드가 많아서이다.

  • 기본형 타입 : byte, short, int, long, float, double, char, boolean
  • 래퍼 클래스 : Byte, Short, Integer, Long, Float, Double, Character, Boolean



참고 ) 해당 체크 박스 클릭 안하고 검색하면 내가 만든 파일에서 검색, 체크 하고 검색하면 전체 파일 검색
오토 박싱이 되는 경우도 있고 개발자가 메서드를 줘서 박싱이 되는 경우가 있다.

//박싱 (int -> Integer)
int a = 10;
Integer a2 = Integer.valueOf(a); // 대부분의 클래스에 valueOf() 메서드가 있음

//오토 박싱 (int -> Integer)
Integer a3 = a;
// 둘다 값은 같음

오토 박싱은 제네릭 컬렉션에 값을 추가하는 경우 유용
제내릭은 <> 안에 넣어주는데 기본 타입은 들어갈 수 없음.

public class AutoBoxingExample {
	  public static void main(String args[]) {
				ArrayList<Integer> arrayList = new ArrayList<>();
				
				/* 오토 박싱 */
				arrayList.add(10); // 여기서 만약에 int값이 아닌 다른 값이 들어가면 컴파일로 오류를 내줌
		 // arrayList.add(10); // int -> Integer, 만약 오토 박싱이 안된다면 해당 
				arrayList.add(20);
				arrayList.add(30);
				
				System.out.println("ArrayList: " + arrayList);
		}
}

// 결과
ArrayList: [10, 20, 30]

언박싱

래퍼 클래스를 기본형 타입으로 변환되는 것

int index = 20;
Integer intObject = index;   // 오토박싱

int index = intObject;    // 언박싱 Integer -> int

오토박싱 연산과 primitive 타입 연산 성능 차이

편의성을 위해 오토박싱과 언박싱이 제공되지만, 내부적으로 추가 연산 작업을 거치게 됨.
그렇기 때문에, 오토박싱과 언박싱이 일어나지 않도록 동일한 타입 연산이 이루어지도록 구현함.

// 오토박싱 연산
public class AutoBoxingPerformanceExample {
    public static void main(String[] args) {
        long startTimeMs = System.currentTimeMillis(); // 시간 체크용 메서드
        Integer sum = 0;   
        for (int i = 0; i < 1000000; i++) {
		        // 반복문이 실행될때마다 박싱이 실행됨, int -> Integer
            sum = sum + 1;
        }
        System.out.println("실행 시간: " + (System.currentTimeMillis() - startTimeMs) + "ms");
    }
}

// 실행 시간: 37ms
//primitive 연산
public static void main(String[] args) {
    long startTimeMs = System.currentTimeMillis();
    int sum = 0;
    for (int i = 0; i < 1000000; i++) {
		    // 반복문이 실행되더라도 박싱 x
        sum = sum + 1; 
    }
    System.out.println("실행 시간: " + (System.currentTimeMillis() - startTimeMs) + "ms");
}

// 실행 시간: 5ms (1s(초)는 1000ms)
// 실 테스트 코드
package chap02;

public class PrimitiveTypePerformanceExample {
    public static void main(String[] args) {
        // 성능 측정 (오토 박싱 vs 오토 박싱 x)
        // 실행 시점 시간
        long currentTimeMillis = System.currentTimeMillis();

        Integer sum = 0; // 오토 박싱
        for (int i = 0; i < 2000000; i++) {
            sum = sum + i;
        }
        long term = System.currentTimeMillis() - currentTimeMillis; // 현재 시간 - 실행 시점 시간
        System.out.println("오토박싱 소요시간: " + term);

        long currentTimeMillis2 = System.currentTimeMillis();
        int sum2 = 0; // 기본 타입, 즉 오토 박싱 x
        for (int i = 0; i < 2000000; i++) {
            sum2 = sum2 + i;
        }
        long term2 = System.currentTimeMillis() - currentTimeMillis2;
        System.out.println("primitive type 연산 소요시간:" + term2);
    }
}


둘 다 ms로 상당히 빠른 속도로 계산 되지만 해당 계산이 쌓이면 쌓일수록 큰 차이가 나 성능 차이가 커질 수 있음. 따라서 기본 타입 연산이 이루어지도록 구현 해야함

문자열과 숫자 변환 (중요!)

문자열 → 숫자 변환

문자열에서 숫자 primitive type으로의 변환은 Xxx.parseXxx(문자열) 메소드를 사용하여 변환하고,
문자열에서 숫자 Wrapper class로의 변환은 valueOf() 메소드를 사용하여 변환

public class StringConverter {
    public static void main(String[] args) {
        // String -> 숫자 변환 , 이때 변환을 시키려면 정확하게 숫자만 있어야함. 그렇지 않으면 에러가남.
        String str = "12345"; // int/Integer
        int primitiveStr = Integer.parseInt(str);
//        int sum = primitiveStr + 1; // 이때 변환을 하지 않고 연산을 한다면 "123451"
        Integer wrapperStr = Integer.valueOf(str);

        // String -> Long/long
        long primitiveLong = Long.parseLong(str);
        Long wrapperLong = Long.valueOf(str);

         String value = "10000.345";
        // String -> float/Float
//        float primitiveFloat = Float.parseFloat(str);
//        Float wrapperFloat = Float.valueOf(str);
        float primitiveFloat = Float.parseFloat(value);
        Float wrapperFloat = Float.valueOf(value);
        System.out.println("primitiveFloat: " + primitiveFloat);
        System.out.println("wrapperFloat: " + wrapperFloat);


        // String -> double/Double
        double primitiveDouble = Double.parseDouble(value);
        Double wrapperDouble = Double.valueOf(value);
        System.out.println("primitiveDouble: " + primitiveDouble);
        System.out.println("wrapperDouble: " + wrapperDouble);

// String str = "12345L" 이런 거는 변환이 안 되고 "12345.5F" 같은 경우는 되던데
// 검색해봤는데 잘 이해가 안 되서 그냥 자바에서는 그렇게 처리한다고 알고 있으면 될까요?? 그렇다.

//        오류 남
//        String str5 = "454875839545436L";
//        long primitveLong2 = Long.parseLong(str5);

        String str6 = "12345.5F";
        float floatString = Float.parseFloat(str6);
    }
}

숫자 → 문자 형변환

int → String

  • Interger.toString()
  • String.valueOf()
  • 변수 + “”(Casting 방식) → 제일 간편함
int intValue = 10;
String StrValue;

StrValue = String.valueOf(intValue);
StrValue = Integer.toString(intValue);
StrValue = "" + intValue; // 정수값에 빈 문자열을 더해 문자열 합치기 연산으로 작동되게 한다

//실습
int intValue = 10;
String s1 = intValue + "";
String s2 = Integer.toString(intValue);
String s3 = String.valueOf(intValue);

System.out.println(intValue + 10);
System.out.println("s1: " + s1);
System.out.println("s2: " + s2);
System.out.println("s3: " + s3);

// 결과값
20
10 // 만약 해당 괄호 안에 + 10을 넣어서 확인하면 1010. 즉 문자열로 잘 변환 되었음.
10
10

퀴즈

타입에 들어갈 단어는~? double

타입에 들어갈 단어는 ~? float
wrapper타입 변수로 받으려면 어떤 메소드를 사용하면 될까~? valueOf(문자열)

타입에 들어갈 단어는 ~? String, String

int인 a2에 double 타입을 초기화할 수 없기 때문에 강제 형 변환을 통해 int타입으로 바꾸어야 합니다.
int a2 = d; → int a2 = (int) d

int-> double 자동형변환

30

3

Hello world

  • 데일리 퀴즈

    7. 다음 수식의 결과 값과 타입은?

    1. 100 + 10.5

    2. 100 / 5

    3. 10.0 / 5

      int example7Value1 = 100;
      float example7Value2 = 10.5F;
      float example7Value3 = 10.0F;
      int example7Value4 = 5;
      
      System.out.println(example7Value1 + example7Value2)
      System.out.println(example7Value1 / example7Value4)
      System.out.println(example7Value3 / example7Value4)
      
      // 결과값
      110.5
      20
      2.0

      8. ‘가’라는 한글 문자의 유니코드를 찾아서 char 타입의 변수로 만들어봅시다.

      char charValue = '가';
      intValue = charValue;
      System.out.println("'가'의 유니코드= " + intValue);

      1. 아래 2개의 변수 number1, number2의 사칙 연산 결과(result1 ~ result4)를 정수로 출력하세요. (사칙연산: +, -, *, /) 주석처리 된 곳에 코드를 채우면 됩니다.

      public class Question {
          public static void main(String args[]) {
              int number1 = 10;
              double number2 = 2.0;
              
              // 사칙연산 코드 추가
              
              System.out.println(result1);
              System.out.println(result2);
              System.out.println(result3);
              System.out.println(result4);
          }
      }
      
      // 정답!
      double result1 = number1 + number2; // 덧셈
      double result2 = number1 - number2; // 뺄셈
      double result3 = number1 * number2; // 곱셈
      double result4 = number1 / number2; // 나눗셈
      

      2. 아래 코드의 출력값은 무엇일까요? 코드를 돌려보기 전에 예측해보세요.

      public class Question {
          public static void main(String args[]) {
              // 아래 코드의 출력값은 무엇일까요?
              System.out.println(10 / 2 + 3 * 4);
          }
      }
      // 17

      4. 아래 코드의 실행 결과가 true가 되도록 수정해보세요.

      public class Question {
      public static void main(String args[]) {
          // 아래 코드의 실행 결과가 true가 되도록 수정해보세요.
          String str1 = new String("Hello world!");
          String str2 = new String("Hello world!");
          
          System.out.println(str1 == str2);
      	}
      			}
      
      // 정답!
      System.out.println(str1.equals(str2));
      	
profile
goldsong

0개의 댓글