처음부터 Java 배우기

그래서, 당신은 자바로 프로그래밍하고 싶습니까? 훌륭합니다. 당신은 바로 이곳에 왔습니다. 자바 101 시리즈는 기초부터 시작하고 생산적인 자바 개발자되기 위해 알아야 할 핵심 개념을 포함, 자바 프로그래밍에 셀프 가이드 소개합니다. 이 시리즈는 기술적이며, 우리가 진행하는 동안 개념을 이해하는 데 도움이되는 많은 코드 예제가 있습니다. Java가 아닌 프로그래밍 경험이 이미 있다고 가정합니다.

이 첫 번째 기사에서는 Java 플랫폼을 소개하고 Java SE, Java EE 및 Java ME의 세 가지 에디션 간의 차이점을 설명합니다. 또한 Java 애플리케이션을 배포 할 때 JVM (Java Virtual Machine)의 역할에 대해서도 학습합니다. Java 프로그램을 개발하고 실행할 수 있도록 시스템에 JDK (Java Development Kit)를 설정하는 데 도움을 드리고 일반적인 Java 애플리케이션의 아키텍처를 시작하도록하겠습니다. 마지막으로 간단한 Java 앱을 컴파일하고 실행하는 방법을 배웁니다.

Java 12 및 새로운 JShell 용으로 업데이트 됨

이 시리즈는 Java 12 용으로 업데이트되었으며 Java jshell학습 및 Java 코드 프로토 타이핑을위한 대화 형 도구 인 새로운 기능에 대한 간략한 소개가 포함되어 있습니다.

다운로드 코드 받기이 자습서에서 예제 응용 프로그램의 소스 코드를 다운로드합니다. JavaWorld를 위해 Jeff Friesen이 만들었습니다.

Java 란 무엇입니까?

Java는 C 및 C ++와 매우 유사하지만 사용하기 쉽고보다 강력한 프로그램을 만들 수있는 범용 객체 지향 언어로 생각할 수 있습니다. 불행히도이 정의는 Java에 대한 많은 통찰력을 제공하지 않습니다. 2000 년에 Sun Microsystems (Java 플랫폼의 창시자)는 Java를 다음과 같이 설명했습니다. 

Java는 단순하고 객체 지향적이며 네트워크에 정통하며 해석되고 강력하고 안전하며 아키텍처 중립적이며 이식 가능한 고성능 다중 스레드 동적 컴퓨터 언어입니다.

이러한 각 정의를 개별적으로 고려해 봅시다.

Java는 간단한 언어 입니다. Java는 초기에 C 및 C ++를 모델로하여 잠재적으로 혼란스러운 기능을 뺀 것입니다. 포인터, 다중 구현 상속 및 연산자 오버로딩은 Java의 일부가 아닌 일부 C / C ++ 기능입니다. C / C ++에서는 필수가 아니지만 Java에 필수적인 기능은 객체와 배열을 자동으로 회수하는 가비지 수집 기능입니다.

Java는 객체 지향 언어 입니다. Java의 객체 지향 초점을 통해 개발자는 언어 제약을 충족하기 위해 문제를 조작하도록 강요하는 대신 Java를 조정하여 문제를 해결하는 작업을 수행 할 수 있습니다. 이것은 C와 같은 구조화 된 언어와 다릅니다. 예를 들어 Java를 사용하면 저축 계좌 객체에 집중할 수 있지만 C에서는 저축 계좌 상태 (예 : 잔액)와 동작 (예 : 입금 및 인출)에 대해 별도로 생각해야합니다 .

Java는 네트워크에 정통한 언어 입니다. Java의 광범위한 네트워크 라이브러리는 HTTP (HyperText Transfer Protocol) 및 FTP (File Transfer Protocol)와 같은 TCP / IP (Transmission Control Protocol / Internet Protocol) 네트워크 프로토콜에 쉽게 대처할 수 있도록하며 네트워크 연결 작업을 단순화합니다. 또한 Java 프로그램은 로컬 파일 시스템에서 액세스 할 때와 마찬가지로 쉽게 URL (Uniform Resource Locator)을 통해 TCP / IP 네트워크를 통해 객체에 액세스 할 수 있습니다.

Java는 해석 된 언어 입니다. 런타임시 Java 프로그램은 가상 머신 (가상 플랫폼의 소프트웨어 표현) 및 관련 실행 환경을 통해 기본 플랫폼 (예 : Windows 또는 Linux)에서 간접적으로 실행됩니다. 가상 머신은 해석을 통해 Java 프로그램의 바이트 코드 (명령 및 관련 데이터)를 플랫폼 별 명령으로 변환합니다. 해석 은 바이트 코드 명령어가 의미하는 바를 파악한 다음 실행할 동등한 "미리 준비된"플랫폼 별 명령어를 선택하는 작업입니다. 그런 다음 가상 머신은 이러한 플랫폼 별 명령을 실행합니다.

해석을 사용하면 런타임에 더 많은 컴파일 시간 정보를 사용할 수 있으므로 결함이있는 Java 프로그램을 쉽게 디버깅 할 수 있습니다. 해석은 또한 런타임까지 Java 프로그램 조각 간의 링크 단계를 지연시켜 개발 속도를 높일 수 있습니다.

Java는 강력한 언어 입니다. Java 프로그램은 Blu-ray 플레이어에서 차량 내비게이션 또는 항공 제어 시스템에 이르는 소비자 및 미션 크리티컬 애플리케이션 모두에서 사용되기 때문에 신뢰할 수 있어야합니다. Java를 강력하게 만드는 데 도움이되는 언어 기능에는 선언, 컴파일 타임 및 런타임시 중복 유형 검사 (버전 불일치 문제 방지), 자동 경계 검사 기능이있는 진정한 배열, 포인터 생략이 포함됩니다. (Java 언어 유형, 리터럴, 변수 등을 시작하려면 "기본 Java 언어 기능"을 참조하십시오.)

Java의 견고성의 또 다른 측면은 0이 거짓이고 0이 아닌 값이 참인 정수 표현식 대신 부울 표현식으로 루프를 제어해야한다는 것입니다. 예를 들어 Java는 while (x) x++;루프가 예상 한 곳에서 끝나지 않을 수 있기 때문에 C 스타일 루프를 허용하지 않습니다 . 대신 while (x != 10) x++;( x10이 될 때까지 루프가 실행됨을 의미 함) 과 같은 부울 표현식을 명시 적으로 제공해야합니다 .

Java는 안전한 언어 입니다. Java 프로그램은 네트워크 / 분산 환경에서 사용됩니다. Java 프로그램은 네트워크의 다양한 플랫폼으로 마이그레이션하여 실행할 수 있기 때문에 바이러스를 유포하거나 신용 카드 정보를 도용하거나 기타 악의적 인 행위를 수행 할 수있는 악성 코드로부터 이러한 플랫폼을 보호하는 것이 중요합니다. 견고성을 지원하는 Java 언어 기능 (예 : 포인터 생략)은 Java 샌드 박스 보안 모델 및 공개 키 암호화와 같은 보안 기능과 함께 작동합니다. 이러한 기능을 함께 사용하면 바이러스와 기타 위험한 코드가 의심하지 않는 플랫폼에 큰 피해를 입히는 것을 방지 할 수 있습니다.

이론적으로 Java는 안전합니다. 실제로 다양한 보안 취약점이 탐지되고 악용되었습니다. 그 결과 Sun Microsystems와 Oracle은 이제 계속해서 보안 업데이트를 릴리스합니다.

Java는 아키텍처 중립적 인 언어 입니다. 네트워크는 다양한 마이크로 프로세서 및 운영 체제를 기반으로하는 다양한 아키텍처의 플랫폼을 연결합니다. Java가 플랫폼 별 지침을 생성하고 네트워크의 일부인 모든 종류의 플랫폼에서 이러한 지침을 "이해"할 것으로 기대할 수 없습니다. 대신 Java는 각 플랫폼이 (JVM 구현을 통해) 해석하기 쉬운 플랫폼 독립적 인 바이트 코드 명령을 생성합니다.

Java는 이식 가능한 언어 입니다. 아키텍처 중립성은 이식성에 기여합니다. 그러나 플랫폼 독립적 인 바이트 코드 명령어보다 Java의 이식성에 더 많은 것이 있습니다. 정수 유형 크기는 다양하지 않아야합니다. 예를 들어, 32 비트 정수 유형은 32 비트 정수가 처리되는 위치 (예 : 16 비트 레지스터가있는 플랫폼, 32 비트 레지스터가있는 플랫폼 또는 플랫폼 64 비트 레지스터 사용). Java의 라이브러리는 이식성에도 기여합니다. 필요한 경우 가능한 가장 이식 가능한 방식으로 플랫폼 별 기능과 Java 코드를 연결하는 유형을 제공합니다.

Java는 고성능 언어 입니다. 해석은 일반적으로 적절한 수준 이상의 성능을 제공합니다. 고성능 애플리케이션 시나리오의 경우 Java는 해석 된 바이트 코드 명령어 시퀀스를 분석하고 자주 해석되는 명령어 시퀀스를 플랫폼 별 명령어로 컴파일하는 Just-In-Time 컴파일을 사용합니다. 이러한 바이트 코드 명령어 시퀀스를 해석하려는 이후 시도는 동등한 플랫폼 별 명령어를 실행하여 성능을 향상시킵니다.

Java는 다중 스레드 언어 입니다. 한 번에 여러 작업을 수행해야하는 프로그램의 성능을 향상시키기 위해 Java는 스레드 실행 개념을 지원합니다 . 예를 들어, 네트워크 연결에서 입력을 기다리는 동안 GUI (그래픽 사용자 인터페이스)를 관리하는 프로그램은 두 작업 모두에 기본 GUI 스레드를 사용하는 대신 다른 스레드를 사용하여 대기를 수행합니다. 이렇게하면 GUI가 계속 반응합니다. Java의 동기화 기본 요소를 사용하면 스레드가 데이터를 손상시키지 않고 데이터를 안전하게 통신 할 수 있습니다. (Java 101 시리즈의 다른 부분에서 논의 된 Java의 스레드 프로그래밍을 참조하십시오.)

Java는 동적 언어 입니다. 프로그램 코드와 라이브러리 간의 상호 연결은 런타임에 동적으로 발생하기 때문에 명시 적으로 연결할 필요가 없습니다. 결과적으로 프로그램 또는 라이브러리 중 하나가 발전하면 (예 : 버그 수정 또는 성능 향상을 위해) 개발자는 업데이트 된 프로그램 또는 라이브러리 만 배포하면됩니다. 동적 동작으로 인해 버전이 변경 될 때 배포 할 코드가 줄어들지 만이 배포 정책은 버전 충돌로 이어질 수도 있습니다. 예를 들어 개발자는 라이브러리에서 클래스 유형을 제거하거나 이름을 바꿉니다. 회사에서 업데이트 된 라이브러리를 배포하면 클래스 유형에 의존하는 기존 프로그램이 실패합니다. 이 문제를 크게 줄이기 위해 Java는 인터페이스 유형을 지원합니다., 이는 두 당사자 간의 계약과 같습니다. (Java 101 시리즈의 다른 부분에서 논의 된 인터페이스, 유형 및 기타 객체 지향 언어 기능을 참조하십시오.)

이 정의를 풀면 Java에 대해 많은 것을 배울 수 있습니다. 가장 중요한 것은 Java가 언어이자 플랫폼이라는 것을 보여줍니다. 이 자습서의 뒷부분에서 Java 플랫폼 구성 요소 (예 : Java 가상 머신 및 Java 실행 환경)에 대해 자세히 알아 봅니다.

Java의 세 가지 에디션 : Java SE, Java EE 및 Java ME

Sun Microsystems는 1995 년 5 월에 Java 1.0 소프트웨어 개발 키트 (JDK)를 출시했습니다. 최초의 JDK는 데스크탑 응용 프로그램과 애플릿을 개발하는 데 사용되었으며 이후 Java는 엔터프라이즈 서버 및 모바일 장치 프로그래밍을 포함하도록 발전했습니다. 필요한 모든 라이브러리를 단일 JDK에 저장하면 JDK가 너무 커져서 배포 할 수 없었을 것입니다. 특히 1990 년대 배포는 작은 크기의 CD와 느린 네트워크 속도로 인해 제한 되었기 때문입니다. 대부분의 개발자가 마지막 API를 모두 필요로하지 않았기 때문에 (데스크톱 애플리케이션 개발자는 엔터프라이즈 Java API에 액세스 할 필요가 거의 없음) Sun은 Java를 세 가지 주요 에디션으로 분류했습니다. 이들은 결국 Java SE, Java EE 및 Java ME로 알려지게되었습니다.

  • Java SE (Java Platform, Standard Edition) 는 클라이언트 측 응용 프로그램 (데스크톱에서 실행) 및 애플릿 (웹 브라우저에서 실행)을 개발하기위한 Java 플랫폼입니다. 보안상의 이유로 애플릿은 더 이상 공식적으로 지원되지 않습니다.
  • Java EE (Java Platform, Enterprise Edition )는 엔터프라이즈 지향 서버 응용 프로그램을 개발하는 데 독점적으로 사용되는 Java SE 위에 구축 된 Java 플랫폼입니다. 서버 측 애플리케이션에는 애플릿과 유사하지만 클라이언트가 아닌 서버에서 실행되는 Java 프로그램 인 Java 서블릿이 포함 됩니다. 서블릿은 Java Servlet API를 따릅니다.
  • Java ME (Java Platform, Micro Edition) 도 Java SE 위에 구축됩니다. 모바일 정보 장치에서 실행되는 Java 프로그램 인 MIDlet 과 임베디드 장치에서 실행되는 Java 프로그램 인 Xlet 을 개발하기위한 Java 플랫폼입니다 .

Java SE는 Java의 기본 플랫폼이며 Java 101 시리즈의 핵심입니다. 코드 예제는 작성 당시 Java의 최신 버전 인 Java 12를 기반으로합니다.

자바 플랫폼과 JVM

Java는 컴파일 된 Java 코드를 실행하기위한 프로그래밍 언어이자 플랫폼입니다. 이 플랫폼은 주로 JVM으로 구성되지만 기본 (네이티브) 플랫폼에서 JVM의 실행을 지원하는 실행 환경도 포함합니다. JVM에는 Java 코드를로드, 확인 및 실행하기위한 여러 구성 요소가 포함되어 있습니다. 그림 1은이 플랫폼에서 Java 프로그램이 실행되는 방법을 보여줍니다. 

Jeff Friesen

다이어그램의 맨 위에는 일련의 프로그램 클래스 파일이 있으며 그 중 하나는 기본 클래스 파일로 표시됩니다. Java 프로그램은로드, 확인 및 실행되는 첫 번째 클래스 파일 인 기본 클래스 파일로 구성됩니다.

JVM은 클래스 로딩을 클래스 로더 구성 요소에 위임합니다. 클래스 로더는 파일 시스템, 네트워크 및 아카이브 파일과 같은 다양한 소스에서 클래스 파일을로드합니다. 클래스 로딩의 복잡성으로부터 JVM을 격리합니다.

로드 된 클래스 파일은 메모리에 저장되고 Class클래스 에서 생성 된 객체로 표시됩니다 . 로드되면 바이트 코드 검증 도구는 다양한 바이트 코드 명령이 유효하고 보안을 손상시키지 않는지 확인합니다.

클래스 파일의 바이트 코드가 유효하지 않으면 JVM이 종료됩니다. 그렇지 않으면 인터프리터 구성 요소는 바이트 코드를 한 번에 한 명령 씩 해석합니다. 해석은 바이트 코드 명령어를 식별하고 동등한 기본 명령어를 실행합니다.

일부 바이트 코드 명령어 시퀀스는 다른 것보다 더 자주 실행됩니다. 인터프리터가이 상황을 감지하면 JVM의 JIT (Just-In-Time) 컴파일러가 더 빠른 실행을 위해 바이트 코드 시퀀스를 원시 코드로 컴파일합니다.

실행 중에 인터프리터는 일반적으로 다른 클래스 파일의 바이트 코드 (프로그램 또는 라이브러리에 속함)를 실행하라는 요청을 만납니다. 이 경우 클래스 로더는 클래스 파일을로드하고 바이트 코드 검증기는로드 된 클래스 파일의 바이트 코드가 실행되기 전에 확인합니다. 또한 실행 중에 바이트 코드 명령은 JVM이 파일을 열거 나 화면에 무언가를 표시하거나 소리를 내거나 기본 플랫폼과의 협력이 필요한 다른 작업을 수행하도록 요청할 수 있습니다. JVM은 JNI (Java Native Interface) 브리지 기술을 사용하여 응답하여 기본 플랫폼과 상호 작용하여 작업을 수행합니다.