자바생
article thumbnail
Published 2022. 5. 6. 20:42
java 연산자 Java
728x90

0.1. 산술 연산자(Arithmetic Operators)

  • 간단한 수학 연산을 하기 위해 사용하는 연산자
  • 기본 숫자 및 그에 대응하는 boxed type에서만 작동
  • +, -, *, /, %가 존재한다
    • '/'는 몫, '%'는 나머지를 의미한다
<code />
@Test @DisplayName("산술 연산") void op() throws Exception{ int a = 6; int b = 4; System.out.println("a/b = " + a / b); //몫 System.out.println("a%b = " + a % b); //나머지 }

0.2. 비트 연산자(Bitwise Operators)

  • 비트 연산자에는 Bitwise Logical Operators, Bitwise Shift Operators로 나눌 수 있다

 

0.2.1. Bitwise Logical Operators

  • AND, OR, XOR, Complement Operator 가 있다

 

0.2.2. Complement 연산

b는 현재 0000 0110 이고, ~b는 1111 1001

최고 비트가 1이므로 b의 보수는 음수를 의미한다

따라서 음수인 수는 그 수의 보수를 구하여 다시 10진수로 변환해야 한다

 

따라서 1111 1001의 2의 보수는 0000 0110 + 1 이므로 0000 0111

즉, -7이 된다~

 

0.2.3. Bitwise Shift Operators

  • Signed Left/Right Shift, Unsigned Right Shift가 있다

 

0.2.4. Signed Left Shift

  • 변수 << [이동 횟수]
  • 이동 횟수만큼 비트를 왼쪽으로 이동
  • 오른쪽의 빈 공간은 0으로 채워짐
  • 즉, 왼쪽으로 n번 움직이는 것은 2^n을 곱한 것과 같다
<code />
@Test @DisplayName("비트 leftshift") void shift() throws Exception{ int x = 12; System.out.println("12를 2진수 = " + Integer.toBinaryString(x)); //1100 int leftShift = x << 2; System.out.println("leftShift = " + leftShift); //48 x = -12; leftShift = x << 2; System.out.println("leftShift = " + leftShift); //-48 }

 

0.2.5. Signed Right Shift

  • left shift와 형식은 비슷하지만 방향만 다르다
  • 이동횟수만큼 비트를 오른쪽으로 이동
  • 변수가 음수일 때(가장 왼쪽 비트 1), 빈 공간은 1로 채워짐
  • 변수가 양수일 때(가장 왼쪽 비트 0), 빈 공간은 0으로 채워짐
<code />
@Test @DisplayName("비트 right_shift") void right_shift() throws Exception{ int x = 12; System.out.println("12를 2진수 = " + Integer.toBinaryString(x)); //1100 int right_shift = x >> 2; System.out.println("right_shift = " + right_shift); //3 x = -12; right_shift = x >> 2; System.out.println("right_shift = " + right_shift); //-3 }

 

0.2.6. Unsigned Right Shift

  • Signed Right Shift와 매우 유사
  • 다른 점은 숫자를 이동하고 난 뒤, 양수 음수 상관없이 0으로 채워짐
  • 따라서 결과는 항상 양의 정수가 나옴
<code />
@Test @DisplayName("비트 unsigned_right_shift") void unsigned_right_shift() throws Exception{ int x = 12; System.out.println("12를 2진수 = " + Integer.toBinaryString(x)); //1100 int unsigned_right_shift = x >>> 2; System.out.println("unsigned_right_shift = " + unsigned_right_shift); //3 x = -12; unsigned_right_shift = x >>> 2; System.out.println("unsigned_right_shift = " + unsigned_right_shift); //1073741821 }

 

0.3. 관계 연산자(Relational Operators)

  • 관계 연산자는 "비교 연산자(Comparison operators)"라고도 한다
  • ==, !=, >, >=, <, <= 가 있지만 우리는 ==을 유심히 봐보자

Java에서 비교를 할 시, ==와 equals 중에 어떤 것을 사용해야 할까?라는 의문이 들 수 있다

나는 대부분 값을 비교할 시 ==을 사용하고, 객체를 비교할 시 무조건 equals를 사용한다

 

각 숫자에 대응되는 wrapper class들(interget ...)도 equals를 사용한다

  • Integer를 비교할 때 ==을 사용 시 -128~127까지는 올바르게 비교 값이 나오지만 그 이후에는 예상치 못한 결괏값이 나올 수 있다
  • 해당 부분은 "IntegerCache"를 참고하면 알 수 있다
<code />
@Test @DisplayName("Integer 비교") void relational() throws Exception{ Integer a = 129; Integer b = 129; Integer c = 124; Integer d = 124; System.out.println(a == b); //false System.out.println(c == d); //true System.out.println(a.equals(b)); //true System.out.println(c.equals(d)); //true }

 

0.4. 논리 연산자(Logical Operators)

  • java에서 제공되는 논리 연산자에는 AND, OR 연산자가 있다
  • &&와 || 로 표현

 

0.4.1. ||(OR) 연산자 특징

  • 만약 이 앞의 조건이 참이라면 뒤의 연산을 계산하지 않고 true를 반환한다
<code />
@Test @DisplayName("|| 특징") void logical() throws Exception{ int a = 4; int b = 5; if (a >= 4 || ++b > 5) { System.out.println("b = " + b); //b의 값은 5 } if (a >= 5 || ++b > 5) { System.out.println("b = " + b); //b의 값은 6 } }

 

0.5. instance of

참조 변수 instanceof 클래스

 

참조 변수가 "참조"하고 있는 "인스턴스"의 실제 타입을 알아보기 위해 사용한다

따라서 형 변환이 가능한지 검사하는 기능 또한 가지고 있다

 

<java />
static class A{} static class B extends A{} static class C extends A{} @Test @DisplayName("instance of") void instance_of() throws Exception{ A a = new A(); System.out.println(a instanceof B); //f System.out.println(a instanceof C); //f a = new B(); System.out.println(a instanceof A); //t System.out.println(a instanceof B); //t System.out.println(a instanceof C); //f }

처음에 참조 변수 a는 A 클래스를 참조하고 있다

그래서 A 클래스는 B 클래스로 형 변환을 할 수 있을까에 대한 답은 NO다  C 또한 마찬가지

 

두 번째에서는 참조 변수 a는 B 클래스를 참조하고 있다

B 클래스는 A 클래스로 형 변환할 수 있을까에 대한 답은 YES다

 

B와 C는 아무런 관계가 없으므로 당연히 NO다

 

0.6. assignment operator(=)

= 연산은 primitive type과 reference type에 따라 의미가 달라진다

 

primitive에서 int a = 3; 을 하게 되면 우리는 a의 값에 3을 저장한다

 

reference type에서는 주소 값을 할당하는 것이다

<code />
/** * a = study.querydsl.QuerydslBasicTest$A@3f78a5ed * b = study.querydsl.QuerydslBasicTest$A@630e5010 * a = study.querydsl.QuerydslBasicTest$A@630e5010 * b = study.querydsl.QuerydslBasicTest$A@630e5010 */ @Test @DisplayName("reference type에서 = 연산") void assignment() throws Exception{ A a = new A(); A b = new A(); System.out.println("a = " + a); System.out.println("b = " + b); a = b; System.out.println("a = " + a); System.out.println("b = " + b); }

처음에는 a와 b가 주소값을 가지고 있었다

 

a = b의 연산을 하고 나서 a와 b 모두 b의 주소값을 참조하고 있게 된다

이 뜻은 a의 주소 값에 b의 주소 값을 저장한다 즉, a는 b가 참조하고 있는 주소 값을 참조한다 라는 뜻이다

 

reference type의 assignmnet operator는 주소값을 할당해주는 것을 알 수 있다

 

0.6.1. Compound Assignments

+=, -=, *=, /=, %= 을 compound assignment 라고 한다

 

a += b 의미는 a = a + b라는 뜻이다 

나머지 연산들도 모두 같은 말이다

 

 

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

java 8에서 람다의 도입에 따라 화살표 연산자도 등장하게 됐다

 

이는 람다식을 배우게 되면 사용하게 되는 연산자이다

람다식 공부

 

0.8. 3항 연산자(Ternary Operator)

  • if-else 문을 줄여주기 위해 사용되는 연산자
  • 조건 ? true일 경우 행동 : false일 경우 행동
<code />
@Test @DisplayName("|| 특징") void logical() throws Exception{ int a = 4; String result1 = a >= 4 ? "참" : "거짓"; String result2 = a > 4 ? "참" : "거짓"; System.out.println("result1 = " + result1); //참 System.out.println("result2 = " + result2); //거짓 }

 

 

0.9. 연산자 우선순위

https://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html

unary(단항) 연산자와 assignment 연산자는 <- 방향으로 진행, 나머지 연산들은 -> 방향으로 진행된다

 

산술 -> 비교 -> 논리 -> 대입 순서로 알 수 있다~

 

 

0.10. Java 13 switch 연산자

 

0.10.1. Java 12 전 switch 연산

<code />
@Test void post12_switch() throws Exception{ int a = 1; switch (a) { case 1: System.out.println("1"); break; case 2: System.out.println("2"); break; default: System.out.println("3"); break; } }

 

-"-사용" href="#article-0-10-2--java-12-이후-"--->-"-사용">0.10.2. Java 12 이후 " - > " 사용

switch expression으로 사용할 수 있게 됐다

즉, 단일 값으로 평가되어 명령문에서도 사용할 수 있다

<code />
@Test void switch_12() throws Exception { int a = 1; switch (a) { case 1 -> System.out.println("1"); case 2 -> System.out.println("2"); default -> System.out.println("many"); } }

여기에 이어서 인자로 사용할 수도 있게 됐다

<code />
@Test void switch_12() throws Exception { int a = 1; System.out.println( switch (a) { case 1 -> 1; case 2 -> 2; default -> 3; } ); }

 

0.10.3. Java 13 yield

 

Java 13에서 인자로 사용할 수 있기 때문에 변수에도 할당할 수 있게 "yield"를 사용했다

switch statement는 break의 target, switch의 expression은 yield의 타겟이 될 수 있다

<code />
@Test void switch_13() throws Exception { int num = 1; int numLetters = switch (num) { case 2 -> { System.out.println(7); yield 7; } case 7 -> { System.out.println(8); yield 8; } case 1 -> { System.out.println(1); yield 0; } default -> throw new IllegalStateException("Invalid num: " + num); }; System.out.println("numLetters = " + numLetters); /** * 1 * numLetters = 0 */ }

현재 num 값은 1이므로 case 1에 걸리게 되고 1을 출력하게 된다.

여기서 yield 0을 하게 되면 0을 반환하고, numLetters에는 0이 저장된다

 

따라서 numLetters를 출력하면 0이 출력된다~


1. REFERENCES

switch Java 13(oracle)

연산자(baeldung)

비트 연산

728x90

'Java' 카테고리의 다른 글

정적 메서드는 왜 오버라이딩 되지 않을까?  (0) 2022.08.29
throw vs throws  (0) 2022.05.17
Primitive Type, Reference Type, Literal  (0) 2022.05.03
Java volatile keyword  (0) 2022.04.18
final 키워드  (0) 2022.03.05
profile

자바생

@자바생

틀린 부분이 있다면 댓글 부탁드립니다~😀

검색 태그