본문 바로가기
IT

자바 초보를 위한 기본 용어 A to Z 정리

by 느긋한 판다 2025. 6. 18.
728x90
반응형

자바 초보를 위한 기본 용어 A to Z 정리

자바 초보를 위한 기본 용어 A to Z 정리

 

왜 자바 용어 정리가 중요한가?

햇살이 부드럽게 내려앉은 오후, 나는 오래된 노트북을 켜고 처음으로 자바 강의를 틀었다. 강사의 목소리는 친절했지만 화면에 쏟아지는 단어들은 그렇지 않았다. '클래스', '객체', 'JVM', '리터럴'... 마치 번역되지 않은 외국어를 듣는 느낌이었다. 한 문장을 이해하기 위해 수십 개의 개념을 검색하고, 다시 돌아와도 문맥이 이어지지 않았다. 그때 느꼈다. 자바를 배울 때 가장 중요한 건 코드가 아니라 '용어'라는 것을.

자바는 객체지향 언어다. 이 말은 곧, 자바의 세계를 구성하는 기본 단위들이 명확한 개념과 언어로 설명된다는 뜻이다. 따라서 '클래스'와 '객체'의 차이, '메서드'와 '생성자'의 용도, 그리고 'JDK', 'JRE', 'JVM'의 관계를 명확히 알지 못하면, 코드를 따라 쓰는 것만으로는 절대 자바를 이해할 수 없다. 자바는 말로 이해되지 않으면 손으로 구현되지 않는 언어다.

용어 정리는 단순한 암기가 아니다. 그것은 자바 세계로 입장하는 관문이다. 기초 개념을 모른 채 중급 문법을 배우면, 결국 다시 기초로 되돌아와야 한다. 그래서 이 글은 자바 초보자들이 가장 헷갈려 하는 용어들을 A부터 Z까지 정리하고자 한다. 단순한 나열이 아닌, 개념 간의 연계성과 흐름을 고려해 이야기처럼 풀어갈 것이다.

“개념을 모르면 따라할 수는 있어도 만들 수는 없다.”

자바를 시작하는 모든 이들에게 전하고 싶다. 코드를 쓰기 전에 개념을 익히고, 문법을 배우기 전에 언어의 맥락을 이해하라. 용어를 이해하면 그 안에 담긴 철학과 구조가 보인다. 그리고 그때 비로소 자바는 암호에서 언어로, 도전에서 즐거움으로 바뀐다.

TIP

자바를 배우기 전에 용어 정리를 따로 해두면 이후 학습 효율이 두 배 이상 올라갑니다. 코드를 작성하기 전에 그 코드의 단어들이 무엇을 의미하는지 먼저 살펴보세요.

 

JDK, JRE, JVM의 관계 이해하기

처음 자바를 설치할 때 가장 먼저 마주치는 것이 바로 이 세 가지 용어다. JDK, JRE, JVM. 이름도 비슷하고, 각자의 역할도 헷갈린다. “나는 분명 자바를 설치했는데 또 뭐를 설치하라는 거지?”라는 질문이 자연스럽게 따라온다. 이 세 가지는 자바 프로그램이 실행되기까지의 전 과정을 책임지는 각각의 구성 요소로, 그 관계를 정확히 이해하는 것은 자바를 구조적으로 접근하는 데 큰 도움이 된다.

먼저 JDK(Java Development Kit)는 자바 개발에 필요한 모든 도구를 모아놓은 ‘개발자용 풀세트’다. 이 안에는 자바 컴파일러, 디버거, 다양한 개발 툴이 포함되어 있으며, 개발뿐 아니라 실행도 가능하다. 반면 JRE(Java Runtime Environment)는 말 그대로 ‘실행 환경’이다. JRE에는 JVM과 자바 프로그램 실행에 필요한 라이브러리들이 포함되어 있지만, 개발 툴은 없다. 즉, 자바 앱을 실행할 수는 있어도 만들 수는 없다.

그리고 JVM(Java Virtual Machine)은 JRE의 일부로, 자바 바이트코드를 실제 운영체제에서 실행 가능한 코드로 바꿔주는 가상 머신이다. 메모리 관리, 쓰레드 스케줄링, 보안 기능 등 자바 프로그램이 운영체제와 독립적으로 실행될 수 있도록 하는 핵심 엔진이다. JVM 덕분에 자바는 '한 번 작성하면 어디서든 실행된다'는 플랫폼 독립성을 실현할 수 있다.

“JDK는 개발을, JRE는 실행을, JVM은 해석을 담당한다.”

JDK는 JRE를 포함하고, JRE는 JVM을 포함한다. 이 계층적 구조를 이해하면, 자바 설치 오류나 실행 문제를 훨씬 쉽게 해결할 수 있다. 특히 최신 JDK는 자바 실행 환경까지 포함되어 있어 별도 JRE 설치 없이도 모든 작업이 가능하다. 자바를 본격적으로 배우기 시작했다면, JDK를 설치하고 그 안에 어떤 도구들이 포함되어 있는지 직접 살펴보는 것이 좋다.

 

클래스, 객체, 인스턴스 완전 정복

‘클래스’, ‘객체’, ‘인스턴스’는 자바뿐 아니라 모든 객체지향 언어의 핵심 개념이다. 하지만 이 세 가지는 그 의미가 미묘하게 달라 많은 초보자들이 혼동을 겪는다. 쉽게 비유하자면, ‘클래스’는 설계도, ‘객체’는 그 설계도로 만든 실체, 그리고 ‘인스턴스’는 메모리 상에 존재하는 객체를 가리키는 말이다. 설계도 없이 건물을 지을 수 없듯, 자바에서도 클래스를 먼저 정의해야 객체를 만들 수 있다.

예를 들어 자동차를 모델링한다고 해보자. ‘Car’라는 클래스를 정의하면, 그 안에는 바퀴의 수, 색상, 주행 기능 같은 속성과 동작이 들어간다. 이 클래스를 기반으로 만든 실제 자동차 — 예를 들면 '현대 아반떼', '기아 K5' — 가 바로 객체다. 그리고 이 객체가 메모리에 로딩되었을 때, 우리는 그것을 ‘인스턴스’라고 부른다. 즉, 클래스는 추상이고, 객체는 구체이며, 인스턴스는 존재의 순간이다.

자바에서는 하나의 클래스로 여러 객체를 만들 수 있다. 이를테면 ‘Person’ 클래스를 정의하면, ‘홍길동’, ‘김영희’, ‘이민호’와 같은 객체들을 무수히 만들어낼 수 있다. 객체는 클래스의 변수와 메서드를 상속받고, 각기 다른 값을 가질 수 있다. 객체 간 데이터는 독립적으로 존재하므로, 객체지향의 장점 중 하나인 ‘재사용성과 확장성’이 가능해지는 것이다.

“클래스는 가능성, 객체는 현실, 인스턴스는 그 흔적이다.”

초보자들이 가장 많이 하는 질문 중 하나가 "클래스와 객체는 같은 것 아닌가요?"이다. 이는 맞는 말이자 틀린 말이다. 개념적으로는 다르지만, 코드 상에서는 클래스 이름을 기반으로 객체를 생성하고, 그 객체가 인스턴스가 되기 때문이다. 결국 문맥에 따라 의미가 달라지는 용어들이기에, 자바를 공부할수록 이 세 가지 단어는 더 깊은 층위에서 연결되어 있다는 것을 알게 된다.

TIP

‘인스턴스’라는 단어는 메모리에 생성된 객체를 지칭합니다. 자바에서는 new 키워드를 사용해 인스턴스를 생성하며, 이 과정을 ‘인스턴스화’라고 합니다.

 

변수, 자료형, 리터럴의 기본 개념

‘변수’는 자바 프로그램에서 데이터를 저장하기 위한 공간이다. 이 공간에는 이름이 있고, 저장할 수 있는 데이터의 종류에 따라 ‘자료형’이 지정된다. 자바는 정적 타입 언어이기 때문에, 변수를 선언할 때 반드시 자료형을 명시해야 한다. 예를 들어 `int age = 25;` 라는 구문은 정수형 변수 age에 숫자 25라는 값을 저장한 것이다. 여기서 25는 ‘리터럴’이라 부른다 — 코드에 직접 쓰인 고정값을 의미한다.

자바의 기본 자료형에는 정수형(int, long), 실수형(float, double), 문자형(char), 논리형(boolean)이 있다. 이들은 자바 메모리 상에 고정된 크기를 차지하며, 원시값(primitive value)을 저장한다. 이외에도 배열, 열거형(enum), 클래스 같은 참조 자료형도 존재하지만, 초보 단계에서는 기본 자료형에 익숙해지는 것이 가장 중요하다.

리터럴은 다양한 형태로 표현된다. 정수 리터럴은 숫자 그대로, 문자 리터럴은 작은 따옴표로, 문자열 리터럴은 큰 따옴표로 감싸서 표현한다. 예를 들어 `char grade = 'A';`, `String name = \"홍길동\";` 같은 식이다. 리터럴은 값 그 자체이므로, 변수와 함께 쓰여야 프로그램이 동작할 수 있다. 리터럴 없이 선언만 된 변수는 초기화되지 않았기 때문에, 자바에서는 반드시 값을 할당해주어야 한다.

“자바에서 변수는 이름 붙여진 기억 공간이다.”

초보자들이 자주 실수하는 부분 중 하나는 ‘자료형이 다르면 연산도 다르다’는 점이다. 예를 들어 정수형과 실수형을 함께 연산하면, 암묵적으로 실수형으로 변환된다. 이를 ‘형 변환’이라 하며, 자동형 변환과 강제형 변환이 존재한다. 이러한 개념은 자바의 타입 안정성과 직결되므로, 초기 단계에서부터 명확히 이해해두는 것이 중요하다.

 

메서드와 생성자의 차이점

자바에서 ‘메서드’와 ‘생성자’는 모두 클래스 내부에 정의되며, 특정 동작을 수행하는 코드 블록이라는 점에서 유사하다. 하지만 이 둘은 본질적으로 다른 목적을 가진다. 메서드는 객체가 수행할 수 있는 ‘기능’을 정의하고, 생성자는 객체가 메모리에 처음 생성될 때 호출되어 ‘초기 상태’를 설정한다. 즉, 메서드는 동작을 수행하고, 생성자는 초기화를 담당한다.

생성자는 클래스 이름과 동일한 이름을 가지며 반환형이 없다. 예를 들어 `public Car()`는 Car 클래스의 생성자이다. 반면 메서드는 반드시 반환형을 가지며, 이름도 자유롭게 정할 수 있다. 또한 생성자는 객체가 생성될 때 단 한 번 호출되지만, 메서드는 객체가 존재하는 동안 여러 번 호출될 수 있다. 이 차이점을 명확히 이해하면, 객체의 생성과 동작 흐름을 쉽게 파악할 수 있다.

자바에서는 오버로딩을 통해 생성자도 여러 개 만들 수 있다. 이를 통해 다양한 초기화 옵션을 제공할 수 있으며, 이는 메서드 오버로딩과 유사한 원리로 동작한다. 단, 생성자는 상속되지 않기 때문에 서브 클래스에서 별도로 정의해야 한다는 점도 기억해야 한다.

“생성자는 객체의 출생신고서이고, 메서드는 그 객체의 삶이다.”

초보자들이 자주 혼동하는 부분 중 하나는 생성자에도 void를 붙이는 실수다. 하지만 생성자는 반환형 자체가 없기 때문에 void를 붙이면 오히려 일반 메서드로 인식된다. 이처럼 문법상 유사하지만 개념적으로 다른 요소들을 구분하는 것이 자바를 제대로 이해하는 첫 걸음이다.

 

접근 제어자: public, private, protected

접근 제어자는 자바에서 클래스, 변수, 메서드 등에 대한 접근 범위를 제어하는 키워드다. 크게 `public`, `protected`, `default(명시 안 함)`, `private` 네 가지가 있으며, 이를 통해 클래스 외부에서 해당 구성 요소에 접근할 수 있는지를 정의한다. 이 제어자는 캡슐화(encapsulation)를 구현하는 핵심 수단이기도 하다.

`public`은 어디서든 접근이 가능하다는 의미다. 같은 프로젝트의 어떤 클래스에서도 해당 필드나 메서드를 사용할 수 있다. `private`은 해당 클래스 내부에서만 접근 가능하며, 가장 높은 수준의 은닉화를 제공한다. `protected`는 같은 패키지 내부이거나, 다른 패키지의 서브클래스에서 접근할 수 있도록 허용한다. `default`는 같은 패키지 내에서만 접근 가능하다.

예를 들어 `private int age;` 라는 필드는 외부 클래스에서는 접근이 불가능하다. 이를 읽거나 수정하려면 public 메서드 — getter와 setter — 를 통해 우회해야 한다. 이러한 구조는 데이터를 보호하고, 변경을 통제하는 객체지향의 핵심 원칙을 반영한 것이다.

“정보 은닉은 객체지향의 시작이자 끝이다.”

접근 제어자를 적절히 사용하면 코드의 구조와 보안이 향상된다. 모든 필드를 public으로 선언하면 간편해 보일 수 있지만, 이는 내부 구조를 외부에 노출시키는 위험한 방식이다. 초보자라면 처음에는 헷갈릴 수 있으나, 코드를 많이 작성하면서 의도적인 설계와 보호가 왜 필요한지를 체감하게 될 것이다.

 

오버로딩 vs 오버라이딩 차이점

오버로딩(Overloading)과 오버라이딩(Overriding)은 자바에서 메서드를 재정의하거나 다형성을 구현할 때 사용되는 중요한 개념이다. 이름은 비슷하지만 그 목적과 작동 방식은 완전히 다르다. 오버로딩은 하나의 클래스 안에서 같은 이름의 메서드를 매개변수 형태만 다르게 하여 여러 개 정의하는 것이고, 오버라이딩은 상속 관계에서 부모 클래스의 메서드를 자식 클래스에서 다시 정의하는 것을 말한다.

오버로딩은 컴파일 시점에 결정되는 ‘정적 바인딩’이며, 오버라이딩은 실행 시점에 결정되는 ‘동적 바인딩’이다. 예를 들어 `void print(int a)`와 `void print(String a)`는 오버로딩이며, 각각 다른 매개변수를 갖는다. 반면 부모 클래스에 정의된 `print()` 메서드를 자식 클래스에서 동일한 시그니처로 재정의하는 것이 오버라이딩이다.

“오버로딩은 선택지를 넓히고, 오버라이딩은 의미를 덮어쓴다.”

오버라이딩 시에는 반드시 메서드 시그니처(이름, 매개변수, 반환형)가 동일해야 하며, 접근 제어자는 부모보다 더 좁아질 수 없다. 또한 @Override 어노테이션을 통해 오버라이딩 의도를 명확히 할 수 있는데, 이 어노테이션을 사용하면 실수로 메서드 시그니처를 잘못 작성했을 때 컴파일러가 오류를 알려준다. 이는 실무에서도 매우 중요한 습관이다.

 

자바 메모리 구조: 스택, 힙, 메소드 영역

자바 프로그램이 실행될 때 내부적으로 어떤 메모리 공간에 무엇이 저장되고 관리되는지는 초보자가 놓치기 쉬운 부분이다. 하지만 이 구조를 이해하면 NullPointerException 같은 오류를 해석하고, 성능을 높이기 위한 코드를 작성하는 데 결정적인 도움이 된다. 자바 메모리는 크게 네 영역으로 나눌 수 있다: 메소드 영역, 스택 영역, 힙 영역, 그리고 프로그램 카운터(PC) 레지스터이다.

먼저 메소드(Method) 영역은 클래스 수준의 정보가 저장되는 공간이다. 클래스 이름, 변수 이름, 메서드 시그니처, static 변수 등이 여기에 로딩된다. 이 영역은 JVM이 클래스를 로딩할 때 한 번만 생성되며, 프로그램 종료 시까지 유지된다. 메소드 영역은 ‘정적’인 메모리 구조의 대표 주자다.

스택(Stack) 영역은 메서드 호출 시 생성되는 지역 변수, 매개 변수 등이 저장되는 곳이다. 각 메서드는 호출될 때마다 스택 프레임이라는 블록을 형성하고, 종료되면 자동으로 제거된다. 이 때문에 스택은 매우 빠르지만, 수명이 짧고 제한된 공간이다. 재귀 호출이 너무 깊어지면 StackOverflowError가 발생하는 이유가 바로 이것이다.

힙(Heap) 영역은 new 키워드를 통해 생성된 객체들이 저장되는 공간이다. 이 공간은 JVM의 가비지 컬렉터에 의해 자동으로 관리되며, 비교적 넓고 유연하지만 속도는 느릴 수 있다. 모든 참조 타입 변수는 이 힙 영역의 주소를 참조하게 되며, 실질적인 데이터는 힙에 저장된다. 자바의 메모리 누수(Memory Leak) 문제도 대부분 이 힙 공간에서 발생한다.

“힙은 객체의 고향이고, 스택은 변수의 무대다.”

이 구조를 알면, 객체를 여러 번 생성할 때 힙을 효율적으로 사용하는 전략을 세울 수 있다. 예를 들어 불변 객체를 싱글톤으로 처리하거나, 메모리 풀을 활용하는 방식은 모두 메모리 구조를 바탕으로 한 설계다. 또한 static 변수는 힙이 아닌 메소드 영역에 저장된다는 점도 중요한 구분이다.

 

예외 처리 관련 용어 정리

프로그램을 작성하다 보면 피할 수 없는 것이 오류와 예외다. 자바에서는 예외(Exception)를 체계적으로 처리하기 위한 다양한 용어와 구조를 제공한다. Exception, RuntimeException, Throwable, try-catch-finally, throws, throw 등은 자바 예외 처리의 핵심 용어들이다. 이들을 이해하고 적절히 사용하는 것은 견고한 프로그램을 만드는 필수 조건이다.

자바의 모든 예외는 Throwable 클래스를 상속받는다. 이 클래스는 Error와 Exception 두 가지 하위 클래스를 가지며, 일반적으로 Exception만을 예외 처리 대상으로 삼는다. 그중에서도 RuntimeException은 실행 중 발생하는 예외이며, 컴파일 시 검사되지 않기 때문에 unchecked exception이라 불린다. 반면 IOException, SQLException 같은 checked exception은 반드시 try-catch로 처리하거나 throws로 선언해야 한다.

예외를 처리할 때 가장 기본이 되는 구문은 try-catch-finally이다. try 블록 안에 예외 가능성이 있는 코드를 작성하고, catch 블록에서 예외를 처리하며, finally 블록은 예외 발생 여부와 관계없이 반드시 실행되는 부분이다. 이를 통해 자원 정리나 로그 기록 같은 후속 작업을 안정적으로 수행할 수 있다.

“예외는 피하는 것이 아니라 대비하는 것이다.”

또한 throw와 throws의 차이도 중요하다. throw는 예외를 발생시키는 키워드이고, throws는 예외가 발생할 수 있음을 메서드 선언부에 명시하는 키워드다. 이 둘의 용법 차이를 이해하지 못하면 예외 처리 코드에서 컴파일 오류를 자주 만나게 된다. 예외 처리 용어는 단순 암기가 아니라, 코드 흐름 전체를 조율하는 중요한 언어 구성 요소임을 기억하자.

 

컬렉션 프레임워크 핵심 용어

배열로는 부족하다 — 자바를 조금만 써보다 보면 데이터를 더 유연하게 다루고 싶어진다. 그 순간 등장하는 것이 바로 자바의 컬렉션 프레임워크다. 이 프레임워크는 데이터를 효율적으로 저장하고 검색할 수 있도록 List, Set, Map 등의 자료구조를 제공하며, 각각의 인터페이스와 구현 클래스들은 나름의 규칙과 특성을 가지고 있다.

List는 순서가 있는 데이터 집합으로, 중복을 허용한다. ArrayList와 LinkedList가 대표적인 구현체다. ArrayList는 내부적으로 배열을 사용해 인덱스 접근이 빠르지만, 중간 삽입이나 삭제는 느리다. 반면 LinkedList는 노드 기반으로 구성되어 삽입/삭제가 빠르지만, 인덱스 접근은 느리다. 사용 목적에 따라 선택이 달라져야 한다.

Set은 중복을 허용하지 않으며, 순서를 보장하지 않는 자료구조다. HashSet은 가장 일반적인 Set이며, 내부적으로 해시 알고리즘을 사용해 빠른 검색을 제공한다. TreeSet은 정렬된 데이터를 유지하며, NavigableSet 등의 기능도 지원한다. 중복 없이 정렬된 데이터가 필요할 때 매우 유용하다.

Map은 키-값 쌍으로 데이터를 저장하며, 하나의 키에는 하나의 값만 대응된다. HashMap이 가장 일반적이며, 키의 중복은 허용되지 않는다. TreeMap은 키 기준 정렬을, LinkedHashMap은 삽입 순서를 유지한다. 이들 각각은 구현 목적에 따라 최적화된 동작을 보여주며, 실무에서는 용도에 따라 전략적으로 선택해야 한다.

“컬렉션을 알면 자바가 보이고, 자바를 알면 구조가 보인다.”

컬렉션 프레임워크는 단순히 데이터를 담는 도구를 넘어서, 데이터의 흐름을 설계하는 구조다. 이를 잘 활용하면 복잡한 데이터를 효율적으로 처리할 수 있으며, 성능 최적화에도 큰 도움이 된다. 초보자는 List부터 차근차근 익혀나가되, 인터페이스와 구현체의 관계를 함께 이해하는 것이 중요하다.

반응형