『자바의 신 3판』 을 읽고 내용 정리 및 공부한 내용을 정리한 글입니다.
서적: 자바의 신 3판 구입처
기본 자료형을 제외한 참조 자료형은, 항상 예외가 되는 String이라는 클래스만이 + 연산이 가능하다.
다시 말해서, 계산을 위한 산술 연산자는 기본 자료형 중에서 boolean을 제외한 나머지 타입에서 사용할 수 있다.
산술 연산자와 대입 연산자를 붙여 사용하면, 연산 후 결과를 바로 대입할 수 있다.
하나의 피연산자를 갖는 연산자이다.
비트 연산자는 부록에서 상세히 설명되어 있습니다.
아래는 부록을 정리한 내용입니다.
비트 연산자는 비트 단위로 데이터를 처리할 때 사용한다. C언어를 사용할 때에는 이 비트 연산을 많이 했지만, 자바에서는 API가 풍부하게 제공되므로 이 비트 연산자를 사용할 일은 그다지 많지 않다.
하지만, CPU의 성능이 아주 느린 작은 장비에 들어가는 프로그램을 작성하거나, 암호화 작업과 관련된 작업을 할 때에는 조금이라도 메모리를 줄이고, 성능을 개선하기 위해서 필요할 수도 있다.
즉, 유지보수해야하는 누군가가 만든 코드에 비트 연산이 있을 수도 있기 때문에 알아두어야만 한다.
컴퓨터의 기본적인 처리는 0과 1, 꺼져 있는 것과 켜져 있는 것으로 나뉜다. 1 bit라는 것은 0과 1로 표시할 수 있는 하나의 단위다. 그리고, 8 bit는 1 byte가 된다.
8 비트로 나타낼 수 있는 수는 가지, 총 256가지가 된다.
여기서 8 비트를 4자리씩 끊으면 4비트 두 개로 표현할 수 있고, 각 4자리는 16진수로 표현이 가능하기 때문에 16진수 두 개로 8비트, 즉 1 바이트를 표현할 수 있다.
2진수 8자리로 표현하는 것보다, 16진수 2자리로 표현하는 것이 훨씬 효율적이다.
2진수를 16진수로 표현한 표.
숫자 10부터는 알파벳 A부터 시작한다.
10진수 | 2진수 | 16진수 | 10진수 | 2진수 | 16진수 |
---|---|---|---|---|---|
0 | 0000 | 0 | 10 | 1010 | A |
1 | 0001 | 1 | 11 | 1011 | B |
2 | 0010 | 2 | 12 | 1100 | C |
3 | 0011 | 3 | 13 | 1101 | D |
4 | 0100 | 4 | 14 | 1110 | E |
5 | 0101 | 5 | 15 | 1111 | F |
6 | 0110 | 6 | |||
7 | 0111 | 7 | |||
8 | 1000 | 8 | |||
9 | 1001 | 9 |
두 개의 숫자를 비교하는 연산자.
비트 연산자 중 유일한 단항 연산자다. 각 bit의 값을 반대로(0은 1, 1은 0) 바꿔버린다.
비트를 이동하는 연산자. 왼쪽에 있는 값을 오른쪽에 있는 값만큼 비트를 이동시킨다.
모든 비교 연산자의 결과는 반드시 boolean이다. 해당 “조건에 맞으면 true, 그렇지 않으면 false”가 된다.
💡 기본 자료형과 참조 자료형, 즉 모든 타입에서 사용할 수 있다. 기본 자료형은 같은 종류끼리 비교가 가능하다 (숫자형끼리, boolean끼리)
종류
// 아래와 같은 자료형이 있을 때
char charVal = 'a' // ASCII 97
int intVal = 1;
double doubleVal = 1.0;
// 아스키코드 97 = 'a'이기 때문에 true이고,
// 같은 숫자형은 int와 double도 true로 나온다.
System.out.println(97 == charVal); // true
System.out.println(intval == doubleVal); // true
💡 boolean을 제외한 기본 자료형, 그 중에서도 숫자형에서만 사용 가능하다.
종류
연산자 | 식 | true 조건 |
---|---|---|
> | a < b | a가 b보다 작을 때 |
< | a > b | a가 b보다 클 때 |
<= | a <= b | a가 b와 같거나, b보다 작을 때 |
>= | a >= b | a가 b와 같거나, b보다 클 때 |
연산자 | 명칭 | true 조건 |
---|---|---|
&& | AND 결합. Conditional AND | 두 개의 조건이 모두 true일 때에만 true |
그리고, 숫자에 사용하면 비트 연산을 수행하지만 boolean 타입 사이에 사용하면 논리 연산을 수행해주는 연산자들이 있다.
연산자 | true 조건 |
---|---|
& | 두 값이 모두 true일 때에만 true |
^ | 두 값이 서로 다를 경우에는 true. 모두 true이거나, false이면 false |
&과 &&, |과 ||는 같아보이지만 실제 연산하는 방식에서는 차이가 있다.
&&의 경우 좌측에 있는 연산이 false 이면 우측에 있는 연산을 수행하지 않는다. 왜냐하면 두 개의 조건이 모두 true 여야만 true이기 때문에, 앞의 연산이 false이면 뒤의 연산을 수행할 필요가 없기 때문이다.
하지만 &의 경우는 좌측 연산 결과와 우측 연산 결과를 비교해야만 하기 때문에 모든 연산을 수행한다.
때문에 &&와 ||를 사용하는 것을 권장한다.
= 왼쪽에 있는 변수에 값을 할당할 때 사용한다. 이때, 대입하는 값은 변수와 같은 타입이어야 한다.
변수 = (결과가 boolean인 조건식) ? true일 때 값 : false일 때 값
유일하게 자바의 예약어로 되어있는 연산자이며, 상속의 개념을 알고 있어야 하므로 10장에서 다시 설명한다.
각 연산자에는 우선 순위가 있어서, 해당 순위 별로 먼저 계산해준다. 원하는 연산부터 하도록 하고 싶다면 괄호를 사용한다.
괄호 예시: (1+2)*3
구분 | 연산자 | 우선 순위 |
---|---|---|
단항 연산자 | ++ -- + - ! ~ | 1 |
산술 연산자 | * / % | 2 |
+ - | 3 |
서로 다른 타입 사이에 변환하는 작업을 하는 것을 말한다. 자바의 형 변환은 기본 자료형과 참조 자료형 모두 괄호로 묶어주면 된다.
boolean 타입은 숫자로 변환할 수 없기 때문에 형 변환이 불가능하다.
바이트 크기가 커지는 캐스팅을 할 경우에는 별도로 해줄 것이 없다. 명시적으로 형 변환을 해주지 않아도 자바에서 자동으로 형 변환 해주기도 한다.
하지만, 바이트 크기가 작아지는 캐스팅을 할 경우에는 앞의 바이트를 버려버리기 때문에 데이터의 손실이 일어난다.
일례로 실수 타입을 정수 타입으로 강제 타입 변환하면 소수점 이하의 데이터들이 버려진다.
범위의 순서
byte → short, char → int → long → float → double
아래 내용은 참고 사이트에서 일부 발췌했다. 이 블로그에 설명이 자세히 되어 있다.
long 타입은 8바이트이고 float은 4바이트이기 때문에 따라서 float가 long 보다는 작은 타입이 되어야 하지만, 범위를 보면 long 보다 float이 더 크다고 되어있다.
왜냐하면 일반적으로 메모리 설계상 정수 타입보다 실수 타입이 더 크게 되어 있기 때문이다.
4바이트 float이 더 큰 수를 표현할수 있는 이유는 바로 부동소수점 방식으로 표현하기 때문이다.
부동 소수점 방식에서는 지수부와 가수부를 나누고, 가수부에는 실제 값을 지수부에는 2제곱을 얼마나 곱할지 표현하기 때문에 수의 표현 범위는 long 타입보다 더 커지게 되는 것이다.
int → float 로 형 변환하는 경우, 정밀도의 손실이 일어날 수 있다고 한다. 자세한 것은 위 인용의 참고 사이트 참고.
구분 | 연산자 명칭 | 연산자 |
---|---|---|
결과가 boolean인 경우 | 숫자 비교 연산자 | <, <=, >, >= |
숫자 동등 연산자 | ==, != | |
결과가 int나 long인 경우 | 기본 사칙 연산자 | +, -, *, /, % |
증감 연산자 | ++, -- | |
비트 연산자 | &, | |
기타 연산자 | 삼항 연산자 | ? : |
형 변환 연산자 | (타입) | |
문자열 더하기 연산자 | + |
자바에서 제공하는 모든 연산자를 사용할 수 있다.
소수형은 비트 연산이 불가능하다.
구분 | 연산자 |
---|---|
동등 연산자 | ==, != |
조건적 논리 연산자 | &&, |
논리 연산자 | !, &, |
삼항 연산자 | ? : |
문자열 더하기 연산자 | + |
참조 자료형은 + 연산만 가능하다.
연산자 | 설명 |
---|---|
+ | 해당 클래스에 있는 toString() 메소드의 결과와 그 연산자 뒤에 있는 문자열을 더한다. |
Me: =
Me: +, -, *, /, %
Me: 좌측 변수와 우측의 값을 더한 후 좌측 변수에 대입해준다.
Me: 소괄호 ()
Me: 두 값을 비교해서 ==는 같을 경우 true를, !=는 다를 경우 true를 반환한다.
Me: <는 작은지, <=는 작거나 같은지를 검사한다.
Me: boolean 타입
Me: 좌측 변수에 대입할 값을 말한다. 연산의 결과에 따라 ? 뒤는 true일 경우, :는 false일 경우 대입된다.
Me: 하지 않아도 괜찮지만, 명시적으로 지정해주고 싶다면 (long) 을 사용한다.
Me: (short)
Me: long값을 short에 할당했을 경우
💡 책에 있는 내용이 아닙니다.
책을 읽으며 설명이 더 필요하거나, 추가로 궁금한 점에 대해 질문 형식으로 작성 후, 답을 구해보고 있습니다.
참고한 사이트나 영상은 [출처]로 달아두었으며, 오류 지적은 언제나 환영합니다.
'a'는 아스키코드 97이므로, int 값 97에 ~ 연산자를 쓴 것과 동일한 결과가 나옴을 확인할 수 있다.
char는 아스키코드와 유니코드를 표현할 목적으로 사용되기 때문에, 음수는 표현하지 않는다. 그러므로 둘 사이에서도 자동 형 변환은 일어나지 않는다.
명시적 형 변환은 사용할 수 있으며, char → byte 는 char의 양수 범위가 byte 범위를 벗어나면 앞의 비트를 버리고 들어갈 것을 예상해볼 수 있다.
서로 자동 형 변환은 불가능하고, 강제로 형 변환해주면 가능하다.
예제와 함께 확인 (이미지가 많아서 토글로 감춤)위와 동일한 변수로 명시적 형 변환을 했을 경우엔 동작하는 걸 볼 수 있다.
short의 범위와 char의 범위가 일부 겹치기는 하나, 다른 부분도 존재하기 때문에 자동 형 변환은 지원하지 않는 것 같다.
char → short
1. char에 Char범위 MAX값을 설정한 후, short로 형 변환
2. char에 Short범위 MAX값을 설정한 후, short로 형 변환
3. char에 (Short범위 MAX + 1)값을 설정한 후, short로 형 변환
둘은 같은 16비트지만, char는 부호가 없고(unsigned) short는 부호가 있다. 따라서, 첫번째 결과는 Char의 최댓값을 넘어가므로 최소값으로 이동되어 최소값 부터 을 더 간, 을 출력한다.
두번째는 넘치지 않았으므로 값 그대로 출력되고, 세번째는 1이 넘쳤으므로 최소값이 출력된다.
short → char
short 에 음수를 넣고 char로 형 변환했다. 없는 문자라는 ‘?’가 출력되어서, int로 형 변환해서 값을 확인했다.
short 에 양수를 넣고 char로 형 변환하면, 숫자에 대응하는 char 값을 확인할 수 있다.