본문으로 건너뛰기

Ch 3.1 연산자(Operator) 기초

프로그램에서 데이터를 가공하고 계산하기 위해 사용되는 기호를 연산자(Operator) 라고 합니다. 자바는 수학적 계산, 논리적 판단 등을 위한 다양한 연산자를 제공합니다. 이 챕터에서는 연산자의 개념, 분류, 우선순위, 결합 방향을 체계적으로 정리합니다.


1. 연산자와 피연산자​

  • 연산자(Operator): 연산을 수행하는 기호 (예: +, -, *, /, =)
  • 피연산자(Operand): 연산자의 작업 대상 (변수, 상수, 리터럴, 수식)
int result = x + 3;
// 연산자: = , +
// 피연산자: result, x, 3

연산자는 피연산자로 연산을 수행한 후 항상 결과값(Result) 을 반환합니다. 그 결과값은 변수에 저장하거나 다른 연산의 피연산자로 사용할 수 있습니다.

public class OperatorBasic {
public static void main(String[] args) {
int x = 10;
int y = 3;

// + 연산자: x와 y를 더한 결과(13)를 sum에 저장
int sum = x + y;

// * 연산자: sum과 2를 곱한 결과(26)를 product에 저장
int product = sum * 2;

// == 연산자: x와 10이 같은지 비교한 결과(true)를 isEqual에 저장
boolean isEqual = (x == 10);

System.out.println("sum = " + sum); // 13
System.out.println("product = " + product); // 26
System.out.println("isEqual = " + isEqual); // true
}
}

2. 연산자의 분류​

자바의 연산자는 피연산자의 개수 에 따라 세 가지로 분류할 수 있습니다.

분류설명예시
단항 연산자 (Unary)피연산자가 1개++i, --i, -x, !flag
이항 연산자 (Binary)피연산자가 2개a + b, x > y, a && b
삼항 연산자 (Ternary)피연산자가 3개조건 ? 참값 : 거짓값

또한 기능 에 따라 다음과 같이 분류할 수 있습니다.

종류연산자설명
산술 연산자+, -, *, /, %사칙연산 및 나머지
비교 연산자==, !=, >, <, >=, <=크기 및 동등 비교, 결과는 boolean
논리 연산자&&, ||, !, ^논리 AND, OR, NOT, XOR
대입 연산자=, +=, -=, *=, /=, %=우변 값을 좌변 변수에 저장
비트 연산자&, |, ^, ~, <<, >>, >>>이진수 비트 단위 연산
조건 연산자? :삼항 연산자, 조건에 따라 값 선택
기타instanceof, ->, ::타입 확인, 람다, 메서드 참조

3. 연산자 우선순위(Precedence)​

식에 여러 연산자가 섞여 있을 때, 어느 연산자를 먼저 처리할지 결정 하는 규칙입니다. 수학의 사칙연산 우선순위(*가 +보다 먼저)와 유사합니다.

아래 표는 우선순위가 높은 것부터 낮은 순 으로 정리한 것입니다.

우선순위연산자결합 방향설명
1 (최고)(), [], .좌 → 우괄호, 배열 접근, 멤버 접근
2++, -- (후위)좌 → 우후위 증감
3++, -- (전위), +, -, ~, !우 → 좌전위 증감, 단항 부호, 비트 NOT, 논리 NOT
4*, /, %좌 → 우곱셈, 나눗셈, 나머지
5+, -좌 → 우덧셈, 뺄셈
6<<, >>, >>>좌 → 우비트 시프트
7<, >, <=, >=, instanceof좌 → 우대소 비교, 타입 확인
8==, !=좌 → 우동등 비교
9&좌 → 우비트 AND
10^좌 → 우비트 XOR
11|좌 → 우비트 OR
12&&좌 → 우논리 AND
13||좌 → 우논리 OR
14? :우 → 좌삼항(조건) 연산자
15 (최저)=, +=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>=, >>>=우 → 좌대입 연산자
public class Precedence {
public static void main(String[] args) {
// * 가 + 보다 우선순위가 높으므로 먼저 계산됨
int result1 = 2 + 3 * 4; // 2 + 12 = 14
System.out.println(result1); // 14

// 괄호로 우선순위를 직접 지정
int result2 = (2 + 3) * 4; // 5 * 4 = 20
System.out.println(result2); // 20

// 비교 연산자가 논리 연산자보다 우선순위가 높음
boolean check = 5 > 3 && 10 < 20; // (5>3) && (10<20) = true && true = true
System.out.println(check); // true
}
}
우선순위가 헷갈릴 때는 괄호를 사용하세요

우선순위 표를 외우려 하지 않아도 됩니다. 복잡한 식에서는 괄호 ()를 사용해 우선순위를 직접 명시 하는 것이 가독성도 높이고 버그도 줄이는 좋은 습관입니다.


4. 결합 방향(Associativity)​

우선순위가 동일한 연산자 가 여러 개 나올 때, 왼쪽부터 처리할지 오른쪽부터 처리할지를 결정하는 규칙입니다.

좌결합(Left-to-Right)​

대부분의 이항 연산자는 왼쪽에서 오른쪽으로 처리됩니다.

// 좌결합 예시: - 연산자
int a = 10 - 3 - 2;
// (10 - 3) - 2 = 7 - 2 = 5 (왼쪽부터)
System.out.println(a); // 5

// 좌결합 예시: / 연산자
int b = 24 / 4 / 2;
// (24 / 4) / 2 = 6 / 2 = 3 (왼쪽부터)
System.out.println(b); // 3

우결합(Right-to-Left)​

단항 연산자, 대입 연산자, 삼항 연산자는 오른쪽에서 왼쪽으로 처리됩니다.

// 우결합 예시: 대입 연산자 =
int x, y, z;
x = y = z = 10;
// z = 10 → y = 10 → x = 10 (오른쪽부터)
System.out.println(x + ", " + y + ", " + z); // 10, 10, 10

// 우결합 예시: 전위 단항 연산자
int n = 5;
int result = -(-n); // -(-(5)) = -(-5) = 5
System.out.println(result); // 5

5. 대입 연산자와 복합 대입 연산자​

단순 대입 연산자 (=)​

우변(오른쪽)의 값을 좌변(왼쪽) 변수에 저장합니다. 자바에서 가장 빈번하게 사용되는 연산자입니다.

int score = 100;       // 100을 score에 저장
String name = "Alice"; // "Alice"를 name에 저장
boolean pass = true; // true를 pass에 저장

복합 대입 연산자 (Compound Assignment)​

산술 연산 + 대입을 한 번에 처리하는 축약 표현입니다.

복합 대입풀어쓴 표현설명
a += ba = a + ba에 b를 더한 값을 a에 저장
a -= ba = a - ba에서 b를 뺀 값을 a에 저장
a *= ba = a * ba와 b를 곱한 값을 a에 저장
a /= ba = a / ba를 b로 나눈 값을 a에 저장
a %= ba = a % ba를 b로 나눈 나머지를 a에 저장
a &= ba = a & b비트 AND 후 a에 저장
a |= ba = a | b비트 OR 후 a에 저장
a ^= ba = a ^ b비트 XOR 후 a에 저장
a <<= ba = a << b왼쪽 시프트 후 a에 저장
a >>= ba = a >> b오른쪽 시프트 후 a에 저장
public class CompoundAssignment {
public static void main(String[] args) {
int score = 80;

score += 10; // score = score + 10 = 90
System.out.println("+=: " + score); // 90

score -= 5; // score = score - 5 = 85
System.out.println("-=: " + score); // 85

score *= 2; // score = score * 2 = 170
System.out.println("*=: " + score); // 170

score /= 4; // score = score / 4 = 42 (정수 나눗셈, 소수점 버림)
System.out.println("/=: " + score); // 42

score %= 10; // score = score % 10 = 2
System.out.println("%=: " + score); // 2
}
}
복합 대입 연산자의 내부 형변환

복합 대입 연산자는 내부적으로 자동 형변환(묵시적 캐스팅) 을 수행합니다.

byte b = 10;
// b = b + 5; // 컴파일 에러! b+5의 결과는 int이므로 byte에 바로 대입 불가
b += 5; // 정상 동작! 내부적으로 b = (byte)(b + 5) 로 처리됨
System.out.println(b); // 15

단순 대입에서는 명시적 캐스팅이 필요한 경우라도, 복합 대입 연산자는 자동으로 처리해 줍니다.


6. 연산자 우선순위 실수 예제와 괄호 권장​

우선순위를 잘못 이해하면 예상치 못한 결과가 나올 수 있습니다.

public class PrecedenceTrap {
public static void main(String[] args) {
// 함정 예시 1: + 와 * 의 우선순위
int a = 1 + 2 * 3; // 1 + (2*3) = 1 + 6 = 7 (의도가 7이면 OK)
int b = (1 + 2) * 3; // (1+2) * 3 = 3 * 3 = 9 (의도가 9이면 괄호 필수)
System.out.println("a = " + a); // 7
System.out.println("b = " + b); // 9

// 함정 예시 2: 비트 연산자와 비교 연산자
// & 의 우선순위는 == 보다 낮음!
int flags = 0b0110;
// 잘못된 코드: flags & 0b0010 == 0 → flags & (0b0010 == 0) → flags & false → 컴파일 에러
// 올바른 코드: 괄호로 명확히
boolean hasBit = (flags & 0b0010) != 0;
System.out.println("hasBit = " + hasBit); // true

// 함정 예시 3: 논리 연산자와 대입
int x = 5, y = 3;
boolean result = x > 0 && y > 0; // (x > 0) && (y > 0) → true
System.out.println("result = " + result); // true

// 함정 예시 4: 문자열 + 연산자 순서
System.out.println(1 + 2 + "3"); // "33" (1+2=3, 3+"3"="33")
System.out.println("1" + 2 + 3); // "123" ("1"+2="12", "12"+3="123")
System.out.println("1" + (2 + 3)); // "15" (괄호로 먼저 더함)
}
}
비트 연산자 사용 시 반드시 괄호 사용

&, |, ^ 연산자는 ==, != 보다 우선순위가 낮습니다. 비트 연산 결과를 비교할 때는 항상 괄호로 묶어야 의도한 대로 동작합니다.

// 잘못된 예
if (flags & MASK == 0) { ... } // flags & (MASK == 0) 로 해석됨

// 올바른 예
if ((flags & MASK) == 0) { ... } // 괄호로 비트 연산을 먼저 수행

7. 실전 예제: 복잡한 수식 계산​

아래 예제는 실제 시험 점수 처리와 등급 계산을 통해 다양한 연산자를 함께 사용하는 모습을 보여줍니다.

public class ScoreCalculator {
public static void main(String[] args) {
// 과목별 점수
int korean = 85;
int english = 92;
int math = 78;
int science = 88;
int history = 76;

// 총점 계산 (산술 연산자)
int total = korean + english + math + science + history;

// 평균 계산 (산술 연산자 + 형변환)
double average = (double) total / 5;

// 최고점 계산 (삼항 연산자 중첩)
int maxScore = (korean > english) ? korean : english;
maxScore = (maxScore > math) ? maxScore : math;
maxScore = (maxScore > science) ? maxScore : science;
maxScore = (maxScore > history) ? maxScore : history;

// 합격 여부 (비교 + 논리 연산자)
boolean pass = (average >= 70.0) && (math >= 60);

// 보너스 점수 (복합 대입 연산자)
double bonusAverage = average;
bonusAverage += 5.0; // 출석 보너스 5점

// 등급 판별 (복합 비교)
String grade;
if (bonusAverage >= 90) {
grade = "A";
} else if (bonusAverage >= 80) {
grade = "B";
} else if (bonusAverage >= 70) {
grade = "C";
} else {
grade = "F";
}

// 출력
System.out.println("===== 성적표 =====");
System.out.println("총점 : " + total + "점");
System.out.printf("평균 : %.2f점%n", average);
System.out.printf("보너스 : %.2f점%n", bonusAverage);
System.out.println("최고점 : " + maxScore + "점");
System.out.println("합격 여부: " + (pass ? "합격" : "불합격"));
System.out.println("등급 : " + grade);
}
}

실행 결과:

===== 성적표 =====
총점 : 419점
평균 : 83.80점
보너스 : 88.80점
최고점 : 92점
합격 여부: 합격
등급 : B

8. 핵심 정리​

개념설명
연산자(Operator)연산을 수행하는 기호
피연산자(Operand)연산의 대상이 되는 값 또는 변수
우선순위(Precedence)여러 연산자가 있을 때 처리 순서 (높을수록 먼저)
결합 방향(Associativity)같은 우선순위의 연산자를 왼쪽 또는 오른쪽부터 처리
복합 대입 연산자+=, -= 등 연산과 대입을 한 번에 수행
실무 코딩 습관
  1. 우선순위가 불확실한 식에는 괄호를 적극 활용 하세요.
  2. 복잡한 산술식은 단계별로 변수에 나눠 저장 하면 디버깅이 쉬워집니다.
  3. 대입 연산자 체이닝(x = y = z = 0)은 간단한 초기화에만 사용하세요.