Java

연산자

donggi 2022. 8. 10. 15:07

산술 연산자

산술 연산자

산술 연산자에는 사칙 연산자 (+, -, *, /)와 나머지 연산자 (%)가 있다.

사칙 연산자 + - * /

일반적인 연산과 같이 곱셈, 나눗셈, 나머지 연산이 덧셈, 뺄셈 연산보다 우선 순위가 높아 먼저 처리된다

나누는 연산 시 주의할 점

  • 피연산자가 정수형인 경우, 나누는 수로 0을 사용할 수 없다. 만일 0으로 나누게되면 에러(ArithmeticException)가 발생한다
  • 나누기 연산자의 두 피연산자가 모두 int 타입인 경우, 연산 결과 또한 int 타입이 반환된다
    • 예로 10 / 4 와 같이 나머지가 있는 연산을 / 연산자를 통해 연산하게 되면 연산 결과로 int 타입이 반환되기 때문에 정수만 남고 소수점 이하 값은 버려지게 된다
    • 소수점을 포함한 연산 결과를 얻기 위해서는 두 피연산자 중 한 쪽을 실수형으로 변환하여 연산을 수행해야 한다
      • 그렇게 되면 정수형인 int 타입은 실수형인 float double 타입으로 type conversion이 이루어진다

비트 연산자

비트 연산자는 피연산자를 비트단위로 논리 연산한다. 피연산자로 실수는 허용하지 않는다. 정수만 허용된다.

OR (|)

비트 OR 연산자는 | 로 표시되며 주로 특정 비트의 값을 변경할 때 사용되는 이항 연산자다. 입력 값으로 논리적 OR 연산을 수행한다.

OR 비트 연산 중 연산되는 비트 중 하나라도 1이면 1을 반환하고 그렇지 않으면 0을 반환한다

5 = 0101(binary)
7 = 0111(binary)

5  7 OR 연산
	0101
|	0111
==========
	0111 -> 7 (decimal)

AND (&)

비트 AND 연산자는 & 주로 특정 비트의 값을 뽑아낼 때 사용된다.

AND 연산은 두 비트 모두가 1이어야 1을 반환하고, 연산되는 비트 중 하나라도 1이 아니면 0을 반환한다

	0011
&	0101
========
	0001

XOR (^)

비트 XOR 연산자는 ^ 는 두 피연산자의 비트가 다를 때만 1이 된다.

또한 같은 값으로 XOR 연산을 수행하면 원래의 값으로 돌아온다는 특징이 있어 간단한 암호화에 사용된다

	10101011
^	00001111
===========
	10100100
^	00001111
===========
	10101011  // 같은 값으로 XOR 연산을 수행하여 원래의 값으로 돌아왔다

비트 전환 연산자 ~

이 연산자는 피연산자를 2진수로 표현했을 때, 0은 1로, 1은 0으로 바꾼다

비트 전환 연산자에 의해 비트 전환이 되면, 부호 있는 타입의 피연산자는 부호가 반대로 변경된다. 즉, 피연산자의 1의 보수를 얻을 수 있다. 그래서 비트 전환 연산자를 1의 보수 연산자라고도 한다.

쉬프트 연산자 << >>

쉬프트 연산자는 피연산자의 각 자리를 오른쪽 또는 왼쪽으로 이동한다고 하여 쉬프트 연산자라고 한다.

8 << 2 // 왼쪽 피연산자인 10진수 82진수를 왼쪽으로 2자리 이동한다

쉬프트 연산 과정은 다음과 같다

  1. 10진수 8은 2진수로 ‘00001000’이다
  2. 8 << 2 는 10진수 8의 2진수를 왼쪽으로 2자리 이동시킨다
  3. 자리 이동으로 인해 저장 범위를 벗어난 값은 버려지고, 빈자리는 0으로 채워진다 ‘00001000`00``
    1. 각각의 00은 버려진 값과, 빈자리에 채워진 값
  4. 8 << 2 의 결과는 2진수로 00100000 이 된다 (10진수로는 32)

<< 연산자의 경우, 피연산자의 부호에 상관없이 각 자리를 왼쪽으로 이동시키며 빈칸을 0으로만 채우면 되지만, >> 연산자는 오른쪽으로 이동시키기 때문에 부호있는 정수는 부호를 유지하기 위해 왼쪽 피연산자가 음수인 경우 빈자리를 1로 채운다. (양수일 때는 0으로 채움)

// -8 >> 2 -> -2
1. 11111000
2.   111110 00 // 버려지는 값인 00
3. 11111110 00 // 음수의 경우 오른쪽으로 이동시키면서 생긴 빈자리는 1 채워주었다
4. 11111110    // 오른쪽 쉬프트 연산의 결과 (10진수로는 -2 됨)

쉬프트 연산자의 방향에 따른 산술변환

쉬프트 연산자의 좌측 피연산자는 산술변환이 적용되어 int보다 작은 타입은 int타입으로 자동 변환되고 연산결과 역시 int타입이 된다. 그러나 쉬프트 연산자는 다른 이항연산자들과 달리 피연산자 타입을 일치시킬 필요가 없기 때문에 우측 피연산자에는 산술변환이 적용되지 않는다.

관계 연산자

관계 연산자의 종류

Java에는 6가지의 관계 연산자가 있다

a < b

  • a 가 b 보다 작은가

a > b

  • a 가 b 보다 큰가

a ≤ b

  • a 는 b 보다 작거나 같은가

a ≥ b

  • b 는 a 보다 작거나 같은가

a == b

  • a 와 b 는 같은가

a ≠ b

  • a 와 b 는 다른가

논리 연산자

논리 연산자는 둘 이상의 조건을 ‘그리고(AND)’나 ‘또는(OR)’로 연결하여 하나의 식으로 표현할 수 있게 해준다

논리 연산자 - &&, ||, !

논리 연산자 ‘&&’  우리말로 그리고(AND)에 해당하며  피연산자가 모두 true 때만 true 결과로 얻는다
||’ 는 또는(OR)에 해당하며, 두 피연산자 중 어느 한 쪽만 ture여도 true를 결과로 얻는다
논리 부정 연산자 '!'  피연산자가 true이면 false를, false  true 결과로 반환한다

논리 연산자는 피연산자로 boolean형 또는 boolean형 값을 결과로 하는 조건식만 허용한다

효율적인 연산

논리 연산자의 특징은 효율적인 연산을 한다는 것이다

OR연산 ‘||’ 의 경우, 두 피연산자 중 어느 한 쪽만 true면 전체 연산결과가 true 이므로 좌측 피연산자가 true면 우측 피연산자는 평가하지 않는다

AND연산 ‘&&’ 또한 마찬가지로 두 피연산자가 모두 true일 때 true를 반환하기 때문에, 좌측 피연산자가 false면 우측 피연산자는 평가하지 않아도 false를 반환할 수 있게 된다

instanceof

instanceof는 참조 변수에 입력한 유형의 객체가 참조되고 있는지 확인하는데 연산자다

@Test
void instanceofTest() {
    List<String> helloArray = new ArrayList<>();
    boolean expected = helloArray instanceof List;
assertThat(expected).isTrue();
}
  • helloArray 라는 ArrayList 가 List 를 참조하고 있는지 테스트를 해보았다

위처럼 테스트가 통과하게 된다

  • helloArray 가 Map 을 참조하고 있는가에 대한 테스트를 해보았다
  • 당연히 테스트가 통과하지 않게 되었다

assignment(=) operator

할당 연산자 = assignment operator

  • 할당 연산자의 왼쪽 피연산자는 변수이고, 오른쪽 피연산자는 값(value)이다
  • 오른쪽에 있는 값은 피연산자의 데이터 유형과 같아야 한다 (그렇지 않으면 컴파일러 오류 발생)
  • 오른쪽에 있는 값은 왼쪽에 있는 변수에 할당된다

단순 할당 연산자

단순 할당 연산자는 왼쪽이 피연산자로 구성되고 오른쪽이 값으로 구성되는 = 기호와 함께 사용된다. 오른쪽 값은 왼쪽에 정의된 것과 동일한 데이터 유형이어야 한다.

복합 할당 연산자

복합 연산자는 + - * / % 와 같은 연산자가 = 연산자와 함께 사용된다

class AssignmentOperatorEx{
	public static void main(String[] args) {
		int num;
		num = 10;  // 단순 할당 연산, 정수형 10이 변수 num에 할당됨
		
		num += 10; // 복합 할당 연산자, num = num + 10 과 같다
		num -= 10;
		num *= 10;
		num /= 10;
		num %= 10;
	}
}

화살표(->) 연산자

Java 8부터 도입된 람다를 표현하기 위한 화살표 연산자

Lambda식

화살표는 매개변수와 본문을 구분한다

  • (parameter) → {body} 각각 매개변수와 람다식 본문을 화살표 연산자를 통해 구분한다
  • 매개변수는 메서드와 같은 방식으로 소괄호로 묶여 있다
  • 람다식 본문(body)은 중괄호로 묶은 코드 블럭이 또는 표현식일 수 있다
    • 본문은 단일 문으로 작성이 가능하다 (이 때는 중괄호가 필요 없음)
    • 본문에 여러 문이 있는 경우에는 코드 블럭이 필요하다

컴파일러는 람다 형식을 유추한다

  • 람다를 정의할 때 매개변수 유형을 지정하지 않으면 컴파일러는 매개변수 유형을 유추한다
  • 매개변수 유형을 모두 지정하거나 지정하지 않거나 해야함
    • 여러 유형 중 몇몇 매개변수만 유형을 지정하면 컴파일 에러 발생
  • 매개변수가 하나만 있는 경우엔 괄호를 생략할 수 있다
    • 이 경우 매개변수에 타입을 명시할 수 없다
    • 컴파일러가 매개변수 타입을 유추하게 둬야함
  • 람다 함수의 반환 유형은 본문(body)에서 유추된다

이중 콜론(::) 연산자

이중 콜론 연산자란

  • Java에서 메서드 참조 연산자라고 하는 해당 클래스의 도움을 받아 메서드를 직접 참조하여 메서드를 호출하는데 사용된다
  • 람다식과 똑같이 동작한다
  • 람다식과 다른 점은 메서드에 변수를 통해 접근하는 게 아닌 메서드에 대한 직접 참조를 사용한다

이중 콜론 연산자의 사용

언제 어떻게 사용하나?

메서드 참조 또는 이중 콜론 연산자를 사용하여 다음을 참조할 수 있다

  • 정적 메서드
  • 인스턴스 메서드
  • 생성자

Java에서 참조를 사용하는 방법

<클래스 이름> :: <메서드 이름>

3항 연산자

  • 삼항 연산자는 세 개의 피연산자를 사용하는 유일한 조건 연산자이다
  • if else 조건 대신 삼항 연산자를 사용하거나 중첩 삼항 연산자를 사용할 수도 있다
  • if else 문과 동일한 알고리즘을 따르지만 공간을 덜 차지하고 짧은 코드로 if else 문을 작성할 수 있다
value = exp1 ? exp2 : exp3
// exp1가 true면 exp2가 실행되고
// exp1이 false면 exp3이 실행된다

연산자 우선 순위

(optional) Java 13. switch 연산자

https://www.w3schools.com/java/java_operators.asp

https://www.geeksforgeeks.org/java-arithmetic-operators-with-examples/

https://www.javatpoint.com/java-operator-precedence

 

'Java' 카테고리의 다른 글

5주차 클래스  (0) 2022.08.18
제어문  (0) 2022.08.12
자바 데이터 타입, 변수 그리고 배열  (5) 2022.07.28
JVM은 무엇이며 자바 코드는 어떻게 실행하는 것인가  (9) 2022.07.24
자바 프로그램의 개발과 구동  (0) 2022.01.17