성빈
[JAVA] 3주차 연산자 본문
목표
자바가 제공하는 다양한 연산자를 학습하세요.
학습할 것
- 산술 연산자
- 비트 연산자
- 관계 연산자
- 논리 연산자
- instanceof
- assignment(=) operator
- 화살표(->) 연산자
- 3항 연산자
- 연산자 우선 순위
- (optional) Java 13. switch 연산자
산술 연산자
- 사칙연산을 다루는 연산자
- 더하기(+), 빼기(-), 곱하기(*), 나누기(/), 나머지(%)
- 피연산자에 대한 연산
- int형 타입보다 범위가 작은 데이터 연산 시, int형으로 변환 후 연산을 한다.
ex) byte+int → int+int = int - int형 타입보다 큰 범위의 데이터가 있다면, int형 보다 큰 타입이 반환 후 연산을 한다.
ex) int+long → long+long = long - 피연산자 중에 실수 타입이 존재한다면, 실수 타입으로 변환 후 연산을 한다.
ex) int+double → double+double = double
연산자 | 의미 | 예 | 결과 |
+ | 더하기 | 25.5 + 4.6 | 29.1 |
- | 빼기 | 3 - 5 | -2 |
* | 곱하기 | 2.5 * 4.0 | 10.0 |
/ | 나누기 | 5 / 2 | 2 |
% | 나머지 | 5 % 2 | 1 |
✅ 정수와 정수를 나누기(/)를 했을 때 소수점의 결과를 얻고 싶다면,
나눠주는 값을 실수 타입으로 형 변환 해야 한다.
int a = 10; int b = 4; System.out.printf("%d / %d = %d\n", a, b, a/b); // 2 출력 System.out.printf("%d / %f = %f\n", a, (float)b, a/(float)b); // 2.5 출력
✅ 문자도 산술연산이 가능하다.
→ 문자는 실제로 해당 문자의 유니코드로 바꾸어 저장되기 때문이다.
System.out.println('f' - 'a'); // 102-97 = 5 출력
<유니코드 표 참조>
비트 연산자
비트 연산
- 비트 논리 연산 : AND, OR, XOR, NOT 연산
- 비트 시프트 연산 : 비트를 오른쪽이나 왼쪽으로 이동시킨다.
- 비트 논리 연산(&, |, ^, ~)
- 피연산자의 각 비트들끼리 이루어지는 AND, OR, XOR, NOT의 논리 연산
- a & b (AND 연산) : 두 비트 모두 1이면 1, 그렇지 않으면 0
- a | b (OR 연산) : 두 비트 모두 0이면 0, 그렇지 않으면 1
- a ^ b (XOR 연산) : 두 비트가 다르면 1, 같으면 0
- ~ a (NOT 연산) : 1을 0으로, 0을 1로 변환
- 피연산자의 각 비트들끼리 이루어지는 AND, OR, XOR, NOT의 논리 연산
- 비트 시프트 연산(>>, >>>, <<)
- 새로운 비트를 오른쪽이나 왼쪽 끝에 삽입하면서 비트의 자리를 이동시키는 연산
- 저장 공간의 크기가 정해져 있으므로 시프트되는 방향에 따라 끝에 있는 비트는 사라지게 된다.
- 시프트 연산자
- a >> b : a의 각 비트를 오른쪽으로 b번 시프트한다. (산술적 오른쪽 시프트, 최상위 비트의 빈자리는 시프트 전의 최상위 비트로 채운다.)
- a >>> b : a의 각 비트를 오른쪽으로 b번 시프트한다. (논리적 오른쪽 시프트, 최상위 비트의 빈자리는 항상 0으로 채운다.)
- a << b : a의 각 비트를 왼쪽으로 b번 시프트한다. (산술적 왼쪽 시프트, 최하위 비트의 빈자리는 항상 0으로 채운다.)
✅
최상위 비트(MSB) : 이진수의 제일 높은 자리수
최하위 비트(LSB) : 이진수의 제일 낮은 자리수
ex. 21 → 00010101 ⇒ 최상위비트 : 0, 최하위비트 : 1
- byte, short, int, long, char 타입만 가능하고, float, double, boolean은 사용할 수 없다.
- >> 와 <<는 1비트 시프트 할 때마다 나누기 2, 곱하기 2의 효과가 각각 나타난다.
관계 연산자(비교 연산자)
- 두 개의 피연산자를 비교하여 true 또는 false의 논리 값을 내는 연산
- 비교하는 피연산자의 타입이 다르면 자료형의 범위가 큰 쪽으로 타입을 일치 시킨 뒤 비교한다.
연산자 | 내용 | 예제 | 결과 |
a < b | a가 b보다 작으면 true | 3 < 5 | true |
a > b | a가 b보다 크면 true | 3 > 5 | false |
a <= b | a가 b보다 작거나 같으면 true | 1<= 0 | false |
a >= b | a가 b보다 크거나 같으면 true | 10 >= 10 | true |
a == b | a가 b와 같으면 true | 1 == 3 | false |
a != b | a가 b와 같지 않으면 true | 1 != 3 | true |
논리 연산자
- 논리 값을 대상으로 AND, OR, XOR, NOT의 논리 연산을 하여 true 또는 false의 논리 값을 내는 연산자
연산자 | 내용 | 예제 | 결과 |
! a | a가 true이면 false, false이면 true | ! (3<5) | false |
a || b | a와 b의 OR 연산. a와 b 모두 false인 경우에만 false | (3>5) || (1==1) | true |
a && b | a와 b의 AND 연산. a와 b 모두 true인 경우에만 true | (3<5) && (1==1) | true |
a ^ b | a와 b의 XOR 연산. a와 b가 서로 다를 때 true | (3>5) ^ (1==1) | true |
✅ 효율적인 연산
논리 연산자의 또 다른 특징은 효율적인 연산을 한다는 것인데,
OR연산인 || 의 경우, 두 피연산자 중 어느 한쪽만 참이여도 참이기에 좌측에 우선 평가 될 피연산자에 참이 될 가능성이 높은 피연산자를 위치하면 좌측의 피연산자가 참일 경우 우측의 피연산자 수행을 하지 않고 진행하게 된다.
AND연산인&& 도 마찬가지로 어느 한 쪽만 거짓이여도 결과는 거짓이 되기 때문에 false를 반환할 확률이 높은 평가식을 좌측 피연산자위치에 놓을 경우 더 빠른 연산결과를 얻을 수 있다.
instanceof
- 객체 타입을 확인하는 연산자
- 형변환 가능 여부를 확인하며 true 또는 false의 값으로 결과를 반환한다.
- 주로 상속 관계에서 부모객체인지 자식 객체인지 확인하는 데 사용된다.
- instanceof 연산의 결과가 true라는 것은 검사한 타입으로의 형변환이 가능하다는 의미이다.
- 사용 방법
object instanceof type
⇒ object가 type을 상속받는 클라스라면 true를 리턴하고, 그렇지 않다면 false를 리턴한다.
- 예제
public class InstanceofTest {
public static void main(String[] args) {
A a = new A();
B b = new B();
//객체 a는 자기 자신의 객체이기 때문에 형변환 가능
System.out.println(a instanceof A); //true 출력
//객체 b는 A의 자식객체이기 때문에 A로 형변환 가능
System.out.println(b instanceof A); //true 출력
//객체 a는 B의 부모객체이기때문에 형변환 불가능
System.out.println(a instanceof B); //false 출력
//객체 b는 자기 자신의 객체이기때문에 형변환 가능
System.out.println(b instanceof B); //true 출력
}
}
class A{ }
class B extends A{ }
assignment(=) operator (대입 연산자)
- 연산자의 오른쪽 식의 결과를 왼쪽에 있는 변수에 대입한다.
- 피연산자들의 결합 방향은 오른쪽에서 왼쪽
대입 연산자 | 내용 | 대입 연산자 | 내용 |
a = b | b의 값을 a에 대입 | a &= b | a = a & b |
a += b | a = a + b | a ^= b | a = a ^ b |
a -= b | a = a - b | a |= b | a = a | b |
a *= b | a = a * b | a <<= b | a = a << b |
a /= b | a = a / b | a >>= b | a = a >> b |
a %= b | a = a % b | a >>>= b | a = a >>> b |
화살표(->) 연산자
- 자바 8에 추가된 "람다"를 지원하기 위한 연산자
- 메소드를 람다 표현식으로 표현하면, 클래스를 작성하고 객체를 생성하지 않아도 메소드를 사용할 수 있다.
- 함수형 인터페이스에서만 사용 할 수 있다.
- 익명 함수에 사용한다.
- 간결한 코드를 작성할 수 있고 가독성이 향상되지만 재사용이 불가능하고 디버깅이 어렵다.
- 재사용 하지 않을 메서드를 변수에 담지 않고 사용할 수 있어 메모리 낭비를 줄일 수 있다는 장점이 있다.
- 형태 (매개변수목록) ->{실행문/리턴문} (실행문만 있는 경우 괄호를 생략 할 수 있다.)
//기존 방식
Foo foo1 = new Foo() {
@Override
public int plus(int a, int b) {
return a + b;
}
};
//람다식 이용
Foo foo2 = (int a, int b) -> a+b;
int a = foo1.plus(1, 2);// 3 출력
int b = foo2.plus(1, 2);// 3 출력
3항 연산자
- 3개의 피연산자를 필요로 하는 연산자
- if-else문을 축약하는 문법
- 문법 : (조건문) : ? 참 : 거짓
- if문과 비교했을 때, 확연히 로직이 간단해지는 걸 볼 수 있다.○ if문
int a;
if(5<4) {
a = 50;
}else {
a = 40;
}
System.out.println(a); // 40 출력
○ 3항 연산자
int b = (5 < 4) ? 50 : 40;
System.out.println(b); // 40 출력
- 주의사항
○ 삼항 연산자를 사용하여 코드의 라인이 줄어들었다고 컴파일 속도가 빨라지는 것은 아니다.
○ 삼항 연산자를 중복해서 처리할 경우. 가독성이 떨어질 수 있어 지양하는게 좋다.
연산자 우선 순위
- 식에 여러 개의 연산자가 있는 경우, 우선순위가 높은 연산자를 먼저 처리한다.
- 우선순위가 동일하면 왼쪽에서 오른쪽으로 처리한다.
(단, 대입 연산자, --, ++, +(양수 부호), -(음수 부호), !, 타입 변환 연산자는 오른쪽에서 왼쪽으로 처리한다.) - 괄호는 항상 최우선적으로 처리한다.
- 단항→이항→삼항 연산자 순으로 우선순위를 갖는다.
- 산술→비교→논리→대입 연산자 순으로 우선순위를 갖는다.
Java 13. switch 연산자
- 자바 13부터는 switch문이 아니라 switch식이라고 표현된다. 이 말은 switch 가 값을 갖는다는 뜻이다.
- : 대신 -> 를 사용할 수 있다.
- return 대신 yield 키워드를 사용해 값을 리턴할 수 있다.
- switch 연산자 예제
static void howMany(int n) {
switch (n) {
case 1 -> System.out.println("one");
case 2 -> System.out.println("two");
default -> System.out.println("many");
}
}
public static void main(String[] args) {
howMany(1); // one 출력
howMany(2); // two 출력
howMany(3); // many 출력
}
참고
https://catsbi.oopy.io/c750e102-a202-4b70-b679-71c2fb24188a
'JAVA' 카테고리의 다른 글
[JAVA] 2주차 자바 데이터타입, 변수, 배열 (0) | 2023.07.24 |
---|---|
[JAVA] 1주차 JVM (0) | 2023.07.17 |