기록하자..
자바가 제공하는 다양한 연산자 | 백기선님 LIVE-STUDY 본문
학습할 것
- 산술 연산자
- 비트 연산자
- 관계 연산자
- 논리 연산자
- instanceof
- assignment(=) operator
- 화살표(->) 연산자
- 3항 연산자
- 연산자 우선 순위
- (optional) Java 13. switch 연산자
산술 연산자
| 연산자 | 피연산자 수 | 산출 값 | 설명 |
|---|---|---|---|
| + | 이항 | 숫자 | 덧셈 연산 |
| - | 이항 | 숫자 | 뺄셈 연산 |
| * | 이항 | 숫자 | 곱셈 연산 |
| / | 이항 | 숫자 | 좌측 피연산자를 우측 피연산자로 나눗셈 연산 |
| % | 이항 | 숫자 | 좌측 피연산자를 우측 피연산자로 나눈 나머지를 구하는 연산 |
자바에는 다음가 같은 산술 연산자들이 있다. 산술 연산자의 경우 숫자 타입(byte, short, int, long, float, double)으로 결과가 나온다.
사용법을 보자.
int a = 4;
int b = 5;
System.out.println("a + b: " + (a + b));
System.out.println("a - b: " + (a - b));
System.out.println("a * b: " + (a * b));
System.out.println("a / b: " + (a / b));
System.out.println("a % b: " + (a % b));
a + b: 9
a - b: -1
a * b: 20
a / b: 0
a % b: 4비트 연산자
비트 연산자는 데이터를 비트 단위로 연산한다. 주의할 점은 실수 타입인 float, double은 비트 연산이 불가능하다는 것이다. 비트 연산자는 기능에 따라 비트 논리 연산자(&, |, ^, ~)와 비트 이동 연산자(<<, >>, >>>)로 구분한다.
비트 논리 연산자
| 연산자 | 피연산자 수 | 산출 값 | 설명 |
| ----- | ------- | ----- | --- |
| & | 이항 | 숫자 | 두 비트 모두 1일 경우에만 연산 결과가 1
| | | 이항 | 숫자 | 두 비트 중 하나만 1이면 연산 결과가 1
| ^ | 이항 | 숫자 | 두 비트 중 하나는 1이고 다른 하나가 0일 경우 연산결과가 1
| ~ | 단항 | 숫자 | 보수
사용법을 보자.
int a = 3; // 0000 0011
int b = 4; // 0000 0100
System.out.println("a & b: " + (a & b));
System.out.println("a | b: " + (a | b));
System.out.println("a ^ b: " + (a ^ b));
System.out.println("~a: " + ~a);
System.out.println("~b: " + ~b);
a & b: 0
a | b: 7
a ^ b: 7
~a: -4
~b: -5비트 연산자는 피연산자를 int 타입으로 자동 타입 변환한 후 연산을 수행하게 된다. 그렇기에 비트 연산의 결과 타입은 int 타입이 된다.
비트 이동 연산자
| 연산자 | 피연산자 수 | 산출 값 | 설명 |
| ----- | ------- | ----- | --- |
| << | 이항 | 숫자 | 왼쪽 정수의 각 비트를 오른쪽 정수의 수만큼 왼쪽으로 이동시킨다.
| >> | 이항 | 숫자 | 왼쪽 정수의 각 비트를 오른쪽 정수의 수만큼 오른쪽으로 이동시킨다.
| >>> | 이항 | 숫자 | 왼쪽 정수의 각 비트를 오른쪽 정수의 수만큼 오른쪽으로 이동시킨다.
/*
00000000 00000000 00000000 00000001
000은 버림
00000000 00000000 00000000 00001000
*/
System.out.println(1 << 3);
/*
11111111 11111111 11111111 11111000
빈공간을 1로 채우고, 0은 버림
11111111 11111111 11111111 11111111
*/
System.out.println(-8 >> 3);
/*
11111111 11111111 11111111 11111000
빈공간을 무조건 0으로 채우고, 0은 버림
00011111 11111111 11111111 11111111
*/
System.out.println(-8 >>> 3);
8
-1
536870911>> 연산자는 비트를 오른쪽으로 밀게되는데 이때 빈공간을 최상위 부호 비트와 동일한 값으로 채우게 된다.
반면 >>> 연산자는 빈자리를 0으로 채우게된다.
관계 연산자
| 연산자 | 피연산자 수 | 산출 값 | 설명 |
|---|---|---|---|
| == | 이항 | boolean | 두 개의 항이 같으면 참, 다르면 거짓을 반환한다. |
| != | 이항 | boolean | 두 개의 항이 다르면 참, 같으면 거짓을 반환한다. |
| > | 이항 | boolean | 왼쪽에 있는 항이 더 크면 참, 그렇지 않으면 거짓을 반환한다. |
| < | 이항 | boolean | 오른쪽에 있는 항이 더 크면 참, 그렇지 않으면 거짓을 반환한다. |
| >= | 이항 | boolean | 왼쪽에 있는 항이 더 크거나 같으면 참, 그렇지 않으면 거짓을 반환한다. |
| <= | 이항 | boolean | 오른쪽에 있는 항이 더 크거나 같으면 참, 그렇지 않으면 거짓을 반환한다. |
System.out.println("1 == 1: " + (1 == 1));
System.out.println("2 != 2: " + (2 != 2));
System.out.println("1 > 3: " + (1 > 3));
System.out.println("1 < 3: " + (1 < 3));
System.out.println("2.3 >= 2: " + (2.3 >= 2));
System.out.println("3.1 <= 3: " + (3.1 <= 3));
1 == 1: true
2 != 2: false
1 > 3: false
1 < 3: true
2.3 >= 2: true
3.1 <= 3: false관계연산자는 비교연산자로, boolean 값인 true와 false를 반환한다.
논리 연산자
| 연산자 | 피연산자 수 | 산출 값 | 설명 |
|---|---|---|---|
| && 또는 & | 이항 | boolean | 피연산자 모두가 true일 경우에만 true를 반환한다. |
| || 또는 | | 이항 | boolean | 피연산자 중 하나만 true이면 true를 반환한다. |
| ! | 단항 | boolean | 피연산자의 논리 값을 바꾼다. |
System.out.println("true && false: " + (true && false));
System.out.println("true && true: " + (true && true));
System.out.println("true || false: " + (true || false));
System.out.println("true || true: " + (true || true));
System.out.println("false || false: " + (false || false));
System.out.println("!true: " + !true);
System.out.println("!false: " + !false);
System.out.println("!false: " + !false);
true && false: false
true && true: true
true || false: true
true || true: true
false || false: false
!true: false
!false: true논리 연산자는 비트 연산과 비슷하지만 피연산자가 boolean 타입의 논리 값이다.
instanceof
instanceof 연산자는 이항연산자로, 객체가 주어진 타입이 맞는지 검사하는 연산자이다. instanceof 연산자의 결과는 boolean값인 true, false가 나오게된다.
static class Parent {
}
interface Shape {
}
static class Child extends Parent implements Shape {
}
public static void main(String[] args) {
Child child = new Child();
boolean result = child instanceof Parent;
boolean result2 = child instanceof Shape;
System.out.println(result);
System.out.println(result2);
System.out.println(null instanceof Parent);
}
true
true
falseinstanceof 연산자는 is-a관계의 원리에 의해 동작한다. is-a관계는 상속이나 인터페이스 구현에 기반을 두고 있다. 위의 코드를 보면 Parent를 상속받고 Shape를 구현하고 있는 Child 클래스가 Parent와 Shape의 인스턴스인 것을 확인할 수 있다.
참고로 null은 어떤 것의 인스턴스도 아니라는 것을 기억해두자.
assignment(=) operator
| 연산자 | 피연산자 수 | 설명 |
|---|---|---|
| = | 이항 | 우측 피연산자의 값을 좌측 변수에 저장한다. |
assignment operator, 대입 연산자는 오른쪽 피연산자의 값을 좌측 피연산자 변수에 저장하는 연산자이다. 기본적인 형태는 다음과 같다.
x = 1;
x = y = z = 1;
x (operator)= y;x(operator)= y; 는 정해진 연산(operator)을 수행한 후 결과를 변수에 저장한다.
- 대입 연산자 사용시 주의할 점이 하나 있는데, 피연산자가 reference type 일 경우 주소 값을 할당한다는 것을 주의해야 한다.
int x, y, z;
A a1 = new A();
A a2 = new A();
x = 1;
System.out.println("x = " + x);
x = y = z = 3;
System.out.println("x = " + x + ", y = " + y + ", z = " + z);
System.out.println("a1 = " + a1);
System.out.println("a2 = " + a2);
// reference type에 대입 연산자 사용시 주소 값 할당에 주의!
a1 = a2;
System.out.println("a1 = " + a1);
x = 1
x = 3, y = 3, z = 3
a1 = A@62043840
a2 = A@5315b42e
a1 = A@5315b42e화살표(->) 연산자
화살표 연산자는 Java8부터 지원하는 람다식의 문법 중 일부이고, 함수의 몸체로 부터 파라미터를 분리한다. 익명함수의 매개변수와 리턴변수를 통해 만들어지는데, 익명함수를 접어 간결하게 표현하기 위해 사용한다.
(argument, ...) -> { expression }Runnable 인터페이스를 익명 함수를 통해 구현한 모습을 살펴보자.
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("Runnable.run()");
}
};
다음과 같은 익명함수가 있을 때 화살표 연산자를 통해 줄일 수 있다.
Runnable runnable = () -> System.out.println("Runnable.run()");
3항 연산자
삼항 연산자는 세 개의 피연산자를 필요로 하는 연산자를 말한다. ? 앞의 조건식과 : 앞뒤의 피연산자가 선택된다.
조건식 ? (값 또는 연산식) : (값 또는 연산식)조건식을 연산했을 때 true가 나오게 되면 콜론(:) 앞 연산식이, false가 나오면 콜론(:) 뒤 연산식이 실행된다.
String result;
int score = 80;
result = score > 70 ? "good" : "bad";
System.out.println("result = " + result);
result = good연산자 우선 순위
위의 연산자들을 한 문장안에 사용했을 때는 어떤 순서로 실행이 될까? 각 연산자에는 우선순위가 있는데, 다음과 같다.
| 연산자 | 우선순위 |
|---|---|
| expr++ expr-- | 1 |
| ++expr --expr +expr -expr ~ ! | 2 |
| * / % | 3 |
| + - | 4 |
| << >> >>> | 5 |
| < > <= >= instanceof | 6 |
| == != | 7 |
| AND & | 8 |
| ^ | 9 |
| | | 10 |
| && | 11 |
| || | 12 |
| ? : | 13 |
| = += -= *= /= %= &= ^= |= <<= >>= >>>= | 14 |
(optional) Java 13. switch 연산자
Java13 부터 변경된 내용이 하나 있는데, switch 연산자이다. break문을 사용하지 않고 화살표 연산자를 통해 표현할 수 있다.
switch(value) {
case 1:
result = 1;
break;
case 2:
result = 2;
break;
case 3:
result = 3;
break;
default:
result = 4;
break;
}
이를 화살표 연산자를 통해 바꿀 수 있다.
switch(value) {
case 1 -> result = 1;
case 2 -> result = 2;
case 3 -> result = 3;
default -> result = 4;
}
또 switch 연산자를 통해 값을 반환받을 수도 있다.
int result = switch(value) {
case 1 -> 1;
case 2 -> 2;
case 3 -> 3;
default -> 4;
}
또 한 가지 재미있는 점은 yield를 통해 산출값을 리턴할 수 있다. break를 통해 하던 것을 간결하게 바꿔준 느낌이다.
int result = switch(value) {
case 1:
yield 1;
case 2:
yield 2;
case 3:
yield 3;
default:
yield 4;
}
참고자료
'자바' 카테고리의 다른 글
| 클래스 | 백기선님 LIVE-STUDY (0) | 2022.05.02 |
|---|---|
| 제어문 | 백기선님 LIVE-STUDY (0) | 2022.05.02 |
| 자바 데이터 타입, 변수 그리고 배열 | 백기선님 LIVE-STUDY (0) | 2022.03.24 |
| JVM은 무엇이며 자바 코드는 어떻게 실행하는 것인가 | 백기선님 LIVE-STUDY (0) | 2022.03.09 |
| JVM (0) | 2021.12.23 |