[자바] 3. 연산자

[자바] 3. 연산자

목차

자바 연산자는 연산을 수행하는 기호로, 종류가 많아 보이지만 기능이 비슷한 것끼리 묶으면 몇 가지로 정리된다. 이 글에서는 산술·비교·논리 연산자를 비롯한 자바 연산자의 종류와 우선순위, 결합 규칙, 그리고 형변환까지 예제 코드와 함께 정리한다.

이 글은 [자바] 기초 시리즈의 3편이다. 1편 자바란?, 2편 변수에 이어 연산자를 다루며, 다음은 4편 조건문과 반복문으로 이어진다.

1. 연산자와 피연산자

연산자는 ‘연산을 수행하는 기호’를 말한다. 예를 들어 + 기호는 덧셈 연산을 수행하며 ‘덧셈 연산자’라고 부른다. 자바는 사칙연산(+ - * /)을 비롯해 다양한 연산자를 제공한다.

연산자가 연산을 수행하려면 반드시 연산의 대상이 있어야 하는데, 이 대상이 피연산자다. 4 * x + 3이라는 식에서 4, x, 3이 피연산자이고 *+가 연산자다.

2. 연산자의 종류

연산자의 개수는 많지만 기능이 비슷한 것끼리 묶어 보면 종류는 몇 가지 안 된다.

자바 연산자의 종류 분류 표

피연산자의 개수로 연산자를 분류하기도 한다. 피연산자가 하나면 단항 연산자, 둘이면 이항 연산자, 셋이면 삼항 연산자다. 예를 들어 -3 - 5에서 첫 번째 -는 부호 연산자(단항)이고 두 번째 -는 산술 연산자(이항)다. 연산자의 모양이 같아도 피연산자의 개수로 구분할 수 있다.

이렇게 연산자를 기능과 피연산자 개수로 나누어 분류하는 이유는 연산자의 우선순위 때문이다. 종류별로 우선순위를 익혀 두면 식을 읽기가 편해진다.

3. 연산자의 우선순위

자바 연산자 우선순위 표

초등 수학에서 배운 것처럼 곱셈과 나눗셈이 덧셈·뺄셈보다 우선순위가 높다. 같은 우선순위의 연산자가 이어질 때 어느 쪽부터 계산하는지는 다음에 나오는 결합 규칙으로 결정된다.

4. 연산자의 결합 규칙

자바 연산자 결합 규칙 예시

결합 규칙은 같은 우선순위의 연산자를 어느 방향부터 계산할지 정한다. 산술 연산자는 왼쪽에서 오른쪽으로 결합한다. 예를 들어 3 + 4 - 53 + 4를 먼저 계산한 뒤 그 결과인 7 - 5를 계산한다.

반면 대입 연산자는 오른쪽에서 왼쪽으로 결합한다. x = y = 3은 오른쪽의 y = 3이 먼저 실행되어 y에 3이 저장되고, 그다음 x에 3이 저장된다. 수학의 등호 =와 대입 연산자 =의 모양이 같아 처음에는 어색하지만 익숙해지면 자연스럽다.

5. 증감 연산자 ++ 와 —

증가 연산자(++)와 감소 연산자(--)를 합쳐 증감 연산자라고 한다. 증감 연산자는 피연산자의 왼쪽이나 오른쪽에 붙을 수 있는데, 왼쪽에 위치하면 전위형, 오른쪽에 위치하면 후위형이라고 한다.

전위(++i)로 쓰나 후위(i++)로 쓰나, 독립적으로 사용하면 i의 값을 1 증가시키므로 결과의 차이가 없다. 차이가 나는 경우는 다른 연산과 함께 쓰일 때다.

자바 전위 증감 연산자와 후위 증감 연산자 차이 예시

전위는 i의 값을 먼저 증가시킨 뒤 그 값을 참조하지만, 후위는 i의 값을 먼저 참조하여 연산한 다음에야 i를 증가시킨다. 이 차이는 반복문을 배울 때 다시 다루므로, 지금 이해가 잘 되지 않으면 반복문과 함께 복습해도 좋다.

6. 부호 연산자

부호 연산자 -를 붙이면 피연산자의 부호를 반대로 바꾼 결과를 반환한다. 피연산자가 음수면 양수로, 양수면 음수로 만든다. 부호 연산자 +도 존재하지만 값을 바꾸지 않으므로 쓸 일은 거의 없다.

7. 형변환(casting) 연산자

형변환이란 변수 또는 상수의 타입을 다른 타입으로 변환하는 것이다. 방법은 간단하다. 형변환하려는 변수나 리터럴 앞에 변환하려는 타입을 괄호에 넣어 (타입)피연산자 형태로 붙여 주면 된다.

자바 기본형 형변환 예시

앞 단원(변수)에서 String 변환은 빈 문자열을 붙이는 방법으로 했다. 그 이유는 String이 기본 데이터 타입이 아니기 때문이다. 기본형은 (타입)피연산자 형태로 형변환한다.

참고로 String을 변환할 때는 빈 문자열을 더하기보다 String.valueOf() 메서드나 객체의 toString() 메서드를 사용하면 가독성이 더 좋다. 또한 기본형뿐 아니라 상속 관계에 있는 객체 타입도 (타입)피연산자로 형변환할 수 있다.

class Parent {}
class Child extends Parent {}

public class Main {
    public static void main(String[] args) {
        Parent parent = new Child();  // 업캐스팅 (자동 형변환)
        Child child = (Child) parent; // 다운캐스팅 (명시적 형변환)
    }
}

위 코드는 상속 관계에 있는 클래스 간의 업캐스팅과 다운캐스팅 예시다. 지금은 기본형 외에도 (타입)피연산자로 형변환하는 경우가 있다는 정도만 알아 두면 된다.

8. 자동 형변환(묵시적 형변환)

서로 다른 타입 간에 대입이나 연산을 할 때는 먼저 형변환하여 타입을 일치시키는 것이 원칙이다. 다만 편의상 형변환을 생략할 수 있는데, 이때 형변환을 안 하는 것이 아니라 컴파일러가 생략된 형변환을 자동으로 추가해 준다.

float f = 1234; // float f = (float)1234; 에서 (float)가 생략됨

9. 사칙 연산자

앞서 말한 대로 곱셈(*), 나눗셈(/), 나머지(%) 연산이 덧셈(+), 뺄셈(-)보다 우선순위가 높다. 그리고 피연산자가 정수형인 경우 나누는 수로 0을 사용할 수 없으며, 사용하면 에러가 발생한다.

10. 산술 변환

이항 연산자는 두 피연산자의 타입이 일치해야 연산이 가능하다. 타입이 다르면 연산 전에 형변환으로 타입을 맞춰야 하는데, 이처럼 연산 직전에 자동으로 일어나는 형변환을 산술 변환이라고 한다. 이항 연산뿐 아니라 단항 연산에서도 일어나며 규칙은 다음과 같다.

  • ① 두 피연산자의 타입을 더 큰 타입으로 일치시킨다. 예: long + int → long + long → long, float + int → float + float → float
  • ② 피연산자의 타입이 int보다 작으면 int로 변환한다. 예: byte + short → int + int → int, char + short → int + int → int

산술 변환은 연산 직전에 발생하는 자동 형변환일 뿐이니 너무 어렵게 생각하지 않아도 된다.

11. Math.round()로 반올림하기

반올림을 하려면 Math.round()를 사용한다. 이 메서드는 소수점 첫째 자리에서 반올림한 결과를 정수로 반환한다.

long result = Math.round(4.52); // result에 반올림된 정수 5가 저장된다

12. 나머지 연산자

나머지 연산자 %는 왼쪽 피연산자를 오른쪽 피연산자로 나눈 나머지를 반환한다. 나눗셈과 마찬가지로 나누는 수로 0을 사용할 수 없으며, 피연산자로 정수와 실수를 허용한다. 주로 홀수·짝수 판별이나 배수 검사에 사용한다.

10 % 8 // 2

13. 비교 연산자

비교 연산자는 두 피연산자를 비교하는 데 사용된다. 주로 조건문과 반복문의 조건식에 쓰이며, 연산 결과는 오직 truefalse뿐이다.

자바 비교 연산자 종류 표
1 == 1 // true
1 < 2  // true

14. 문자열의 비교

두 문자열을 비교할 때는 비교 연산자 ==가 아니라 equals() 메서드를 사용해야 한다. 비교 연산자는 두 문자열이 같은 객체인지를 비교할 뿐, 내용이 같은지를 비교하지 못한다. 대소문자를 구분하지 않고 비교하려면 equals() 대신 equalsIgnoreCase()를 사용하면 된다.

15. 논리 연산자 && 와 ||

  • || (OR): 피연산자 중 어느 한쪽이라도 true이면 true를 반환한다.
  • && (AND): 피연산자 양쪽 모두 true여야 true를 반환한다.
자바 논리 연산자 진리표

비교 연산의 결과가 true 또는 false이므로 1 == 1 || 2 == 3 // true처럼 비교 결과를 논리 연산으로 이어 붙일 수 있다.

한 가지 더, || 연산은 왼쪽 피연산자가 true이면 오른쪽 피연산자를 아예 평가하지 않는다. 이를 단축 평가(short-circuit evaluation)라고 한다.

16. 논리 부정 연산자 !

논리 부정 연산자 !truefalse로, falsetrue로 바꾼다. !를 ‘not’으로 생각하면 이해하기 쉽다. 어떤 값에 !를 반복해서 적용하면 토글 버튼처럼 truefalse를 번갈아 오간다.

17. 조건 연산자(삼항 연산자)

조건 연산자는 조건식, 식1, 식2까지 세 개의 피연산자를 필요로 하는 삼항 연산자이며, 자바의 삼항 연산자는 이 조건 연산자 하나뿐이다.

자바 조건 연산자(삼항 연산자) 구조

아래 코드는 앞서 언급한 논리 연산자 ||의 단축 평가를 조건 연산자와 함께 확인하는 예제다.

package ch01;

public class Hello {
    public static void main(String[] args) {
        boolean result = true || expensiveOperation();  // 논리 연산자 사용
        System.out.println(result
            ? "왼쪽 피연산자가 true라 단축 평가로 expensiveOperation은 호출되지 않습니다."
            : "볼 일 없는 메시지");
    }

    public static boolean expensiveOperation() {
        System.out.println("왼쪽 피연산자가 false인가 보네요");
        return true;
    }
}

조건 연산자는 조건식 resulttrue이면 첫 번째 문자열을, false이면 두 번째 문자열을 출력한다. 그런데 boolean result = true || expensiveOperation();에서 왼쪽 피연산자가 true이므로 ||는 오른쪽의 expensiveOperation()을 호출하지 않는다. 따라서 “왼쪽 피연산자가 false인가 보네요”는 출력되지 않는다.

만약 truefalse로 바꾸면 ||가 오른쪽 피연산자까지 평가하게 되어 expensiveOperation()이 호출되고, 그 안의 메시지가 출력된다.

18. 대입 연산자

대입 연산자는 연산 진행 방향이 오른쪽에서 왼쪽이다. 대입 연산자에서 왼쪽 피연산자를 lvalue, 오른쪽 피연산자를 rvalue라고 부른다.

19. 복합 대입 연산자

자바 복합 대입 연산자 종류 표

복합 대입 연산자는 종류가 많지만 규칙은 같다. = 왼쪽에 있는 연산을 양쪽 피연산자로 먼저 수행한 뒤 그 결과를 대입한다. 예를 들어 i += 3i = i + 3과 같다. 복합 대입 연산자도 증감 연산자처럼 반복문과 함께 복습하면 이해하기 좋다.

정리

자바 연산자는 산술·비교·논리·대입 등으로 나뉘며, 각각의 우선순위와 결합 규칙, 그리고 연산 전에 일어나는 형변환(산술 변환)을 이해하는 것이 핵심이다. 비교 연산자의 결과가 true/false라는 점, 문자열 비교는 equals()를 쓴다는 점, 논리 연산의 단축 평가까지 익혀 두면 다음 단계인 제어문을 수월하게 다룰 수 있다.

다음 글은 [자바] 4. 조건문과 반복문에서 if·switch 조건문과 for·while 반복문을 다룬다.

💬 댓글 0

💬 댓글을 남기려면?
첫 댓글을 남겨보세요 ✨

이 콘텐츠가 도움이 됐나요?

누스쿨 커뮤니티에서 더 많은 커리어 전략을 나눠요