📝 TIL

[TIL] Java 연산자의 종류, 우선순위, 타입 변환

오늘 ONEUL 2022. 11. 8. 21:12

✍ Today I Learned

 

  • 버벅거렸던 첫날에 비해 시간이 많이 단축되었다. 익숙해지는 중!
  • 연산을 진행하면서 타입 변환이 되는 부분을 꼼꼼하게 숙지해보자.

 


 

03 연산자

03-1 연산자와 연산식

시작하기 전에

  • 연산자(operator): 연산에 사용되는 표시나 기호
  • 피연산자(operand): 연산자와 함께 연산되는 데이터
  • 연산식(expression): 연산자와 피연산자를 이용하여 연산의 과정을 기술한 것
    • 연산식은 반드시 하나의 값을 산출하며, 값 대신에 연산식을 사용할 수 있다.

연산의 방향과 우선순위

  • 단항, 이항, 삼항 연산자 순으로 우선순위를 가진다.
  • 산술, 비교, 논리, 대입 연산자 순으로 우선순위를 가진다.
  • 단항, 부호, 대입 연산자를 제외한 모든 연산의 방향은 왼쪽에서 오른쪽이다.(→)
  • 복잡한 연산식에는 괄호()를 사용해서 우선순위를 정한다.
우선순위 연산자 설명 결합 방향
1 [] 첨자 연산자 왼쪽에서 오른쪽으로
  . 멤버 연산자 왼쪽에서 오른쪽으로
2 ++ 후위 증가 연산자 왼쪽에서 오른쪽으로
  -- 후위 감소 연산자 왼쪽에서 오른쪽으로
3 ! 논리 NOT 연산자 오른쪽에서 왼쪽으로
  ~ 비트 NOT 연산자 오른쪽에서 왼쪽으로
  + 양의 부호 (단항 연산자) 오른쪽에서 왼쪽으로
  - 음의 부호 (단항 연산자) 오른쪽에서 왼쪽으로
  ++ 전위 증가 연산자 오른쪽에서 왼쪽으로
  -- 전위 감소 연산자 오른쪽에서 왼쪽으로
  (타입) 타입 캐스트 연산자 오른쪽에서 왼쪽으로
4 * 곱셈 연산자 왼쪽에서 오른쪽으로
  / 나눗셈 연산자 왼쪽에서 오른쪽으로
  % 나머지 연산자 왼쪽에서 오른쪽으로
5 + 덧셈 연산자 (이항 연산자) 왼쪽에서 오른쪽으로
  - 뺄셈 연산자 (이항 연산자) 왼쪽에서 오른쪽으로
6 << 비트 왼쪽 시프트 연산자 왼쪽에서 오른쪽으로
  >> 부호 비트를 확장하면서 비트 오른쪽 시프트 왼쪽에서 오른쪽으로
  >>> 부호 비트까지 모두 비트 오른쪽 시프트 왼쪽에서 오른쪽으로
7 < 관계 연산자(보다 작은) 왼쪽에서 오른쪽으로
  <= 관계 연산자(보다 작거나 같은) 왼쪽에서 오른쪽으로
  > 관계 연산자(보다 큰) 왼쪽에서 오른쪽으로
  >= 관계 연산자(보다 크거나 같은) 왼쪽에서 오른쪽으로
  instanceof 인스턴스의 실제 타입 반환 왼쪽에서 오른쪽으로
8 == 관계 연산자(와 같은) 왼쪽에서 오른쪽으로
  != 관계 연산자(와 같지 않은) 왼쪽에서 오른쪽으로
9 & 비트 AND 연산자 왼쪽에서 오른쪽으로
10 ^ 비트 XOR 연산자 왼쪽에서 오른쪽으로
11 | 비트 OR 연산자 왼쪽에서 오른쪽으로
12 && 논리 AND 연산자 왼쪽에서 오른쪽으로
13 || 논리 OR 연산자 왼쪽에서 오른쪽으로
14 ? : 삼항 조건 연산자 오른쪽에서 왼쪽으로
15 = 대입 연산자 및 복합 대입 연산자
(=, +=, -=, *=, /=, %=, <<=, >>=, >>>=, &=, ^=, |=)
오른쪽에서 왼쪽으로

 

 

03-2 연산자의 종류

부호 연산자

  • 부호 연산자(+, -)는 변수의 부호를 유지(+)하거나 변경(-)한다.
  • 부호 연산자의 결과는 int 타입이다. byte 타입 변수를 부호 연산하면 int 타입으로 변환된다.
byte b = 100;
byte result = -b; // 컴파일 에러

byte b = 100;
int result = -b; // 부호 연산의 결과는 int타입 이므로 int 변수에 저장해야함

증감 연산자

  • 연산식에서 증감 연산자만 사용된다면 증감 연산자의 위치는 상관없으나, 다른 연산자와 함께 사용된다면 증감 연산자의 위치에 따라 연산식의 결과가 다르게 나온다.
int x = 1;
int y = 1;
int result1 = ++x + 10; // 12
int result2 = y++ + 10; // 11

++i와 i = i + 1의 연산 속도 차이

  • 두 연산식 모두 컴파일해서 바이트 코드를 비교해보면 동일하다. 연산 속도의 차이는 없다.

산술 연산자

  • long 타입을 제외한 정수 타입 연산은 int 타입으로 산출되고, 피연산자 중 하나라도 실수 타입이면 실수 타입으로 산출된다.
  • ex1) 피연산자들이 byte, short, char 타입일 경우 모두 int 타입으로 변환된 후 연산 수행
byte + byte -> int + int = int
  • ex2) 피연산자들이 모두 정수 타입이고 long 타입이 포함되어 있을 경우, 모두 long 타입으로 변환된 후 연산 수행
int + long -> long + long = long
  • ex3) 피연산자 중 실수 타입(float, doule)이 있을 경우, 허용 범위가 큰 실수 타입으로 변환된 후 연산 수행
int + double -> double + double = double

비교 연산자

  • 피연산자가 char 타입이면 유니코드 값으로 비교 연산을 수행한다.
('A' < 'B') -> (65 < 66)
  • 비교 연산자가 연산을 수행하기 전에 피연산자 타입을 일치시킨다.
3 == 3.0 -> 3이 double 타입으로 변환되어 3.0 == 3.0
  • 예외: 0.1과 0.1f의 결과는 같지 않다.
    • 이유는 실수의 저장 방식인 부동 소수정 방식이 0.1을 정확히 표현할 수 없기 때문이다.
    • 피연산자를 모두 float타입으로 변환해서 비교하거나 정수 타입으로 변환해서 비교해야 한다.
0.1 == 0.1f -> false
  • 기본 타입(byte, char, short, int long, float, double, boolean) 변수의 값을 비교할 때에는 == 연산자를 사용하지만 참조 타입인 String 변수를 비교할 때에는 equals() 메서드를 사용한다.

논리 연산자

  • XOR(베타적 논리합): 피연산자가 하나는 ture이고 다른 하나가 false일 경우에만 true → ^
  • &&은 앞의 피연산자가 false라면 뒤의 피연산자를 평가하지 않고 바로 false라는 산출 결과를 낸다. 그러나 &는 두 피연산자 모두를 평가해서 산출 결과를 낸다. 따라서 &보다는 &&이 더 효율적으로 동작한다.
  • ||도 마찬가지!

대입 연산자

  • 대입 연산자는 모든 연산자들 중에서 가장 낮은 연산 순위를 가지고 있기 때문에 제일 마지막에 수행된다.

 

 

 

 

※ 이 내용은 책 [혼자 공부하는 자바]를 보고 정리한 내용입니다.