C++ 을 배우고 자바를 배우는 도중 자바에서의 연산은 기존에 알고 있던 C++ 의 연산과 많은 차이점이 발견되어 잊지 않기위해 게시물로 기록하려 한다.
1. 연산 도중 피연산자로 문자열을 만나면 그 뒤의 피연산자 또한 모두 문자열로 치환한다.
public class Main {
public static void main(String[] args) {
System.out.println("Your number: " + 7564); // Your number: 7564
System.out.println(1234 + "56" + 78); // 12345678
int a = 5; int b = 10;
System.out.println(a + b); // 15
System.out.println("result: " + a + b); // result: 510
System.out.println("result: " + (a + b)); // result: 15
}
}
눈으로 봐도 이해할 수 있기에 굳이 부가 설명은 하지 않겠다.
2. 정수 타입 연산의 경우 피연산자가 int형보다 작을 때, 피연산자는 int형으로 형변환 후 연산을 진행한다.
public class Main {
public static void main(String[] args) {
byte a = 1;
byte b = 2;
byte c = a+b; // 컴파일 에러
}
}
위 코드는 컴파일 에러를 일으킨다. 다른 언어를 배우고 자바를 처음 접하는 사람의 경우 위 코드를 보고 왜 에러를 일으키는지 의문을 품을 것이다. 이는 자바에서의 특이한(?) 연산 방법 때문인데
정수 타입의 피연산자가 int형보다 작을 경우 피연산자를 int 형으로 형변환 후 연산을 수행한다.
따라서 byte 자료형은 int 자료형보다 작기 때문에 int형으로 형 변환 후 연산을 수행한다. 결론적으로 보면 아래와 같은 연산을 수행하고 있는 것이다.
byte c = (int)a + (int)b;
a와 b, 둘다 int형으로 형 변환 후 연산을 수행 했기 때문에 결과값 또한 int형으로 반환 된다.
하지만 결과값 int(4 byte) 를 byte(1 byte) 라는 작은 그릇에 담으려 했기 때문에 에러가 발생하는 것이다.
public class Main {
public static void main(String[] args) {
byte a = 1;
byte b = 2;
byte c = (byte)(a+b);
}
}
위 코드처럼 결과값 int를 byte 자료형으로 형 변환 후 담게되면 그릇의 크기가 맞기 때문에 에러를 일으키지 않고 정상적으로 동작한다.
3. 문자열에서의 == 과 equlas()
equlas() 함수의 경우 문자열만을 비교하는 함수이다. 반면 문자열에서 == 연산자는 객체의 주소 값을 비교한다. 이해를 돕기 위해 아래 코드를 보도록 하자.
public class Main {
public static void main(String[] args) {
String A = "abcd";
String B = "abcd";
System.out.println(A == B); // true
System.out.println(A.equals(B)); // true
}
}
String 객체 A와 B는 서로 같은 문자열을 가지고 있다. 자바에서는 메모리 낭비를 줄이기 위해 같은 문자열의 경우 같은 곳을 참조하게끔 한다. 때문에 A와 B가 참조하고 있는 주소는 같다.
따라서 5, 6 번째 줄이 true 로 출력되는 것은 당연한 결과다.
public class Main {
public static void main(String[] args) {
String A = new String("abcd");
String B = "abcd";
System.out.println(A == B); // false
System.out.println(A.equals(B)); // true
}
}
이번에는 new 연산자를 통해 새로운 영역을 생성한 후 A에 담았다. new 연산자는 무조건 힙 영역에서 새로운 영역을 할당받는다. 때문에 A와 B가 참조하는 곳은 다르다. (사용자가 임의로 new 연산자를 통해 차별화 해두었기 때문에)
그럼 이제 코드를 살펴보자.
5번째 줄에 == 연산자를 통해 서로가 참조하는 곳을 비교했으나 A는 new 연산자를 통해 만들어진 새로운 영역을 참조하고 있기에 false 값을 반환한다.
반면 6번째 줄에 equlas() 함수는 영역이고 나발이고 단지 문자열 만을 비교하기 때문에 true 값을 반환한다.
위 결과를 통해 문자열끼리의 비교는 가급적 equlas() 함수를 쓰는 것이 바람직하다는 것을 알 수 있다.
'Java > 기본' 카테고리의 다른 글
자바에는 Call by reference 가 없다 ..? (0) | 2023.07.31 |
---|