posted by 박영창 2009/01/25 05:18
1. 개요
2. 연산자 우선순위

C++에서는 operator overloading 이라는 강력한 기능을 이용하여 언어에서 정의된 각 연산자들의 의미를 다른 식으로 가져갈 수 있게 해 주죠. 하지만 이 기능은 복잡할 뿐만 아니라 각 연산자들에게는 고유한 자신의 기능이 정해져 있는데, 이것을 엉뚱한 기능으로 대체해 사용할 가능성도 있고 해서 실제로 많은 C++ 프로그래머가 이 기능을 사용하는 경우는 많지 않은 편입니다. 그래서 자바에서는 operator overloading 기능을 아예 제거해 버렸답니다.

3. unary 연산자
unary 연산자란 operand가 하나만 있는 연산자들 입니다. unary 연산자는 우선 순위에 있어서 가장 높은 순위를 갖고 있습니다. 지금부터 총 7개의 unary 연산자에 대해 알아 보겠습니다.

1) ++(increment) 연산자, -- (decrement) 연산자
 변수의 값을 하나 증가, 또는 하나 감소 시켜 놓는 연산자 (operator)입니다.
 
       int   sum = 0;

     sum++;
     ++sum;
 
  위와 같이 변수에 ++ 나 -- 연산을 하게 하는 문장 단독으로 쓰일 때는 ++ 나 -- 연산자가 변수의 앞이나 뒤에 와도 별 차이가 없지만, 어떤 문장의 일부로 사용될 때는 ++ 나 -- 연산자가 변수의 어디에 위치하느냐에 따라 문장에 대한 해석이 다르게 나타날 수도 있습니다.
 
int   i = 2;       
int   r = i++;    // 라인 1.
 
  라인 1이 수행된 시점에서 문장의 결과는 변수 r 에는 2가 저장되고, 변수 i 에는 3이 저장됩니다. 즉, 변수 i의 값을 변수 r에 대입시킨 후 변수 i의 값을 1 증가시킨 것입니다.
 그러나 다음과 같은 경우에는
 
int   i = 2;       
int   r = ++i;    // 라인 1.
 
  라인 1이 수행된 시점에서 문장의 결과는 변수 r 에는 3이 저장되고, 변수 i 에도 3이 저장됩니다. 즉, 변수 i의 값을 먼저 1 증가시켜 변화한 후 이것을 변수 r에 대입 시킨 것입니다. 이러한 규칙은 -- 연산자에도 동일하게 적용됩니다.
 
 boolean, char, byte, short, int, long, float, double 등의 Primitive Data Type 중 ++, -- 연산자를 적용할 수 없는 변수 type은 boolean type입니다.
 
2) unary +, - 연산자
unary +, - 연산자(operator)는 operand의 부호를 바꿔 놓는 연산자입니다.
 
int   i = +3;        // 라인 1.
i = -(i + 10);      // 라인 2.
   라인 1의 경우는 unary + 를 사용하지 않아도 됩니다. 라인 2번은 - 는 unary -로 (i + 10)의 결과에 -1을 곱한 것과 동일한 의미입니다.
 
  boolean, char, byte, short, int, long, float, double등의 Primitive Data Type 중 unary +, - 연산자를 적용할 수 없는 변수 type은 boolean과 char type입니다.
 
3) ~ (unary bitwise inversion) 연산자
~는 자신이 갖고 있는 bit value를 1은 0으로, 0은 1로 변경시키는 연산자(operator) 입니다.
 
byte i = 0x0a;        // 라인 1.       00001010
i = ~ i;              // 라인 2.       11110101
   위의 comment 부분에 표시된 1 byte 8개 bit의 각 값을 살펴보면 ~ 연산자에 의해 어떤 변화가 일어나는지 알 수 있을 것입니다. 한가지 주의할 점은 ~ 연산 전에는 양수였던 것이 ~ 연산 후에 맨 좌측 bit가 1이 되어버려 결국 음수로 될 수도 있다는 점입니다. 

  boolean, char, byte, short, int, long, float, double 등의 Primitive Data Type 중 int와 long type에 대해서만 ~ 연산자를 취할 수 있습니다. 그리고 int type보다 작은 type은 int type으로 자동 Conversion되어 ~ 연산식을 진행합니다.
 
4) ! (unary boolean complement) 연산자
 ~ 연산자와 달리 ! 연산자는 boolean type에만 적용 시킬 수 있는 것으로, true를 false로 또는 false를 true로 변경시켜 줍니다. 따라서 boolean type 변수의 값을 toggle 시키는데 편리하게 사용될 수 있습니다.
 
boolean  flag = false;
flag = ! flag;    // flag에는 true가 저장됩니다.
 
  또한 ! 연산자는 비교 결과가 true와 false로 나타나는 조건문에도 사용됩니다.
 
boolean  b1 = false;
if (!b1)
   System.out.println("FALSE");
else
   System.out.println("TRUE");
 5) cast 연산자 : (data type)
 cast 연산자는 operand의 type을 명확하게 바꿔 놓고 싶을 때 사용하는 연산자입니다.
 
float   f = 0.1f;
int      i = (int) f;
 
  위와 같이 특정 type의 변수 값을 다른 type의 변수 값으로 전환(Conversion)하고 때  () 안에 변환하고 싶은 type을 넣어서 변환하고자 하는 변수(operand) 앞에 코딩합니다.
 
   자바에서 operand 사이의 Type Conversion(형 전환)은 몇가지 규칙에 의해 자세한 규칙은 다음 장인 4장에서 설명하겠습니다.
 
4. binary arithmetic 연산자
1) * (multiplication)과 / (division) 연산자
 모든 숫자 type들과 char type에 적용될 수 있는 연산자입니다. 여기서 반드시 주의할 것은 * 연산에 있어서는 overflow가 일어날 수 있다는 것입니다. 다음의 예문을 보면서 * 연산자를 사용할 때 발생될 수 있는 overflow에 대해 알아보겠습니다.
 
byte    b1 = 64;
byte    b2 = 4;
byte    b3 = b1 * b2;
 
  일단 이와 같은 코드는 컴파일시 error가 발생합니다. 왜냐구요? 바로  int type 보다 크기가 작은 숫자 type들은 연산식을 처리 할 때 int로 Type Conversion을 하고 연산식을 처리한다.
 
int type 보다 크기가 작은 숫자 type들은 연산식을 처리 할 때 int로
Type Conversion을 하고 연산식을 처리한다.
 
  는 규칙 때문입니다.
 
  따라서 byte b3 = b1 * b2; 문장은 b1 * b2의 결과가 int type으로 결과가 나오는데, 이것을 byte type인 b3에 대입하려 하니 자바의 Type Conversion 규칙에 따라할 수 없다는 error 가 나오게 되는 것입니다.
 
byte    b1 = 64;
byte    b2 = 4;
byte    b3 = (byte) (b1 * b2);
   위와 같이 (b1 * b2) 연산의 결과를 byte type으로 전환하면 일단 컴파일 error는 없을 겁니다. 그런데 실제 연산의 결과가 256(64 * 4) 인데 반해 이를 대입하려는 b3는 -128부터 127 까지의 값만을 가질 수 있는 byte type이므로 자신의 범위를 넘어선 값을 받아들여야만 하게 되버립니다. 그래서 b3에는 엉뚱하게도 0 이라는 값이 할당되어 버리죠. 왜 하필 0 이 들어 갔을까요? 그 이유는 256을 4 byte인 int로 나타냈을 때 맨 아래의 byte에 들어 있는 값이 0이고, 바로 이 값이 b3에 할당 되었기 때문입니다.
 
  이번에는 /(Division) 연산자(operator)를 사용하는 예를 한번 살펴볼까요?
 
int      i = 11;
float    f = i / 4;
   float type 변수 f 에는 어떤 값이 대입될까요? 우리가 예상한 답은 2.75 입니다만...  실제 f에 대입된 값은 2.0입니다.
왜냐하면 (int type) / (int type) 의 결과는 int type으로 나오기 때문입니다. 따라서 우리가 원하는 결과를 얻기 위해서는
 
  float f = i / (float) 4;
 
  와 같이 해주어야 할 것입니다.
 
  만약 / 연산자를 사용함에 있어 0 으로 나누기를 하는 연산이 있다면 자바는 ArithmeticException 이라는 예외를 발생시킬 것입니다.

2) % (modulo) 연산자
이 연산자는 나누기를 취하고 남은 나머지를 얻기 위해 사용되는 연산자(operator)입니다.
 
  boolean, char, byte, short, int, long, float, double 등의 Data Type 중 % 연산자를 적용할 수 없는 변수 type은
boolean type입니다.  int type보다 작은 type은 int type으로 자동 Conversion 되어 % 연산식을 진행합니다.
 
3) + (addision) 과 - (substraction) 연산자
이 두 연산자(operator)는 Primitive Data Type 중 boolean type을 제외한 숫자 type과 char type operand에 사용할 수 있습니다.
 
  + 와 - 연산자를 이용한 연산의 결과 역시 overflow, underflow에 의해 원하는 값을 얻지 못할 수도 있습니다.
 
int   i = 2147483647;   // int type이 가질 수 있는 양의 최대값
int   j = 1;long  l = i + j;   // 라인 1.
 
  위와 같은 경우 라인 1의 i + j 에 대한 계산 결과가 int로 나오면서 이미 overflow가 발생해 버리는 것입니다. 그러므로 계산 결과를 long type으로 받는다 해도 결과는 -2147483648로 되는 것이지요.
 
  특히 자바의 + 연산자는 operand로 String Object를 사용할 수 있습니다. 즉, 이미 자바 언어 내부에서 String class type에 대해서는 operator overload가 되어 있다고 볼 수 있는 것입니다. 따라서 다음과 같은 경우
 
String   msg1 = "Welcome-";
String   msg2 = "SCJP";
msg1 = msg1 + msg2;
   msg1에 "Welcome-SCJP" 라는 결과가 대입될 것입니다.
 
  하지만 자바가 사용자에 의한 operator overload를 지원하지 않으니 String class type이 아닌 다른 Reference Data Type에 대해서는 + 연산자를 사용할 수 없습니다. 즉,
 
Date  d1 = new Date();
Date  d2 = new Date();
d1 = d1 + d2;
   위와 같은 프로그램은 만들 수 없는 것입니다.
 
  그렇다면 + 연산자를 사용하는 연산식에서 한 operand는 String object이고  operand는 String object가 아니라면 과연 어떤 결과가 나올까요? 예문을 통해 살펴보기로 하지요.

String     stoday = "today is";
int           iday    =  29;
stoday = stoday + iday;
 이 코드 결과 stoday에는 "today is 29" 라는 문자열이 대입됩니다. 즉, int type의 값이 String class type으로 자동 전환되어 결과적으로 두 개의 Stiring object에 + 연산이 이루어진 것입니다.
 
String     stoday = "today is";
Date       rdate   =  new Date();
stoday = stoday + rdate;
 위의 코드도 Date object가 String object로 전환되어 + 연산이 이루어지게 됩니다.
 
   + 연산자는, 만약 한 operand만 String 이고 나머지가 String이 아닌 모든 경우(Primitive Data Type이거나 Reference Data Type), String이 아닌 다른 쪽이 무조건 String으로 conversion 됩니다.
 
만약 두개의 String object에 + 연산자가 아닌 -, *, / 와 같은 연산자를 사용하면 어떤 결과가 나올까요?
 
5. binary bitwise shift 연산자
1) << 연산자
 << 연산자는 지정된 숫자만큼 변수의 bit 단위 값을 좌측으로 자리 이동시키는 연산자입니다. 무슨 얘기인지 잘 이해되지 않지요? 다음의 예를 보면 쉽게 이해가 될 것입니다.
 
int  i = 0x00000010      // 라인 1.
i = i << 1               // 라인 2.  
   라인 1은 변수 i에 16의 hexa(16진수) 값인 0x00000010을 대입시킨 것입니다. 일단 이것을 4byte bit pattern으로 나타내 볼까요?
 
  00000000 00000000 00000000 00010000 (십진수로 16)
 자, 라인 2는 이와같은 bit pattern의 값을 좌측으로 1만큼 이동시키라고 한 연산이니까 이대로 해보면 바로 다음과 같이 될 것입니다.
 
  00000000 00000000 00000000 00100000 (십진수로 32)
   (자바의 shift 연산자에 의한 bit의 이동은, C와 마찬가지로, bit가 rotate 되는 아니라, 맨 끝의 shift된 bit가 없어지게 됩니다.)
 
  한 칸 좌측으로의 이동이 잘 안보일 수도 있으니 두 개를 합쳐 놓아보겠습니다.
 
00000000 00000000 00000000 00010000
00000000 00000000 00000000 00100000
   결국 << 연산자는 연산이 가해지는 변수(이 경우 i)에, 2에 이동하는 이 경우 1)만큼의 지수승을 곱하는 결과를 만들어 냅니다. 즉
 
  i << N 는i * (2의 N승) 과 같은 뜻입니다.
   << 연산자는 2의 지수승에 대한 빠른 계산 결과를 갖기 원할 때 사용되기도 합니다.

2) >> 연산자
>> 연산자는 지정된 숫자만큼 변수의 bit 단위 값을 우측으로 자리 이동시키는 하지만 이 때 shift시키려고 하는 숫자가 음수일 경우에는 난 후 무조건 맨 왼쪽 bit가 0으로 채워지는 것이 아니라 자신의 bit로 채워집니다. shift 시키고 난 후에도 음수 값이 유지되어야 하기 때문이죠.
 
  자바에서 정수 계열 숫자를 표현하는 방법으로 2의 보수(2's complement)를 이용합니다.
 
  2의 보수에 대해서 예를 들어 설명하겠습니다. 1바이트(8비트)를 사용할 수 있는 byte형에 -1이라는 숫자는 어떻게 저장되는지 다음 순서대로 따라가 봅시다.
 
   우선, 사용 가능한 자릿수(8비트)에서 표현 가능한 최대 숫자에 1을 더한 숫자를 만듭니다. 8비트에서 표현 가능한 최대 숫자는 11111111이고, 여기에 1을 더하는 것이니까 100000000이 되겠네요.
 
 표현하고자 하는 음수(우리의 예에서는 -1)에 대한 절대값을 구합니다.  물론 -1에 대한 절대값은 1이고, 이를 8비트 자릿수에 맞게 예쁘게 써보면 00000001이 되겠군요.
 
 1에서 만든 값에서 2에서 만든 값을 뺍니다.
  100000000 - 00000001이므로 2의 보수에 의한 -1은 11111111로 표현되는군요.
 
   같은 요령으로 계산해 보면 -192 는 bit pattern 이 아래와 같습니다.
 
  1111 1111 1111 1111 1111 1111 0100 0000 (십진수로 -192)
 -192 >> 2 와 같은 연산을 하면,
 
1111 1111 1111 1111 1111 1111 1101 0000 (십진수로 -48) 
  위와 같이 shift가 일어날 때마다 맨 왼쪽이 0 이 아닌 1로 채워지게 됩니다. shift하려는 숫자가 음수이기 때문이죠. 하지만 양수였다면 sign bit가 0일 것이고, 따라서 shift가 일어날 때마다 빈 곳은 0으로 채워질 것입니다.
 
  결국 >> 연산자는 연산이 가해지는 변수를 2에 이동하는 숫자만큼의 지수승을 나누기 한 결과를 만들어 냅니다.
즉 i >> N는 i / (2의 N승) 과 같은 뜻입니다.
 
int   i = 192;
      i = i >> 1;          // 192 / 2 = 96
int   i = 192;
      i = i >> 2;          // 192 / (2 * 2) = 48
int   i = -192;
      i = i >> 2;          // -192 / (2 * 2) = -48
  그러므로 >> 연산자는 2의 지수승 나누기에 대한 빠른 계산 결과를 갖기 원할 때 사용되기도 합니다.

3) >>> 연산자
   >>> 연산자는 >> 와 달리 shift시키려고 하는 숫자가 음수이건 양수이건 shift시키고 난 후 무조건 맨 왼쪽 bit가 0으로 채워지는 연산자 입니다.
 
  그러므로 음수이건 양수이건 shift 후 양수가 됩니다. 가장 왼쪽의 sign bit가 0 이 되기 때문입니다. 즉 unsigned type 형식으로 shift시키는 연산자입니다. 자바는 unsigned 숫자 type이 없기 때문에 c에는 없는 >>> 연산자를 제공하여 signed type에 unsigned 효과를 주고 있는 것입니다.
 
  int i = -192;
    i >>> 2;
 - 192 의 bit pattern은 다음과 같습니다.
 
  1111 1111 1111 1111 1111 1111 0100 0000 (십진수로 -192)
   i >>> 2 연산식을 처리한 후에는 아래와 같이 되는 것이죠.
 
  0011 1111 1111 1111 1111 1111 1101 0000 (십진수로 1073741776)
   sign bit 부분이 0 로 채워지니까 shift 결과는 상당히 큰 양수가 되죠.

4) binary bitwise shift 연산자에서 알아둬야 할 사항
shift연산식을 처리하면서 몇가지 재미있는 사항을 알아보겠습니다.
 
  첫째로 shift연산자는 byte, short, int, long 같은 primitive 숫자 type과 char type에 적용해서 쓸 수 있는데, 이때 int보다 작은 type들은 일단 int로 conversion된 후 결국은 int를 shift하게 되어 있다는 점입니다. 그래서 byte 같이 int 보다 작은 type들은 >>> 연산식 이후에 무조건 양수가 되지 않고 음수가 되는 경우도 있습니다.
 
  byte b = -1;b = b >>> 2 ;
 이 코드는 error입니다. 왜냐하면 b >>> 2 의 결과는 int로 나오기 때문입니다. int type을 byte type에 assign하면 자바의 conversion rule에 의해 error가 발생합니다. 그러므로 error를 없애려면 아래와 같이 cast 연산자를 붙입니다.
 
b = (byte) ( b >>> 2 );
 자 그럼 다시 따져 볼까요?
 
먼저 b가 int 로 conversion되면서 int로 -1 이 됩니다.
 
1111 1111 1111 1111 1111 1111 1111 1111 (십진수로 -1(32 bit)
   그리고 이 int -1의 값이 2자리 shift되며 그때마다 맨 좌측 bit는 매번 0으로 채우겠지요? 다음은 이동 후 결과입니다.
 
0011 1111 1111 1111 1111 1111 1111 1111
  마지막으로 byte로 다시 assign하기 위해 int로 나온 결과를 byte type으로 conversion 하는데, 이때 32bit 중 아래 8bit 즉, low byte가 assign되므로, 결국 b는 다시 -1이 됩니다.
 
  shift연산식을 처리하면서 재미있는 또 한가지 사항!  int type의 숫자에 35 자리 만큼 이동하라고 한다면 어떻게 될까요? shift 연산식은 이동할 자리수, 즉 오른쪽 operand를 항상 int일 경우는 % 32, 경우는 % 64 로 modulo 연산식을 처리한 나머지를 갖고 shift를 취하게 그러므로 35 만큼 이동하라는 연산식은 실제로는 3자리만 이동하는 모양이 됩니다. 예제를 살펴 볼까요?
 
  int   i = -1;i = i >>> 32;
  이 경우 만약 0 이 나오기를 기대했다면 잘못입니다.  이동하는 대신 32 % 32 한 결과, 즉 0 만큼 이동하므로 실제 이 연산식은 자리이동도 일어나지 않게 되는 것이지요.
따라서 결과는 그대로 -1 입니다.

6. binary comparision 연산자
1) <, <=, >, >= 연산자
 C 언어에서 사용하였던 것처럼 두 개의 operand에 대한 대/소의 비교 또는 대/소와 같음을 함께 비교할 때 사용되는 연산자 입니다.
 
  이 연산자는 operand로 byte, short, int, long, char, float, double을 취할 수 있으며, 이들 중 서로 다른 type의 operand 사이는 Type Conversion 규칙에 의해 결과가 조절됩니다.
 
  그러나 boolean type이나 다른 Reference Data Type의 operand에는 이들 연산자를 사용할 수 없습니다

2) instanceof 연산자

이 연산자는 Reference Data Type에만 적용해서 쓸 수 있는 연산자로 그 object의 run-time type을 알아낼 수 있게 해 줍니다.

 

  어떻게 사용되는지 한번 볼까요?

 

String   str1 = new String("hello");

if (str1 instanceof String) {  // 라인 1.

   // ...

}

  라인 1을 살펴보면 instanceof 연산자 왼쪽 operand String class type으로 변수명 str1 이 오고 오른쪽 operand로는 class name String이 옴을 볼 수 있습니다.

 

  이와 같은 연산문의 결과는 왼쪽 operand가 오른쪽 operand로 놓여진 Reference Data Type이면 true이고 그렇지 않은 경우 false가 되는 것입니다. 위의 경우라면 true가 만들어지겠죠?

 

  instanceof연산자는 자바에서 object에 다양하게 사용되는 연산자입니다. 자세한 사용법은 "8장 자바의 class object" 에서 다루어집니다.


3) ==, != 연산자

== 연산자는 왼쪽과 오른쪽에 있는 operand의 값이 같은지 (Equal)를 비교할 때 사용하는 연산자이며, 반대로 같지 않음(Not Equal)을 비교할 때 사용하는 것은 연산자입니다.

 

  이 두 연산자는 자바의 모든 Data Type에 적용하여 사용할 수 있습니다. 물론 이 연산자들은 모든 type의 연산식에 적용하여 사용할 수 있지만, operand로 Reference Data Type Primitive Data Type을 섞어서 사용할 수는 없습니다. 참고적으로 연산자 중 유일하게 Reference Data Type Primitive Data Type이 섞여서 사용 가능한 연산자는 + 연산자 뿐입니다. + 연산식도 한쪽 operand가 반드시 String class type 이어야만 하겠죠.)

 

  이 연산자를 Reference Data Type operand에 적용할 때는, 실제 object가 가지고 있는 내용이 비교되는 것이 아니라는 점을 유념하여야만 합니다.

 이와 관련된 예를 하나 살펴볼까요?

 

String   str1 = new String("hello");

String   str2 = new String("hello");

if (str1 == str2)   System.out.println("equal");

else    System.out.println("not equal");

 위 코드의 결과는 not equal 이 출력되는 것입니다. 이유는 둘은 각각 다른 메모리에 생성된 object를 가지고 hello라는 값을 갖는 것으로, str1 str2는 이렇게 생성된 각각의 object를 가리키는 서로 다른 주소값을 가지고 있기 때문입니다.

 

그렇다면 다음의 경우는 어떨까요?

 

String   str1 = new String("hello");

String   str2 = str1; // 라인 1.

if (str1 == str2)   System.out.println( "equal" );

else    System.out.println( "not equal");

 위 코드는 equal을 출력할 것입니다. 라인 1에서 str2 str1이 대입되면서 결국 같은 주소 값을 갖게 될테니까요.


  혹시 이런 궁금증이 생기지 않나요? 그렇다면 object의 값은 어떻게 비교하는지... 바로 자바의 모든 object들이 갖는 equals() 라는 메소드를 이용하여 object간의 값을 비교할 수 있습니다.

 

  만약 어떤 String object str1 str2의 값을 비교하고 싶다면 다음의 코드를 참조하십시오.

 

if (str1.equals(str2))   System.out.println("equal");

else    System.out.println("not equal");

7. 그외의 연산자들
1) binary bitwise 연산자

binary bitwise 연산자(operator) & | ^ bitwise 연산자 우선순위가가장 낮은 연산자들입니다.

 

연산자들은 byte, short, int, long, char type 아니라 boolean type 에도 적용할 있습니다. (float double type에는 사용할 없습니다.) boolean type 경우는 1 bit 생각하여, true 때는 1 false 일때는 0의 값으로 취급하면 됩니다.

 

boolean   b1 = true;

boolean   b2 = false;

if (b1 | b2) System.out.println("TRUE");

else System.out.println("FALSE");

 위와 같이 if 문의 조건문에서 논리합이나 논리곱을 만들어 다음에 배울 && || 연산자를 주로 사용 하지만 bitwise 연산자 | & 사용할 수도 있습니다.

하지만 다음에 배울 && || 달리 short curcuit으로 사용되어지지는 않습니다.

 

  , 그럼 연산자를 하나씩 살펴볼까요?

 

& (binary bitwise and) 연산자

AND 연산식을 처리하는 연산자입니다.

, 1 and 1 때만 1 이고 나머지 조합은 0입니다.

 

| (binary bitwise or) 연산자

OR 연산식을 처리하는 연산자입니다.

, 0 or 0 때만 0 이고 나머지 조합은 1입니다.

 

^ (binary bitwise xor) 연산자

XOR 연산식을 처리하는 연산자입니다.

, 1 xor 0, 0 xor 1 때만 1 이고 0 xor 0, 1 xor 1 0 입니다

 

 

이들 연산자는 bit 단위의 정보를 유지하는 경우 특정 bit들을 set시키거나 clear, 또는 mask 씌워 무슨 값을 갖고 있는지 알아내려고 주로 사용합니다. 예를 들어, Font 정보를 유지하는 int 크기의 value 있다고 가정할 때 첫번째 bit 1이면 BOLD, 0 이면 일반 PLAIN으로 보여줄 것인지 아닌지의 정보를 유지 하려고 했다면 적절히 bit 1 만들거나 또는 0 으로 변경시켜야 하는 상황이 있을 것입니다. , 1 만들고자 했다면 1 or(|) 연산식을, 0으로 하려면 0으로 and(&) 연산식을, 현재 bit 값을 보려고 했다면 1 exclusive or(^) 취하면 됩니다.

 

 서로 다른 type 사이에 연산자들의 연산식을 취하면 자바의 promotion conversion rule 의해 보다 넓은 type으로의 Type Conversion 이루어져, 결과는 보다 넓은 type으로 나오게 됩니다. 자세한 Type Conversion rule 다음 장에서 다루게 됩니다.


2) binary short circuit logical 연산자

binary short circuit logical 연산자(operator) || && 논리 연산자입니다. 그러므로 true false값을 갖는 boolean type에만 적용하여 사용할 있습니다.

 

&& 연산자는 AND 조건을 의미하는 logical 연산자로서, 이미 알고 있는 것과 같이 양쪽의 operand true 때만 true 값이 얻어지며, || 연산자는 OR조건으로 양쪽 최소 하나만 true 이면 true 값이 얻어집니다.

 

&& || 양쪽 operand evaluation 하지 않고도 연산의 결과를 결정할 있습니다. ,

 

String    str1 = null;

int   i = 0;

if (( i != 0 ) && (str1.length() > 5)) {

   //...

}

  같은 비교문에 있어, 처리 순서에 의해 먼저 && 연산자의 왼쪽을 evaluation 보면 벌써 false 결정되어 이상의 연산 없이 false 값이 결정되어지는 것입니다. 따라서 && 연산자는 먼저 evalution 쪽의 결과가 true 경우에만 다른 쪽도 evaluation 것입니다.

 

물론 || 연산자도 마찬 가지 경우로 처리됩니다. , 쪽의 evaluation 결과가 true이면 다른 쪽의 결과에 관계없이 true 결과를 결정할 테니까요.

 

참고적으로 만약 위와 같은 코드에서 왼쪽이 true 나왔다면 코드는 실행시 NullPointerException 이라는 exception 나올 것입니다. 왜냐하면 str1 null 값을 갖고 있는 생성되지 않은 object인데 length()라는 메소드를 사용하도록 되어 있으니까요.


3) ternary 연산자

ternary 연산자(operator) ? : 자바의 유일한 3 항식 연산자 입니다. operand 3 필요한 연산자란 뜻이지요. 연산자는 if else 문장 대용으로 사용할 있습니다.


다음 예를 보며 사용법을 알아보도록 하죠.

 

if (x > y)      max = x;

else   max = y;

 이런 logic 갖는 문장을 다음과 같이 문장으로 간단히 표현할 있습니다.

max = (x > y) ? x : y;

위의 코드에서 있듯이

 

? 연산자 앞쪽 operand boolean type 와야만 하고 값이 true ? 연산자 뒤의 것이 결과로 결정되며 값이 false : 연산자 뒤의 것으로 결과가 결정됩니다.


4) assignment 연산자

오른쪽에 있는 값을 왼쪽에 대입해 주는 연산자로 = 연산자 외에 op= 형태의 assignment 연산자(operator) 있습니다.

 

= 연산자는 오른쪽에서 왼쪽으로 진행되는 연산자입니다.

따라서

 

  x = y = z = 3;

  같은 문장의 경우, 일단 z 3 할당되고 z 값이 y 그리고 다시 y값이 x 할당됩니다.

 

 op= 연산자의 op 있는 연산자는 boolean 값을 만들어 주는 연산자를 제외한 나머지가 있습니다.

 

 op 부분에 있는 연산자를 통한 예를 살펴 보겠습니다.

 

i += 10;       // i = i+10;

i -= 10;        // i = i - 10;

i *= 10;        // i = i * 10;

i /= 10;         // i = i / 10;

i %= 3;            // i = i % 3;

i <<= 2;        // i = i << 2;

i >>= 2;        // i = i >> 2;

i >>>= 2;       // i = i >>> 2;

i &= 16;        // i = i & 16;

i ^= 16;        // i = i ^ 16;

i |= 16;        // i = i | 16;

i <== 16;       // error!!  >, <, == 같은 boolean type으로

             // 결과가 나오는 경우는 op 없습니다.


크리에이티브 커먼즈 라이선스
Creative Commons License