온라인 자바 스터디 #3 - 연산자
by coco3o목표
자바가 제공하는 다양한 연산자를 학습하세요.
학습할 것
- 산술 연산자
- 비트 연산자
- 관계 연산자
- 논리 연산자
- instanceof
- assignment(=) operator
- 화살표(->) 연산자
- 3항 연산자
- 연산자 우선 순위
- (optional) Java 13. switch 연산자
산술 연산자
산술 연산자는 사칙 연산자(+, -, *, /), 나머지 연산자(%)로 이루어져 있다.
산술 연산자는 모두 두개의 피연산자를 취하는 이항 연산자이다.
- 이항 연산자는 피연산자의 크기가 4 byte보다 작으면 4byte(int형)로 변환한 다음에 연산을 수행한다.
- 이항 연산자는 연산을 수행하기 전에 피연산자들의 타입을 일치시킨다.
사칙 연산자 - + , -, *, /
사칙연산자의 우선순위는 곱셈(*), 나눗셈(/), 나머지(%) 연산자가 덧셈(+), 뺄셈(-)연산자보다 우선순위가 높다.
1. int형 (4byte)보다 크기가 작은 자료형은 int형으로 형변환 후에 연산을 수행한다.
byte + short ㅡ> int + int ㅡ> int
2. 두 개의 피연산자 중 자료형의 표현범위가 큰 쪽에 맞춰서 형변환 된 후 연산을 수행한다.
int + float ㅡ> float + float ㅡ> float
3. 정수형 간의 나눗셈에서 0으로 나누는 것은 금지되어 있다.
나머지 연산자- %
왼쪽의 피연산자를 오른쪽 피연산자로 나누고 난 나머지 값을 돌려주는 연산자이다.
boolean을 제외하고 모든 기본형 변수에 사용할 수 있다.
public class Example {
public static void main(String[] args) {
int x = 10;
int y = 5;
System.out.println(x + y); // 15
System.out.println(x - y); // 5
System.out.println(x * y); // 50
System.out.println(x / y); // 2
System.out.println(x % y); // 5
}
}
비트 연산자
비트 연산자는 데이터를 비트 단위로 연산한다. 그러므로 0과 1로 표현이 가능한 정수 타입만 비트 연산이 가능하다.
비트 연산자는 기능에 따라 비트 이동연산자, 비트 논리연산자로 구분한다.
비트 이동 연산자(shift 연산자) (<<, >>, >>>)
연산식 | 설명 |
x << y | 정수 x의 각 비트를 y만큼 왼쪽으로 이동시킨다. (빈자리는 0으로 채워진다.) |
x >> y | 정수 x의 각 비트를 y만큼 오른쪽으로 이동시킨다. (빈자리는 정수 a의 최상위 부호비트와 같은 값으로 채워진다.) |
x >>> y | 정수 x의 각 비트를 y만큼 오른쪽으로 이동시킨다. (빈자리는 0으로 채워진다.) |
비트 논리 연산자 (&, |, ^, ~)
연산자 | 논리 | 설명 |
& | AND | 두 비트 모두 1일 경우에만 결과가 1 |
| | OR | 두 비트 중 하나라도 1일 경우에 결과가 1 |
^ | XOR | 값이 서로 다를때만 결과가 1 |
~ | NOT | 비트 반전(보수) |
비트 연산자의 2진 연산 결과
x | y | x & y | x | y | x ^ y | x ~ y |
1 | 1 | 1 | 1 | 0 | 0 |
1 | 0 | 0 | 1 | 1 | 1 |
0 | 1 | 0 | 1 | 1 | 1 |
0 | 0 | 0 | 0 | 0 | 1 |
관계 연산자
비교 연산자라고도 하며 관계연산자의 결과는 true 혹은 false의 값인 boolean 자료형으로 반환이 된다.
연산자 | 기능 | 연산 예 |
> | 왼쪽 항이 크면 true 아니면 false를 반환 | num > 10; |
< | 왼쪽 항이 작으면 true 아니면 faslse를 반환 | num < 10; |
>= | 왼쪽 항이 오른쪽 항보다 크거나 같으면 true 아니면 false를 반환 | num >= 10; |
<= | 왼쪽 항이 오른쪽보다 작거나 같으면 true 아니면 false를 반환 | num <= 10; |
== | 두 개의 항이 같으면 true 아니면 false를 반환 | num == 10; |
!= | 두 개의 항이 다르면 true 아니면 false를 반환 | num != 10; |
논리 연산자
논리 연산자는 AND(&&), OR(||), NOT(!) 세가지 연산자가 있으며, 관계연산자와 같이 사용되는 경우가 많다.
논리 연산자 역시 연산의 결과가 true 혹은 false로 반환된다.
연산자 | 기능 | 연산 예 |
&& (논리 곱) |
두 항이 모두 true인 경우에만 결과 값이 true 아니면 false를 반환 | num = (10 > 5) && (10 < 4); |
|| (논리 합) |
두 항 중 하나라도 true면 결과 값은 true 아니면 false를 반환 | num = (10 > 3) || (10 < 4); |
! (부정) |
단항 연산자이다. true인 경우엔 false로 바꾸고, false인 경우엔 true로 바꾼다. | num = !(10 > 5); |
instanceof
참조변수가 참조하고 있는 인스턴스의 실제 타입을 알아보기 위해 instanceof 연산자를 사용한다.
이 연산자는 부모 변수가 참조하는 객체가 부모객체인지, 자식 객체인지 확인할 수 있다.
주로 조건문에 사용되며, 참조 변수가 instanceof로 형 변환 가능한 타입인지 연산한다.
형 변환이 가능하다면 true를 반환하고, 가능하지 못한다면 false를 반환한다.
참조변수 a가 Object 클래스로 형변환 할 수 있는지 조건문으로 알아봤다.
조건문이 true라면 실행하기 때문에 형 변환이 가능하다는 것을 알았다.
그렇다면 부모 클래스는 어디까지 형 변환을 할 수 있을까?
부모클래스 instanceof 연산시 자식 클래스를 제외하고 true가 나오는 것을 볼 수 있다.
왜 false가 나온 것일까?
부모가 자식이 되려했기 때문에 결과가 false가 나온 것이다.
또, 그렇다면 자식 클래스는 어디까지 형 변환을 할 수 있을까?
자식 클래스에 포함된 범위는 object, 부모, 자신까지 모두 포함되는 것을 볼 수 있다.
부모 클래스에서는 자식 클래스를 instanceof할 수 없지만,
자식 클래스에서는 부모 클래스를 instanceof할 수 있는 것을 알 수 있다.
대입 연산자(assignment operator)
대입 연산자는 변수에 값을 대입할 때 사용하는 이항 연산자이며, 피연산자들의 결합 방향은 오른쪽에서 왼쪽이다.
대입 연산자 | 설명 |
= | 왼쪽의 피연산자에 오른쪽의 피연산자를 대입함 |
+= | 왼쪽의 피연산자에 오른쪽의 피연산자를 더한 후, 그 결과를 왼쪽의 피연산자에 대입 |
-= | 왼쪽의 피연산자에 오른쪽의 피연산자를 뺀 후, 그 결과를 왼쪽의 피연산자에 대입 |
*= | 왼쪽의 피연산자에 오른쪽의 피연산자를 곱한 후, 그 결과를 왼쪽의 피연산자에 대입 |
/= | 왼쪽의 피연산자에 오른쪽의 피연산자를 나눈 후, 그 결과를 왼쪽의 피연산자에 대입 |
%= | 왼쪽의 피연산자에 오른쪽의 피연산자를 나눈 후, 그 나머지를 왼쪽의 피연산자에 대입 |
&= | 왼쪽의 피연산자를 오른쪽의 피연산자와 비트 AND 연산한 후, 그 결과를 왼쪽의 피연산자에 대입 |
|= | 왼쪽의 피연산자를 오른쪽의 피연산자와 비트 OR 연산한 후, 그 결과를 왼쪽의 피연산자에 대입 |
^= | 왼쪽의 피연산자를 오른쪽의 피연산자와 비트 XOR 연산한 후, 그 결과를 왼쪽의 피연산자에 대입 |
<<= | 왼쪽의 피연산자를 오른쪽의 피연산자와 비트 왼쪽 시프트한 후, 그 결과를 왼쪽의 피연산자에 대입 |
>>= | 왼쪽의 피연산자를 오른쪽의 피연산자만큼 부호를 유지하며 오른쪽 시프트한 후, 그 결과를 왼쪽의 피연산자에 대입 |
>>>= | 왼쪽의 피연산자를 오른쪽의 피연산자만큼 부호를 유지하며 오른쪽 시프트한 후, 그 결과를 왼쪽의 피연산자에 대입 |
화살표 (->) 연산자
화살표 연산자는 Java 8에 포함된 람다 표현식의 한 부분이다.람다식은 함수를 변수처럼 사용할 수 있는 개념이다. JDK8 이전의 자바에는 '메소드'라는 함수 형태가 존재하지만객체(혹은 클래스)를 통해서만 접근이 가능하고, 메소드 그 자체를 변수로 사용하지는 못했다.하지만 람다식 사용부터는 함수를 변수처럼 사용할 수 있기 때문에 파라미터로 다른 메소드의 인자로 전달할 수 있고,리턴값으로 함수를 받을 수도있다.
자바 람다식은 사실 완벽한 함수형 프로그래밍방식이라 할 수는 없다. 그 이유는 자바 람다식은 함수형에 대해서 새로 정의한게 아닌 기존에 존재하는 Interface형태와 같이 람다식을 표현하기 때문이다.
장점 :
1. 코드의 라인수가 줄어듦
2. 병렬 프로그래밍이 가능
3. 메소드로 행동방식을 전달 가능
4. 의도의 명확성(가독성 Up)
단점 :
1. 람다식의 호출을 위해 직접 메소드를 불러야 함
2. 재귀 람다식의 호출이 까다롭다.
3. 클로저가 지원되지 않음.
4. 함수 외부의 값을 변경한다.
자세한 내용은 추후에 람다식 공부할 때 알아보자.
3항 연산자
3항 연산자는 조건식과 조건식이 true일 때와 false일 때 반환되는 값, 이 세 가지가 삼항 연산자의 피연산자이다.
3항 연산자의 조건식에는 연산결과가 true 또는 false인 식이 사용되어야 한다.if - else 문과 바꿔 쓸 수 있으며, 코드 간결화가 가능하다.
조건식 ? 식1 : 식2
조건식이 true라면 식1
조건식이 false라면 식2
예제를 하나 보자.
int num = 10;
System.out.println((num > 1) ? "양수" : (num < 0) ? "음수" : 0);
결과는 '양수'이다.
위의 코드를 if - else문으로 바꾸면 아래처럼 코드 라인 수가 늘어나는 것을 볼 수 있다.
int num = 10;
if(num > 1) {
System.out.println("양수");
}else if(num < 0) {
System.out.println("음수");
}else {
System.out.println("0");
}
연산자 우선순위
우선순위 | 연산자 | 내용 |
1 | (). [] | 괄호 / 대괄호 |
2 | !, ~, ++, -- | 부정 / 증감 연산자 |
3 | *, /, % | 곱셈, 나눗셈, 나머지 연산자 |
4 | +, - | 덧셈, 뺄셈연산자 |
5 | <<, >>, >>> | 쉬프트 연산자 |
6 | <, <=, >, >= | 관계 연산자 |
7 | ==, != | |
8 | & | 논리 연산자 |
9 | ^ | |
10 | | | |
11 | && | 논리곱 연산자 |
12 | || | 논리합 연산자 |
13 | ? : | 조건 연산자 |
14 | =, +=, -=, *=, /=, %=, <<=, >>=, >>>=, &=, ^=, ~= | 대입 연산자 |
(optional) Java 13. switch 연산자
Java 12부터는 콜론(:) 대신 화살표(->) 연산자를 사용할 수 있고,
Java 13부터는 break 대신 yield를 사용할 수 있다.
기본 switch문
public enum Day { SUNDAY, MONDAY, TUESDAY,
WEDNESDAY, THURSDAY, FRIDAY, SATURDAY; }
// ...
int numLetters = 0;
Day day = Day.WEDNESDAY;
switch (day) {
case MONDAY:
case FRIDAY:
case SUNDAY:
numLetters = 6;
break;
case TUESDAY:
numLetters = 7;
break;
case THURSDAY:
case SATURDAY:
numLetters = 8;
break;
case WEDNESDAY:
numLetters = 9;
break;
default:
throw new IllegalStateException("Invalid day: " + day);
}
System.out.println(numLetters);
Java 12 콜론(:) -> 화살표(->)
int numLetters = 0;
Day day = Day.WEDNESDAY;
switch (day) {
case MONDAY, FRIDAY, SUNDAY -> numLetters = 6;
case TUESDAY -> numLetters = 7;
case THURSDAY, SATURDAY -> numLetters = 8;
case WEDNESDAY -> numLetters = 9;
default -> throw new IllegalStateException("Invalid day: " + day);
};
System.out.println(numLetters);
Java 13 break -> yield
Day day = Day.WEDNESDAY;
int numLetters = switch (day) {
case MONDAY:
case FRIDAY:
case SUNDAY:
System.out.println(6);
yield 6;
case TUESDAY:
System.out.println(7);
yield 7;
case THURSDAY:
case SATURDAY:
System.out.println(8);
yield 8;
case WEDNESDAY:
System.out.println(9);
yield 9;
default:
throw new IllegalStateException("Invalid day: " + day);
};
System.out.println(numLetters);
break 대신 yield를 사용한다면, 주의해야할 점이 있다.
콜론이 있는 구문에서 yield가 빠지게 되면 컴파일 에러가 발생하여 미리 알 수 있기 때문에
화살표(->) 연산자를 사용할 것을 권장한다.
int numLetters = switch (day) {
case MONDAY, FRIDAY, SUNDAY -> {
System.out.println(6);
yield 6;
}
case TUESDAY -> {
System.out.println(7);
yield 7;
}
case THURSDAY, SATURDAY -> {
System.out.println(8);
yield 8;
}
case WEDNESDAY -> {
System.out.println(9);
yield 9;
}
default -> {
throw new IllegalStateException("Invalid day: " + day);
}
};
출처 : https://docs.oracle.com/en/java/javase/13/language/switch-expressions.html
'🌈Programming > Java' 카테고리의 다른 글
온라인 자바 스터디 #5 - 클래스, 메소드, 생성자 정의, this, 객체 new 키워드 (0) | 2020.12.17 |
---|---|
JUnit 5 소개 (0) | 2020.12.16 |
온라인 자바 스터디 #4 - 제어문 (0) | 2020.12.14 |
온라인 자바 스터디 #2 - 자바 데이터 타입, 변수 그리고 배열 (0) | 2020.12.09 |
자바 기본 개념 (3) | 2020.12.08 |
블로그의 정보
슬기로운 개발생활
coco3o