[Java] 데이터타입과 형변환, 연산자

김아현·2022년 7월 30일
0

Java

목록 보기
1/1

이번 포스팅에서는 기본적인 자바 개념으로, 데이터 타입과 형변환 그리고 연산자에 대해 다뤄보도록 하겠습니다.

데이터 타입

Java에서는 데이터 타입을 두 종류로 나눌 수 있습니다. 기본형(Primitive)참조형(Referance) 타입인데요, 둘의 차이는 변수를 생성할 때 메모리의 크기가 정해지느냐 정해지지 않느냐, 그리고 변수가 값을 가지는지 주소를 참조하는지에 따라 구분됩니다.

각각의 특징을 먼저 살펴보고 한 번 더 정리해 보기로 합시다.

기본형

기본형은 앞서 말씀드린대로, 메모리 크기가 미리 정해져 있는 데이터타입으로 8가지 종류가 있습니다.

이미 정해져 있는 메모리 크기 때문에, 오버플로우를 주의 해야 합니다. 가령 int타입의 최대값에서 1을 더한다면 어떻게 될까요?

int i1 = Integer.MAX_VALUE;
int i2 = i1 + 1;
System.out.println(i1);		// 2147483647
System.out.println(i2);		// -2147483648

최대값에서 초기화되어 맨 앞의 부호자리가 1로 바뀌면서 제일 작은 마이너스로 바뀌게 됩니다. 그렇기 때문에 기본형의 데이터타입을 사용할 때는 얼마만큼의 수를 담을 것인지를 염두해 두고 그에 맞는 타입 선택이 필요합니다.

덧붙여서 실수형 중 double을 사용할 때 주의해야 할 것은 정밀도가 떨어진다는 것입니다. double 타입은 내부적으로 수를 저장할 때 이진수의 근사치를 저장했다가, 십진수로 변환하는 과정에서 소수점 이하의 수가 유실되는 경우가 있다고 합니다.
그래서 double로 계산을 할 때는,
1. 정수로 변환해 계산하거나
2. BigDecimal을 이용해서 계산하는 것이 좋습니다.

import java.math.BigDecimal;

public class Test {

	public static void main(String[] args) {
		float f1 = 2.0f;
		float f2 = 1.1f;
		float f3 = f1 - f2;
		System.out.println(f3); // 0.9

		double d1 = 2.0;
		double d2 = 1.1;
		double d3 = d1 - d2;
		System.out.println(d3); //8.9999999999

		// 정수로 계산하면 정확한 결과를 얻을 수 있음
		System.out.println(( (int)(d1*100) - (int)(d2*100))/100.0);	// 0.9

		BigDecimal b1 = new BigDecimal("2.0");
		BigDecimal b2 = new BigDecimal("1.1");
		System.out.println("BigDecimal을 이용한 빼기 : " + b1.subtract(b2));	// 0.9
	}

}

참조형

참조형 타입은 기본형과는 달리 메모리 크기가 미리 정해져 있지 않고, 값을 저장하는 메모리의 주소값을 참조합니다. 기본형에 8가지 타입이 있다면, 8가지 외의 모든 타입은 참조형이라고 생각하시면 됩니다. 가장 많이 쓰는 참조형 타입을 예로들면, Array, String, Object 등이 있습니다.

차이 정리

아래와 같이 간단하게 정리할 수 있습니다.


형변환

형변환은 말 그대로 변수의 형(타입)을 다른 형으로 변환하는 것을 말합니다. 형변환의 종류는 두 가지로 나눌 수 있습니다. 묵시적 형변환과 명시적 형변환입니다.

묵시적 형변환

어떤 타입의 데이터를 다른 타입의 데이터에 대입할 때, 암묵적으로 어떤 타입을 다른 타입으로 변환해 주는 것을 의미합니다. 묵시적 형변환이 가능하려면 갖추어야 할 조건은, 작은 크기의 타입이 큰 크기의 타입으로 대입해야 됩니다.

기본형 타입들을 크기에 따라 오름차순 정렬한 그림입니다. 여기서 짚어야 할 것은, 메모리의 크기가 아니라 담을 수 있는 수의 범위에 초점을 맞춰야 합니다.

int i = 10;
long l = i;
double d = l;

명시적 형변환

작은 범위의 타입에서 큰 범위의 타입은 암묵적으로 허용이 되는게, 데이터가 손실될 가능성이 없기 때문입니다. 그럼 반대로 큰 타입이 작은 타입에 대입되는 것은 데이터가 손실될 수 있다는 것입니다. 그렇기 때문에 형변환을 담당하는 JVM은 이때만큼은 개발자가 데이터 손실 가능성에 대해 책임을 지라는 의미로 명시적으로 형변환할 것을 요구하게 됩니다.

double d = 7.3;
long l = (long)d;
int i = (int)l;

Wrapper 클래스

객체지향 프로그래밍 언어인 자바에서는 기본형 타입도 객체로 처리해야 하는 상황이 왕왕 생기게 됩니다. 이때 사용되는 것이 Wrapper 클래스입니다. Wrapper 클래스는 기본타입에 해당하는 데이터를 객체로 감싸주는 역할을 수행해서 기본형 변수를 참조형 변수로 형변환 시켜줍니다.
Wrapper 클래스는 java.lang 패키지에 포함되어 제공되므로 자동으로 import 됩니다.

박싱(Boxing)과 언박싱(UnBoxing)

위 그림처럼 기본형의 데이터를 래퍼 클래스의 인스턴스로 변환하는 과정을 Boxing, 래퍼 클래스 인스턴스에서 저장된 값을 다시 기본 타입으로 꺼내는 과정을 UnBoxing이라고 합니다.

오토 박싱(AutoBoxing)과 오토 언박싱(AutoUnBoxing)

JDK 1.5부터는 박싱과 언박싱이 필요한 상황에서 자바 컴파일러가 이를 자동으로 처리해 줍니다.

Integer num = new Integer(17); // 박싱
int n = num.intValue();        // 언박싱
System.out.println(n);

Character ch = 'X'; // Character ch = new Character('X'); : 오토박싱
char c = ch;        // char c = ch.charValue();           : 오토언박싱
System.out.println(c);

Object[] obj = new Object[1];
obj[0] = 1;  // 오토 박싱
System.out.println(obj[0].getClass().getName()); // java.lang.Integer

연산자

산술 연산

산술 연산의 특징은 아래와 같습니다.
1. 산술 연산의 최소 단위는 int 다.
-> int보다 작은 byte로의 산술연산은 에러 발생
-> charchar의 연산을 통해 아스키코드 값(int)으로 변환이 가능하다.
ex) 'C' - '0'
2. 산술 연산 시 메모리가 큰 타입을 따라가게 된다.
3. 실수는 double을 기본으로 한다.

byte b1 = 10;
byte b2 = 20;
// TODO: 다음에서 발생하는 오류를 읽고 원인을 말한 후 수정하시오.
// Type mismatch: cannot convert from int to byte
 byte b3 = b1 + b2;
// 산술연산의 최소단위는 int타입이기 때문
 byte b3 = (byte)(b1 + b2);
 int b3 = b1 + b2;

int i1 = 10;
long l1 = 20;
// TODO: 다음에서 발생하는 오류를 읽고 원인을 말한 후 수정하시오.
// Type mismatch: cannot convert from long to int
 int i2 = i1 + l1;
// 산술 연산 시 큰 타입을 따라가게 됨
 long i2 = i1 + l1;

// TODO: 다음에서 발생하는 오류를 읽고 원인을 말한 후 수정하시오.
// Type mismatch: cannot convert from long to int
 float f1 = 10.0; 
 float f2 = f1 + 20.0;
// 실수는 double을 기본으로 함
 float f1 = 10.0f;
 double f2 = f1 + 20.0;

연산자의 우선순위

TIP

  1. 산술 > 비교 > 논리 > 대입. 대입은 제일 마지막에 수행된다.
  2. 단항(1) > 이항(2) > 삼항(3). 단항 연산자의 우선순위가 이항 연산자보다 높다.
  3. 단항 연산자와 대입 연산자를 제외한 모든 연산의 진행방향은 왼쪽에서 오른쪽이다.

참고

[Java 연산자] https://gksdudrb922.tistory.com/135

profile
Want to be backend developer

0개의 댓글