크게크게 먼저 보면
==는 주소값을 비교하고
equals는 데이터 값을 비교한다.
따라서
String st1 = "love";
String st2 = "love";
st1==st2 -> true
st1.equals(st2) -> true
String st1 = "love";
String st2 = new String("love");
st1==st2 -> false
st1.equals(st2) -> true
왜 이런 결과가 나올까?
String st1 = "love";
String st2 = "love";
여기서 st1과 st2는 멤버 변수이기 때문에 method영역에 저장되고
각 데이터는 Runtime Constant Pool이라는 것을 가지게 된다. 이는 각 데이터의 Reference를 가지고 있어서 실제 물리적 메모리 위치를 참조할 때 사용하게 된다. 이후, 실행 중에 중복되는 정보가 필요할 때에 기존의 정보를 사용한다. 따라서 "love" 중복되는 정보가 존재하여 같은 물리적 위치를 가지게 된다.
하지만
String st2 = new String("love");
는 참조형(Reference Type) 데이터 타입을 갖는 객체(인스턴스)이기 때문에 heap에 저장된다. 따라서 String st1= "love"와 다른 주소를 가지고 있다. 그래서 주소값을 비교하는 == 연산에서는 데이터 값이 같음에도 주소값이 다르기 때문에 false의 결과가 나오는 것이다.
결론적으로 String의 값을 비교할 때는 == 연산이 아닌 equals라는 메소드를 이용하도록 하자.
import java.util.*;
class Main{
public static int solution(String[][] arr){
int answer=0;
for(int j=0;j<8;j+=2){
for(int i=0;i<8;i+=2){
if(arr[j][i].equals("F")) answer++;
}
}
for(int j=1;j<8;j+=2){
for(int i=1;i<8;i+=2){
if(arr[j][i].equals("F")) answer++;
}
}
return answer;
}
public static void main(String[] args){
Scanner kb = new Scanner(System.in);
String[][] arr = new String[8][8];
for(int i=0;i<8;i++){
String k = kb.next();
arr[i]=k.split("");
}
System.out.println(solution(arr));
}
}
두개의 블로그를 참고하여 작성하였다.
매우매우 자세하고 이해가 잘되게 그림이 많아서 좋다 감사합니다.
https://inpa.tistory.com/entry/JAVA-%E2%98%95-%EA%B7%B8%EB%A6%BC%EC%9C%BC%EB%A1%9C-%EB%B3%B4%EB%8A%94-%EC%9E%90%EB%B0%94-%EC%BD%94%EB%93%9C%EC%9D%98-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EC%98%81%EC%97%AD%EC%8A%A4%ED%83%9D-%ED%9E%99
https://re-build.tistory.com/2
그렇다면 heap? method영역? 에 대한 정리를 해보도록 하자.
Java 프로그램은 JVM(자바 가상 머신)을 이용해서 메모리를 관리하는데 OS로부터 메모리를 할당받아 관리한다.
프로그램이 실행되면 용도에 따라서 알맞는 메모리 영역에 저장한다.
과정을 살펴보면
1. 프로그램을 실행하면 개발자가 작성한 코드 .java가 컴파일러(javac.exe)에 의해서 JVM이 읽을 수 있는 .class 파일로 변환
2. 기계가 읽을 수 있는 Byte Code인 .class 파일은 JVM 내부에 있는 Class Loader가 읽어들여 Runtime Data Area에 저장한다.
3. Runtime Data Area에 저장된 코드들은 Excution Engine이 하나의 명령어 단위로 읽어들여 프로그램을 실행
4. 사용이 끝난 코드은 Garage Collector가 모아서 메모리 해제
✔ Runtime Data Area(JVM의 메모리 영역)을 자세히 살펴보자
Stack 영역
메소드 내에서 정의하는 기본 자료형인 지역변수의 데이터 값이 저장되는 공간
메소드가 호출될 때 스택 영여에 스텍 프레임이 생기고 그 안에 메소드를 호출
메소드가 종료되면 메모리에서 사라짐
Heap 영역
JVM이 관리하는 프로그램 상엣 데이터를 저장하귀 위해 런타임 시 동적으로 할당하여 사용하는 영역
참조형 데이터 타입을 갖는 객체, 배열 등이 저장되는 공간
단, Heap영역에 있는 오브젝트들을 가리키는 레퍼런스 변수는 Stack에 적재
Heap영역은 Stack 영역과 다르게 보관되는 메모리가 호출이 끝나더라도 삭제되지 않고 유지
그러다 어떤 참조 변수도 Heap 영역에 있는 인스턴스를 참조하지 않게 된다면 가비지 컬렉터에 의해 메모리가 해제된다.
stack은 쓰레드 개수마다 heap은 단 하나