피연산자와 연산자에서 반환된 결과는 하나의 리터럴처럼 사용할 수 있습니다. 이는 일반 산술 연산 뿐아니라 대입 연산 등 모든 연산에서의 값을 다른 변수에 지정할 수 있다는 것을 말합니다.
기본 연산을 수행하는 피연산자의 데이터 타입이 다르다면, 더 큰 범위를 갖는 피연산자의 데이터형으로 프로모션(업캐스팅)되어 연산된 결과가 반환됩니다.
산술연산자는 boolean
을 제외한 primitive type
간 기본 연산을 수행 결과를 반환합니다.
+, -, *, /, %
와 같은 연산자가 있으며 모두 이항 연산자입니다.
+
)더하기(+
) 는 양 옆의 두 피연산자를 더해준 결과를 반환합니다.
기본형 타입이 아닌 변수는 더하기 연산이 불가능하지만 String Class
는 예외적으로 +
로 산술연산이 가능합니다. 어떤 연산식에 String
객체 혹은 String
리터럴이 포함된다면 해당 수식의 모든 값은 String으로 비교하여 반환됩니다.
연산 간 프로모션이 발생하여 기본형 변수는 값이 가르키고 있는 실제 값이 String으로 반환되어 연산되며 참조형 변수는 해당 객체의 toString()
메소드를 통해 반환된 문자열로 치환됩니다.
Object o1 = new Object();
Object o2 = new Object();
System.out.println(o1 + o2);
// println 메소드는 기본적으로 레퍼런스의 toString을 호출하지만 객체 간 산술연산은 불가능하므로 에러가 발생합니다.
String str = "hello";
System.out.println(str + o1 + o2);
//hello o1.toString() o2.toString()
//산술연산식에 String이 각 레퍼런스는 toString()을 호출하여 반환된 String으로 연산합니다.
System.out.println(o1 + o2 + "");
//o1.toString() o2.toString()
//이 역시 연산식에 String이 포함되었으므로 연산이 가능합니다.
-
)빼기 연산자(-
)는 왼쪽 피연산자에서 오른쪽 피연산자를 뺀 결과를 반환합니다.
*
)곱하기 연산자(*
)는 두 피연산자의 곱의 결과를 반환합니다.
/
)나누기 연산자(/
)는 왼쪽 피연산자에서 오른쪽 피연산자를 나눈 결과를 반환합니다.
몫만 반환하는 것이 아니라 전체 결과를 반환하지만 두 피연산자가 모두 정수형이라면 결과도 정수형으로 반환되므로 몫만 반환받습니다.
반대로 두 피연산자 중 하나라도 실수형 값이 있다면, 타입 프로모션에 의해서 실수형 결과값이 반환됩니다.
0
나누기 연산자바에서는 정수형을 결과로 갖는 0
으로 나누는 연산을 허옹하지 않습니다. 이 때는 ArithmeticException
을 발생시킵니다.
실수를 결과로 갖는 0
으로 나누는 연산은 infinity
값을 갖게됩니다.
//infinity
System.out.println(1.0/0);
//infinity
System.out.println(1/0.0);
//ArithmeticException
System.out.println(1/0);
%
)나머지 연산자(%
)는 왼쪽 피연산자에서 오른쪽 피연산자를 나눴을 때의 나머지 값을 반환합니다.
피연산자와 결과값에 모두 실수형을 가질 수 있지만 결과는 연산 프로모션에 의해 가장 큰 범위의 데이터형으로 반환됩니다.
System.out.println(2 % 1.2);
System.out.println(2.4 % 1.2);
System.out.println(5 % 2);
/*
출력
0.8
0.0
1
*/
0
나머지 연산나머지 연산에서도 정수형을 결과로 갖는 0
으로 나누는 연산을 허옹하지 않으며ArithmeticException
을 발생시킵니다.
실수 간 연산에서도 0
으로 나눴을 때 나머지를 갖는 수는 없으므로 NaN
값을 갖게 됩니다.
//NaN
System.out.println(1.0%0);
//NaN
System.out.println(1%0.0);
//ArithmeticException
System.out.println(1%0);