목차
1. 자바의 연산자 종류(산술, 비트, 논리, 관계, instanceof, assignment, arrow, tenary operator)
2. 기존의 switch expression과 JDK 13+의 switch operator
3. 연산자 우선순위
1. 자바에서의 연산자
- 산술연산자 + - * / , Infinity 혹은 NaN(not a number)
Java에서 / 또는 % 연산자를 사용할 때 제수가 정수 0인 경우에는 RuntimeException의 하위 클래스인 ArithmeticException이 발생한다. 그런데 만약 제수가 정수 0이 아니라 실수 0.0f 혹은 0.0d인 경우에는 Infinity 혹은 NaN(not a number)가 반환된다.
이 값에 추가적인 산술연산을 하더라도 Infinity 혹은 NaN으로 바뀐 이후에는 추가 연산을 해도 값이 바뀌지 않는다. 또한 이 값들은 비교연산을 할 수 없는 값으로서 비교연산 시에 무조건 false를 반환하게 된다.- 부동소수점 표준인 IEEE 754에서는 NaN이라는 값을 정의해 놓았고, 자바에서도 float, double 표준에 이를 구현해놓았다.
- 나누기, 모듈러 연산 시에 Double.isInFinity(result) 혹은 Double.isNaN(result) 메서드로 체크할 수 있지만 처음부터 실수 나누기, 모듈러 연산을 안하도록 정수로 변환하고 연산하도록 하는게 좋을 것 같다.
- 비트 연산자
- ~, &, |, ^
- >> : 비트 값들을 오른쪽으로 이동시키고, 왼쪽의 빈 공간을 양수의 경우 0, 음수는 1로 채운다.
- <<: 왼쪽 비트가 끝이 잘리고 없어짐.
- >>> (bitwise right shift with zero extension): 비트 값들을 이동시킨 후에 빈 공간은 무조건 0으로 채운다.
- unsigned shift를 이용해서 두 수에 대하여 평균값을 구해볼 수 있다. (간지가 난다!)
- XOR 배타논리합을 이용해서 집합 내 중복되지 않는 원소를 리턴하는 함수를 작성할 수 있다.
int s = 20억, e = 21억 int mid = s + (e - s) / 2; int mid = (s + e) >>> 1; // Bitwise right shift with zero extension 이건 간지용 // 구글에 면접보거나 아마존에서 일할 때나 쓰자. 일반적인 개발자들이 잘 모름... 오픈소스에서는 종종 보인다
// 5 ^ 0 = 5 // 5 ^ 5 = 0; // 101 ^ 000 = 101 // {5,2,4,1,2,4,5} 중에 중복되지 않는 원소를 리턴하는 함수 작성하기 // -> 모든 원소들을 XOR연산 하면 남는 값이 중복되지 않는 원소다. private int solution(int[] nums) { int result = 0; for(int num: nums) result ^= num; return result; }
- 논리 연산자
- 논리 연산 and or 사용시 short circuit 방식으로 이후 연산이 필요없을 경우 스킵해서 연산량을 줄인다
- &&, ||, !
- 관계 연산자
- <, ≤,>, ≥
- 피연산자 중 하나가 boxing 되어 있다면 unboxing된다.
- 피연산자 중 하나가 byte, short, char이면 int로 변환되어 연산됨
- 더 작은 범위의 유형에서 더 큰 범위 유형으로 변환됨
- instanceof
- 참조변수가 참조하고 있는 인스턴스의 실제 타입을 알아야할 때 instanceof 연산자를 사용한다.
- 조상타입의 참조변수로 자손타입의 인스턴스를 참조할수도 있기 때문에, 참조변수 타입과 인스턴스 타입은 무조건 일치하지 않는다. (BMW → Car → Object) <참조방향>
- 어떤 타입에 대한 instanceof 연산이 true이면 그 타입으로 형변환이 가능하다
( Object reference variable ) instanceof (class/interface type) void doWork(Car c) { if(c instanceof BMW) { BMW c = (BMW)c c.runSoftly(); } else if(c instanceof Kickboard) { Kickboard c = (Kickboard) c; c.kickQuickly(); } }
- assignment(=) operator
- =, +=, -=, *=, /=, %=, &=, |=, ^=, <≤, >≥, >>≥(부호 상관없이 오른쪽 시프트)
- 대입 연산자에서 rvalue는 변수, 식, 상수 모두 가능하지만, lvalue는 반드시 변수처럼 값을 변경할 수 있는 것이어야 한다.
x = y = 3; // 연산 순서 1. y = 3, 2. x = y;
- 화살표(->) 연산자(JDK 8+)
- 람다 표현식으로 익명함수, 또는 함수 인터페이스를 구현하는 익명 클래스의 인스턴스를 정의함
- 메서드에서 이름과 반환타입을 제거하고 선언부와 블록 사이에 → 를 추가한다
a -> a + 1 // a lambda that adds one to its argument a -> { return a + 1; } // an equivalent lambda using a block. // lambda 안씀 JButton btn = new JButton("My Button"); btn.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { System.out.println("Button was pressed"); } }); // 람다씀 JButton btn = new JButton("My Button"); btn.addActionListener(e -> { System.out.println("Button was pressed"); });
- 삼항 연산자 expr ? a : b
2. switch operator, expression(JDK 13+)
기존 switch expression이 너무 장황하고, 에러 발생시 디버깅이 어렵고, break 체크하기가 힘든 점이 있었음
기존의 switch expression
- switch에 들어가는 표현식은 래퍼 타입이 허용되지만 case엔는 허용하지 않는다.
- 케이스 값은 리터럴 또는 상수여야 한다.
- 각 케이스는 고유해야 하고, 중복 케이스가 있으면 컴파일 오류가 발생
- 각 케이스에는 선택적으로 break문이 있음. 어떠한 케이스에도 break문이 없으면 break에 도달할 때까지 다음 case 실행이 됨.
- 모든 케이스에 해당되지 않으면 default가 실행됨(fall-through) 폴 쓰루라고 함. 기본 케이스에는 break가 필요없음
switch(this.type) {
case MOTORCYCLE:
a = 0.05;
break;
case MINIVAN:
a = 0.1;
break;
default:
assert(false): "Unrecongnized vehicle type: " + this.type;
break;
}
// switch 문 작성시에 default case에 assert문으로 확인을 해주자
- case → 인 경우 branch fall-through가 아님(아래 case까지 내려가지 않고 거기서 끝남)
- break문 대신 yield를 사용함(switch operator에서 yield로 받은 산출값을 반환함)
switch(v){
case a -> ret1;
case b -> ret2;
...
default -> throw new IllegalStateException("에러에러");
};
switch(expression){
case expression:
expression;
yield expression;
...
default:
expression;
yield expression;
};
int a = 1;
int b = switch(a) {
case 1 -> {
System.out.println("case1");
yield 10;
}
case 2 -> {
System.out.println("case2");
yield 11;
}
}
3. 연산자 우선순위
참고: https://www.cs.bilkent.edu.tr/~guvenir/courses/CS101/op_precedence.html
- 백기선님의 자바 온라인 스터디 https://github.com/whiteship/live-study 주제를 정리한 내용입니다.
참고
- 자바의 정석 2판
- https://www.cs.bilkent.edu.tr/~guvenir/courses/CS101/op_precedence.html
-https://www.baeldung.com/java-not-a-number
'Java > basic' 카테고리의 다른 글
자바의 클래스, 인스턴스, 메서드 관련 개념 (0) | 2022.10.30 |
---|---|
자바 변수의 종류, 특징 - Primitive type, Reference type (0) | 2022.10.30 |
JIT 컴파일러 동작과정 (0) | 2022.10.30 |
JVM 이란? (0) | 2022.10.30 |
String constant pool를 이해하면 왜 String이 불변으로 설계됬는지 이해할 수 있다 (0) | 2022.04.13 |