연산자
이제 변수를 선언하고 초기화하는 방법을 배웠으니 이제 변수로 무언가를 하는 방법을 알고 싶을 것입니다. Java 프로그래밍 언어의 연산자를 배우는 것이 좋은 시작점입니다. 연산자는 하나, 둘 또는 세 개의 피연산자에 대해 특정 연산을 수행한 다음 결과를 반환하는 특수 기호입니다.
Java 프로그래밍 언어의 연산자를 살펴보면서 어떤 연산자가 우선순위가 가장 높은지 미리 알아두면 도움이 될 수 있습니다. 다음 표의 연산자는 우선순위에 따라 나열되어 있습니다. 표의 맨 위에 가까운 연산자일수록 우선 순위가 높습니다. 우선 순위가 높은 연산자는 상대적으로 우선 순위가 낮은 연산자보다 먼저 평가됩니다. 같은 줄에 있는 연산자는 동일한 우선순위를 갖습니다. 동일한 표현식에 동일한 우선 순위의 연산자가 나타나는 경우 어떤 연산자가 먼저 평가되는지에 대한 규칙이 적용되어야 합니다. 할당 연산자를 제외한 모든 이진 연산자는 왼쪽에서 오른쪽으로 평가되고, 할당 연산자는 오른쪽에서 왼쪽으로 평가됩니다.
| Operators | Precedence |
|---|---|
| postfix | expr++ expr-- |
| unary | ++expr --expr +expr -expr ~ ! |
| multiplicative | * / % |
| additive | + - |
| shift | << >> >>> |
| relational | < > <= >= instanceof |
| equality | == != |
| bitwise AND | & |
| bitwise exclusive OR | ^ |
| bitwise inclusive OR | | |
| logical AND | && |
| logical OR | | |
| ternary | ? : |
| assignment | = += -= *= /= %= &= ^= |= <<= >>= >>>= |
범용 프로그래밍에서는 특정 연산자가 다른 연산자보다 더 자주 등장하는 경향이 있습니다. 예를 들어, 부호가 없는 오른쪽 시프트 연산자 >>>보다 할당 연산자 =가 훨씬 더 많이 사용됩니다. 이를 염두에 두고 다음 논의에서는 가장 자주 사용할 가능성이 높은 연산자를 먼저 살펴본 후 덜 자주 사용되는 연산자를 중심으로 마무리합니다. 각 설명에는 컴파일하고 실행할 수 있는 샘플 코드가 함께 제공됩니다. 그 결과물을 공부하면 방금 배운 내용을 강화하는 데 도움이 될 것입니다.
단순 할당 연산자
가장 흔히 접할 수 있는 연산자 중 하나는 단순 대입 연산자 =입니다. Bicycle 클래스에서 이 연산자를 보셨죠? 이 연산자는 오른쪽에 있는 값을 왼쪽에 있는 피연산자에 할당합니다:
int cadence = 0;
int speed = 0;
int gear = 1;이 연산자는 객체 생성 및 사용 섹션에서 설명한 대로 객체 참조를 할당하는 데 객체에도 사용할 수 있습니다.
산술 연산자
Java 프로그래밍 언어는 덧셈, 뺄셈, 곱셈, 나눗셈을 수행하는 연산자를 제공합니다. 이러한 연산자는 기초 수학의 연산자와 비슷하기 때문에 쉽게 알아볼 수 있습니다. 한 피연산자를 다른 피연산자로 나누고 그 결과로 나머지를 반환하는 %라는 기호만 생소하게 보일 수 있습니다.
| Operator | Description |
|---|---|
+ | 덧셈 연산자(문자열 연결에도 사용됨) |
- | 뺄셈 연산자 |
* | 곱셈 연산자 |
/ | 나누기 연산자 |
% | 나머지 연산자 |
다음 프로그램인 ArithmeticDemo는 산술 연산자를 테스트합니다.
class ArithmeticDemo {
public static void main (String[] args) {
int result = 1 + 2;
// result is now 3
System.out.println("1 + 2 = " + result);
int original_result = result;
result = result - 1;
// result is now 2
System.out.println(original_result + " - 1 = " + result);
original_result = result;
result = result * 2;
// result is now 4
System.out.println(original_result + " * 2 = " + result);
original_result = result;
result = result / 2;
// result is now 2
System.out.println(original_result + " / 2 = " + result);
original_result = result;
result = result + 8;
// result is now 10
System.out.println(original_result + " + 8 = " + result);
original_result = result;
result = result % 7;
// result is now 3
System.out.println(original_result + " % 7 = " + result);
}
}이 프로그램은 다음을 출력합니다:
1 + 2 = 3
3 - 1 = 2
2 * 2 = 4
4 / 2 = 2
2 + 8 = 10
10 % 7 = 3산술 연산자와 단순 대입 연산자를 결합하여 복합 대입을 만들 수도 있습니다. 예를 들어 x += 1;과 x = x + 1;은 모두 x의 값을 1씩 증가시킵니다.
또한 + 연산자는 다음 ConcatDemo 프로그램에서 볼 수 있듯이 두 문자열을 연결(결합)하는 데에도 사용할 수 있습니다:
class ConcatDemo {
public static void main(String[] args){
String firstString = "This is";
String secondString = " a concatenated string.";
String thirdString = firstString+secondString;
System.out.println(thirdString);
}
}이 프로그램이 끝나면 thirdString 변수에 This is a concatenated string.가 포함되어 표준 출력으로 인쇄됩니다.
단항 연산자
단항 연산자는 피연산자가 하나만 필요하며 값을 1씩 증가/감소시키거나 식을 부정하거나 boolean의 값을 반전시키는 등 다양한 연산을 수행합니다.
| Operator | Description |
|---|---|
+ | 단항 더하기 연산자; 양수 값을 나타냅니다(단, 이 연산자가 없으면 숫자는 양수입니다). |
- | 단항 마이너스 연산자; 표현식을 부정합니다. |
++ | 증가 연산자; 값을 1씩 증가시킵니다. |
-- | 감산 연산자; 값을 1씩 감소시킵니다. |
! | 논리 보완 연산자; boolean값을 반전시킵니다. |
다음 프로그램인 UnaryDemo는 단항 연산자를 테스트합니다:
class UnaryDemo {
public static void main(String[] args) {
int result = +1;
// result is now 1
System.out.println(result);
result--;
// result is now 0
System.out.println(result);
result++;
// result is now 1
System.out.println(result);
result = -result;
// result is now -1
System.out.println(result);
boolean success = false;
// false
System.out.println(success);
// true
System.out.println(!success);
}
}증가/감소 연산자는 피연산자 앞(접두사) 또는 뒤(접미사)에 적용할 수 있습니다. result++;와 ++result; 코드는 모두 결과가 1씩 증가되는 것으로 끝납니다. 유일한 차이점은 접두사 버전(++result)은 증가된 값으로 평가되는 반면, 접두사 버전(result++)은 원래 값으로 평가된다는 것입니다. 단순한 증가/감소만 수행하는 경우에는 어떤 버전을 선택하든 상관없습니다. 하지만 이 연산자를 더 큰 식의 일부로 사용하는 경우 어떤 버전을 선택하느냐에 따라 큰 차이를 만들 수 있습니다.
다음 프로그램인 PrePostDemo는 접두사/접미사 단항 증분 연산자를 보여줍니다:
class PrePostDemo {
public static void main(String[] args){
int i = 3;
i++;
// prints 4
System.out.println(i);
++i;
// prints 5
System.out.println(i);
// prints 6
System.out.println(++i);
// prints 6
System.out.println(i++);
// prints 7
System.out.println(i);
}
}
등호 연산자와 관계 연산자
등호 연산자와 관계형 연산자는 한 피연산자가 다른 피연산자보다 크거나, 작거나, 같거나, 같지 않은지를 결정합니다. 이러한 연산자의 대부분은 여러분에게도 친숙하게 보일 것입니다. 두 기본값이 같은지 테스트할 때는 =가 아닌 ==를 사용해야 한다는 점에 유의하세요.
| Operator | Description |
|---|---|
== | 와 같은 |
!= | 와 같지 않음 |
> | 보다 큰 |
>= | 보다 크거나 같은 |
< | 보다 작은 |
<= | 보다 작거나 같은 |
다음 프로그램인 ‘ComparisonDemo’는 비교 연산자를 테스트합니다:
class ComparisonDemo {
public static void main(String[] args){
int value1 = 1;
int value2 = 2;
if(value1 == value2)
System.out.println("value1 == value2");
if(value1 != value2)
System.out.println("value1 != value2");
if(value1 > value2)
System.out.println("value1 > value2");
if(value1 < value2)
System.out.println("value1 < value2");
if(value1 <= value2)
System.out.println("value1 <= value2");
}
}이 프로그램을 실행하면 다음과 같은 출력이 생성됩니다:
value1 != value2
value1 < value2
value1 <= value2
조건 연산자
&& 및 || 연산자는 두 개의 부울 표현식에 대해 조건-AND 및 조건-OR 연산을 수행합니다. 이러한 연산자는 “단락” 동작을 나타내므로 두 번째 피연산자는 필요한 경우에만 평가됩니다.
| Operator | Description |
|---|---|
&& | 조건-AND |
| | | | 조건-OR |
?: | 삼항(if-then-else 구문의 약어) |
다음 프로그램인 ConditionalDemo1은 이러한 연산자를 테스트합니다:
class ConditionalDemo1 {
public static void main(String[] args){
int value1 = 1;
int value2 = 2;
if ((value1 == 1) && (value2 == 2))
System.out.println("value1 is 1 AND value2 is 2");
if ((value1 == 1) || (value2 == 1))
System.out.println("value1 is 1 OR value2 is 1");
}
}또 다른 조건 연산자는 ?:로, if-then-else 문(제어 흐름 문 섹션에서 설명)의 줄임말이라고 생각할 수 있습니다. 이 연산자는 피연산자가 세 개이기 때문에 ternary 연산자라고도 합니다. 다음 예제에서 이 연산자는 다음과 같이 읽어야 합니다: “someCondition이 참이면 value1의 값을 결과에 할당합니다. 그렇지 않으면 value2의 값을 결과에 할당합니다.”라고 읽어야 합니다.
다음 프로그램인 ConditionalDemo2는 ?: 연산자를 테스트합니다:
class ConditionalDemo2 {
public static void main(String[] args){
int value1 = 1;
int value2 = 2;
int result;
boolean someCondition = true;
result = someCondition ? value1 : value2;
System.out.println(result);
}
}someCondition이 참이므로 이 프로그램은 화면에 “1”을 출력합니다. 코드의 가독성을 높이려면 if-then-else 문 대신 ?: 연산자를 사용하세요;
예를 들어 표현식이 간결하고 부작용(예: 할당)이 없는 경우입니다.
타입 비교 연산자 Instanceof
Instanceof 연산자는 객체를 지정된 타입과 비교합니다. 이 연산자를 사용하여 객체가 클래스의 인스턴스인지, 서브클래스의 인스턴스인지, 특정 인터페이스를 구현하는 클래스의 인스턴스인지 테스트할 수 있습니다.
다음 프로그램인 InstanceofDemo는 부모 클래스(이름 Parent), 간단한 인터페이스(이름 MyInterface), 부모로부터 상속되어 인터페이스를 구현하는 자식 클래스(이름 Child)를 정의합니다.
class InstanceofDemo {
public static void main(String[] args) {
Parent obj1 = new Parent();
Parent obj2 = new Child();
System.out.println("obj1 instanceof Parent: "
+ (obj1 instanceof Parent));
System.out.println("obj1 instanceof Child: "
+ (obj1 instanceof Child));
System.out.println("obj1 instanceof MyInterface: "
+ (obj1 instanceof MyInterface));
System.out.println("obj2 instanceof Parent: "
+ (obj2 instanceof Parent));
System.out.println("obj2 instanceof Child: "
+ (obj2 instanceof Child));
System.out.println("obj2 instanceof MyInterface: "
+ (obj2 instanceof MyInterface));
}
}
class Parent {}
class Child extends Parent implements MyInterface {}
interface MyInterface {}다음 프로그램은 다음과 같은 출력을 생성합니다:
obj1 instanceof Parent: true
obj1 instanceof Child: false
obj1 instanceof MyInterface: false
obj2 instanceof Parent: true
obj2 instanceof Child: true
obj2 instanceof MyInterface: trueinstanceof 연산자를 사용할 때 null은 어떤 것의 인스턴스도 아니라는 점에 유의하세요.
비트 연산자 및 비트 시프트 연산자
Java 프로그래밍 언어는 적분 타입에 대해 비트 단위 및 비트 시프트 연산을 수행하는 연산자도 제공합니다. 이 섹션에서 설명하는 연산자는 자주 사용되지 않습니다. 따라서 다루는 내용은 간략하며, 단순히 이러한 연산자가 존재한다는 것을 알리는 것이 목적입니다.
단항 비트 보간 연산자 ~는 비트 패턴을 반전시켜 모든 “0”을 “1”로, 모든 “1”을 “0”으로 만드는 모든 정수 타입에 적용될 수 있습니다. 예를 들어 바이트는 8비트를 포함하며, 비트 패턴이 00000000인 값에 이 연산자를 적용하면 패턴이 11111111로 변경됩니다.
부호가 있는 왼쪽 시프트 연산자 <<는 비트 패턴을 왼쪽으로 이동시키고 부호가 있는 오른쪽 시프트 연산자 >>는 비트 패턴을 오른쪽으로 이동시킵니다. 비트 패턴은 왼쪽 피연산자로, 이동할 위치의 수는 오른쪽 피연산자로 주어집니다. 부호가 없는 오른쪽 시프트 연산자 >>는 0을 가장 왼쪽 위치로 시프트하고, >> 뒤의 가장 왼쪽 위치는 부호 확장에 따라 달라집니다.
비트 단위 & 연산자는 비트 단위 AND 연산을 수행합니다.
비트 단위 ^ 연산자는 비트 단위 배타 OR 연산을 수행합니다.
비트 | 연산자는 비트 포함 OR 연산을 수행합니다.
다음 프로그램인 BitDemo는 비트 AND 연산자를 사용하여 숫자 “2”를 표준 출력으로 인쇄합니다.
class BitDemo {
public static void main(String[] args) {
int bitmask = 0x000F;
int val = 0x2222;
// prints "2"
System.out.println(val & bitmask);
}
}