연산자(operator) - 연산을 수행하는 기호(+, -, *, / 등)
피연산자(operand) - 연산자의 작업 대상(변수, 상수, 리터럴, 수식)
public static void main(String[] args) {
int a = 10;
int b = 3;
//덧셈
System.out.println("a + b = %d%n", a + b); // a + b = 13
//뺄셈
System.out.println("a - b = %d%n", a - b); // a - b = 7
//곱셈
System.out.println("a * b = %d%n", a * b); // a * b = 30
//나눗셈
System.out.println("a / b = %d%n", a / b); // a / b = 3
//나눗셈 실수형 형 변환
System.out.println("a / b = %f", a / (float) b); // a / b = 3.333333
System.out.println("a %% b = %d%n", a % b); // 1
b = 0;
System.out.println("a / b = %f", a / b); // 0으로 정수형을 나누게 되면 컴파일시에는 문자가 없으나 런타임시 ArithmeticException 발생
System.out.println("a / b = %f", a / (float) b); // a / b = Infinity
}
public static void main(String[] args) {
byte a = 10;
byte b = 20;
byte c = a + b;
System.out.println("a + b = %d", c); //컴파일 오류 발생
}
+
연산자는 변수를 int형으로 변환해 연산을 수행한다.
byte형 변수에 형변환 없이 넣으려 했기 때문에 컴파일 오류가 발생한다.
byte c = (byte)(a + b);
public static void main(String[] args) {
byte a = 10;
byte b = 30;
byte c = (byte)(a * b);
System.out.println("a * b = %d", c); // a * b = 44
}
연산 과정에서 자료형이 int형으로 바뀌고 결과값은 300이 된다.
결과값 300을 byte형 변수 c에 담기 위해 byte 형으로 형변환 수행
byte 자료형의 최대 값 127을 초과하므로 오버플로우 발생
오버플로우 발생을 예방하기 위해서는 연산시 충분히 큰 자료형을 사용해야한다.
데이터를 bit 단위로 논리 연산하는 연산자이다.
실수형은 허용하지 않고 정수형만 연산이 가능하다.
public static void main(String[] args) {
int a = 1;
int b = 0;
// OR 연산
System.out.println("a | b = %d%n", a | b); // a | b = 1
// AND 연산
System.out.println("a & b = %d%n", a & b); // a & b = 0
// XOR 연산
System.out.println("a ^ b = %d%n", a ^ b); // a ^ b = 1
}
public static void main(String[] args) {
int a = 10;
int b = 3;
System.out.println("a > b : %b%n", a > b); // a > b : true
System.out.println("a < b : %b%n", a < b); // a < b : false
System.out.println("a >= b : %b%n", a >= b); // a >= b : true
System.out.println("a <= b : %b%n", a <= b); // a <= b : false
System.out.println("a == b : %b%n", a == b); // a == b : false
System.out.println("a != b : %b%n", a != b); // a != b : true
}
public static void main(String[] args) {
int a = 10;
int b = 3;
// AND 결합
System.out.println("a > 7 && b < 1 ==> %b%n", a > 7 && b < 1); // a > 7 && b < 1 ==> false
// OR 결합
System.out.println("a > 7 || b < 1 ==> %b%n", a > 7 || b < 1); // a > 7 || b < 1 ==> true
// ! 연산자
System.out.println("!(a > 7) ==> %b%n", !(a > 7)); // !(a > 7) ==> false
}
변수가 참조하고 있는 객체의 실제 타입을 확인하기 위해 사용하는 연산자이다.
public static void main(String[] args) {
CustomClass variable = new CustomClass();
System.out.println("variable instance of CustomClass : %b", variable instanceof CustomClass); // variable instance of CustomClass : true
}
public static class CustomClass {
public CustomClass () {
}
}
변수의 타입 클래스가 다른 클래스를 상속받는 클래스일 경우, 상위 클래스를 대상으로 instanceof 연산을 수행했을 때도 true가 반환된다.
public static void main(String[] args) {
Bar bar = new Bar();
System.out.println("bar instance of Bar : %b%n", bar instanceof Bar); // bar instance of Bar : true
System.out.println("bar instance of Foo : %b%n", bar instanceof Foo); // bar instance of Foo : true
}
public static class Foo {
publid Foo () {
}
}
public static class Bar extends Foo {
public Bar () {
}
}
인터페이스를 구현하는 클래스의 경우, 인터페이스를 대상으로 instanceof 연산을 수행했을 때도 true가 반환된다.
public static void main(String[] args) {
Bar bar = new Bar();
System.out.println("bar instance of Bar : %b%n", bar instanceof Bar); // bar instance of Bar : true
System.out.println("bar instance of Foo : %b%n", bar instanceof Foo); // bar instance of Foo : true
}
public interface Foo {
}
public static class Bar implements Foo {
public Bar () {
}
}
대입 연산자는 변수와 같은 저장공간에 값 또는 연산 결과를 저장하는데 사용된다.
대입 연산자는 연산자들 중에서 우선순위가 가장 낮기 때문에 식에서 제일 나중에 수행되고 저장된 값을 연산 결과로 반환한다.
public static void main(String[] args) {
int x, y;
System.out.println(x=y=3); // 3
System.out.println(x); // 3
System.out.println(y); // 3
}
public static void main(String[] args) {
Bar bar = new Bar();
bar.doSomething("test");
}
@FunctionalInterface
public interface Foo {
String doSomething(String s);
}
public static class Bar implements Foo {
@Override
public String doSomething(String s) {
return "Bar ::: " + s;
}
}
익명 클래스 활용
public static void main(String[] args) {
Foo foo = new Foo() {
@Override
public String doSomething(String s) {
return "anonymous class " + s;
}
};
foo.doSomething("test");
}
@FunctionalInterface
public interface Foo {
String doSomething(String s);
}
람다 활용
public static void main(String[] args) {
Foo foo = (s) -> "lambda " + s;
foo.dosomething("test");
}
@FunctionalInterface
public interface Foo {
String doSomething(String s);
}
3개의 피연산자를 필요로하는 연산자이다.
조건식 ? 식1 : 식2
public static void main(String[] args) {
int a = 10;
int b = 3;
String result = (a > b) ? "참" : "거짓";
System.out.println("(a > b) ? 참 : 거짓 ==> %s", result); // (a > b) ? 참 : 거짓 ==> 참
}
단항 연산자 > 이항 연산자(곱셈, 나눗셈 > 덧셈, 뺄셈) > 비교 연산자 > 논리 연산자 > 삼항 연산자 > 대입 연산자 > 람다 표현식
public static void main(String[] args) {
//Java 12이전
int a = 1;
int b = 0;
switch(a) {
case 1:
b = 1;
break;
case 2:
b = 2;
break;
case 3:
b = 3;
break;
}
import java.util.*;
public class Test {
public static void main(String[] args) {
// java 12
int a = 1;
int b = 0;
b = switch(a) {
case 1 -> 1;
case 2 -> 2;
default -> throw new IllegalStateException("예외값: " + a);
}
}
```java
import java.util.*;
public class Test {
public static void main(String[] args) {
// java 13
int a = 1;
int b = 0;
b = switch(a) {
case 1: yield 3;
default : throw new IllegalStateException("예외값: " + a);
}
}
yield 키워드
스위치 표현식 및 스위치 문장에서 값을 명시적으로 리턴하기 위한 새로운 키워드