티스토리 뷰

반응형

목표

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


학습할 것

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

산술 연산자

수학적 계산( 사칙 연산 ) 에 사용되는 연산자입니다. ( +, -, *, /, % )
연산자 설명 에러
+ 이항 더하기 연산자 하나의 숫자를 다른 숫자에 더합니다.
단항 플러스 연산자
숫자 프로모션을 트리거하는 것과 별개의 기능을 수행
문자열 연결을 수행  두 개의 문자열을 조인하여 세 번째 문자열을 제공합니다.
- 이항 더하기 연산자 다른 숫자에서 하나의 숫자를 뺍니다
단항 플러스 연산자 (-1) 피연산자를 0에서 뺀 것과 같습니다.
* 이항 연산자 한 숫자에 다른 숫자를 곱합니다.
/ 이항 연산자
(  n / d = q )
한 숫자를 다른 숫자로 나눕니다.

Java 정수부는 0을 반올림.
Java 부동 소수점 분할의 기본 아이디어는 결과 q  d . q = n 를 만족시키는 데 가장 가까운 값입니다. d* q = n .

부동 소수점 나누기의 결과는 IEEE 754 산술 규칙에 따라 결정됩니다.

 분모가 0이면  ArithmeticException
% 이항 연산자 한 숫자를 다른 숫자로 나눌 때 나머지를 계산합니다.
Java 프로그래밍 언어에서는 부동 소수점 피연산자도 허용합니다.
부동 소수점 나머지는 b 가 0 일 때와 같이 경계 케이스에서 INF  NaN 값을 생성 할 수 있습니다. 
정수 나머지 연산자의 제수 값이 0이면 an ArithmeticException
INF "무한"또는 INF 값은 너무 큰 숫자를 나타냅니다. +INF 값은 너무 크고 양수 인 숫자를 나타냅니다. 
-INF 값은 너무 크고 음수 인 숫자를 나타냅니다.
INF 값은 오버플로를 일으키는 부동 연산 또는 0으로 나누는 부동 소수점 연산에 의해 생성됩니다

NAN "무기한"/ "숫자가 아님"또는 NaN은 의미없는 작업으로 인해 발생하는 값을 나타냅니다.
NaN 값은 0을 0으로 나누거나 0을 나머지로 계산하여 생성됩니다

 

//Please don't change class name 'Main'

class Main {

  public static void main(String[] args) {
      // result 의 값은 3
      int result = 1 + 2;
      System.out.println(result);

      // result 의 값은 2
      result = result - 1;
      System.out.println(result);

      // result 의 값은 4
      result = result * 2;
      System.out.println(result);

      // result 의 값은 2
      result = result / 2;
      System.out.println(result);

      // result 의 값은 10
      result = result + 8;
      // result 의 값은 3
      result = result % 7;
      System.out.println(result);

      String firstString = "This is";
      String secondString = " a concatenated string.";
      String thirdString = firstString+secondString;
      System.out.println(thirdString);
  }
}

 

 

더보기
// java cat Main.class ( 바이트 코드 ) 
????;5

java/lang/Object<init>()V    



java/lang/SystemoutLjava/io/PrintStream;

java/io/PrintStreamprintln(I)This i a concatenated string.
                                                          makeConcatWithConstants8(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;

(Ljava/lang/String;)VMainCodeLineNumberTablemain([Ljava/lang/String;)V
SourceFile    Main.javaBootstrapMethods(
)*+
   ,$java/lang/invoke/StringConcatFactory?(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite.
                                  InnerClasses1%java/lang/invoke/MethodHandles$<MN,-?:??!B/lang/invoke/MethodHandlesLookup  *??!    "# ?S<?

#*/4;>AJR $%'-/

피연산자 및 결과 유형 및 숫자 승격

연산자는 숫자 피연산자가 필요하며 숫자 결과를 생성합니다. 피연산자 유형은 java.lang 에서 정의 된 임의의 원시 숫자 유형 (즉, byte , short , char , int , long , float 또는 double )이거나 숫자 래퍼 유형 일 수 있습니다. ie( Byte , Character , Short , Integer , Long , Float 또는 Double .)

 

결과 유형은 다음과 같이 피연산자 또는 피연산자 유형에 따라 결정됩니다.
  • 피연산자 중 하나가 double 또는 Double 이면 결과 유형은 double 입니다.
  • 그렇지 않으면 피연산자 중 하나가 float 또는 Float 이면 결과 유형은 float 입니다.
  • 그렇지 않으면, 피연산자 중 하나가 long 또는 Long 이면 결과 유형은 long 입니다.
  • 그렇지 않은 경우 결과 유형은 int 입니다. 여기에는 byte , short , char 피연산자와`int.
연산의 결과 유형에 따라 산술 연산이 수행되는 방식과 피연산자가 처리되는 방식이 결정됩니다.
  • 결과 유형이 double 이면 피연산자가 double 으로 승격되고 연산은 64 비트 (배정 밀도 이진) IEE 754 부동 소수점 산술을 사용하여 수행됩니다.
  • 결과 유형이 float 이면 피연산자가 float 로 승격되고 연산은 32 비트 (단 정밀도 2 진수) IEE 754 부동 소수점 산술을 사용하여 수행됩니다.
  • 결과 유형이 long 경우, 피연산자는 long 으로 승격되고 연산은 64 비트 부호있는 2의 보수 2 진 정수 산술을 사용하여 수행됩니다.
  • 결과 유형이 int 이면 피연산자가 int 로 승격되고 연산은 32 비트 부호있는 2의 보수 2 진 정수 연산을 사용하여 수행됩니다.
  • ( 정수 타입의 연산의 결과가 int타입으로 나온느 이유는 자바가상기계(JVM)이 기본적으로 32bit 단-위로 계산하기 때문입니다. )
프로모션은 다음 두 단계로 수행됩니다.
  1. 피연산자 유형이 래퍼 유형 인 경우, 피연산자 값은 해당 프리미티브 유형의 값에 unboxed 됩니다.
  2. 필요한 경우 기본 유형이 필수 유형으로 승격됩니다.
  • int 또는 long 으로 정수를 승격하는 것은 손실이 적습니다.
  • double 하는 float 프로모션은 손실이 적습니다.
  • 부동 소수점 값으로 정수를 승격하면 정밀도가 떨어질 수 있습니다. 변환은 IEE 768 "가장 가까운 값으로 반올림"의미론을 사용하여 수행됩니다.

비트 연산자와 논리 연산자

  • 보수 ( ~ ) 연산자는 하나의 피연산자 비트를 비트 또는 논리 반전하는 단항 연산자입니다.
  • AND ( & ) 연산자는 두 개의 피연산자의 비트 또는 논리 "and"를 수행하는 이항 연산자입니다.
  • OR ( | ) 연산자는 2 개의 피연산자의 비트 또는 논리 "포함 또는"을 수행하는 2 진 연산자입니다.
  • XOR ( ^ ) 연산자는 두 개의 피연산자의 비트 또는 논리 "배타적 논리합"을 수행하는 이항 연산자입니다.
연산자는 실제로 모든 32 또는 64 비트의 피연산자 또는 피연산자를 병렬로 연산합니다.
~ 연산자는 부울 값을 뒤집거나 정수 피연산자의 모든 비트를 변경하는 데 사용됩니다.
& 연산자는 정수 피연산자의 비트 중 일부를 "마스킹"하는 데 사용됩니다. 
int word = 0b00101010;
int mask = 0b00000011;   // Mask for masking out all but the bottom 
                         // two bits of a word
int lowBits = word & mask;            // -> 0b00000010
int highBits = word & ~mask;          // -> 0b00101000
연산자는 두 피연산자의 진리 값을 결합하는 데 사용됩니다.
int word2 = 0b01011111; 
// Combine the bottom 2 bits of word1 with the top 30 bits of word2
int combined = (word & mask) | (word2 & ~mask);   // -> 0b01011110
^ 연산자는 비트 전환 또는 "뒤집기"에 사용됩니다.
int word3 = 0b00101010;
int word4 = word3 ^ mask;             // -> 0b00101001

관계 연산자 (<, <=,>,> =)

< , <= , >  >= 연산자는 숫자 유형 비교를위한 이항 연산자입니다. 
이러한 연산자의 결과 유형은 모든 경우에 boolean 입니다. 관계 연산자를 사용하여 숫자를 다른 유형과 비교할 수 있습니다.
int i = 1;
long l = 2;
if (i < l) {
    System.out.println("i is smaller");
}

class Main {

	public static void main(String[] args) {

		char i = 'A';
		long l = 2;
		if (i < l) {
			System.out.println("i is smaller");

		}
		else{
			System.out.println("l is smaller");  //!!!! 이게 출력된다.
		}

	}
}

더보기
// 바이트 코드
????;"

java/lang/Object<init>()V	



java/lang/SystemoutLjava/io/PrintStream;
                                       i is smaller

java/io/PrintStreamprintln(Ljava/lang/String;)V
StackMapTable                                 j is smallerMainCodeLineNumberTablemain([Ljava/lang/String;)V
SourceFile	Main.java ?	"A<A ???	??
                                                  ?	??
? !%    

 

이러한 연산자를 사용하여 문자열, 숫자 배열 등을 비교할 수 없습니다 
  1. 피연산자 중 하나가 박스형이면 unbox입니다.
  2. 현재 피연산자 중 하나가 byte , short 또는 char 이면 int 로 승격됩니다.
  3. 피연산자의 유형이 동일하지 않으면 "더 작은"유형의 피연산자가 "더 큰"유형으로 승격됩니다.
  4. 결과는 int , long , float 또는 double 값에 대해 비교가 수행됩니다.

instanceof

객체가 특정 클래스 / 인터페이스 유형인지 여부를 확인합니다. instanceof 연산자는 다음과 같이 작성됩니다.
객체 타입을 확인하는데 사용하는 연산자. 해당 여부를  true, false 로 알려준다. 부모 객체의 인스턴스인지 자식 객체인지 를 알려줄 때 사용합니다.
객체 instanceof 클래스
( Object reference variable ) instanceof  (class/interface type)
class A {}

class B extends A {}

public static void main(String[] args) {

    A a = new A();
    B b = new B();
    
    System.out.println(a instanceof A); // true
    System.out.println(b instanceof A); // true
    System.out.println(a instanceof B); // false
    System.out.println(b instanceof B); // true

}
더보기

 

 바이트 코드

????;!

java/lang/Object<init>()A

B

	
        java/lang/SystemoutLjava/io/PrintStream;

java/io/PrintStreamprintln(Z)VMainCodeLineNumberTablemain([Ljava/lang/String;)V
SourceFile	Main.java!?	9?Y?	L?
Y?
+???
,?
??

$
8 %  

assignment(=) operator :: 할당 연산자

값을 변수에 할당할 때 쓰는 연산자입니다.

http://tcpschool.com/java/java_operator_assignment

 

주소 할당과 값 할당을 다르게 생각해야합니다.
  • 깊은 복사와 얕은 복사
    • 얕은 복사 = 주소를 이어준다. B 를 수정하는 것은 A를 수정하는 것과 같습니다.
    • 깊은 복사 = 값을 복사해서 제대로 복사합니다.
      • 배열 복사 메서드 예 : 원본배열.clone(), Arrays.copyOf(원본배열, 내가 원하는 length까지) System.copyOfRange(원본배열, 원하는 시작점, 원하는 끝점), System.arrayCopy() (지정된 배열을 대상 배열의 지정된 위치에 복사해줍니다.) 
      • 2차원 배열의 경우 1차원 배열과 같은 방식을 취하면, a[x][y]는 얕은 복사가 된다. 무조건 반복문을 돌려서 일일이 복사해줘야합니다.
import java.util.Arrays;
public class Array_Copy{
	public static void main(String[] args)  {
		int[] a = { 1, 2, 3, 4 };
		int a2[][] = {{1,2,3},{4,5,6,},{7,8,9}};
		int[] shallowCopy = a; // 얕은 복사 => 주소만 복사함
		/* 1-1번. 반복문  */
		int[] b1 = new int[a.length]; 
		for (int i = 0; i < a.length; i++) {
			b1[i] = a[i];
		}
		/* 1-2번. clone -> 가장 보편적  */ 
		int[] b2 = a.clone();
		/* 1-3번. Arrays.copyOf() -> 가변 길이(끝)  */ 
		int[] b3 = Arrays.copyOf(a, a.length);
		/* 1-4번. AArrays.copyOfRange() -> 가변 길이(시작, 끝)  */
		int[] b4 = Arrays.copyOfRange(a, 1, 3);
		/* 1-5번.   System.arraycopy -> 원하는 위치에  */
		int[] b5 = new int[a.length];
		System.arraycopy(a, 0, b5, 0, a.length);
		/* 2-1번. 이중배열 이중 반복문으로 생성  */
		int[][] b21 = new int[a2.length][a2[0].length];

		for(int i=0; i<a2.length; i++) {
			for(int j=0; j<a2[i].length; j++) {
				b21[i][j] = a2[i][j];  
			}
		}

		/* 2-2번. 이중배열 1 반복문 +  System.arraycopy으로 생성  */
		int b22[][] = new int[a2.length][a2[0].length];

		for(int i=0; i<b22.length; i++){
			System.arraycopy(a2[i], 0, b22[i], 0, a2[0].length);
		}

	}
}

 

https://coding-factory.tistory.com/548
https://coding-factory.tistory.com/548
주의해야하는 2차원 복사:  https://coding-factory.tistory.com/548

 

더보기

바이트코드

????;*

java/lang/Object<init>()[I




clone()Ljava/lang/Object;

java/util/ArrayscopyOf([II)[I


copyOfRang([III)[I

ava/lang/System	arraycopy*(Ljava/lang/Object;ILjava/lang/Object;II)V[[I 
StackMapTable'[Ljava/lang/String;([Ljava/lang/String;)V
SourceFileArray_Copy.java!!*??"	#$!?

                                    ?
YOYOYOYOL?Y?
YOYOYOSY?
YOOYOSY?
YOOY	OSM+N+??
:+?:+??O????+?	?:++??
+??,?,2??:	6

,??+6

     ,
2??	
2
 ,
2
 .O?
    ???
???,?,2??:
6


??
  2

2,2???
      ???"^S[	e
}???????????!?"!
%%?^&??7
        &?	????()%         

화살표 연산자

Java 8 이후부터 람다 연산자 ( -> )는 람다 식을 도입하는 데 사용되는 연산자입니다. 다음 예에서 볼 수 있듯이 두 가지 공통적 인 구문이 있습니다. 람다 표현식은 익명 함수, 또는 함수 인터페이스 를 구현하는 익명 클래스의 인스턴스를보다 정확하게 정의합니다.
a -> a + 1              // a lambda that adds one to its argument
a -> { return a + 1; }  // an equivalent lambda using a block.

람다식

Lambda 표현식은 표현식을 사용하는 단일 메서드 인터페이스를 구현하는 명확하고 간결한 방법을 제공합니다.
// lambda 안씀
JButton btn = new JButton("My Button");
btn.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("Button was pressed");
    }
});

인터페이스 ActionListener는 하나의 메서드 만 정의 actionPerformed()하므로 기능적 인터페이스이므로 Lambda 식을 사용하여 표준 코드를 대체 할 수 있습니다. 위의 예는 다음과 같이 Lambda 표현식을 사용하여 다시 작성할 수 있습니다.

// 람다씀
JButton btn = new JButton("My Button");
btn.addActionListener(e -> {
    System.out.println("Button was pressed");
});

삼항연산자

삼항 연산자는 자바에서 유일하게 피연산자를 세 개나 가지는 조건 연산자입니다.
삼항 연산자의 문법은 다음과 같습니다. 물음표(?) 앞의 조건식에 따라 결괏값이 참(true)이면 반환값1을 반환하고, 결괏값이 거짓(false)이면 반환값2를 반환합니다.
조건식 ? 반환값1 : 반환값2
int num1 = 5, num2 = 7;
int result;
result = (num1 - num2 > 0) ? num1 : num2;
System.out.println("두 정수 중 더 큰 수는 " + result + "입니다.");
//두 정수 중 더 큰 수는 7입니다.
더보기
//바이트코드
????;/

java/lang/Object<init>()V	



java/lang/SystemoutLjava/io/PrintStream;
                                        makeConcatWithConstants(I)Ljava/lang/String;

StackMapTableStreamprintln(Ljava/lang/String;)VMainCodeLineNumberTablemain([Ljava/lang/String;)V
SourceFile	Main.javaBootstrapMethods"
#$%
   &$java/lang/invoke/StringConcatFactory?(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite()두 정수 중 더 큰 수는 입니다.
        InnerClasses+%java/lang/invoke/MethodHandles$Lookup-java/lang/invoke/MethodHandlesLookup!*??   <=?>???      ?@!')
*,.%  

연산자 우선 순위

 

https://medium.com/@katekim720/%EC%97%B0%EC%82%B0%EC%9E%90%EB%B6%80%ED%84%B0-%EC%A1%B0%EA%B1%B4-%EB%B0%98%EB%B3%B5%EB%AC%B8%EA%B9%8C%EC%A7%80-3d5cec6513d4


java13 switch 연산자

입력값이 정형화되어 있고, 조건이 많은 경우 if문보다는 switch/case문을 쓰는것이 가독성에서 좀 더 유리하다.
switch(입력변수) {
    case 입력값1: ...
         break;
    case 입력값2: ...
         break;
    ...
    default: ... // 그 외
         break;
}

 

더보기
public class SwitchDemo {
    public static void main(String[] args) {
        int month = 8;
        String monthString = "";
        switch (month) {
            case 1:  monthString = "January";
                     break;
            case 2:  monthString = "February";
                     break;
            case 3:  monthString = "March";
                     break;
            case 4:  monthString = "April";
                     break;
            case 5:  monthString = "May";
                     break;
            case 6:  monthString = "June";
                     break;
            case 7:  monthString = "July";
                     break;
            case 8:  monthString = "August";
                     break;
            case 9:  monthString = "September";
                     break;
            case 10: monthString = "October";
                     break;
            case 11: monthString = "November";
                     break;
            case 12: monthString = "December";
                     break;
            default: monthString = "Invalid month";
                     break;
        }
        System.out.println(monthString);
    }
}

 


참고문헌

https://riptutorial.com/ko/java/example/678/%EC%82%B0%EC%88%A0-%EC%97%B0%EC%82%B0%EC%9E%90--plus-------------

tcpschool.com/java/java_operator_etc

coding-factory.tistory.com/548

riptutorial.com/fr/java/topic/91/expressions-lambda

medium.com/@katekim720/%EC%97%B0%EC%82%B0%EC%9E%90%EB%B6%80%ED%84%B0-%EC%A1%B0%EA%B1%B4-%EB%B0%98%EB%B3%B5%EB%AC%B8%EA%B9%8C%EC%A7%80-3d5cec6513d4

wikidocs.net/263 (점프투자바)

 

반응형

'스프링, 자바' 카테고리의 다른 글

why we use spring?  (0) 2020.12.02
제어문  (4) 2020.11.28
mvc 아키텍처  (0) 2020.11.18
mocMvc Controller Test  (0) 2020.11.18
타임리프 찾아본 로그  (0) 2020.11.16
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함