[Java 21] (1) - getting started with Java

자바란?

 

자바는 썬 마이크로시스템즈에서 개발하여 1996년 1월에 공식적으로 발표한 객체지향 프로그래밍 언어이며, 추후에 함수형 프로그래밍 기능이 추가되었습니다. 자바는 SE(Standard Edtition), ME(Micro Edition), EE(Enterprise Edition) 등 여러가지 종류가 있으며 대부분의 경우 자바는 'Java SE'를 의미합니다.

 

모던 프로그래밍 언어에서 가장 핵심적인 것은 객체지향 개념과 함수형 개념인데, 자바로 작성된 객체지향 개념과 관련된 좋은 자료가 많기 때문에 객체지향 개념을 배우기에 자바만한 언어가 없습니다. 빅데이터에서 많이 쓰이는 함수형 프로그래밍 언어인 스칼라(Scala)도 자바에서 발전된 것으로 자바를 잘 배워두면 여러 언어로 쉽게 확장해 나갈 수 있습니다.

 

자바의 역사

 

자바의 역사는 1991년에 썬의 엔지니어들에 의해서 고안된 오크(Oak)라는 언어에서부터 시작되었습니다. 원래 목표는 가전제품에 탑재될 소프트웨어를 만드는 것이었는데, 객체지향 언어인 C++을 확장하려다가 부족함을 느껴서 C++의 단점을 보완한 새로운 언어인 Oak를 개발하기로 결정하였습니다.

 

인터넷이 등장하자 운영체제에 독립적인 Oak가 이에 적합하다고  판단하여 개발 방향을 인터넷에 맞게 바꾸면서 이름을 자바(Java)로 변경하고, 1996년 1월에 자바의 정식 버전을 발표했습니다. 그 당시만 해도 자바로 작성된 애플릿(Applet)은 웹페이지에 사운드와 애니메이션 등의 멀티미디어적인 요소들을 제공할 수 있는 유일한 방법이었기 때문에 많은 인기를 얻고 단 기간에 많은 사용자층을 확보할 수 있었습니다.

 

이후에 애플릿이 매크로 미디어사의 플래시(flash)에게 밀려서 자바의 인기가 줄어들었으나 1990년 말에 웹의 폭발적인 성장으로 자바의 인기가 다시 급상승하였습니다. 대규모의 서버 애플리케이션의 개발에 자바가 사용됨으로써 실무에서 탄탄한 입지를 확보하게 되었습니다. 그러다가 2008년에 모바일 운영체제인 안드로이드에 자바가 사용되면서 자바의 활용 분야가 더욱 확대되면서 자바가 쓰이지 않는 곳이 없다고 할 정도가 되었습니다.

 

Oracle

썬은 자바와 MySQL 데이터베이스등으로 오픈소스 발전에 큰 기여를 해왔으나, 2000년대 후반에 리눅스의 발전과 닷컴 버블의 붕괴로 주 수익원이던 하드웨어 판매의 급락과 수익이 낮은 오픈소스의 특성으로 경영란에 빠지게 되었습니다. 결국 데이터베이스의 1인자 오라클(Oracle)이 2010년에썬을 인수함으로써 자바와 MySQL 데이터베이스를 확보하게 되었습니다. 그동안 무료로 사용해 왔던 자바의 유료화가 우려되었으나 기업이나 상업적 용도가 아니면 여전히 자바는 무료로 사용할 수 있습니다.

 

오라클은 자바 개발도구인 JDK(Java Development Kit)의 대부분을 Oracle OpenJDK라는 오픈소스로 jdk.java.net 사이트에서 공개하고 있으며, 이를 기반으로 여러 기업이 자신만의 JDK를 오픈소스로 개발해서 공개하고 있습니다. 오픈소스인 Oracle OpenJDK와 달리, Oracle JDK는 오픈 소스가 아니며 상업용 목적이 아닌 개인 사용자에게만 무료입니다. Oracle OpenJDK는 Oracle JDk가 제공하는 JMC(Java Mission Control)와 JFR(Java Flight Recorder) 등의 상용도구가 포함되지 않는다는 점을 제외하면 Oracle JDK와 거의 동일합니다.

 

기존에는 JDK의 발표 후 3년까지 보안 업데이트와 버그 수정이 무료로 지원되었으나 JDK 8부터는 LTS로 지정된 특정 버전만 '장기 지원(최소 8년)'을 제공하고, LTS가 아닌 버전은 다음 버전이 나오는 6개월 후면 지원이 종료됩니다. 따라서 상용 제품이나 기업 환경에서는 반드시 LTS버전의 JDK를 선택해야 합니다.

 

Java의 새로운 기능

현재 2025년을 기준으로 JDK 21이 최신 LTS버전이고, 아래에 JDK 8부터 JDK 21까지 새로 추가된 주요 기능의 목록을 정리하였습니다.

  • JDK 8 - 2014.3 LTS
    • 함수형 프로그래밍 지원 - 람다식 & 스트림 API
    • java.time 패키지
    • Optional 클래스
  • JDK 9 - 2017.9
    • 모듈 시스템 (JEP 261)
    • G1을 기본 GC로 변경 (JEP 254)
    • compact strings
    • 인터페이스에 private method 허용
  • JDK 10 - 2018.3
    • 지역 변수 타입 추론 - var (JEP 286)
  • JDK 11 - 2018.9 LTS
    • HTTP Client API
    • String 클래스 메서드 추가
    • var를 Lambda식에 사용 가능 (JEP 323)
  • JDK 14 - 2020.3
    • switch expressions (JEP 361)
  • JDK 15 - 2020.9
    • 텍스트 블럭 (JEP 378)
  • JDK 16 - 2021.3
    • record (JEP 395)
    • instanceof를 위한 패턴 매칭 (JEP 394)
  • JDK 17 - 2021.9 LTS
    • sealed classes (JEP 409)
  • JDK 18 - 2022.3
    • 간단한 웹서버 제공 (JEP 408)
    • 기본 인코딩 UTF-8로 변경 (JEP 400)
  • JDK 21 - 2023.9 LTS
    • 가상 쓰레드 (JEP 444)
    • switch문을 위한 패턴매칭 (JEP 441)
    • 레코드 패턴 (JEP 440)
    • Sequenced Collections 추가 (JEP 431)

위의 목록에서 새로운 실험적 기능을 개발자의 피드백을 받기 위해 미리보기 형식으로 제공하는 프리뷰 기능(preview features)은 제외하였습니다. 

 

JEP(Java Enhancement Proposal)

JDK 8부터 도입된 '자바 개선 제안 제도(JEP)'는 자바에 새로운 기능의 추가나 기존 기능의 개선을 제안하는 공식 문서입니다. JEP마다 고유 번호가 있으며, OpenJDK 커뮤니티(openjdk.org)를 통해 논의, 승인, 구현 과정을 거칩니다. OpenJDK는 오픈소스 답게 OpenJDK 커뮤니티와 JEP를 통해 Java 플랫폼의 발전 방향을 개발자들과 함께 고민하고 결정하며, 개발자들에게 Java의 미래를 이해할 수 있게 합니다.

 

자바의 특징

 

자바는 비교적 최근에 발표된 언어답게 기존의 다른 언어에는 없는 많은 장점들이 있습니다.

1. 운영체제에 독립적

기존의 언어는 한 운영체제에 담제 개발된 프로그램을 다른 종류의 운영체제에 적용하기 위해서는 많은 노력이 필요하였지만, 자바에서는 더 이상 그런 노력을 하지 않아도 됩니다. 이것은 일종의 애뮬레이터인 자바가상머신(JVM)을 통해서 가능한 것인데, 자바 응용프로그램은 운영체제나 하드웨어가 아닌 JVM하고만 통신하고 JVM이 자바 응용프로그램으로부터 전달받은 명령을 해당 운영체제가 이해할 수 있도록 변환하여 전달합니다. 자바로 작성된 프로그램은 운영체제에 독립적이지만 JVM은 운영체제에 종속적이어서 썬에서는 여러 운영체제에 설치할 수 있는 서로 다른 버전의 JVM을 제공하고 있습니다. 

그래서 자바로 작성된 프로그램은 운영체제와 하드웨어에 관계없이 실행 가능하며 이것을 'Write once, run anywhere'라고 표현합니다.

2. 객체지향 언어이자 함수형 언어

자바는 프로그래밍의 대세로 자리 잡은 객체지향 프로그래밍언어(object-oriented programming language) 중의 하나로 객체지향개념의 특징인 상속, 캡슐화, 다형성이 잘 적용된 수수한 객체지향언어라는 평가를 받고 있습니다. JDK 8부터 함수형 프로그래밍을 지원하고 있어서 최신 변화의 흐름에 맞춰 지속적으로 성장해 가고 있습니다.

3. 비교적 배우기 쉽다

자바의 연산자와 기본구문은 C++에서, 객체지향관련 구문은 스몰톡(small talk)이라는 객체지향언어에서 가져왔습니다. 이 언어들의 장점은 취하면서 복잡하고 불필요한 부분은 과감히 제거하여 단순화함으로서 쉽게 배울 수 있으모, 간결하고 이해하기 쉬운 코드를 작성할 수 있도록 하였습니다.

4. 자동 메모리 관리

자바로 작성된 프로그램이 실행되면, 가비지 컬렉터(garbage collector)가 자동적으로 메모리를 관리해주기 때문에 프로그래머는 메모리를 따로 관리하지 않아도 됩니다. 자동으로 메모리를 관리한다는 것이 다소 비효율적인 면도 있지만, 프로그래머가 보다 프로그래밍에 집중할 수 있도록 도와줍니다.

5. 네트워크와 분산처리를 지원

인터넷과 대규모 분산환경을 염두에 둔 까닭인지 풍부하고 다양한 네트워크 프로그래밍 라이브러리(Java API)를 통해 비교적 짧은 시간에 네트워크 관련 프로그램을 쉽게 개발할 수 있도록 지원합니다.

6. 멀티쓰레드 지원

일반적으로 멀티쓰레드(multi-thread)의 지원은 사용되는 운영체제에 따라 구현방법도 상이하며, 처리 방식도 다릅니다. 그러나 자바에서 개발되는 멀티쓰레드 프로그램은 시스템과는 관계없이 구현가능하며, 관련된 라이브러리(Java API)가 제공되므로 구현이 쉽습니다. 그리고 여러 쓰레드에 대한 스케쥴링은 자바 인터프리터가 담당하게 됩니다.

JDK 21부터 가상 쓰레드(virtual thread)가 추가되어 자바로 고성능, 고처리량의 서버를 만들 수 있게 되었습니다.

7. 동적 로딩 지원

보통 자바로 작성된 애플리케이션은 어러 개의 클래스로 구성되어 있습니다. 자바는 동적 로딩을 지원하기 때문에 실행 시에 모든 클래스가 로딩되지 않고 필요한 시점에 클래스를 로딩하여 사용할 수 있다는 장점이 있습니다. 그 외에도 일부 클래스가 변경되어도 전체 애플리케이션을 다시 컴파일하지 않아도 되며, 애플리케이션의 변경사항이 발생해도 비교적 적은 작업만으로도 처리할 수 있는 유연한 애플리케이션을 작성할 수 있습니다.

 

JVM

 

JVM은 'Java virtual machine'을 줄인 것으로 직역하면 '자바를 실행하기 위한 가상 기계'라고 할 수 있습니다. 가상 기계(virtual machine)는 소프트웨어로 구현된 하드웨어를 뜻하는 넓은 의미의 용어이며, 실제 컴퓨터(하드웨어)가 아닌 소프트웨어로 구현된 컴퓨터라고 생각하면 됩니다.

 

자바로 작성된 애플리케이션은 모두 이 가상 컴퓨터(JVM)에서만 실행되기 때문에, 자바 애플리케이션이 실행되기 위해서는 반드시 JVM이 필요합니다.

위 그림에서 볼 수 있듯이 일반 애플리케이션은 OS와 바로 맞붙어 있기 때문에 OS종속적입니다. 그래서 다른 OS에서 실행시키기 위해서는 애플리케이션을 그 OS에 맞게 변경해야합니다. 반면에 Java 애플리케이션은 JVM하고만 상호작용을 하기 때문에 OS와 하드웨어에 독립적이라 다른 OS에서도 프로그램의 변경없이 실행이 가능합니다. 단, JVM은 OS에 종속적이기 때문에 해당 OS에서 실행가능한 JVM이 필요합니다.

일반 애플리케이션의 코드는 OS만 거치고 하드웨어로 전달되는데 비해 Java애플리케이션은 JVM을 한 번 더 거치기 때문에, 그리고 하드웨어에 맞게 완전히 컴파일된 상태가 아니고 실행 시에 해석(interpret)되기 때문에 속도가 느리다는 단점을 갖고 있습니다. 그러나 요즘엔 바이트코드(컴파일된 자바코드)를 하드웨어의 기계어로 바로 변환해주는 JIT 컴파일러와 향상된 최적화 기술이 적용되어서 속도의 격차를 많이 줄였습니다.

- javac는 JDK에서 제공하는 빌드 타임(정적) 컴파일러이고, JIT은 JVM에 내장된 런타임 컴파일러입니다.
- 대부분의 Java 배포판은 HotSpot JVM을 사용하며, 내부적으로 JIT 컴파일러를 사용합니다.

 

그랄 VM - Graal Virtual machine

그랄 VM은 고성능, 다중언어 실행환경으로 기존의 핫스팟 VM의 JIT 컴파일러를 그랄 컴파일러로 대체한 가상 머신(Virtual Machine)입니다. 자바 외에도 다양한 프로그래밍 언어를 지원하고 심지어는 여러 언어를 혼합해서 코드를 작성하는 것도 가능한데, 그 이유는 그랄 VM은 각 언어의 소스 코드를 인터프리터가 그랄 VM이 이해할 수 있는 중립적인 표현으로 변환해서 처리하기 때문입니다.

 

프로그래밍 언어마다 런타임 환경 성능이 제각각이라 어떤 언어는 성능이 상대적으로 많이 떨어지기도 하는데, 그랄 VM은 입력된 중간 표현을 자동으로 최적화하고 런타임에 JIT 컴파일까지 해주기 때문에 때로는 네이티브 컴파일러보다 실행 성능이 나을 수 있습니다. 특히 서버리스 및 클라우드 환경에 맞게 애플리케이션을 최적화하는 네이티브 바이너리(native image)로 변환하는 기능을 제공하는 것이 큰 장점입니다.

 

오라클은 2018년 5월에 그랄 VM을 처음으로 공식 발표하였으나, 보다 효율적인 개발을 위해 JDK 16부터 JDK에서 독립시켜서 별도의 JDK로 개발하고 있습니다. 현재는 그랄 VM을 사용하려면 그랄 VM이 포함된 JDK를 설치해야하지만, 추후에는 Oracle JDK의 기본 VM으로 포함될 것이라 생각합니다.

 

 

자바 프로그램

 

자바로 개발하려면 먼저 JDK를 설치하고, 코드를 작성할 편집기나 IDE가 필요합니다. 메모장처럼 단순한 편집기로도 가능하지만 자동 완성, 디버깅, 테스트 실행까지 지원하는 IntelliJ IDEA, Eclipse, Visual Studio Code 같은 IDE를 사용하는 편이 훨씬 효율적입니다.

 

자바 프로그램은 “소스 → 바이트코드 → 실행” 순서로 동작합니다. 개발 단계에서 javac(자바 컴파일러)로 소스 파일(.java)을 컴파일하면 바이트코드 클래스 파일(.class)이 만들어지고, 실행 단계에서 java(인터프리터)로 JVM을 구동해 이 바이트코드를 실행합니다. 최근 JDK에는 실행 환경(JRE)이 포함되어 있으므로 보통 JDK만 설치하면 컴파일과 실행을 모두 할 수 있습니다.

 

자바에서는 모든 코드를 반드시 클래스 안에 작성해야 하며, 관련 기능을 가진 클래스들이 모여 하나의 애플리케이션을 이룹니다. 애플리케이션의 시작점은 main 메서드로, 프로그램은 이 메서드가 호출되면서 시작해 그 본문을 끝까지 수행하면 종료됩니다. 모든 클래스에 main이 필요한 것은 아니지만, 실행 가능한 애플리케이션이라면 최소한 하나의 클래스에는 `public static void main(String[] args)` 메서드가 있어야 합니다.

 

그리고 하나의 소스 파일에 여러 클래스를 정의하는 것도 가능하지만, 소스 파일 안에 public 클래스를 선언했다면 파일명은 그 public 클래스의 이름과 반드시 일치해야 합니다(예: public class Hello면 파일명은 Hello.java). 만약 public 클래스가 없다면 파일명은 자유롭게 정할 수 있지만, 유지보수 관점에서는 보통 “한 파일에 한 개의 public 클래스” 규칙을 따르는 것이 가장 깔끔합니다.

 

실행 과정

 

$ java Hello

 

콘솔에서 위와 같이 Java 애플리케이션을 실행시켰을 때 내부적인 순서는 다음과 같습니다.

  1. 프로그램의 실행에 필요한 클래스(*.class파일)을 로드합니다.
  2. 클래스파일을 검사합니다.(파일형식, 악성코드 체크)
  3. 지정된 클래스(Hello)에서 main(String[] args)를 호출합니다.

main 메서드의 첫 줄부터 코드가 실행되기 시작하여 마지막 코드까지 모두 실행되면 프로그램이 종료되고, 프로그램에서 사용했던 자원들은 모두 반환됩니다.

 

주석

 

작성하는 프로그램의 크기가 커질수록 프로그램을 이해하고 변경하는 일이 점점 어려워집니다. 이러한 어려움을 덜기 위해 사용하는 것이 바로 주석입니다. 주석을 이용해서 프로그램에 코드에 대한 설명을 적절히 덧붙여 놓으면 프로그램을 이해하는 데 많은 도움이 됩니다. 

그 외에도 주석은 프로그램의 작성자, 작성일시, 버전과 그에 따른 변경이력 등의 정보를 제공할 목적으로 사용됩니다.

 

주석을 사용하는 방법은 다음과 같이 두 가지 방법이 있습니다.

// 한 줄 주석

/*
범위
주석
*/

 

컴파일러는 주석을 무시하고 건너뛰기 때문에 주석이 많다고 해서 프로그램의 성능이 떨어지는 일은 없으니 안심하고 주석을 활용해도 됩니다. 다만 한 가지 주의할 점은 문자열 안에서의 주석이 있을 때는 주석이 아닌 문자열로 인식됩니다.

 

자주 발생하는 에러

 

자바로 프로그래밍을 할 때 실수로 인해 자주 발생하는 에러들과 그 해결 방법을 간단히 정리하였습니다.

 

1. cannot find symbol  또는 cannot resolve symbol

지정된 변수나 메서드를 찾을 수 없다는 뜻으로 선언되지 않은 변수나 메서드를 사용하거나, 변수 또는 메서드의 이름을 잘못 사용한 경우 발생합니다.

2. ';' expected

세미콜론(;)이 필요한 곳에 없다는 뜻입니다. 자바의 모든 문장의 끝에는 ';'을 붙여주어야 하는데 실수로 빼먹은 경우 발생합니다.

3. Exception in thread "main" java.lang.NoSuchMethodError: main

'main 메서드를 찾을 수 없다.' 는 뜻으로 실제 클래스 내에 main 메서드가 존재하지 않거나 메서드의 선언부 'public static void main(String[] args)'에 오타가 존재하는 경우 발생합니다.

4. Exception in thread "main" java.lang.NoClassDefFoundError: Hello

'Hello 라는 클래스를 찾을 수 없다.' 라는 뜻입니다. 클래스 'Hello'의 철자, 특히 대소문자를 확인해보고 이상이 없으면 클래스 파일(*.class)이 생성되었는지 확인합니다.

5. illegal start of expression

직역하면 문장(수식)의 앞부분이 문법에 맞지 않는다는 의미인데, 간단히 말해서 문장에 문법적 오류가 있다는 뜻입니다. 소괄호나 중괄호를 열고서 닫지 않거나, 수식이나 if문, for문 등에 문법적 오류가 있을 때 또는 public 이나 static과 같은 키워드를 잘못 사용한 경우에도 발생합니다.

6. class, interface, or enum expected

이 메시지의 의미는 '키워드 class나 interface 또는 enum이 없다.' 이지만, 보통 괄호의 개수가 일치하지 않는 경우에 발생합니다.

'Lang > Java' 카테고리의 다른 글

[Java 21] (6) - Object-oriented Programming 1  (0) 2025.09.29
[Java 21] (5) - array  (1) 2025.09.25
[Java 21] (4) - statement  (0) 2025.09.22
[Java 21] (3) - operator  (0) 2025.09.18
[Java 21] (2) - variable  (0) 2025.09.15