자바는 객체 지향 언어로 개발된 프로그래밍 언어로, 자바 가상 머신(JVM, Java Virtual Machine)을 사용하면 OS와 독립적으로 동작시킬 수 있어 어떤 OS를 사용하든지 같은 형태로 실행될 수 있다.
자바는 자동 메모리 관리 등을 지원하여 다른 언어에 비해 안정성이 높고, 연산자 오버로딩을 금지하고 제네릭을 도입하여 코드의 가독성이 높다.
대신 실행을 위해 JVM을 거쳐야 하므로 다른 언어에 비해 실행 속도가 느리고, 예외 처리를 개발자가 일일이 지정해 줘야 한다는 불편함이 있으며, 다른 언어에 비해 작성해야하는 코드의 길이가 긴 편이다.
자바로 작성된 자바 소스 코드(.java)를 JVM이 이해할 수 있는 자바 바이트 코드로(.class) 변환한다.
자바 컴파일러는 자바를 설치하면 javac.exe라는 실행 파일 형태로 설치된다.
자바 바이트 코드를 실행시키는 가상의 기계.
자바로 작성된 모든 프로그램은 JVM에서만 실행 될 수 있다.
서로 다른 운영체제라도 JVM만 설치되어 있으면 같은 자바 프로그램이 동작 가능하다. 단, 자바 프로그램과 달리 JVM은 운영체제에 종속적이므로 각 운영체제에 맞는 JVM을 설치해야 한다.
자바는 동적으로 클래스를 읽어오기 때문에, 프로그램이 실행 중인 런타임에서야 모든 코드가 JVM과 연결된다.
JVM의 구성
자바 프로그램은 한 개 이상의 클래스로 구성되고, 이러한 클래스는 한 개 이상의 필드나 메소드로 구성된다.
class Test {
int field1;
String field2;
public void method1() {
System.out.println("자바 프로그래밍!!");
}
}
// 자바 프로그래밍!!
자바 프로그램이 실행되면 맨 먼저 main() 메소드를 찾아 그 안의 모든 명령문을 차례로 실행한다. 따라서 하나의 자바 프로그램에는 main() 메소드를 가지는 클래스가 반드시 하나는 존재해야 한다.
main() 메소드는 반드시 public static void로 선언되어야 한다.
public static void main(String[] args) {
...
}
자바 클래스 파일(.java)에 public 클래스가 존재하면 소스 파일의 이름은 반드시 해당 public 클래스의 이름과 같아야 한다. 이러한 public 클래스는 자바 클래스 파일마다 단 한개만 가질 수 있다.
자바 프로그램의 동작을 명시하고, 이러한 동작을 컴퓨터에 알려주는 데 사용되는 문장으로 반드시 세미콜론(;)으로 끝나야 한다.
1. // 한 줄 주석
2. /* 여러
줄
주석 */
자바에서는 모든 것이 객체로 표현되므로, 입출력을 담당하는 수단 또한 모두 객체이다.
자바는 System이라는 표준 입출력 클래스를 정의하여 제공한다. 이러한 System 클래스는 java.lang 패키지에 포함되어 제공된다.
System 클래스의 클래스 변수(static variable)
모니터에 전달된 데이터를 출력한 후 줄 바꿈까지 해줌. print() 메소드는 줄바꿈을 하지 않는다.
System.out.println("자바!");
// 자바!
람다 표현식(lambda expression) : 함수형 프로그래밍
스트림 API(stream API) : 데이터의 추상화
java.time 패키지 : Joda-Time을 이용한 새로운 날짜와 시간 API
나즈혼(Nashorn) : 자바스크립트의 새로운 엔진
식별자 없이 실행할 수 있는 함수 표현식으로, 익명 함수(anonymous function)라고도 한다.
메소드를 람다 표현식으로 표현하면 클래스를 만들고 객체를 생성하지 않아도 메소드를 사용할 수 있다.
람다 표현식은 메소드의 매개변수로 전달될 수도 있고, 메소드의 결괏값으로 반환될 수도 있다.
즉 자바에서도 함수형 프로그래밍을 할 수 있게 해준다.
new Thread(new Runnable() {
public void run() {
System.out.println("전통적인 방식의 일회용 스레드 생성");
}
}).start();
new Thread(()->{
System.out.println("람다 표현식을 사용한 일회용 스레드 생성");
}).start();
자바에서는 많은 양의 데이터를 저장하기 위해 배열이나 컬렉션을 사용하고, 이렇게 저장된 데이터에 접근하기 위해서는 반복문이나 반복자(iterator)를 사용하여 매번 코드를 작성해야 했기 때문에 길이가 너무 길고 가독성도 떨어지며, 코드의 재사용이 거의 불가능하다. 또한 정형화된 처리 패턴이 없어 데이터마다 다른 방법으로 접근해야 한다.
스트림 API는 데이터를 추상화하여 다루기 때문에 다양한 방식으로 저장된 데이터를 읽고 쓰기 위한 공통된 방법을 제공한다. 배열이나 컬렉션뿐만 아니라 파일에 저장된 데이터도 모두 같은 방법으로 다룰 수 있다.
String[] arr = new String[]{"넷", "둘", "셋", "하나"};
// 배열에서 스트림 생성
Stream<String> stream1 = Arrays.stream(arr);
stream1.forEach(e -> System.out.print(e + " "));
System.out.println();
// 배열의 특정 부분만을 이용한 스트림 생성
Stream<String> stream2 = Arrays.stream(arr, 1, 3);
stream2.forEach(e -> System.out.print(e + " "));
// 넷 둘 셋 하나
// 둘 셋
JDK 1.0에서는 Date 클래스를 사용하여 날짜를 처리했지만 현재 Date 클래스는 대부분의 메소드가 deprecated 상태이다.
JDK 1.1부터 제공된 Calendar 클래스는 불변 객체가 아니라서 값이 수정될 수 있고, 윤초(leap second)같은 특별 상황을 고려하지 않으며, 월(month)을 나타낼 때 1월~12월을 0~11로 표현해야 하는 불편함이 있다.
지금까지는 자바스크립트의 기본 엔진으로 모질라의 리노(Rhino)가 사용되어 왔으나 현재는 자바의 최신 개선 사항들을 잘 따라오지 못하고 있다.
자바스크립트의 새로운 엔진으로 도입된 오라클의 나즈혼은 기존의 리노에 비해 성능과 메모리 관리 면에서 크게 개선된 스크립트 엔진이다.