본문 바로가기

🧡 목표

자바가 제공하는 다양한 연산자를 학습하세요.

📢 About

산술, 비트, 관계, 논리, assignment(=) 연산자 등에 대해서는 이미 알고 있기에 학습 속도 향상 및 시간을 위해 학습하지 않았다. 모르는 부분이 있을 수 있겠지만 그렇다고 처음부터 정리하는 것은 효율적이지 않다고 개인적으로 판단했다. instanceOf, 화살표(->) 연산자, (optional) Java 13. switch 연산자에 대해서만 학습하였다.

instanceOf

instanceOf 연산자는 객체가 어떤 클래스인지, 어떤 클래스를 상속받았는지 확인하는 데 사용하는 연산자이다.

object instanceOf type

instanceOf 예제

Car이 부모이고 FireEngine, Ambulance가 자식인 구조를 가지고 있다.

class Car {  
  void drive() {  
    System.out.println("drive"); 
  }
} 

class FireEngine extends Car { // 소방차 
  void water() {
    System.out.println("warter!!!"); 
  } 
} 

class Ambulance extends Car { // 앰뷸런스 
  void siren() {  
    System.out.println("siren!!!");
  }
}

 

아래와 같이 car, fe, a 객체가 있을 때, instanceOf를 사용하면 이 객체가 어떤 class로부터 상속받은 클래스의 객체인지 확인할 수 있다.

class Main {
  public static void main(String[] args) {
    Car car = new Car();
    FireEngine fe = new FireEngine();
    Ambulance a = new Ambulance();

    System.out.println(car instanceof Car); // true
    System.out.println(fe instanceof Car); // true
    System.out.println(a instanceof Car); // true

    System.out.println(car instanceof FireEngine); // false
    System.out.println(fe instanceof FireEngine); // true
    //System.out.println(a instanceof FireEngine); // error

    System.out.println(car instanceof Ambulance); // false
    // System.out.println(fe instanceof Ambulance); // error
    System.out.println(a instanceof Ambulance); // true
  }
};

부모 클래스에서 만들어진 객체가 자식 클래스로 instanceOf를 사용할 경우에는 false를 반환하며, 자식클래스에서 만들어진 객체가 부모 클래스로 instanceOf를 사용할 경우에는 true를 반환한다.
부모-자식 간의 관계가 아닌 경우에 instanceOf 연산자를 사용할 경우에는 오류가 발생한다.

 

어떤 타입의 대한 instanceOf연산의 결과가 true라는 것은 검사한 타입으로 형 변환이 가능하다는 것을 뜻한다.

Object에 대한 instanceOf

모든 클래스는 Object를 상속하기 때문에 object instanceOf Object는 항상 true를 리턴한다.

class Main {
  public static void main(String[] args) {
    Car car = new Car();
    FireEngine fe = new FireEngine();
    Ambulance a = new Ambulance();
    System.out.println(car instanceof Object); // true
    System.out.println(fe instanceof Object); // true
    System.out.println(a instanceof Object); // true
  }
};

 

Null 객체에 대한 instanceOf

object가 null이라면 instanceOf는 항상 false를 리턴한다.

class Main {
  public static void main(String[] args) {
    Car car = new Car();
    FireEngine fe = new FireEngine();
    Ambulance a = new Ambulance();

    Car nullOb = null;
    System.out.println(nullOb instanceof Car); // false
    System.out.println(nullOb instanceof FireEngine); // false
    System.out.println(nullOb instanceof Ambulance); // false
  }
};

 

Generics의 instanceOf

Car처럼 Generic으로 생성된 객체도 동일하게 instanceOf로 타입을 체크할 수 있다.

class Main {
  public static void main(String[] args) {
    Car<String> car = new Car<String>();
    FireEngine fe = new FireEngine();
    Ambulance a = new Ambulance();

    System.out.println(car instanceof Car); // true
    System.out.println(fe instanceof FireEngine); // true
    System.out.println(a instanceof Ambulance); // true
  }
};

그러나 Generic 클래스 내에서 T와 같이 타입이 결정되지 않은 상태에서 instanceOf로 타입 체크를 할 수 없다. T는 컴파일 과정에서 실제 타입으로 변경되기 때문이다.

참고

화살표(->) 연산자

화살표 연산자는 Arrow 연산자라고 불리기도 한다.
Java 8버전부터 추가된 것으로, 람다 표현식과 함께 사용된다.

 

람다 표현식은 간단히 말해 메서드를 하나의 식으로 표현한 것이다.
// 메소드
int min(int x, int y) {
  return x < y ? x : y;
}

// 람다 표현식
(x, y) -> x < y ? x : y;​

람다 표현식으로 표현하면, 클래스를 작성하고 객체를 생성하지 않아도 메서드를 사용할 수 있다.
자바에서는 클래스의 선언과 동시에 객체를 생성하므로, 단 하나의 객체만을 생성할 수 있는 클래스를 익명 클래스라고 한다. 따라서 자바에서 람다 표현식은 익명 클래스와 같다.

참고

(optional) Java 13. switch 연산자

기존에 switch 연산자를 이용한 예제 코드이다.

class Example {
  public static void main(String[] args) {
    Example e = new Example();
    e.printDay(EDAY.MON);
    e.printDay(EDAY.SUN);
  }

  public void printDay(EDAY today) {
    switch(today) {
      case MON:
      case TUE:
      case WED:
      case THU:
      case FRI:
        System.out.println(today.name() + " is Weekday");
        break;
      case SAT:
      case SUN:
        System.out.println(today.name() + " is Weekend");
        break;
      default:
        System.out.println("ERROR");
        break;
    }
  }

  enum EDAY {
    MON, TUE, WED, THU, FRI, SAT, SUN
  }
};

break의 위치에 따라 실행 결과가 달라지기에 개발자의 실수로 break를 빼거나 다른 곳에 넣을 경우 버그가 생긴다.

Java 13에서 switch 연산자

Java 13에서는 기존에 switch 연산자를 사용하는 방식보다 더 간단하게 사용할 수 있게 만들었다.

class Example {
  public static void main(String[] args) {
    Example e = new Example();
    e.printDay(EDAY.MON);
    e.printDay(EDAY.SUN);
  }

  public void printDay(EDAY today) {
    switch(today) {
      case MON, TUE, WED, THU, FRI -> System.out.println(today.name() + " is Weekday");
      case SAT, SUN -> System.out.println(today.name() + " is Weekend");
      default -> System.out.println("ERROR");
    }
  }

  enum EDAY {
    MON, TUE, WED, THU, FRI, SAT, SUN
  }
};

반환값이 있을 경우

public void printDay(EDAY today) {
  String result = switch(today) {
    case MON, TUE, WED, THU, FRI -> "Weekday";
    case SAT, SUN -> "Weekend";
    default -> "ERROR";
  };
  System.out.println(result);
}

break를 사용하여 값을 대입할 수 있다.(break는 멈춘다는 의미가 아닌 값을 대입하기 위한 키워드이다.)
그러나 break를 다른 곳(switch, 메서드, for문 등)에서도 너무 많이 사용함으로 yield를 사용할 수 있다.

public void printDay(EDAY today) {
  String result1 = switch(today) {
    case MON, TUE, WED, THU, FRI: break "Weekday";
    case SAT, SUN: break "Weekend";
    default: break "ERROR";
  };
  System.out.println(result1);

  String result2 = switch(today) {
    case MON, TUE, WED, THU, FRI: yield "Weekday";
    case SAT, SUN: yield "Weekend";
    default: yield "ERROR";
  };
  System.out.println(result2);
}

여러 코드가 있을 경우

괄호 안 문장이 한 문장이 아닌 여러 문장일 경우이며 그 속에 대입해야 하는 경우에 break나 yield를 사용한다.

public void printDay(EDAY today) {
  String result = switch(today) {
    case MON, TUE, WED, THU, FRI -> {
      System.out.println("Weekday");
      yield "Weekday";
    }
    case SAT, SUN -> {
      System.out.println("Weekend");
      yield "Weekend";
    }
    default -> {
      System.out.println("ERROR");
      yield "ERROR";
    }
  };
  System.out.println(result);
}

참고

 

Live Study URL

개발의 각궁

Spring | Spring MVC | Spring Boot | Spring Security | Mysql | Oracle | PostgreSQL | Mybatis | JPA | Angular.js | Vue.js | Nuxt.js | React.js | TypeScript | JSP | Frontend | Backend