1. 기본 타입과 참조 타입의 차이점
자바의 타입은 크게 기본 타입과 참조 타입으로 분류된다. 참조 타입이란 객체의 번지를 참조하는 타입으로 배열, 열거, 클래스, 인터페이스를 뜻한다.
기본 타입은 실제 값을 저장하는 반면에 참조 타입은 메모리의 번지를 변수 안에 저장한다. 번지를 통해 객체를 참조한다는 뜻에서 참조 타입이라고 한다.
*예시
int age 25;
double price = 100.5
String str = "자바"
String str2 = "파이썬"
위 코드를 입력했을 때 스택 영역에는 각각
str = 100
str2 = 200
age = 25
price = 100.5
으로 저장된다.
저장된 예시를 보면 기본 타입은 입력된 값 자체를 저장한 반면에 str, str2는 번지가 저장되어 있는 것을 볼 수 있다.
힙 영역을 보자면
100번지에 String 객체로 이루어진 "자바"가 들어있는 것이고
200번지에는 String 객체로 이루어진 "파이썬"이 들어있는 것이다.
2. 메모리 사용 영역
JVM은 운영체제에서 할당받은 메모리 영역을 세 영역으로 구분해서 사용한다.
메소드 영역은 JVM이 시작할 때 생성되고 모든 스레드가 공유하는 영역이다. 메소드 영역에서는 클래스들을 클래스 로더로 읽어 클래스별로 정적 필드와 상수, 메소드 코드, 생성자 코드 등을 분류해서 저장한다.
나는 메소드 이론이 잘 이해되지 않아서 활용한 사례를 찾아보고 어떤 식으로 사용할 수 있는지 찾아보았다. 내가 찾아본 바로는 하나의 기능을 따로 만들어두고 필요할 때 객체로 만들어 사용하기 때문에 재사용성이 매우 뛰어난 것 같았다.
찾아본 예시로 직접 코드도 작성해 보았는데 사용자가 입력한 값을 입력받아 곱셈을 해주는 코드를 작성했다.
class Calculation { // 곱셈을 해주는 계산 메서드
int multiply(int x, int y){
return x * y;
}
}
public class test2 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in); // 곱할 수를 입력받기 위한 스캐너
Calculation calculation = new Calculation();
System.out.println("구구단 단 수를 입력하세요: ");
int i = scanner.nextInt();
System.out.println("곱할 수를 입력하세요: ");
int k = scanner.nextInt();
int multiply = calculation.multiply(i,k); // 사용자가 입력한 두 수를 메서드 변수에 대입
System.out.println(multiply); // 계산 결과 출력
}
}
위 코드처럼 만들어진 메서드를 불러와서 파라미터값에 값을 대입해주니 return에 적힌 연산식 대로 연산해 값이 들어왔다. 단순 곱셈이라 매번 연산식을 적는 것과 효율 차이는 느끼지 못했지만 불러올 메서드가 복잡할수록 코드의 효율이 올라갈 것 같다.
힙 영역은 객체와 같이 배열이 생성되는 영역이다. 생성된 객체와 배열은 JVM 스택 영역의 변수나 다른 객체의 필드에서 참조한다.
JVM 스택은 메소드를 호출할 때 마다 프레임을 추가하고 메소드가 종료되면 해당 프레임을 제거한다. 프레임 내부에는 로컬 변수 스택이 있는데 기본타입 변수와 참조 타입 변수가 추가되거나 제거된다. 스택 영역에 변수가 생성되는 시점은 초기화가 될 때, 즉 변수에 값이 저장될 때이다. 특정 블록에 선언된 변수는 블록을 벗어나는 순간 스택에서 제거된다.
이번에 공부한 것은 앞서 공부한 것 보다 더욱 이론적인 부분이 강조된듯 하다. 나는 눈으로 보이는게 익히기 쉬운데 보이지 않는 곳에서 발생하는 것들이다 보니 이해하기 어려움이 있었다. 그래도 절반 이상은 이해하고 가는 것 같긴 하다. 특히 스택 영역과 힙 영역은 서로 연계성이 깊은 것 같다는 생각이 들었다.
기본 타입 변수의 ==, != 연산은 값이 같은이 아닌지의 여부를 판단하지만 참조 타입 변수들 간의 ==. != 연산은 동일한 객체를 참조하는지 아닌지를 판단할 때 사용된다. 즉 힙 영역의 객체 주소가 같은지를 판단한다.
null과 NullPointerException
null
참조 타입 변수는 참조하지 않는다는 뜻으로 null 값을 가질 수 있다.
nullPointerException
자바에서 프로그램 실행 도중에 발생하는 오류를 예외라고 부르는데 참조 변수를 사용하면서 가장 많이 발생하는 것 중 하나로 NullPointerException이 있다.
참조 타입으로 선언된 변수가 참조하고 있는 것이 없을 때 그 변수를 불러와 사용하려고 하면 발생하는 오류이다. 해결 방법은 null이 들어간 이유를 찾아 수정하는 것이다.
예전에 자바 공부를 하면서 실제로 많이 겪었던 오류이다. 보통은 내가 어느 변수에 값을 넣고 싶어서 코드를 작성했는데 중간 과정에서 잘못되어 아무 값도 들어가지 않았을 때 NullPonterExceoption 오류가 발생했었다. 대부분은 값이 들어가지 못한 이유를 찾아내 값을 다시 정확히 넣어주는 방법으로 해결했다.