자바 연산자

KangMyungJoe·2020년 11월 27일
0

java_study

목록 보기
3/8
post-thumbnail

백기선님과 함께하는 Java-Study 3주차

3주차 과제: 자바 연산자
목표: 자바가 제공하는 다양한 연산자 학습하기

  • 산술 연산자
  • 비트 연산자
  • 관계 연산자
  • 논리 연산자
  • instanceof
  • assignment(=) 연산자
  • 화살표(->) 연산자
  • 3항 연산자
  • 연산자 우선 순위
  • Java 13, swithch 연산자

1. 산술 연산자

산술 연산자란, + - * / 와 같이 사칙연산을 하는 산수와 관련된 연산자다. (나눗셈에서 나머지 값을 알려주는 % 연산도 존재한다.)

int a = 6;
int b = 4;

System.out.println("result1 = " + (a+b));
System.out.println("result2 = " + (a-b));
System.out.println("result3 = " + (a*b));
System.out.println("result4 = " + (a/b));
System.out.println("result5 = " + (a%b));


> 결과 값: 
result1 = 10
result2 = 2
result3 = 24
result4 = 1
result5 = 2

프로그래밍에서의 산술 연산은 일상생활의 산술 연산과 조금의 차이점을 보인다. 예를 들어, 아래와 같은 코드가 있을 경우, 프로그래밍을 접한 경험이 없는 사람은 result의 값이 3.333...33이라고 생각할 수 있다.

int num1 = 10;
int num2 = 3;
int result = num1 / num2;

System.out.println("result = " + result);

하지만 출력되는 result는 무엇일까?

result = 3

int 형으로 선언된 result는 실수를 표현할 수 없기 때문에 3이 출력된다.


다른 경우로, int 형이 아닌 double로 선언되었다면?

double num1 = 10;
double num2 = 3;
double result = num1 / num2;

System.out.println("result = " + result);

출력되는 result는 무엇일까?

result = 3.3333333333333335

double 형으로 선언된 result가 실수까지 표현하는 모습을 확인할 수 있다.

산술 연산자에는 ++ --와 같이 간단하게 수를 더하고 뺄 수 있는 연산자도 존재한다. 아래와 같은 코드의 결과 값은 다음과 같다.

int i = 0, j = 1;

System.out.println(i++);
System.out.println(j--);


> 결과 값:
1
0

변수의 앞에 오느냐, 뒤에 오느냐에 따라 전위 증감자 후위 증감자로 불린다.


2. 비트 연산자

비트 연산자란, 컴퓨터가 사용하는 기계어 0 1을 이용해 연산을 진행할 때 사용하는 연산자로, ~ & | ^ 가 존재한다. 연산자의 내용은 아래와 같다.

~ : 단항 연산자, 항의 값이 0인 경우에만 1을 반환 NOT을 의미
& : 이항 연산자, 각 항의 값이 모두 1인 경우에만 1을 반환 AND을 의미
| : 이항 연산자, 각 항의 값 중 1이 존재하는 경우 1을 반환 OR을 의미
^ : 이항 연산자, 각 항의 값이 서로 다를 경우 1을 반환 XOR을 의미

출처: http://www.ddaily.co.kr/cloud/news/article.html?no=126150

참고

아래와 같은 코드의 결과 값과 비트 결과는 다음과 같다.

int num1 = 10;      // 00001010
int num2 = 13;      // 00001101

System.out.println("~ : " + (~num1));          // 11110101
System.out.println("& : " + (num1 & num2));    // 00001000
System.out.println("| : " + (num1 | num2));    // 0001111 <-- 1 | 1 ==> 1 NOT 10
System.out.println("^ : " + (num1 ^ num2));    // 00000111


> 결과값:
~ : -11
& : 8
| : 15
^ : 7

3. 관계 연산자

관계 연산자란, == > >= < <= != 와 같이 양 쪽의 값이 어떤 관계를 이루고 있는지 확인하는 연산자다. 어느 쪽이 큰지, 양 쪽이 같은지 등의 관계를 파악하는 데 주로 사용한다.

관계 연산자의 반환 값은 bool 형으로 true false 둘 중 한가지를 반환한다.

아래와 같은 코드의 결과 값은 다음과 같다.

int num1 = 100;
int num2 = 200;

System.out.println("100 > 200 : " + (num1 > num2));
System.out.println("100 >= 200 : " + (num1 >= num2));
System.out.println("100 < 200 : " + (num1 < num2));
System.out.println("100 <= 200 : " + (num1 <= num2));
System.out.println("100 == 200 : " + (num1 == num2));
System.out.println("100 != 200 : " + (num1 == num2));        

> 결과 값:
100 > 200 : false
100 >= 200 : false
100 < 200 : true
100 <= 200 : true
100 == 200 : false
100 != 200 : false

너무나 당연한 결과이지만, 관계 연산자를 실습해보았다.


4. 논리 연산자

논리 연산자란, 앞서 2번에서 다뤘던 비트 연산자와 비슷하지만 각 항의 타입이 bool 타입으로 이루어진 연산에서 사용되는 연산자로, ! & && | ||가 존재한다. 연산자의 내용은 아래와 같다.

! : 비트 연산자의 ~와 비슷한 의미로, bool 타입의 반대 값을 반환


& : 양 쪽이 모두 true일 때, true를 반환하며,
      첫 번째 인자가 true가 아닐 경우 두 번째 인자 확인 안함

&&: &와 동일한 의미를 갖지만,
      첫 번째 인자가 true가 아닐 경우에도 두 번째 인자 확인

| : 양 쪽 인자 중 하나라도 true면, true를 반환하며,
      첫 번째 인자가 true일 경우 두 번째 인자 확인 안함

|| : |와 동일한 의미를 갖지만,
      첫 번째 인자가 true일 경우에도 두 번째 인자 확인

아래와 같은 코드의 결과 값은 다음과 같다.

boolean _True = true;
boolean _False = false;
        

System.out.println("!_True : " + (!_True));
System.out.println("_True & _False : " + (_True & _False));
System.out.println("_True && _False : " + (_True && _False));
System.out.println("_True | _False : " + (_True | _False));
System.out.println("_True || _False : " + (_True || _False));


> 결과 값:
!_True : false
_True & _False : false
_True && _False : false
_True | _False : true
_True || _False : true

5. instanceof

instanceof 연산자는 참조 변수가 참조하고 있는 인스턴스의 실제 타입을 알아보기 위해 사용하며, bool 타입의 반환 값을 가진다.

아래와 같은 형식으로 사용한다.

(참조 변수) instanceof (참조 타입)

참조 변수가 참조 타입으로 형변환이 가능하면 true를 반환하며,
반대의 경우에는 false를 반환한다.

ex)
부모 참조 변수 instanceof 자손 인스턴스 ==> false
자손 참조 변수 instanceof 부모 인스턴스 ==> false
Object o instanceof 자손 인스턴스 ==> true

아래와 같은 코드의 결과 값은 다음과 같다.

A a = new A();
B b = new B();

System.out.println("객체 a는 Object 클래스로 형변환이 가능한가요? : " + (a instanceof Object));
System.out.println("객체 a는 A 클래스로 형변환이 가능한가요? : " + (a instanceof A));
System.out.println("객체 a는 B 클래스로 형변환이 가능한가요? : " + (a instanceof B));
System.out.println("객체 b는 A 클래스로 형변환이 가능한가요? : " + (b instanceof A));

(메인 밖)
class A {}
class B extends A {}


> 결과 값:
객체 a는 Object 클래스로 형변환이 가능한가요? : true
객체 a는 A 클래스로 형변환이 가능한가요? : true
객체 a는 B 클래스로 형변환이 가능한가요? : false
객체 b는 A 클래스로 형변환이 가능한가요? : true

6. assignment(=) 연산자

assignment 연산자란, 대입 연산자라는 표현이 더 익숙한 연산자로,
연산자 우측에 있는 피연산자를 연산자 좌측에 있는 변수에 대입한다. 이러한 과정을 초기화라고도 부른다.

대입 연산자의 사용은 아래와 같다.

int a = 10;
String name = "유재석";
boolean isHot = false;

대입 연산자는 앞서 다룬 산술 연산자와 같이 사용하여 식을 간단하게 표현한다.

예를 들어, 아래와 같이 1부터 10까지 더하는 코드의 경우,

int sum1 = 0, sum2 = 0;

for( int i = 1; i <= 10; i++ ) {
	sum1 = sum1 + i;
    	sum2 += i;		// sum2 = sum2 + i;
}

System.out.println("sum1의 값 : " + sum1);
System.out.println("sum2의 값 : " + sum2);


> 결과 값:
sum1의 값 : 55
sum2의 값 : 55

sum1에 1부터 10을 더하는 표현 방식과, sum2에 1부터 10을 더하는 표현 방식이 조금 다른 것을 확인할 수 있다. 주석을 통해 코드 해석 결과를 첨부했다.


7. 화살표 (->) 연산자

화살표 연산자란, 익명 함수라고 불리는 람다가 등장하며 사용되는 연산자다. 다음과 같은 문법으로 사용한다.

(매개변수목록) -> { 함수몸체 }

(x, y) -> x < y ? x : y;


int min (int x, int y) {
 return x < y ? x : y;
}

위에서 나타내고 있는 코드는 동일한 역할을 한다. 메서드를 람다 표현식으로 표현하면, 클래스를 작성하고 객체를 생성하지 않아도 메서드를 사용할 수 있다.

아래는 화살표 연산자를 이용한 람다 표현식의 예다.

new Thread(new Runnable() {
      public void run() {
            System.out.println("전통적인 방식의 일회용 스레드 생성");
        }
}).start();


new Thread(()->{
      System.out.println("람다 표현식을 사용한 일회용 스레드 생성");
}).start();


> 결과 값 :
전통적인 방식의 일회용 스레드 생성
람다 표현식을 사용한 일회용 스레드 생성

화살표 연산자를 사용하면 기존 코드보다 가독성이 좋고 불필요한 코드의 사용을 줄일 수 있다.
참고


8. 3항 연산자

3항 연산자란, 항이 3개인 경우에 사용하는 연산자로 다음과 같은 문법으로 사용한다.

(조건) ? (조건이 참인 경우 실행) : (조건이 거짓인 경우 실행)

예를 들어보자.

String name = "유재석";

if( name == "유재석") {
  name = "무한도적의 유재석";
}

System.out.println("name에 들어있는 문자열: " + name);


> 결과 값 :
name에 들어있는 문자열: 무한도적의 유재석

위와 같은 코드가 있을 때, 3항 연산자를 사용해서 나타내면 아래와 같다.

String name = "유재석";

name  = (name == "유재석" ? ("무한도전의 유재석") : ("런닝맨의 유재석"));

System.out.println("name에 들어있는 문자열: " + name);


> 결과 값:
name에 들어있는 문자열: 무한도전의 유재석

3항 연산자는 필요할 때 사용하면 간략하게 단락을 설명할 수 있어 편리하지만, 중첩되게 사용하거나 너무 많이 사용하게 되면 가독성이 매우 떨어질 수 있다.


9. 연산자 우선 순위

연산자 우선 순위는 아래 표와 같다.


10. Java 13, switch 연산자

Switch 연산자란, 많은 case 중 조건에 맞는 경우에 실행할 부분을 구분해주는 역할을 하는 문법이다. Java 13에서는 yield 키워드가 추가되었다.

아래 코드로 예시를 보며 확인하자.

public String printDay(Day today) {
    String result = switch (today) {
        case MON, TUE, WED, THUR, FRI -> today.name() + " is Weekday";
        case SAT, SUN -> {
            System.out.print("Holiday! ");
            yield today.name() + " is Weekend";
        }
    };
    return result;
}

yield 키워드를 통해 반환하며, {}을 통해 추가 작업도 할 수 있다.
참고


profile
소통을 잘하는 개발자가 되고 싶습니다.

0개의 댓글