Pre-Onboarding 5일차

최재하·2022년 11월 11일
0

기본타입

자바의 타입은 크게 기본타입, 참조타입으로 분류된다. 기본타입은 정수, 실수, 문자, 논리 리터럴을 저장하는 타입.

참조타입

참조타입은 배열, 열거, 클래스, 인터페이스가 있다. 기본타입은 실제 값을 변수 안에 저장하지만 참조 타입은 메모리의 번지를 변수 안에 저장한다 번지를 통해 객체를 참조해서 참조타입이라 부른다.

메모리 사용 영역

JVM이 시작되면 JVM은 할당받은 메모리 영역을 메소드, 힙, JVM스택으로 나누어서 사용한다.

  • 메소드영역

    JVM이 시작될때 생성되고 모든 스레드가 공유하는 영역
    코드에서 사용되는 클래스들을 클래스 로더로 읽어 클래스별로 정적필드, 상수, 메소드코드, 생성자 코드 등을 분류해서 저장한다.

  • 힙 영역

    힙 영역은 객체와 배열이 생성되는 영역이다.
    힙 영역에서 생성된 객체와 배열은 JVM 스택 영역의 변수나 다른 객체의 필드에서 참조한다. 메모리의 낮은 주소에서 높은 주소의 방향으로 할당된다.

  • JVM스택 영역

    메소드를 호출할 때마다 프레임을 추가하고 메소드가 종료되면 해당 프레임을 제거하는 역할을한다.
    프레임 내부에는 로컬 변수 스택이 있는데, 기본 타입 변수와 참조 타입 변수가 추가 되거나 제거된다. 변수는 선언된 블록 안에서만 스택이 존재하고 블록 밖에서는 제거된다.

참조변수의 ==, != 연산

기본타입 변수의 ==, !=연산은 변수의 값이 같은지를 비교 하지만 참조타입 변수의 ==, !=연산은 동일한 객체를 참조하는지 다른 객체를 참조하는지를 비교한다.
참조타입의 변수 값은 힙 영역의 객체 주소이므로 ==, !=연산은 번지 값을 비교하는 연산이다. 동일한 번지 값을 가지고 있는건 동일한 객체를 참조한다는 의미이다.

위 그림에서 refVar1과 refVar2는 서로 다른객체를 참조하고 있어서 ==, !=연산 결과는 다음과 같다.

refVar1 == refVar2  //결과 : false
refVar1 != refVar2  //결과 : true

refVar2와 refVar3는 동일한 객체를 참조하고 있으므로 ==, !=의 결과는 다음과 같다.

refVar2 == refVar3  //결과 : true
refVar2 != refVar3  //결과 : false

null

null값은 참조타입 변수가 힙 영역의 객체를 참조하지 않는다는 뜻이다. null값도 초기값으로 사용할 수 있다 null로 초기화된 참조변수는 스택 영역에 생성된다.
참조타입 변수가 null을 가지는지 확인 하려면 ==, !=연산을 수행하면 된다.

위 그림에서 refVar1은 힙 영역의 객체를 참조하므로 연산 결과는 다음과 같다.

refVar1 == null  //결과 : false
refVar1 != null  //결과 : true

refVar2는 null값을 가지므로 다음과 같다.

refVar2 == null  //결과 : true
refVar2 != null  //결과 : false

NullPointerException

참조변수가 null을 가지고 있을때 사용하면 발생하는 에러다.

int[] intArray = null;
intArray[0] = 10; //NullPointerException

위 코드처럼 null값을 가지고 있는 참조변수를 사용하려하면 NullPointerException오류가 발생한다. intArray가 참조하는 배열 객체가 없기 때문이다.
이 오류는 많이 발생하는 오류라고한다.

String 타입

String 변수이름 = "문자열";

이렇게 String변수를 선언하면 문자열은 String객체로 생성되고 변수는 String객체의 번지수를 통해 객체를 참조한다. 하지만 일반적으로 String변수에 저장한다고 표현한다.

String name1 = "항해99";
String name2 = "항해99";

문자열 리터럴이 동일하면 같은 String객체를 공유한다 위 코드처럼 name1, name2가 동일한 문자열인 "항해99"를 참조할 경우 name1, name2는 동일한 String객체를 참조한다.

String name1 = new String("항해99");
String name2 = new String("항해99");
boolean result = name1 == name2;
System.out.println(result); //false

변수에 문자열을 저장안하고 위 코드처럼 new연산자를 사용해서 직접 String객체를 생성시킬 수 있다. 이 경우 힙 영역에 새로운 객체를 만든거라 name1과 name2는 서로 다른 String객체를 참조한다. 서로 다른 객체를 참조하고 있기 때문에 name1, name2에 대한 ==연산의 결과는 false가 나온다.

  • equals
    String객체가 동일한지 다른지 신경안쓰고 내부 문자열을 비교할때는 equals() 메소드를 사용하면 된다.
    String name1 = "항해99";
     String name2 = new String("항해99");
     boolean result = name1.equals(name2);
     System.out.println(result); //true

0개의 댓글