이것이 자바다 신용권의 Java 프로그래밍 정복 - 3장
3장
* 해당 글은 "이것이 자바다 신용권의 Java 프로그래밍 정복"을 기반으로 작성하였으며
책의 모든 목차를 다루는 것은 아니기에 내용중에 목차에서 빠진 부분도 있다는점 참고바랍니다.
3장 목차
- 3.1 연산자와 연산식
- 3.2 연산의 방향과 우선순위
- 3.3 단항 연산자
- 3.4 이항 연산자
- 3.5 삼항 연산자
3.1 연산자와 연산식
연산자는 필요로 하는 피연산자의 수에 따라 단항, 이항, 삼항 연산자로 구분된다.
단항 연산자 : ++x;
이항 연산자 : x + y;
삼항 연산자 : (sum>90) ? "A" : "B";
3.2 연산의 방향과 우선순위
연산자는 종료가 매우 다양하기에 여러 연산자가 나올경우를 대비해
연산자끼리 무엇을 먼저 계산해야할지 우선순위가 존재한다.
다음은 연산자의 연산 방향과 우선순위를 정리한 표이다.
위에 나와있는 표를 글로 정리해보면 다음과 같다.
- 단항 ,이항, 삼항 연산자 순으로 우선순위를 가진다
- 산술, 비교, 논리, 대입 연산자 순으로 우선순위를 가진다.
- 단항과 대입 연산자를 제외한 모든 연산의 방향은 왼쪽에서 오른쪽이다. (->)
- 복잡한 연산식에는 괄호()를 사용해서 우선순위를 정해준다.
정확하게 계산할 때에는 부동소수점 타입을 쓰지 않는 것이 좋다고 한다.
이유는 다음과 같다.
int apple = 1;
double pieceUnit = 0.1;
int number = 7;
double result = apple - number*pieceUnit;
System.out.println(result);
다음과 같은 코드에서 예상되는 출력값은 무엇일지 생각해보면
단순히 계산해봤을때
1 - 7 * 0.1 = 0.3 을 생각할 것이다.
하지만 놀랍게도 출력결과는 0.3이 아니다.
출력값은 0.29999999999999999999993 이다.
왜일까?
이렇게 출력되는 이유는 float, double과 같은 부동소수점 타입은 0.1을 정확히 표현할 수 없어서
근사치로 처리하기 때문이라고 한다. 따라서 0.1에 가장 가까운 수로 처리하기때문에
값이 딱 떨어지지 않고 위와 같은 출력값이 나오게 되는 것이다.
정확한 계산이 필요하다면 정수 연산으로 변경해서 계산해야한다.
자바는 나누는수가 0일 경우 컴파일은 정상적으로 되지만 ,
실행 시에는 ArithmeticExcepiton이라는 오류가 발생한다.
하지만 0.0 또는 0.0f 로 나눌 경우에는 오류가 발생하지 않는다.
/ 를 사용했을때는 infinity라는 결과값을,
% 를 사용했을때는 NaN이라는 결과 값을 출력하게된다.
신기하다..
결과값이 나오므로 이것을 활용할 수 도 있을 것이다.
infinity와 NaN 결과값을 활용하는 함수는
각각 Double.isInfinite(), Double.isNaN() 이다.
이 값이 infinity 또는 NaN이면 true를 리턴하고 아닐 경우 false를 리턴한다.
책 내용중에 "악의성 있는 사용자는 숫자로 변환이 안 되는 "NaN"을 입력할 수도 있다" 라는 말이 있었는데
이 글을 읽고 물론 이정도로는 택도 없겠지만
'아 이런게 코드의 허점을 이용한 공격? 그런건가' 라는 생각을 해보았다.
String 타입의 문자열을 비교할 때에는 대소 연산자를 사용할 수 없고,
동등 비교 연산자는 사용할 수 있으나 문자열이 같은지, 다른지를 비교하는 용도로는 사용하지 못한다.
다음 코드를 보며 이해해보자.
String strVar1 = "Bang";
String strVar2 = "Bang";
String strVar3 = new String("Bang");
자바는 문자열 리터럴이 동일하다면 동일한 String 객체를 참조하도록 되어있다.
그래서 strVar1과 strVar2는 동일한 String 객체의 번지값을 가지고 있다.
그러나 변수 strVar3는 객체 생성 연산자인 new로 생성한 새로운 String 객체의 번지값을 가지고있다.
따라서 두 번지값이 다르기에 저장되어있는 문자열이 같음에도 불구하고
strVar1 == strVar2 는 true 이지만
strVar2 == strVar3 는 false 이다
이는 " == " 연산자는 변수에 저장된 번지값만 비교하기 때문이다.
따라서 String 객체의 문자열만을 비교하려하는 경우에는 " equals() " 메소드를 사용해야한다.
equals() 메소드는 문자열만을 비교하기에
다음과 같은 결과를 얻을 수 있다.
strVar2.equals(strVar3) // true
//strVar2가 원본 문자열이고 strVar3가 비교 문자열이다
3.5 삼항 연산자
삼항 연산자는 말 그대로 세 개의 피연산자를 필요로 하는 연산자이며 조건 연산식이라고 부르기도 한다.
삼항 연산자는 한개밖에 없으며 식은 다음과 같다.
조건식 ? A : B |
A 와 B에는 값 또는 연산식이 들어가며
조건식이 true일 경우 A가
false일 경우 B가 결과값이 된다.