자바에서 타입 변환(Type Conversion)은 데이터 타입을 다른 타입으로 변환하는 과정을 말한다.
이는 프로그래밍에서 매우 일반적인 작업으로, 데이터의 정확성과 프로그램의 효율성을 유지하기 위해 중요하다. 타입 변환에는 크게 자동 타입 변환(묵시적 타입 변환)과 강제 타입 변환(명시적 타입 변환) 두 가지 방법이 있다.
타입 변환은 변수나 리터럴의 데이터 타입을 다른 타입으로 변경하는 과정으로 데이터의 정확성과 프로그램의 효율성을 유지하기 위해 중요하며, 타입 변환에는 크게 자동 타입 변환(묵시적 타입 변환)과 강제 타입 변환(명시적 타입 변환) 두 가지 방법이 있다.
예를 들어, int 타입을 double 타입으로 변환하거나, double 타입을 int 타입으로 변환할 수 있다.
자동 타입 변환은 작은 크기의 타입을 큰 크기의 타입으로 변환하는 것으로, 개발자가 별도의 조치를 취하지 않아도 컴파일러가 자동으로 변환해준다. 이는 데이터 손실이 발생하지 않는 안전한 변환이다.
byte → intchar → int (문자형을 정수형으로 변환 시 유니코드 값이 됨)int → longint → double예시 코드
public class AutoCasting {
public static void main(String[] args) {
ForceCasting fc = new ForceCasting(); // 참조 타입 변수, class 선언
byte byteValue = 10;
int intValue = byteValue; // 타입 변환 (byte -> int)
System.out.println(intValue);
char charValue = '가';
intValue = charValue; // char 타입에서 int 타입으로 변환하면 유니코드가 된다.
System.out.println("'가'의 유니코드= " + intValue);
intValue = 500; // 500으로 초기화
long longValue = intValue; // 타입 변환 (int -> long)
System.out.println(longValue);
intValue = 200; // int 에 200 이라는 정수형값을 넣고 실수형(double) 값으로 변환
double doubleValue = intValue; // 타입 변환 (int -> double), 타입이 변환되면서 더 큰 숫자로 변환된다.(200.0)
System.out.println(doubleValue);
}
}
10
'가'의 유니코드= 44032
500
200.0
유니코드는 전 세계의 모든 문자를 컴퓨터에서 일관되게 표현하고 다루도록 하는 표준이다.
예를 들어, char 타입을 int로 변환하면 해당 문자의 유니코드 값이 된다.
강제 타입 변환은 큰 크기의 타입을 작은 크기의 타입으로 변환하는 것으로, 데이터 손실이 발생할 수 있기 때문에 개발자가 명시적으로 변환을 지시해야한다. 이를 캐스팅(Casting)이라고 한다.
double → int (소수점 이하 버림)long → shortint → byte예시 코드
public class ForceCasting {
public static void main(String[] args) {
// long -> int 변환 || 변형이 일어나지는 않음 (값의 범위 내이기 때문)
long longValue = 300L;
int intValue = (int) longValue; // long을 int로 명시적 변환 (캐스팅)
System.out.println("longValue = " + longValue);
System.out.println("intValue = " + intValue); // 300 출력
// double -> int 변환 || 변형이 일어남 (소수점 이하 손실)
double pi = 3.14;
int convertedInt = (int) pi; // double을 int로 명시적 변환 (캐스팅)
System.out.println("pi = " + pi);
System.out.println("convertedInt = " + convertedInt); // 소수점 이하가 버려져서 3 출력
// String -> char (캐스팅 불가)
String stringValue = "A";
// char ver = (char) stringValue; // 컴파일 오류 발생 (캐스팅 불가)
// charAt() 메서드를 사용하여 String에서 char 추출
char changedValue = stringValue.charAt(0);
System.out.println("stringValue = " + stringValue);
System.out.println("changedValue = " + changedValue); // 'A' 출력
}
}
longValue = 300
intValue = 300
pi = 3.14
convertedInt = 3
stringValue = A
changedValue = A
연산식에서 서로 다른 타입의 변수가 연산에 사용되면, 더 큰 크기의 타입으로 자동 변환된다.
이는 데이터 손실을 방지하고 연산의 정확성을 유지하기 위한 것이다.
예를 들어, int와 double 타입의 값을 더하면 int가 double로 자동 변환되어 연산이 수행되는데, 결과를 int로 내고 싶다면, double타입을 int로 캐스팅해주면 된다.
예시 코드
public class AutoCastingInOperand {
public static void main(String[] args) {
int intValue = 10;
double doubleValue = 5.5;
// 연산식에서 자동 타입 변환이 일어남 (int -> double)
double result = intValue + doubleValue; // intValue가 double로 자동 변환되어 연산이 수행됨
System.out.println("intValue + doubleValue의 결과 (double result) = " + result); // 15.5 출력
// int 타입으로 연산을 수행하려면 doubleValue를 int로 강제 변환
int intResult = intValue + (int) doubleValue; // doubleValue의 소수점 이하가 버려짐
System.out.println("intValue + (int)doubleValue의 결과 (int result) = " + intResult); // 15 출력
}
}
intValue + doubleValue의 결과 (double result) = 15.5
intValue + (int)doubleValue의 결과 (int result) = 15
문자열을 문자로 변환: 문자열(String)을 직접 char 타입으로 변환할 수는 없지만, String 클래스의 charAt(index) 메서드를 사용하여 특정 인덱스의 문자를 char 타입으로 가져올 수 있다.
예시 코드
public class StringToCharExample {
public static void main(String[] args) {
// 문자열 "A"를 char로 변환
String stringValue = "A";
char changedValue = stringValue.charAt(0); // 문자열의 첫 번째 문자를 char로 변환
// 결과 출력
System.out.println("문자열 stringValue = " + stringValue);
System.out.println("변환된 문자 changedValue = " + changedValue);
}
}
문자열 stringValue = A
변환된 문자 changedValue = A
기본 자료형:
참조 자료형:
String s = "Hello";라고 선언하면 s 변수는 "Hello" 문자열이 저장된 메모리 주소를 가리키게 된다.힙 메모리와 스택 메모리:
가비지 컬렉터:
예시 코드
public class ReferenceTypeExample {
public static void main(String[] args) {
// 기본 자료형 변수
int primitiveValue = 42;
// 참조 자료형 변수
String referenceValue = "Hello";
// 메모리 상태
// primitiveValue는 스택에 42라는 값을 직접 저장
// referenceValue는 스택에 문자열 "Hello"의 주소값을 저장하고, 문자열은 힙에 저장
System.out.println("primitiveValue = " + primitiveValue); // 42 출력
System.out.println("referenceValue = " + referenceValue); // "Hello" 출력
}
}
기본 자료형의 초기화:
int a = 10;참조 자료형의 초기화:
new 키워드를 사용하여 초기화한다.String str = new String("Hello");String은 리터럴 값으로도 초기화할 수 있다.String str = "Hello";⭐ String 초기화 예외:
new String()으로 초기화하면 항상 새로운 객체를 생성한다.```java
String str = "실제값";
String str2 = new String("실제값");
String str3 = ""; // null
```
**⭐ new String vs " " 차이** (ch5.3장 참조 자료형 String의 동등 비교 참고)
값을 저장하는 영역이 다르다(저장하는 방식이 다르다).
리터럴로 저장하게 되면 특정 위치에 저장하고,
new라고 선언하면 주소값을 저장한다.예시 코드
public class Sample{
public static void main(String[] args) {
// 기본 자료형 변수의 초기화
int a = 10;
// 참조 자료형 변수의 초기화 (new 키워드 사용)
String str1 = new String("Hello");
// 참조 자료형 변수의 초기화 (리터럴 사용)
String str2 = "Hello";
// str1과 str2는 동일한 문자열 값을 가지지만, 서로 다른 메모리 주소를 가리킴
System.out.println("str1 == str2: " + (str1 == str2)); // false 출력
// 문자열의 값이 같은지 비교할 때는 equals() 메서드 사용
System.out.println("str1.equals(str2): " + str1.equals(str2)); // true 출력
// 같은 리터럴로 초기화된 문자열은 같은 메모리 주소를 가리킴
String str3 = "Hello";
System.out.println("str2 == str3: " + (str2 == str3)); // true 출력
}
}
new 키워드를 사용한 초기화 간에 메모리 처리 방식이 다르다.기본 자료형을 객체처럼 다루기 위해 래퍼 클래스(Wrapper Class)를 사용한다.
래퍼 클래스를 사용하면 기본 자료형을 참조 자료형처럼 사용할 수 있으며, 이 과정에서 박싱과 언박싱이 발생한다.
byte, short, int, long, float, double, char, booleanByte, Short, Integer, Long, Float, Double, Character, BooleanInteger number = Integer.valueOf(10); // 박싱int num = number.intValue(); // 언박싱Integer number = 10; // 오토박싱int num = number; // 오토언박싱예시 코드
Integer number = Integer.valueOf(index); // 박싱(Boxing)
Integer number = index; // 오토박싱(Auto Boxing)
기본 자료형보다 wrapper 타입 크기가 더 크기 때문에 오토박싱해준다.
위 두 방법 모두 가능하지만 wrapper 클래스를 사용하여 박싱을 해주면 좀 더 명시적이다.
import java.util.ArrayList;
public class BoxingUnboxingExample {
public static void main(String[] args) {
// 박싱 예시
int primitiveValue = 10;
Integer wrappedValue = Integer.valueOf(primitiveValue); // 박싱
System.out.println("박싱된 값: " + wrappedValue);
// 언박싱 예시
int unboxedValue = wrappedValue.intValue(); // 언박싱
System.out.println("언박싱된 값: " + unboxedValue);
// 오토박싱 예시
Integer autoBoxedValue = primitiveValue; // 오토박싱
System.out.println("오토박싱된 값: " + autoBoxedValue);
// 오토언박싱 예시
int autoUnboxedValue = autoBoxedValue; // 오토언박싱
System.out.println("오토언박싱된 값: " + autoUnboxedValue);
// 제네릭 컬렉션과 오토박싱
ArrayList<Integer> list = new ArrayList<>();
list.add(primitiveValue); // 오토박싱되어 리스트에 추가됨
System.out.println("리스트의 첫 번째 값: " + list.get(0)); // 언박싱되어 출력됨
}
}
제네릭(Generic)은 특정 타입의 객체만을 다룰 수 있도록 타입을 미리 지정하는 기능으로, 제네릭을 사용하면 컴파일 시점에서 타입 오류를 검출할 수 있어 안전한 코드 작성에 도움이 된다.
웹 페이지에서 사용자 입력을 받아 계산을 수행하거나, 숫자를 문자열로 변환하여 출력할 때 유용하다.
Integer.parseInt(String s): 문자열을 int 타입으로 변환한다.int num = Integer.parseInt("123");NumberFormatException이 발생한다.Integer.valueOf(String s): 문자열을 Integer 객체로 변환한다.Integer number = Integer.valueOf("123");Integer.toString(int i): 숫자를 문자열로 변환한다.String str = Integer.toString(123);String.valueOf(int i): 숫자를 문자열로 변환한다.String str = String.valueOf(123);+ "" (캐스팅 방식): 숫자에 빈 문자열을 더하여 문자열로 변환한다.String str = 123 + "";코드 예시
public class StringConvertor {
public static void main(String[] args) {
// String -> 숫자 변환
String str = "12345";
// 문자열을 int로 변환
int primitiveInt = Integer.parseInt(str); // int로 변환
int sum = primitiveInt + 1; // 12346
Integer wrapperInt = Integer.valueOf(str); // Integer로 변환
// 문자열을 long으로 변환
long primitiveLong = Long.parseLong(str); // long 타입으로 변환
Long wrapperLong = Long.valueOf(str); // Long 타입으로 변환
String value = "10000.345";
// 문자열을 float로 변환
float primitiveFloat = Float.parseFloat(value); // float 타입으로 변환
Float wrapperFloat = Float.valueOf(value); // Float 타입으로 변환
// 문자열을 double로 변환
double primitiveDouble = Double.parseDouble(value); // double 타입으로 변환
Double wrapperDouble = Double.valueOf(value); // Double 타입으로 변환
// 숫자 -> 문자열 변환
int intValue = 10;
String s1 = intValue + ""; // int를 문자열로 변환 (Casting 방식)
String s2 = Integer.toString(intValue); // int를 문자열로 변환
String s3 = String.valueOf(intValue); // int를 문자열로 변환
System.out.println("문자열 '12345' -> int: " + primitiveInt);
System.out.println("문자열 '12345' -> Integer: " + wrapperInt);
System.out.println("문자열 '12345' -> long: " + primitiveLong);
System.out.println("문자열 '12345' -> Long: " + wrapperLong);
System.out.println("문자열 '10000.345' -> float: " + primitiveFloat);
System.out.println("문자열 '10000.345' -> Float: " + wrapperFloat);
System.out.println("문자열 '10000.345' -> double: " + primitiveDouble);
System.out.println("문자열 '10000.345' -> Double: " + wrapperDouble);
System.out.println("int 10 -> 문자열 (빈 문자열 추가): " + s1);
System.out.println("int 10 -> 문자열 (Integer.toString): " + s2);
System.out.println("int 10 -> 문자열 (String.valueOf): " + s3);
// 숫자 -> 문자열 변환 결과 출력
System.out.println(s1);
System.out.println(s2);
System.out.println(s3);
}
}
Integer.parseInt() 또는 Integer.valueOf()를 사용하며, 숫자를 문자열로 변환할 때는 Integer.toString() 또는 String.valueOf()를 사용한다.