Java (r20200302판)

문서 조회수 확인중...

파일:나무위키+유도.png   동음이의어에 대한 내용은 자바 문서를 참조하십시오.

파일:나무위키+하위문서.png   하위 문서: Java/버전 정보, Java/문법

TIOBE에서 선정한 검색어 점유율 상위 20개 프로그래밍 언어
Java
C
Python
C++
C\#
VB .NET
JavaScript
PHP
SQL
Swift
Go
어셈블리어
R
D
Ruby
MATLAB
PL/SQL
Delphi/Object
Pascal

Perl
Objective-C


자바
Java
파일:java 로고.png
개발
오라클
버전
13
2019년 9월 17일 업데이트
웹사이트
홈페이지
1. 개요
2. 어원
3. 분류
4. 역사
4.1. JDK 1.0a
4.2. JDK 1.0a2
4.3. JDK 1.0
4.4. JDK 1.1
4.5. J2SE 1.2
4.6. J2SE 1.3
4.7. J2SE 1.4
4.8. J2SE 5
4.9. Java SE 6
4.10. Java SE 7
4.11. Java SE 8
4.12. Java SE 9
4.13. Java SE 10
4.14. Java SE 11
4.15. Java SE 12
4.16. Java SE 13
6. C, C++와의 비교
7. 특징
7.1. 장점
7.1.1. 수많은 개발자와 레퍼런스
7.1.2. 비교적 높은 생산성
7.1.3. 기기 호환성
7.1.4. 안정성
7.1.5. 소스 코드 가독성
7.2. 단점
7.2.1. 속도 문제
7.2.1.1. JVM 로딩 속도 문제
7.2.1.2. 가상 머신 바이트코드 실행 속도 문제
7.2.1.3. 가비지 컬렉션에 의한 실행 지연 문제
7.2.2. 불편한 예외 처리
7.2.3. 소스 코드 길이
7.2.4. 언어적 불편함
7.2.4.1. 명사형 생각을 강제
7.2.4.2. 클로저 미지원
8. 개발환경, JVM 언어
8.1. 개발환경
8.2. JVM 언어
8.2.1. 유명한 JVM 언어 목록
8.3. 혼동하기 쉬운 것들
9. 구글 vs. 오라클: Java 저작권 분쟁
10. 점유율
11. 불투명한 미래?
12. 도서
13. 여담
14. 관련 문서




1. 개요


package wiki.namu.test;

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, world!");
    }
}
썬 마이크로시스템즈에서 1995년에 개발한 객체 지향 프로그래밍 언어. 창시자는 제임스 고슬링이다. 2010년에 오라클썬 마이크로시스템즈을 인수하면서 Java의 저작권을 소유하였다. 현재는 OpenJDK는 GPL2이나 오라클이 배포하는 Oracle JDK는 상업라이선스로 2019년 1월부터 유료화정책을 강화하고 있다. Java EE는 이클립스 재단의 소유이다. Java 언어는 J2SE 1.4부터는 Java Community Process (JCP)에서 개발을 주도하고 있다.
C#과 문법적 성향이 굉장히 비슷하며, 그에 비해 2019년 Q3에서 가장 많이 이용하는 언어로 뽑혔다. Javascript와는 다르다.

2. 어원


처음엔 고슬링 사무실 앞에 있는 참나무에서 따와 OAK로 지었다가 그대로 상표로 등록하기엔 문제가 생겨서[1] 컨설턴트가 극단적인 방법을 도입, 오후에 개발진들을 회의실에 가둬서(...) 브레인스토밍을 시켰다. "기분이 어떤가요"(Excited!), "무엇이 당신 기분을 좋게 만드나요?"(Java coffee!) 같은 연상적인 작용을 거쳐 여러가지 이름을 정하고, 그 중에서 자바 커피의 Java를 선택했다. Java는 랭킹 중 네 번째. 리스트의 첫 번째 이름은 Silk였고 고슬링이 가장 좋아했던 이름은 Lyrics, 세 번째에 올라왔던 이름이라고.
개발진이 자바산 커피를 좋아해서 그랬다는 설도 있다. 아이콘도 커피잔 모양. 또는 개발자의 이름인 James Gosling, Arthur Van Hoff, Andy Bechtolsheim의 머릿글자를 따온 것이라는 설도 있고, 그냥 사전을 펼쳤는데 눈에 들어온 이름이었다는 설도 있다. 그런데 막 지은 것 치고는 크게 흥하여 썬이 자사의 나스닥 코드를 SUNW에서 JAVA로 바꾸었을 정도로 이제는 썬의 상징이자, 근데 그 썬이 오라클에 인수돼서 사라진 건 함정 세계적으로도 널리 알려진 단어가 되었다. 출처

3. 분류


Java는 크게 다음과 같은 4가지 에디션으로 나뉜다.
  • Java SE(Java Standard Edition / J2SE)
대부분의 사람들이 가장 많이 접하는 표준 에디션. Java의 핵심 API와 기능들을 제공한다. JDK 항목도 참고.
  • Jakarta EE, 구 Java EE(Java Enterprise Edition / J2EE)
기업에서 운영하는 서버 페이지에 특화된 에디션이다. JSP와 서블릿을 비롯한 웹 애플리케이션 서버에 관련된 기술들이 포함되어 있다.
  • Java ME(Java Micro Edition / J2ME)
PDA나 셋톱박스, 센서 등의 임베디드 시스템 환경에 특화된 에디션이다.
  • JavaFX
데스크톱 애플리케이션 개발 및 배포를 위한 에디션으로, 크로스플랫폼 이식과 GUI 라이브러리를 제공한다.

4. 역사


버전 정보와 날짜만 확인한다면, Java/버전 정보 문서 참조.

4.1. JDK 1.0a


1994년 발표.

4.2. JDK 1.0a2


1995년 5월 23일 발표. 언어 자체가 정식으로 발표된 날이기도 하다.

4.3. JDK 1.0


1996년 1월 23일 발표. 발표 이전에 불렸던 이름은 Oak였으며, 안정화 작업을 거친 1.0.2 버전에서 Java로 이름이 바뀌었다.

4.4. JDK 1.1


1997년 2월 19일 발표. 이너 클래스, JavaBeans, RMI, 리플렉션, 유니코드 지원, 국제화(Internationalization) 등이 추가되었다.

4.5. J2SE 1.2


1998년 12월 8일 발표. 일반 지원은 2003년 11월에 종료되었다. 새로운 GUI, JIT, CORBA 등의 굵직한 기능이 추가되면서 2 부터 약칭을 J2SE(Java 2 Standard Edition) 로 표기하기 시작했으며, 이 표기는 5 까지 사용된다. strictfp, Swing GUI, JIT, Java Applet을 구동하는 웹 브라우저 플러그인, CORBA, Collections 등이 추가되었다. 1999년에 업데이트를 통해 HotSpot JVM이 첫 선을 보인다.

4.6. J2SE 1.3


2000년 3월 8일 발표. 일반 지원은 2006년 11월에 종료되었다. HotSpot JVM, JNDI, JPDA, JavaSound 등이 추가되었다. RMI가 CORBA를 지원하도록 변경되었다.

4.7. J2SE 1.4


2002년 2월 6일 발표. 일반 지원[2]은 2008년 10월, 연장 지원[3]은 2013년 2월에 종료되었다. assert, 정규표현식, IPv6, Non-Blocking IO, XML API, JCE, JSSE, JAAS, Java Web Start 등이 추가되었다.

4.8. J2SE 5


2004년 9월 30일 발표. 일반 지원은 2009년 9월, 연장 지원은 2015년 5월에 종료되었다. J2SE 5.0까지 Windows 9x와 Windows NT 4.0이 지원되었다. 이 때부터 버젼 중 앞의 1을 빼버리고 표기하기 시작했다. 그러나 내부적으로는 여전히 1.5, 1.6, 1.7 등으로 데이터가 들어있다. Generics, Annotation, Auto Boxing/Unboxing, Enumeration, 가변 길이 파라미터, Static Import, 새로운 Concurrency API 등이 추가되었다. Java는 표준 입력(stdin) 지원이 시원찮았는데, J2SE 5에 들어서 java.util.Scanner가 추가되면서 이전보다 편하게 표준 입력을 사용할 수 있게 되었다.

4.9. Java SE 6


2006년 12월 11일 발표. 일반 지원은 2013년 2월에 종료되었으며, 연장 지원은 2018년 12월에 종료되었다. 이 때부터 표기가 J2SE에서 Java SE로 바뀌었다. Scripting Language Support, JDBC 4.0, Java Compiler API, Pluggable Annotation 등이 추가되었다. 스크립팅 언어 지원과 함께 Rhino JavaScript 엔진이 기본으로 탑재되었다.

4.10. Java SE 7


2011년 7월 7일 발표. 일반 지원은 2015년 4월에 종료되었으며, 연장 지원은 2022년 7월에 종료될 예정이다. Dynamic Language 지원, switch문에서 String 사용, try문에서 자동 자원 관리, Diamond Operator <>, 이진수 리터럴, 숫자 리터럴에 _ 지원, 새로운 Concurrency API, 새로운 File NIO 라이브러리, Elliptic Curve Cryptography, Java2D를 위한 XRender, Upstream, Java Deployment Ruleset 등이 추가되었다.

4.11. Java SE 8


2014년 3월 18일 발표. 일반 지원은 2019년 1월에 종료되었고, 연장 지원은 2023년 9월에 종료될 예정이다. Lambda Expression, Rhino 대신 Nashorn JavaScript 엔진 탑재, Annotation on Java Types, Unsigned Integer 계산, Repeating Annotation, 새로운 날짜와 시간 API(사실상 JodaTime이라고 보면 된다), Static Link JNI Library, Interface Default Method, PermGen 영역 삭제, Stream API 등이 추가되었다. 본래 일반 지원은 2017년 9월 종료 예정이었으나 Java 9 발표의 지연 때문에 2018년 9월로 연장되었다가, 이후 라이선스 이관 문제로 인해 2019년 1월로 다시 연장되었다.
32비트를 지원하는 마지막 공식 Java 버전으로, 이후 버전의 32비트 지원은 오직 서드파티를 통해서만 지원된다.

4.12. Java SE 9


2017년 9월 21일 발표. 일반 지원은 2018년 3월에 종료되었다.
Project Jigsaw 기반으로 런타임이 모듈화된 것이 가장 큰 특징. 이에 따라 대부분의 콘솔 프로그램 개발에는 더 이상 AWT나 Swing 같은 불필요한 라이브러리를 끌어쓸 필요도 없이, 최상위 모듈인 Base만 사용해도 된다. 더불어 특정 프로그램에 최적화된 최소 런타임을 제작할 수 있게 되면서 패키징 역시 간편해졌다.
여기에 Java를 인터프리터 언어 셸처럼 사용할 수 있는 JShell이 추가되었으며, Java 바이트코드를 기계어로 미리 번역하는 선행 컴파일(Ahead-Of-Time Compilation) 역시 실험 기능으로 추가되었다.[4] 또한 Deprecated 표시에는 해당 버전과 제거 예정 여부를 표시할 수 있게 되었다. 그 외에 구조적 불변 컬렉션, 통합 로깅, HTTP/2, private 인터페이스 메소드, HTML5 Javadoc 등도 지원되며, 프로퍼티 파일에 UTF-8이 지원됨에 따라 더 이상 인코딩 문제로 삽질할 필요가 없어졌다. 또한 Java Applet 기능은 지원이 종료된다.
새로 적용된 버저닝 정책에 따라 이 버전부터는 더 이상 1.x 버전으로 내놓지 않고, 대신 9.0으로 급속한 판올림이 일어났다. 또한 제거 예정인 Deprecated API는 다음 버전인 Java SE 10부터 완전 삭제 예정이므로 해당 API를 쓰는 프로그램은 더 이상 이후의 버전에서 컴파일조차 불가능하게 된다. 그리고 Java SE 9부터는 6개월마다 새로운 버전이 업데이트된다.
본래는 2016년 발표 예정이었으나 2번이나 연기되어 2017년 7월 27일 발표 예정, 그나마도 한번 더 연기되어 9월 21일에 발표되었다. 가장 큰 원인은 역시 Project Jigsaw의 개발 난이도였다. 런타임의 모듈화는 하위 호환성을 어느 정도 포기하고 성능을 추구한 것이기에 아직 현장에서는 Java 9로 넘어가는 것을 꺼리는 분위기다.
이 버전부터 64비트 버전만 출시되었으며, 32비트 버전은 더 이상 공식적으로 나오지 않는다.

4.13. Java SE 10


2018년 3월 20일 발표. 일반 지원은 2018년 9월에 종료되었다. var 키워드를 이용한 지역 변수 타입 추론[5], 병렬 처리 가비지 컬렉션, 개별 쓰레드로 분리된 Stop-The-World, 루트 CA 목록 등이 추가되었다. 또한 JDK의 레포지토리가 하나로 통합되었으며, JVM 힙 영역을 시스템 메모리가 아닌 다른 종류의 메모리에도 할당할 수 있게 되었다. 실험 기능으로 Java 기반의 JIT 컴파일러가 추가되었고, 이전 버전에서 Deprecated 처리된 API는 Java SE 10에서 모두 삭제되었다.

4.14. Java SE 11


2018년 9월 25일 발표. 일반 지원은 2023년 9월, 연장 지원은 2026년 9월에 종료될 예정이다. 이클립스 재단으로 넘어간 Java EE가 JDK에서 삭제되고, JavaFX도 JDK에서 분리되어 별도의 모듈로 제공된다. #[6] 람다 파라미터에 대한 지역 변수 문법[7], 엡실론 가비지 컬렉터, HTTP 클라이언트 표준화 등의 기능이 추가되었다.
가장 커다란 변화는 바로 라이선스 부분. Java SE 11부터 Oracle JDK의 독점 기능이 오픈 소스 버전인 OpenJDK에 이식된다. 이는 다시 말해 Oracle JDK와 OpenJDK가 완전히 동일해진다는 뜻이다. Oracle JDK는 Java SE 11부터 LTS(장기 지원) 버전으로 3년마다 출시되는데, 출시 후 5년 동안 오라클의 기술 지원이 제공되고 최대 3년까지 지원 기간을 연장할 수 있다. Oracle JDK는 이제 3년에 한 번 출시되니 Java의 실질적인 버전 업을 담당하는 것은 OpenJDK가 된 셈이다. OpenJDK는 기업들을 위한 기술 지원은 없고, 새로운 버전이 나오면 이전 버전에 대한 마이너 업데이트와 보안 업데이트는 중단된다.
그리고 Java 11과 함께 발표된 또 다른 소식은 바로 Oracle JDK가 구독형 유료 모델로 전환된다는 점이다. # 2019년 1월부터 오라클이 제공하는 모든 Oracle JDK는 유료화되며, 구독권을 구입하지 않으면 Oracle JDK에 접근 자체가 금지된다. 기존의 일반/연장 지원 서비스는 구독권에 포함되므로 별도의 서비스로는 제공되지 않는다. 개인 사용자는 2021년 1월부터 비용을 지불해야 한다. 이 때문에 많은 기업들이 Oracle JDK에서 발을 빼고 있으며, OpenJDK를 기반으로 한 다른 서드파티 JDK가 대안으로 떠오르고 있다. 대표적인 예로 Azul Systems에서 개발한 Zulu JDK가 있는데, Zulu JDK는 오라클의 TCK(Technology Certification Kit) 인증을 받은 구현체이다. 개인과 기업 모두 무료로 사용할 수 있고, 기술 지원에 한해서만 유료 서비스가 제공된다. 또 다른 대안으로는 AdoptOpenJDK가 있는데, AdoptOpenJDK는 HotSpot VM 대신 Eclipse OpenJ9을 탑재한 버전도 같이 제공하고 있다. 다만 아직 TCK 인증을 받지 않았기에 주의가 필요하다.

4.15. Java SE 12


2019년 3월 19일 공개. 특징 중 하나로 문법적으로 Switch문을 확장한 것이 있다.(출처)
System.out.println(7);break;case TUESDAY:
case THURSDAY:System.out.println(8);break;case SATURDAY:
System.out.println(9);break;case WEDNESDAY:
}
">

예전에는 이렇게 써야 했던 Switch문을 아래와 같은 형식으로도 쓸 수 있게 되었다.

이외에 가비지 컬렉터 개선, 마이크로 벤치마크 툴 추가, 성능 개선의 변경점이 있다.

4.16. Java SE 13


2019년 9월 17일 공개. java 12에서의 스위치 개선을 이어 yield 라는 예약어가 추가되었다.
var a = switch (day) {
    case MONDAY, FRIDAY, SUNDAY -> yield 6;
    case TUESDAY                -> yield 7;
    case THURSDAY, SATURDAY     -> yield 8;
    case WEDNESDAY              -> yield 9;
};

5. 문법


파일:나무위키상세내용.png   자세한 내용은 Java/문법 문서를 참고하십시오.


6. C, C++와의 비교


기존의 C에 객체지향 기능을 추가하다 보니, 언어의 사용에 있어 저수준과 고수준의 개념이 충돌하는 부분이 많았던 C++과는 다르게 아예 처음부터 객체지향 언어로 개발되었다. 다만 많은 사람들이 착각하는 부분인데, Java는 엄밀히 말하면 완벽한 객체지향 언어가 아니다. 원시(Primitive) 타입은 객체로 취급하지 않기 때문. 모든 것을 객체로 취급하는 언어를 순수 객체지향(Pure object-oriented)이라 하며, 이를 지원하는 언어로는 Python, Ruby, Smalltalk등이 있다.
C, C++, Java의 차이점을 말하자면, C는 포인터 등을 활용한 저수준 시스템 프로그래밍에[8] 강점을 가지며, C++는 C의 그런 강점을 거의 그대로 가져오면서 거기에 객체 지향이나 일반화 프로그래밍과 같은 멀티 패러다임을 지원하고자 하는 시도[9]에서 탄생하였다. 이렇게 고수준과 저수준의 개념을 모두 포함하려다 보니 다른 언어에 비해서 상당히 복잡해졌다. 게다가 최신 프로그래밍 환경을 지원하기 위해 지속적으로 개정되고 있는 모던 C++는 변화의 폭이 커서, 새로운 기능을 전부 제대로 다룰 줄 아는 프로그래머는 비교적 적다는 평이 널리 받아들여지고 있다. 이와는 대조적으로 Java는 C++의 초기 발전 방향과는 달리 안정성을 위해 포인터라는 강력한 로우 레벨 기능을 포기하고 가비지 컬렉터를 내장하며, 고수준의 객체지향 부분을 잘 구현하는 것에 집중하는 방식으로 언어가 복잡해지는 것을 방지하였다.
수많은 C계열 프로그래밍 언어가 그렇듯이, C/C++와 비슷한 문법 구조를 가지고 있다. 그러면서도 Java가 C/C++보다 훨씬 더 널리 쓰이는 분야가 많이 존재한다. 웹 애플리케이션 백엔드와 안드로이드 앱이 대표적인 사례. 또한 아파치 소프트웨어 재단에서 개발하는 수많은 오픈 소스 소프트웨어들이 Java로 만들어졌다. 하지만 Java 프로그램에서 속도가 매우 중요시되는 부분은 따로 떼어서 C/C++로 개발하기도 한다. 제작하고자 하는 프로그램의 생산성과 성능을 적절히 고려하여 선택하는 것이 현명하다.

7. 특징


Java의 가장 큰 특징은 플랫폼에 독립적인 언어라는 점이다. 소스 코드를 기계어로 직접 컴파일하여 링크하는 C/C++의 컴파일러와 달리 자바 컴파일러는 바이트코드인 클래스 파일(.class)을 생성하고, 이 파일의 바이트코드를 읽은 뒤 기계어로 바꾸어 실행하는 것은 Java Virtual Machine(JVM)이다.
예를 들어 C 계열 언어들은 윈도우에서 빌드한 프로그램을 그대로 리눅스macOS에서 실행하려 하면 일반적으로 오류가 나지만 Java로 작성 된 프로그램은 플랫폼에 맞는 JVM만 설치되어 있다면 문제 없이 동작한다. 이는 Java 코드 자체가 플랫폼이 아닌 가상머신에 종속적이라는 점, 그리고 프로그램 실행의 주체가 운영체제가 아닌 JVM이라는 점 때문이며 이러한 점을 통틀어 Java는 플랫폼 종속성이 낮은 언어라고 표현한다.
JVM 기반의 프로젝트에서는 하나의 언어만을 고집하지 않는다. 함수형 언어가 유리(최근 유행하는 빅데이터 등)한 부분은 Scala로 작업하며, 견고한 인터페이스와 대규모 통합이 필요한 곳은 Java로 작업한 뒤 이들을 서로 합쳐서 운영하는 게 가능하다. (Java에서 만든 객체를 Scala에서 그대로 사용할 수 있다.) 안드로이드 쪽에서는 크리티컬하지 않은 부분부터 Kotlin으로 코드를 교체하는 경우도 많아지고 있다.
실제 현업에서는 Java를 비롯한 여러가지 인기 언어가 자주 사용되므로 장단점을 잘 알아두는게 좋다. 다른 언어에 대해 맹목적으로 찬양/비판하는 태도보다는 환경이나 주어진 작업의 특성에 따라 적합한 언어를 선택할 수 있는 노하우가 필요하다.
PC에서 자바 런너 업데이트를 할 때 뜨는 창에 '30억개 기기에서 Java 사용'이라는 문구가 나온다.

7.1. 장점



7.1.1. 수많은 개발자와 레퍼런스


나온지도 오래 되었고, 다른 최신 언어에 비해서 여러가지로 욕을 먹는 Java가 그래도 항상 상위권을 유지하는 이유는 바로 수많은 개발자와 레퍼런스를 보유하고 있다는 점이다. 타 언어를 전문적으로 사용하는 개발자들도 Java 정도는 할 줄 안다고 할 정도로 배우기 쉽고 대중적이다. 대중적인 언어라서 참고 자료나 오픈 소스가 많고, 그러한 자료들을 바탕으로 수많은 대형 프로젝트들이 진행되어왔기 때문에 많은 부분에서 안정성이 입증되었다. 즉, 안정적인 인력풀을 유지하면서, 알려진 위협을 제거하고 운영 노하우를 극대화시킬 수 있는 검증된 언어라는 것.
하지만 검증되었다는 건 반대로 말하자면 오래되었다는 뜻이기도 하다. 최근에는 Java에 대한 개발자들의 불만이 누적된 탓인지 JavaScriptPython 같은 다른 언어를 선호하는 경향이 강하다. 국내에서는 전자정부표준프레임워크의 존재 때문인지 아직도 신규 프로젝트의 주 언어로 Java를 선호하는 경향이 강하지만, 세계적으로는 신규 프로젝트에서 Java를 선호하는 비중은 높지 않은 편이다.[10]
국내에서의 언어 외적인 장점은 바로 개발자 구인의 용이성이다. 국내에서 Java 개발자의 인력풀이 타 언어보다 더 큰 이유는 앞서 말했던 전자정부표준프레임워크의 존재 때문이기도 하고, 그 때문에 Java 개발자를 정부에서 국비지원으로 대거 양성했기 때문이기도 하다. 상당수의 정부 하청 프로젝트가 Java와 전자정부표준프레임워크로 개발되었다. 이런 이유 때문에 굳이 정부 프로젝트가 아니더라도 Java 개발자를 구인하기 쉬웠고, 더 많은 프로젝트가 Java로 개발되었다. 그리고 그렇게 만들어진 프로젝트를 유지보수하기 위해서 더 많은 Java 개발자가 필요하므로 더 많은 인력이 유입되는 일종의 선순환 효과가 있다. 취업 사이트를 확인해보면 다른 분야보다 Java 개발자를 구인하는 경우가 많은 건 이 때문이다. 사람을 구하기도 쉽고, 직장을 구하기도 쉽다. 영어권 국가에 비해 공유되는 자료가 비교적 부족한 국내에서도 JSP, Spring에 관한 자료만큼은 높은 퀄리티를 보여주는 경우가 많다. 그러나 반대로 할 줄 아는 사람들이 너무 많아 경쟁력이 떨어지는 면도 있다. 몇몇 회사에서는 Java 개발자에 대한 보수나 기타 대우가 좋지 않은 경우도 많다. 개발자가 많다는 것은 취업이나 구인 면에서는 장점이지만, 다른 측면에서는 단점이 될 수도 있다.
기존의 Java로 만들어진 프로젝트를 재사용하기 위해 Java가 쓰인 대표적인 사례는 카카오뱅크가 있다. 한정된 시간 때문에 Java 코드를 재사용해야 했던 경우다.#

7.1.2. 비교적 높은 생산성


오늘날 프로그램의 덩치와 다루는 것들이 크고 복잡해지면서 생산성과 퍼포먼스 문제가 생기게 되었는데, C/C++ 같은 언어는 생산성이 너무 떨어지고 관리도 힘들어서 프로그램이 커지면 커질수록 작업이 힘들어지게 된다. 그리고 아무리 컴퓨터 하드웨어가 발달한다고 해도 성능이 더 좋아지면 점점 더 복잡한 것을 다루고, 그것이 새로운 표준이 되면서 하드웨어의 속도 향상이 무색해지기 때문이다.
그런데, 그 와중에 나타난 게 바로 Java다. C/C++와 비슷한 문법으로 진입 장벽도 낮고, 객체 지향을 적극적으로 사용하며, 로우 레벨 작업들을 자동으로 처리해 주는 하이 레벨 언어이면서, 퍼포먼스도 다른 하이 레벨 언어들에 비해 빠른 편이다. 거기에 호환성까지! 등장하자마자 순식간에 대세가 된 것도 무리는 아니다. 객체지향 등이 일반화되면서 프로그래밍 환경도 점차 중요한 개념을 언어 안으로 숨기고 사용자에겐 그것을 간편히 다룰 수 있는 인터페이스만 제공하는 추세로 흘러가고 있는데, Java는 여기에 정확하게 부합하는 언어였던 것. 다만 최근 인기를 끌고 있는 Python이나 Go 같은 언어에 비하면 Java의 생산성은 상대적으로 낮은 편이다.

7.1.3. 기기 호환성


장점으로는, 해당 운영체제Java Virtual Machine(JVM)을 설치하면 Java로 만든 프로그램은 어떤 컴퓨터에서도 완벽히 똑같이 동작한다. 가상머신이 각각의 운영체제에 맞춰서 결과적으로 완벽히 똑같이 돌아갈 수 있도록 제작되는 덕. 가상머신 없는 운영체제라면 아예 Java 프로그램을 사용하지 못하겠지만, 썬 마이크로시스템즈는 주요 OS용의 가상 머신을 발표하고 있고, IBM, 휴렛팩커드 등의 회사는 직접 자사 운영체제용 JDK/JVM을 제작하여 발표하며, 이들과 상관없이 독립적으로 특화된 성능향상 기능을 가진 JVM을 만들어서 발표하는 회사도 존재한다. 그래서 이 부분은 보통 단점으로 꼽히지 않는다. 오히려 여러 운영체제에 발 벌리는 업체라면 윈도우용, 맥용 등을 따로 제작할 필요 따위가 없이 "그냥 하나 만들면 끝!"이라고 Java 초창기에 홍보되었다.
그러나 다른 크로스 플랫폼 언어들과 마찬가지로 각 플랫폼마다 미묘하게 기능이나 작동에 차이가 있는 부분이 결국은 존재하기 때문에, 이러한 부분을 고려하지 않고 작성된 프로그램을 그대로 다른 데에서 돌릴 때에 문제가 발생할 가능성이 존재한다. JVM의 장점은 그나마 이런 부분들이 다른 언어에 비해서 매우 적은 편이라는 점이다. 이런 경우, 대부분 크로스 플랫폼으로 작성된 코드가 그러하듯 타겟 플랫폼을 인지하여 특정 플랫폼에서는 다르게 동작하게 하는 식으로 코딩을 하게 된다. 주로 java.nio 패키지에 속한 API 에서 이러한 경우를 발견할 수 있으며, OS X 에서만 일부 특이하게 동작하는 MIDI 관련 API 또한 이러한 경우에 속한다. Java의 모토는 Write once, run everywhere(한 번 짜서, 어디서나 실행하라)인데 프로그래머들은 이를 비꼬아 Write once, test everywhere(한 번 짜서, 모든 플랫폼에서 테스트하라)라고 말하곤 한다.
C나 C++에서도 크로스 플랫폼 형태로 소스코드를 작성하는 것이 가능하기는 했지만, 개발자가 타겟 플랫폼과 해당 플랫폼용 바이너리 코드를 생성하는 컴파일러에 대해서 잘 이해하고 나서 #define, #if 등 전처리기를 써서 각 타겟 플랫폼에 맞게 동작하도록 코드를 직접 작성해줘야 했다. 이와 달리, Java는 단일 소스코드를 컴파일하여 생성된 바이트코드 클래스 파일을 JVM이 존재하는 환경이라면 어디서나 (대부분은) 추가 컴파일이나 수정작업 없이 그대로 똑같이 실행할 수 있다는 점이 차이점이다. 기업 입장에서 컴파일된 바이너리가 크로스 플랫폼을 보장해주는 Java는 매력적인 언어였다.
JVM 위에서 구동 가능한 언어는 Java 외에도 존재하는데, 이 언어들을 사용하면 Java와 동일한 수준의 호환성을 구현할 수 있다.[11] 구글에서 안드로이드 개발의 차세대 언어로 밀어주는 Kotlin이 대표적인 케이스다. Java의 개발 주체인 Oracle에서 개발하는 GraalVM이라는 한국어에서 자주 쓰이는 어떤 욕설과 관계 없다 프레임워크도 있다. 이 프레임워크에서는 C++도 JVM 위에서 실행하는 것이 가능하다.
요즘은 하드웨어와 밀접하게 연동되어야 하는 프로그램이 아니라면, 또는 메인 로직은 서버에서 돌아가고 클라이언트에서는 인터페이스만 제공해주면 되는 경우라면 JVM보다는 웹 기술을 이용한 방식이 더 주목받고 있다. 아예 어디에서나 동일한 동작을 보증하는 웹 사이트의 형식으로 서비스를 하거나, 네이티브 앱의 UI가 필요한 경우에는 React Native 또는 Flutter 등의 프레임워크를 이용하는 경우가 많다. 전자는 웹 개발에서 주로 쓰이는 JavaScript를 이용하고, 후자는 구글에서 웹 프로그래밍의 용도로 만든 Dart라는 언어를 이용한다. 이 외에 게임이나 3D 렌더링이 필요한 앱의 경우 게임 엔진을 이용한다.

7.1.4. 안정성


다른 언어에 비해 높은 안정성을 꼽고 있다. 우선 C나 C++에 안정성 문제가 제기되는 포인터 연산자[12] 및 메모리 직접접근 함수들을 지원하지 않는다. 여기에 C++과는 다르게 다중 상속을 허용하지 않는다. 이는 객체지향의 특성 중 하나인 '상속'의 자유도를 확 떨어트리는 것이기에 언뜻 보기에는 객체지향적 관점에 위배되는 것처럼 보일 수 있으나, 반대로 오히려 이게 더 객체지향적이라고 볼 수도 있다. 객체지향의 목적 자체가 재사용을 통한 생산성의 향상과 관리 상의 이점인데, 다중 상속은 잘못 사용할 시 극도로 복잡하게 꼬인 프로그램을 만들 위험성을 갖고 있다. 물론 코드 관리의 측면에서도 다중상속에 의해 발생하는 문제는 좋지 않다. 수준 높은 프로그래머라면 이 문제도 잘 해결할 수 있지만, Java는 아예 미연에 방지하기 위해 다중상속을 언어 스펙에서 제거하는 방법을 택했다.[13]
메모리를 대용량으로 사용하는 프로그램에서 상대적으로 C/C++보다 안정적인 모습을 보일 때도 있는데, 이런 경우에 JVM이 시작될 때 필요한 메모리를 먼저 통으로 잡아버리기 때문이다. 메모리를 자주 할당하거나 해제하는 C/C++ 프로그램은 오히려 Java보다 성능이 느릴 수 있다. 다만 이는 메모리 할당자 없이 매번 힙 영역 메모리를 운영체제로부터 할당받는 경우에 해당하는 말이고[14], 실제 C/C++ 프로젝트에서는 jemalloc 등 메모리 할당자 라이브러리를 사용하거나 메모리 할당자를 직접 구현하여 이런 문제를 해결하는 것이 일반적이다.

7.1.5. 소스 코드 가독성


고급 프로그래밍 언어가 만들어진 첫째 목적은 '좀 더 인간 친화적인' 코드의 작성을 돕는 데 있다. 기계어어셈블리어로 진화하고 그것이 C언어로 진화한 배경에는 '사람이 더 쉽게 읽고 이해할 수 있는 코드'가 있다. Java는 동시기에 발표된 다른 언어에 비해 코드가 명료하고 가독성이 뛰어났다. C++은 어려운 문법으로 인해 코드가 이리저리 꼬이는 경우가 많고, 특히 연산자 오버로딩과 템플릿 기반의 일반화 프로그래밍(Generic Programming) 개념이 코드 난독화에 결정타를 날렸는데 Java는 연산자 오버로딩을 배제하고 오로지 메소드를 통해서만 객체의 조작을 허용함으로써 코드의 일관성을 지켜냈다.[15]
C++ 템플릿 프로그래밍의 주 사용 용도인 일반화 프로그래밍도 제네릭이라는 더 쉬운 개념을 도입해서(Java 5부터 지원) 코드의 가독성을 해치지 않고 일반화 프로그래밍을 성공적으로 도입했다.[16][17] 키워드에 약어 사용을 자제한 점도 코드 가독성 상승에 기여했다.
하지만 Java가 로우레벨 언어인 C나 C++보다 읽기 쉽다고 해서[18] 일반적인 시각에서 보기에 가독성이 좋은 언어는 아닌데, 그 이유는 단점 항목에서 언급된 소스 코드의 길이 문제 때문이다. 일반적으로 개발자들 사이에서 Java가 가독성이 좋은 언어로 통용되지는 않는다. Kotlin이 구글에 의해 Java의 대체 언어로 선정된 이유는 오라클과의 저작권 관련 분쟁 때문도 있지만, Java 문법의 장황함과 가독성의 불편함에서 기인한 것이기도 하다. 비유를 하자면 Java는 입문 장벽을 낮춘 대신 이런저런 제약을 울타리처럼 둘러친 언어이고, C/C++는 프로그래머에게 자유도를 부여한 대신 입문 장벽을 높여버린 언어라고 할 수 있다.

7.2. 단점



7.2.1. 속도 문제


여기서 잠시 유의할 점은, 느리다는 내용은 대부분 C/C++, Pascal, Fortran 같은 네이티브 바이너리 코드를 만드는 언어와 비교했을 때의 이야기이다. Java가 C/C++보다 2~3배 느리다고 하지만 다른 고수준 언어들에 비해서는 그리 떨어지지 않는다.[19] 특히 인터프리터/스크립트 언어는 구조적으로 Java에 비해서도 훨씬 느리다는 것을 기억하자. 예를 들어 요즘 인기있는 Python은 C보다 수십 배 느리다. 그나마 빠르다고 하는 JavaScript도 Java에 비해서 2배 정도 느리다.
또한 속도 관련 문제는 하드웨어의 성능이 점점 좋아지고 메모리 가격이 떨어지면서 희석되고 있다. 처음 Java가 나왔을 때인 1995년만 하더라도, 느린 성능 때문에 그다지 많이 쓰이지는 않을 것이라고 예상했지만 현재 Java가 가장 많이 사용되는 곳 중 하나는 안정성과 일정 수준 이상의 성능이 요구되는 서버다. Java가 네이티브 코드보다 느리지만 대부분의 상황에서는 큰 문제가 되지 않는다.

7.2.1.1. JVM 로딩 속도 문제

Java의 심각한 단점 중 하나는, 실행하는 과정에서 Java Virtual Machine반드시 완벽하게 로딩되어야 하기 때문에 프로그램의 초기 시작 시간이 완전한 이진 코드로 컴파일된 프로그램을 실행하는 것에 비해 오래 걸리는 것이다. 단적인 예로, 아무것도 안하고 콘솔 화면에 달랑 "Hello, World!" 라고 찍기만 하는 프로그램이 실행되는 데에도 thread가 10개 쯤 뜬다. 특히 그 프로그램에 AWT, Swing, SQL 같이 불필요한 기능을 끌어들이는 것은 매우 심각한 문제이다. 이 문제는 런타임 자체가 아직 모듈화되지 않았다는 점에서 기인한다.
하지만 요즘 같은 고사양 컴퓨터에서는 아주 많은 라이브러리를 끌어오는 것이 아니라면 체감상 차이는 크게 나지 않는다. 또한 Java 9부터는 드디어 런타임 라이브러리를 모듈화하고 있으므로, 필요한 모듈만 끌어서 프로그램을 짤 수 있다.

7.2.1.2. 가상 머신 바이트코드 실행 속도 문제

C/C++, Pascal, Fortran과 같은 언어와 달리, Java는 바이트코드로 된 프로그램을 실행하기 위해 운영체제와 프로그램 사이에 JVM이라는 두꺼운 계층이 하나 더 자리잡게 된다. 그리고 바이트코드는 실시간으로 각 타겟 플랫폼용 기계어로 번역되어 실행된다. 이로 인해 네이티브 바이너리 코드를 출력하는 언어와 비교하여 실행속도와 성능에 일정 부분 손실이 발생할 수밖에 없다. AWT, Swing 같은 GUI 라이브러리를 사용할 때도 심각하게 느린 것을 체감할 수 있다. 이런 문제점을 썬 마이크로시스템즈도 곧 깨달았고, 최초 발표에서 2년 후인 1998년부터 JIT 컴파일러를 JVM에 내장하여 성능이 상당 부분 개선되었다. 하지만, 그만큼 메모리가 뒷받침해줘야 한다. 현재는 보통 같은 기능/알고리즘을 실행하는 데 C++보다 2~3배 정도의 시간이 더 필요하다고 알려져 있다. 이 부분은 꽤 초기부터 지속적으로 개선되어 왔기 때문에 현재 실행속도 자체에 대한 이슈는 예전에 비해 많이 줄어든 편이다.
이 문제는 Java 9에서 '선행 컴파일'이라는 이름으로 개선될 예정이다. JIT 컴파일로 실행과 동시에 컴파일을 하는 게 아니라 기존의 정적 컴파일처럼 바이트코드를 미리 기계어로 번역하면, 컴파일 속도는 다소 느려지지만 실행 속도는 빨라지게 된다. 물론 컴파일 한 번으로 여러 플랫폼에서 동일하게 실행시키는 건 불가능해진다.

7.2.1.3. 가비지 컬렉션에 의한 실행 지연 문제

가비지 컬렉션에 의한 메모리 프리징 현상[20]이 초반부터 지속적으로 Java를 괴롭혔다. 멀쩡하게 동작해야 할 프로그램이 순간적으로 뚝 뚝 끊기는 듯한 현상이 발생하는 것. 오늘날 Java의 문제는 바이트코드 변환으로 인한 속도 저하보다 이 가비지 컬렉션의 영향이 더 크다고 할 수 있다. 이러한 문제점은 가비지 컬렉션을 지원하는 다른 프로그래밍 언어들도 마찬가지이긴 하지만 실행속도와 함께 Java 초기부터 꾸준히 문제로 꼽혀온 것으로, 버전이 올라갈 때마다 다양하게 개선되어 왔다.
Java 8부터는 메모리 누수를 일으키던 메소드 영역의 PermGen Area를 제거하여 static 인스턴스와 리터럴 문자열도 GC의 대상이 되도록 바뀌었으며, 클래스, 메소드, 배열의 메타 정보는 동적 리사이징이 가능한 Metaspace로 이동시켜 시스템 힙 영역에 저장된다. 덕분에 JVM 힙 영역의 공간이 늘어나고 PermGen Area를 스캔/삭제할 필요가 없어져 GC의 성능이 대폭 향상되었다.

7.2.2. 불편한 예외 처리


다른 객체지향 언어들처럼, Java 역시 try~catch문으로 대표되는 예외 처리를 할 수 있다. 대부분의 언어에서 차용하고 있는 좋은 기능이지만... 유독 Java는 다른 언어와는 달리 프로그래머의 검사가 필요한 예외(Exception을 직접 상속하는 예외 클래스)가 등장한다면 무조건 프로그래머가 선언을 해줘야 한다. 그렇지 않으면 컴파일조차 거부한다. 원래 의도는 철저한 예외 처리를 하니까 만약에 발생할 수 있는 모든 상황에 안정성을 확보할 수 있겠지...였으나, 결국 대부분의 경우엔 귀찮다는 이유로, 가장 일반적인 예외인 Exception 더 막나가면 Throwable 하나만 써서 넘어가버리고[21] 폭탄 돌리듯 넘기기만 하거나(예외 던지기만 하고 try~catch 안하면 메소드를 돌고 돌다가 콰광!), 예외 나든 말든 무시해 버리는 경우가 가장 흔하다.[22] 이런 코드가 너무 흔해 빠진 나머지 이딴 식으로 쓸 거면 왜 넣었냐고 까는 사람도 많다. 그런데 선언이 필요없는, 검사 안하는 예외도 Java에 많다(...).[23] 그리고 C++이나 C# 같이 예외가 있는 언어라도 Java처럼 예외를 쓰는 경우는 별로 없다. 두 언어는 모든 예외가 검사 안하는 예외이다. 사실 예외 처리를 한다는 것은 귀차니즘과 견고함을 맞바꾸는 일인데, 안할 사람은 문법으로 강제해도 안한다는 것을 보여준다.
대부분의 다른 언어에서는 원하는 에러만 try-catch문으로 뽑아내고 그렇지 않은 경우에는 그냥 아무 처리를 해주지 않아도 된다. 이러한 언어를 접하던 사람이 Java를 접하면 그 특유의 경직된 예외처리에 불편해하기도 한다. 오히려 명시적으로 예외처리를 할 수 없는 경우도 존재하는데, 인터페이스를 상속받을 때 인터페이스에 선언된 예외가 아니면 구현 클래스에서 그 예외를 던질 수 없다! 특히, Java에서 제공하는 Iterator 인터페이스에는 throws 선언 따위는 없기 때문에 Iterator를 구현받았을 때 명시적으로 예외를 던질 수 없다. 이 상황을 해결하려면 RuntimeException 계열을 쓸 수밖에 없는 상황이 펼쳐진다.
다만, 상기의 내용은 실무적 접근에 의한 내용이고, 실제로는 이는 장점으로도 취급되기도 한다. Assert문을 자유자재로 쓰면서 예외처리를 하거나 코딩과 동시에 발생할 수 있는 각종 예외들을 인지하고 처리해주는 걸 잊어먹는 경우에 대한 대처가 가능하다.[24]

7.2.3. 소스 코드 길이


Java는 소스 코드의 길이가 다른 언어에 비해 상당히 긴 편이다. 같은 기능을 하는 코드를 짠다고 했을 때 다른 언어에 비해 타이핑해야 할 양이 많다. 구체적으로 말하자면 일명 Boilerplate라고 부르는, 기본적인 구조를 짜기 위해서 무조건 의무적으로 작성해 주어야만 하는 서식과 코드의 분량이 많다.
인터프리터 언어에서는 puts("Hello") 정도로 끝났을 일을 Java에서는
package wiki.namu.test;

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello");
    }
}
이만큼을 써야 한다. 같은 일을 하는 C언어 코드는
#include 

void main() { 
    puts("Hello");
}
파이썬의 경우
print("Hello")
위키책에 있는 Hello World 프로그램의 목록이나, 나무위키 내의 프로그래밍 언어/예제 문서를 보면 하이레벨 언어 중에서는 코드량이 긴 편인 걸 알 수 있다.
오죽하면 이런 포스트가 만들어질까. 물론 이건 Java의 문제가 아니고 마세라티 문제[25]라고 알려진 프로그래머의 과욕이 부른 참상이지만 코드에 유연성을 조금 추가하기 위해 써 넣어야 할 코드의 길이가 기하급수로 증가한다는 하나의 예시로 볼 수 있다. 참고로 저 포스트의 5년차 코드는 Spring의 패러디다. Java 이후에 나온 차세대 언어들은 같은 수준의 유연성을 확보하기 위해 들여야 할 노력의 양이 훨씬 적다.
이렇게 의도적인 장황함(verbosity)을 추구하는 언어 설계와 커뮤니티의 문화가 아이러니하게도 위에서 언급한 장점이 무색하게 가독성을 저해하는 요인이 되기도 한다. 같은 기능을 하더라도 수십 줄의 보일러플레이트 코드를 가지는 Java 코드보다 다른 언어의 코드가 보통은 더 읽기 쉽기 때문.
게다가 다른 하이레벨 언어(C#, Python, Ruby 등)에 비해 문법적 설탕(Syntactic sugar)[26]이 적어 이쪽에서 넘어오면 꽤 불편해하는 편. 하지만 최근 Java 8로 넘어오면서 람다 표현식, 스트림[27] 등을 지원하는 식으로 문법적 편리함을 늘려가는 추세다. 이 흐름은 다음 Java 9에서 더욱 강화될 것으로 보는 추세.[28]
그러나 무조건 타이핑의 양이 많다고 해서 나쁜 것만 있는 것이 아니다. 일단 Java는 명색이 클래스 지향적이기 때문에 어쩔 수 없는 부분이고, 커다란 프로젝트 단위에서 봤을 땐 오히려 클래스와 메소드, 변수의 소속이 확실하기 때문에 코드를 금방 파악할 수 있다. 축약어의 사용을 최대한 자제하는 방향으로 만들었기 때문에 그렇다.[29] Python이나 JavaScript 같은 동적 타입 언어들은 소규모 프로젝트에는 좋겠지만 대형 프로젝트에서는 불편할 수도 있다.
JetBrains에서 개발한 Kotlin은 바로 이 Java의 언어적 불편함을 최소화하려고 나온 새 프로그래밍 언어이며, 카카오에서도 카카오톡 메시징 서버에 Kotlin을 도입하는 등(#) Java를 Kotlin으로 대체하려는 움직임이 조금씩 나타나고 있다.

7.2.4. 언어적 불편함



7.2.4.1. 명사형 생각을 강제

Java는 모든 동작이 객체 상위에서 이루어지게 함으로써 명사형으로 생각하는 것을 강제한다. 그 결과로 Java에는 전역 함수가 없고 모든 함수는 어떤 클래스에 종속되어있다. 이 때문에 기능적인 부분을 작성하는데 자잘한 클래스들을 작성해야 한다는 불편함이 있다.
이런 명사 중심적 생각은 확실히 많은 경우 편리하나 동사 중심으로 생각해야 하는 상황도 생각보다 흔하다는 게 문제. 예를 들어서, 퀵소트를 Java에서 엄격하게 의도된 대로 짜려면 quickSort(array)라는 함수 대신 QuickSorter라는 객체의 생성자에 배열을 넣고, 그 생성자를 참조하는 참조변수를 이용해 run()을 호출하여 동작시켜야 하는 것이다.[30]
디자인 패턴을 사용해서 어느 정도 동사형 사고방식으로 코드를 작성할 수 있긴 하다. 디자인 패턴에서 핵심적 지위를 차지하는 인터페이스라는 놈을 사용하면 상당히 동사적인 관점으로 객체를 다룰 수 있다. Java의 리플렉션 API를 사용하는 방법도 있고. 하지만 애초에 언어가 생겨먹은 것 자체가 명사 기준으로 생각하게 디자인된 건 사실이다. Java의 근간을 이루는 표준 java.lang 클래스와 java.util 클래스를 동사형 사고방식으로 재작성하기 전에는 힘들다. 이 재작성 삽질은 이미 Scala에서 해 놨으므로 Java의 이러한 특징이 싫다면 Scala를 쓰면 된다.

7.2.4.2. 클로저 미지원

명사형 생각을 강제한다는 것의 연장선. 버전 7 이하의 Java는 함수를 일급 객체로 취급하지 않는다. 어떤 '동작'을 넘겨야 할 때는 그 동작을 추상화한 인터페이스를 만들고, 그것을 클래스로 구현한 뒤, 객체를 파라미터로 넘겨야 한다. 반면에 클로저를 지원하는 언어는 그냥 함수를 파라미터로 넘기면 된다.
Java의 수많은 디자인 패턴들은 이 클로저 미지원 문제 때문에 만들어졌다. Java라는 언어가 설계될 당시에는 클로저라는 개념 자체가 LISP, Haskell, ML 등의 언어을 사용하거나 프로그래밍 언어를 연구하는 사람들이나 아는 몹시 마이너한 개념이었기 때문에 동시기에 만들어진 다른 많은 프로그래밍 언어들도 클로저를 지원하고 있지는 않았다. 따라서 설계 결함이라고 부를 수는 없고 현대에 들어서 단점으로 부각되기 시작했다는 편이 더 적절하다.
Java 8에서는 람다 표현식을 지원함과 더불어 메소드 참조라는 방식(this::add)을 통해 함수를 다른 함수의 파라미터로 넘길 수 있게 되었다. 이러한 함수 파라미터는 Functional Interface를 이용하여 선언하는데, Functional Interface는 수십여 종이 있으며 인자가 복수개인 것도 당연히 있고, 하나의 추상 메소드를 가진 인터페이스를 새로 만들어서 써도 된다. 다만 자바의 람다식은 바깥에 있는 변수를 참조하려면 그 변수가 final이거나 final을 붙여도 문제가 없는 변수들 뿐이다. 따라서 람다식이 주위에 있는 변수를 '저장'할 수는 있으나 그것의 값을 바꿀수는 없다.
java.util.function에 있는 대표적인 함수형 인터페이스 (Functional Interface)와 그에 대응하는 추상 메소드 몇개를 나열하자면 다음과 같다.
  • Predicate ⇒ boolean test(T)
  • Consumer ⇒ void accept(T)
  • Supplier ⇒ T get()
  • Function ⇒ U apply(T)
  • BiFunction ⇒ R apply(T, U)

8. 개발환경, JVM 언어



8.1. 개발환경


Java에 특정한 라이브러리를 가미해서 웹에서 돌릴 수 있게 한 것이 Java Applet이다. 애플릿 특유의 제약으로 인해 ActiveX보다는 훨씬 안전하다는 이유로 물 건너에서는 인터넷 뱅킹이나 결제용도로 사용하기도 한다. 근데 상대적으로 안전하다는 것일 뿐, 애플릿을 사용한 결제시스템도 툭하면 뚫려서 문제가 발생하곤 한다(…). 더군다나 아이폰안드로이드에서는 되지 않는다. 게다가 크롬과 파이어폭스 등의 브라우저들이 NPAPI 지원 중단 선언을 하고, Java 9부터 애플릿의 개발이 중단되면서 결국 수명이 끝나게 되었다. 이 문제들은 자바 애플릿만이 아닌 다른 대부분의 리치 인터넷 애플리케이션들의 문제점이기도 하다.
웹 애플리케이션 제작을 위해 Java 언어를 사용하는 규격으로 Java 서블릿과 JSP(Java 서버 페이지)가 있다.[31] 주로 기업에서 사용한다. 개인 웹호스팅에서는 이를 지원하는 경우는 많지 않다. 그러나 최근 Java를 지원하는 여러 클라우드 컴퓨팅 서비스가 싼 가격에 등장하고 있고, Java 뿐만이 아닌 JVM 언어를 이러한 환경에서 구동하는 사례가 늘고 있다.
Java Development Kit(Java 개발 도구)을 설치하면 javac라는 컴파일러가 제공된다. 하지만 통합 개발 환경은 제공해 주지 않기 때문에, 반드시 별도의 개발용 프로그램을 써야 한다. 대표적으로 이클립스, 넷빈즈, IntelliJ IDEA 등이 있다. 만약 이것들을 안 쓰겠다고 한다면, 당신에게는 메모장과 javac.exe가 있을 뿐이다. 그리고 Java는 IDE 없이 타이핑만으로 짜기엔 굉장히 불편한 언어라는 것을 명심하자.[32] 실전 Java 개발을 할 때 프로젝트에 필요한 라이브러리 관리나 프로젝트 결과물 배포 등 프로젝트 빌드 관리를 위한 도구로는 아파치 소프트웨어 재단에서 만든 Ant와 Maven, 그 중에서도 Maven이 많이 사용되고 있다. 최근에는 이 두 가지의 단점을 보완한 Gradle이 각광을 받고 있으나 아직 Maven보다 많이 쓰이지는 않고 있다.
TDD 개발을 위한 방법으로는 Jenkins를 통한 CI 관리, SonarQube를 통한 코드 분석, Maven을 통한 빌드 관리, JaCoCo를 통한 Code Coverage 관리 등이 있다.

8.2. JVM 언어


이외에 Java와 똑같이 Java 바이트 코드를 생성하지만 언어 규격이 다른 ScalaClojure라는 언어들도 있다. Scala는 'Scalable Language'에서 따왔는데, Java와 비슷한 부분이 많으며 Java API를 그대로 가져다 쓸 수도 있다. 또한, syntactic sugar가 많고 함수형 프로그래밍의 여러 가지 요소들을 가져와서 Java에 비해 생산성도 높다. 일례로 일일히 타입을 명시하지 않고 var x === 1.5와 같이 넣으면 알아서 float 형으로 추론해준다.[33] 또, switch-case의 확장판이라 할 수 있는 패턴 매칭을 지원하며 클로저도 지원된다. 단점으로는 이런 고수준-고생산성의 언어에서 많이 볼 수 있듯이 같은 Java 코드에 비해 약간 느리다. Clojure는 Java 플랫폼에서 동작하는 LISP의 방언으로 설계되었으며 Common Lisp와 Scheme과 함께 주요 LISP 방언 중 하나로 꼽힌다. 이 언어도 마찬가지로 Java API를 가져다 쓸 수 있다.
Java 6부터 Scripting API라는 것이 추가되었다. JVM 언어 구현체에서 javax.scripting 관련 API를 제공하면 Java 코드에서 동적으로 인터프리터를 생성하고 연동하여 사용할 수 있게 해주는 표준 API이다.

8.2.1. 유명한 JVM 언어 목록


아래에 나열된 언어들이 유명하며, Common LISP, Scheme, Pascal 등 여러 다양한 언어들이 구현되어 있다.
  • Clojure
  • Groovy: Java에 Python, Ruby, SmallTalk 등의 특징을 버무린 동적 타입 언어. 2003년에 등장했다.
  • JRuby: Ruby의 대부분을 Java로 구현한 언어 구현체. 역시 Java와 호환된다.
  • Jython: 파이썬의 Java 구현체. JVM 위에서 동작하며, 따라서 Python 모듈과 함께 Java 클래스, JAR 사용이 가능하다. 참고로 로고는 Java의 커피 컨셉과 Python의 뱀 컨셉을 섞어서 커피잔에서 이 연기처럼 피어나오는 로고다(...)
  • Kotlin : IntelliJ IDEA를 만든 JetBrains에서 개발한 JVM 언어. Google I/O 2017에서 안드로이드의 공식 언어로 지정되었다.[34]
  • Rhino: JVM으로 돌아가는 JavaScript 엔진으로, 모질라 재단이 100% Java로 개발했다. JavaScript와 Java의 API를 동시에 사용해 개발할 수 있다. Java 7 에 내장되어 있다.
  • Nashorn: 또 다른 JVM 위에서 돌아가는 JavaScript 엔진이다. Java 8과 함께 등장했다. 참고로 Nashorn 은 Rhino(코뿔소)의 독일어다.
  • Scala

8.3. 혼동하기 쉬운 것들


JavaScript는 Java와는 아무 상관도 없다. 넷스케이프사에서 Mocha, LiveScript로 개발하던 스크립트 언어를 1996년 전후 열풍이던 Java의 유명세에 묻어가기위해 Sun에서 상표권을 라이선스해 JavaScript라고 이름붙였을 뿐이다. 이름 하나 생각없이 잘못 붙여서 여러 사람을 지금도 헷갈리게 만드는 대표적인 케이스.
이름을 제외한 연관성은 희박한 편이여서 차이점이 아닌 공통점을 나열하는게 훨씬 빠를 정도다. 같은 C-족 언어이긴 하지만 문법조차 별로 비슷하지도 않으며[35], 사용되는 라이브러리나 개념 또한 많이 다르다. 기초 패러다임상 당연한 요소들을 제외하고 나면 둘의 유사점은 오직 객체지향 뿐인데 그 마저도 JavaScript는 프로토타입 베이스라 클래스를 쓰는 Java와 많이 다르다 [ES6]. 또한 Java는 정적 타입 언어인데 반해 JavaScript는 동적 타입 언어다. 웹 서버용 파생 규격 역시 JSPNode.js로 다르다.
떠도는 말로 'Java와 JavaScript의 차이는 인도인도네시아의 차이와 같다'라고도 한다. 왜냐하면 인도인도네시아가 이름만 비슷하고 서로 다른 국가이듯이[36] Java와 JavaScript도 다른 프로그래밍 언어이기 때문이다.
  • Visual J++/Visual J#
Visual J++은 마이크로소프트에서 Java를 변형하여 윈도우 전용으로 만든 언어. 위의 JavaScript는 이름만 바꿨지만 이건 Java 자체를 윈도우에 맞도록 변형한 것이다. 이 때문에 Java 가상머신 없이 윈도우에서 네이티브로 돌아가지만, 다른 플랫폼에서는 전혀 돌아가지 않는다. 거기다 썬 마이크로시스템즈의 허락없이 마구 변형해서 썼기 때문에 소송크리를 먹고 개발이 중단되었다.
이후 윈도우의 프로그램이 닷넷으로 넘어가면서 닷넷 기반의 Visual J#도 만들었다. Visual Studio 2005에 포함되었지만 이것도 개발이 중단되었다. 이때는 썬이 소송하지도 않았는데 중단된 것을 보면 시장성이 없었던 듯 하다. 이미 이 때는 C#이 어느 정도 자리를 잡았기 때문일 수도 있고.

9. 구글 vs. 오라클: Java 저작권 분쟁


Java를 처음 개발한 썬 마이크로시스템즈오라클에게 인수되었고, 2010년에 오라클은 구글안드로이드를 개발하면서 Java API 37개의 소스 코드를 무단 복제하여 사용했다는 이유로 소송을 제기했다. 오라클은 구글이 Java를 이용해 OS를 개발하려는 상업적 목적을 가지고 있었으므로 사전에 허가를 받았어야 했다는 주장이고, 구글은 Java API가 저작권자의 허락 없이 이용할 수 있는 공정 이용(Fair Use)의 대상이라며 맞섰다. 그리고 2018년, 장시간에 걸친 소송전은 오라클의 승리로 결론났다. #
재판의 흐름을 정리하자면 이렇다. 2012년에 이루어진 '저작권 침해'에 관한 재판 1심에서는 구글이 승소하였고, 2014년 항소심에서는 오라클이 승소하였으며 2015년에는 구글의 상고가 기각되었다. 이후 2016년 '공정 이용'에 관한 재판 1심에서는 구글 측의 주장이 받아들여지며 구글이 승소했지만, 결국 2018년 항소심에서 다시 오라클이 승소하게 된 것이다. #
항소심 재판부의 결론은 Java API 역시 저작권이 존재하는 엄연한 저작물이라는 것이다. 재판부는 구글이 Java API를 수정 없이 그대로 긁어다가 안드로이드를 만들어 모바일 OS 시장을 점령하였으며, 단순히 어떤 애플리케이션을 개발한 게 아닌 별도의 운영체제와 플랫폼을 무기로 향후 오라클이 Java를 이용하여 모바일 시장에 진출할 가능성을 꺾어버렸기 때문에 Java의 무단 이용은 불공정한 행위라고 판결했다. 현재 구글이 오라클에게 배상해야 할 금액은 약 90억 달러에 달할 것으로 예상되고 있다.
이 판결이 가져다 줄 여파에 대해 안드로이드 생태계가 큰 위기를 맞이했다는 시각이 있지만, 사실 소송기간 동안 안드로이드는 이미 모바일 OS 시장을 iOS와 함께 5:5로 양분하고 있을 만큼 거대하게 성장했기 때문에 이번 일로 안드로이드가 휘청거릴 일은 단연코 없다. 90억 달러가 작은 돈은 아니지만, 구글은 한창 성장하던 시절인 2006년에 이미 유튜브 인수금액으로 16억 5,000만 달러를 한번에 지불해낼 정도였고, 2007년에는 광고 회사인 더블클릭을 31억 달러에 샀을 정도로 현금 창출력이 상당한 기업이다. 그리고 안드로이드는 직접적인 로열티 수입은 없지만 구글 검색과 광고, 구글 플레이와 유튜브 같은 구글 앱에서 나오는 수익만 해도 매년 수백억 달러에 달한다는 평가를 받고 있는데, 모바일 OS 시장 양분 댓가로 90억 달러를 낸다면 구글 입장에선 거저 먹는 것이나 다름없다.
일단 구글은 연방대법원에 상고할 것이라는 의사를 밝혔다. # 다만 실제로 상고를 신청할지, 신청하더라도 대법원에서 그걸 받아들일지는 나중 문제이다.
구글이 대법원에 오라클의 승소에 대해 다시 검토해줄 것을 요청했고 이와 관련한 첫번째 심리가 오는 2020년 3월 열릴 예정이라고 한다. 최종 판결은 이르면 6월께 나올 것이라고 한다. #

10. 점유율


세계 프로그래밍 언어 중에서 점유율 1위를 2000년부터 무려 19년 째 1위를 질주중인 독재자(...)이다. 2007년까지만 해도 전 세계 프로그래밍 언어 점유율 중에 Java 점유율이 35%까지도 차지했다. 그러나 2010년대 들어서 Python, C++ 등의 점유율이 급상승하면서 Java의 점유율은 점차 하락하는 추세이다. 1위는 수성하고 있지만 점유율은 급격하게 떨어지고 있다. 2019년 지금은 C언어보다 약간 더 많은 수준으로 17~18% 정도를 차지하고 있다. Java 점유율이 하락한 만큼 Python 비율이 크게 올랐다.

11. 불투명한 미래?


이러한 분쟁과는 별도로, 오라클이 Java를 포기하려고 한다는 주장이 있다. "Oracle Mysteriously Fires Almost All of Its Top Java Evangelists"(Softpedia News) 자바 에반젤리스트, 오라클 퇴사의 변 "자바 구하려"(ZDNet Korea)
자바 에반젤리스트는 Java의 전체적인 업계 내에서의 분위기를 결정지을 수 있는, 비교하자면 리눅스계의 리누스 토르발스 같은 사람들인데, 오라클이 이 사람들을 꾸준히 해고하고 있다는 것이다. 장사를 독하게 하기로 유명한 오라클인지라, Java 자체가 지금은 물론이고 미래에도 그다지 수익성이 좋다고 할 수 없기에 망설임 없이 포기하려는 것이 아니냐라는 관측이 있다. 제임스 고슬링도 한마디 했다.
다만 이 부분은 사람에 따라 극단적으로 반응할 수도 있는 문제이므로[37] 업계 분위기에 대한 판단은 스스로 하도록 하자. 위에서도 언급했지만 Oracle JDK를 유료로 전환한 걸 보면 포기할 생각은 없는 듯하다.
2017년 8월 17일, 오라클이 Java EE를 포기한다고 발표했다. 오픈오피스, 넷빈즈 때와 같이 오픈 소스 생태계로 보내려 하고 있으며, 아파치 소프트웨어 재단이클립스 재단이 Java EE를 넘겨받을 유력한 후보로 알려져 있다. Opening Up Java EE 결국 이클립스 재단이 맡는 것으로 확정되었으며, Java EE의 오픈 소스화를 위한 9개 프로젝트를 추진한다고 밝혔다. ## 다만 오라클이 Java EE라는 상표권까지 넘긴 것은 아니기 때문에, 새로운 이름을 공모하였고 이후 자카르타 EE(Jakarta EE)라는 새 명칭이 결정되었다. 엔터프라이즈 자바의 새 이름 ‘자카르타 EE'[38]

12. 도서


서점에 가면 Java 프로그래밍 책이 무궁무진하게 많다. Python, Java, C, SQL 4개는 서점에 가면 프로그래밍 언어 분야에 별도의 카테고리를 차지하고 있다.

13. 여담


  • Java의 창시자인 제임스 고슬링 옹은 진성 앱등이다.[39] 집에서 쓰는 IT 기기에 대해 묻는 질문에 폰, 태블릿, 데스크탑, 랩탑 등 거의 모든 IT 기기를 애플사 제품으로 도배해놨음이 밝혀졌다. 가족들도 마찬가지. 정작 애플은 OS X 레오파드 업데이트 때 Java를 찬밥 취급했지만...[40]
  • 제임스 고슬링과 Java를 창시할 때 같이 일했던 패트릭 노튼은 1999년 FBI아동포르노 함정수사로 인해 체포되었다.[41] 덤으로 IT 관계자들은 노튼이 기업 방화벽을 통과할 수 있는 통신도구를 만드는 일에 관심을 보인 이유를 일찌감치 짐작했었다고...
  • 조엘온 블로그로 유명한 조엘이 엄청나게 싫어하는 언어. 조엘 스폴스키가 Java를 싫어하는 이유로는 성능상의 문제나 문법상 너무 쉽다(...)[42]는 이유도 있지만, Java 자체가 "위원회 기술"이라는 이유도 큰 몫을 차지한다.[43] 사실 이는 Java가 가진 태생적 문제인데 Java라는 언어가 C#처럼 어느 특정 단체나 회사가 주도적으로 끌고가는 물건이 아니다 보니 위원회를 구성하는 각 기업들의 파워게임에 따라 중요한 문제의 해결방안이 빨리 처리되지 않는 경우도 있고 배가 산으로 가는 경우도 있다.
  • Java를 설치하고 환경변수를 설정할 때 CLASSPATH의 디렉토리를 보통 %JAVA_HOME%\\lib로 설정하는데, 이렇게 하면 파일 실행 시 JVM이 무조건 \\lib 경로에서 클래스 파일을 찾기 때문에 해당 파일을 찾거나 로드할 수 없다는 오류 메시지를 뿜게 된다. 매번 실행할 때마다 -classpath . 옵션을 주거나 CLASSPATH 환경변수의 디렉토리 끝에 ;.을 붙이면 해결할 수 있다.[44] 물론 대부분의 IDE는 클래스 패스 설정을 자동으로 처리해 주지만, 역으로 그렇기에 클래스 패스에 대한 이해를 제대로 하지 않고 넘어가 버리는 경우가 많다.
  • Java에서 UI를 만들 때도 고려를 해야할 게, Java는 UI를 만들 때 AWT나 Swing 둘 중 하나 혹은 둘 다 선택하여 UI를 만드는 게 가능하다. 조심해야 할 점은, AWT로 생성한 UI는 Swing UI에 가려져버린다. 그래서 멀쩡히 잘 돌아가는 코드인데도 불구하고 배경이 컨트롤(콤보박스라거나)을 가려버리는 일이 있을 수 있다. 어차피 요즘은 둘 다 안 쓴다 참고로 JetBrains의 IDE 제품들은 이 Swing UI를 거의 마개조에 가깝게 뜯어고쳐서 쓰고 있다.
  • Java 클래스 바이트코드 매직넘버가
    0xCA 0xFE 0xBA 0xBE
    다. 이것을 붙이면 CAFEBABE다. CAFEBABE인 이유는, 제임스 고슬링과 다른 연구원들이 St. Michael's Alley라는 곳에 점심을 먹으러 가곤 했다고 한다. 그 지방 전설에 의하면 그곳에서 더 그레이트풀 데드라는 밴드가 크게 성장하기 전에 연주하던 곳이라고 했다. 그리고 제임스 고슬링과 연구원들은 그곳을 Cafe Dead라고 불렀다. 그러다 CAFE DEAD가 헥스 넘버인 것을 알아냈다고 한다.[45] 그 때 마침 그는 파일 포맷 소스와 매직넘버를 개편하고 있었다.[46] 결국 Object 파일의 매직 넘버는 CAFEDEAD가 되었다. 나머지 하나, 클래스 파일의 매직넘버는 CAFE 다음에 맞을 만한 번호를 정하는 것인데, 그 때 적은 것이 BABE다.
  • 2012년 말에는 Java에 보안 취약점이 발견되어 오라클에서 긴급 보안 패치를 발표했지만 또 다른 취약점이 발견돼버리는 바람에 Java를 계속 써야 하나 말아야 하는 논쟁이 벌어지기도 했다. 지금은 잠잠해진 상태.
  • 기존의 32bit용은 64bit 웹 브라우저에 사용할 수 없기에 64bit용 Java가 공개되어 있다. 그러나 32bit 웹 브라우저와 64bit 웹 브라우저를 각각 돌아가며 사용해야 할 필요가 있을 경우 둘 다 설치해야 제대로 돌아가기 때문에 번거로운 편이다.
  • 2018년 초부터 자바 설치파일로 위장한 랜섬웨어가 기승을 부리고 있다. 어느날 갑자기 직접 설치파일을 다운받거나 하지도 않았는데 설치파일이 저절로 실행되며, 대부분의 감염자들은 이를 자동 업데이트로 인지하고 그대로 업데이트 해버려서 감염된다고 한다. 심지어 사용하는 운영체제의 언어를 인지하여 해당 언어의 자바 설치파일에 있는 문장과 이미지까지 철저하게 재현되어서 의심할 여지가 없다고 한다.
  • 마인크래프트는 원래 Java로 개발되었는데, 속도 문제 때문인지 게임을 통째로 C++로 다시 짰다. 그리고 실제로 속도가 10배 가까이 빨라졌다. 다만 기존의 Java 에디션으로 개발된 애드온들이 워낙 많고, 그것들이 베드락 에디션과 호환이 안 돼서 여전히 Java 에디션을 사용하는 유저들이 많다.

14. 관련 문서



[1] 일반명사나 이미 널리 알려진 표현 등은 상표로 등록 못한다. 물론 상표 등록을 못해도 제품이나 서비스 이름으로 못 쓰는 건 아니지만 해당 이름에 대해 배타적·독점적 권리를 확보하지 못한 상태가 돼서, 남들이 따라 해도 거기에 법적으로 태클을 걸 수가 없다.[2] Premier Support. 오라클에 비용을 내고 기술 지원을 받는 서비스이다.[3] Extended Support. 일반 지원이 종료된 후 추가적인 비용을 지불하여 기술 지원을 더 받을 수 있는 기간이다.[4] GCC 계열 Java 컴파일러인 GCJ에서는 이미 지원하고 있던 기능이다.(현재는 출시 중단)[5] C\#의 var와 똑같은 기능이다.[6] 따라서 이전 버전과 호환이 안 될 가능성도 있다. 이전 버전에서는 그냥 내부 메소드 쓰듯이 JavaFX를 갖다 썼다면, 이제는 라이브러리를 따로 인클루드해서 배포해야 하기 때문.[7] '@Nonnull var x, @Nullable var y'를 'x.process(y)'로 간략화할 수 있게 되었다.[8] 리눅스 커널, 하드웨어 프로그래밍[9] 3D 게임, 그래픽 프로그래밍[10] 특히 웹 개발 분야에서 해외의 경우 Java는 도태되는 추세고, Node.js 덕분에 서버와 프론트엔드 양 쪽에서 쓸 수 있는 JavaScriptDjango를 통하여 쉽고 빠르게 백엔드 구축이 가능한 Python의 사용률이 늘어나고 있다.[11] JVM 위에서 구동 가능한 언어에 대해서는 영문 위키피디아의 List of JVM languages 참고.[12] 정말로 포인터를 써야 할 경우 Unsafe 클래스를 쓰면 된다. 다만 팩토리 메소드가 막혀있어 리플렉션을 사용해야만 이용할 수 있다.[13] 어차피 Java에서는 다중 상속을 포기함으로써 생기는 문제를 interface를 다중 구현할 수 있도록 하여 어느 정도 해결하기도 했다.[14] 쉽게 생각하면 배열 1000개를 할당받기 위해 운영체제에 1번 호출하여 한꺼번에 할당받지 않고, 1000번 호출하여 각각 할당받는 것이다. 기본적으로, 동적 메모리 할당은 운영체제에서 처리하기 때문에 속도가 느리다. 어떤 언어에서라도, 운영체제의 메모리 할당 횟수를 줄이는 것이 성능에 도움이 된다.[15] 하지만 연산자 오버로딩은 분명 제네릭 프로그래밍에 도움을 준다. 가령 제네릭 클래스 내에서 주어진 타입의 변수 두 개를 더하는 연산을 하고 싶다면? 더하는 연산 등 여러 일반적인 작업들은 Java의 primitive 타입에만 필요한 것은 아니다. 행렬 등이 그런 대표적인 예다. 이러한 측면에서 본다면 프로그래머의 작업에 있어서의 일관성은 훼손됐다고 볼 수도 있다.[16] 다만 제네릭은 Type Erasure를 사용하기 때문에 개념적으로 C++의 템플릿과 다르며, 할 수 있는 일도 거의 일반화 프로그래밍 자체로만 한정돼 있다.[17] 기존에 앞 문단 서술에 사용되었던 용어인 "템플릿 메타 프로그래밍"은 개념을 오해하여 사용한 것이므로 "일반화 프로그래밍"으로 대체하였다. 일반화 프로그래밍(Generic Programming)은 Java나 C#에도 "제네릭"이라는 형태로 구현되어 있다. 그러나 템플릿 메타 프로그래밍(Template Meta-Programming)은 Java나 C#에서 전혀 구현되지 않는 별도의 개념이다. 아마도 C++에서 쓰는 "템플릿#s-6"이라는 용어와 Java의 "제네릭"이라는 용어가 같은 것을 지칭한다고 착각해서 나온 결과로 추정된다. C++ 템플릿 프로그래밍 = "일반화 프로그래밍 + 템플릿 메타 프로그래밍", Java/C# 제네릭 = "일반화 프로그래밍"으로 이해하면 쉽다. "템플릿 메타 프로그래밍"은 C++, D 등 극소수의 언어만 지원한다.[18] 이 부분은 주관적인 것으로 C/C++가 Java보다 가독성이 좋지 않다는 것에 대해 동의하지 않는 시각도 많다는 점을 알려둔다.[19] Java는 JIT 컴파일을 기본적으로 사용하기 때문이다. C#이나 PHP 7와 같은 고수준 언어도 해당사항이다. [20] 메모리를 훑으면서 순간적으로 프로그램이 얼어붙어 멈추는 현상.[21] 이를 gotta catch 'em all 패턴이라고 한다.[22] 물론 이렇게 짜면 안되지만 구조적으로 강요받는 형편.[23] 이쪽은 RuntimeException 계열의 예외로, 이것을 던지는 메소드가 throws에 명시적으로 던진다고 선언하지 않았을 경우 검사를 하지 않아도 된다.[24] 대한민국에 국한되는 경향이 강하긴 하지만 현재 한국에서 이러한 예외처리를 코딩하는 순간에 인지하는 개발자는 드물다. 국비지원 학원을 막 졸업한 신입들은 말 할 것도 없으며 현업 몇년 한 초중급 경력자들 역시 이를 인지하지 못하는 경우가 허다하기 때문에, 어찌보면 대한민국 IT계의 버그처리와 예외처리에 있어서만큼은 장점으로 볼 수도 있다.[25]마세라티가 맞다. 자신이 탈수나 있을지도 모르는 마세라티를 타면 어떻게 해야 될까... 라는 쓸데없는 고민을 하는 것을 비유하는 문제로, 당장에 쓸데없는 기능을 위해 과도하게 투자하는 것을 의미한다.[26] 프로그래밍 언어를 좀 더 쉽게 표현할 수 있도록 하는 보조문법. C에서 구조체 포인터를 쓸 때 (*ptr).num은 ptr->num으로도 표현 가능하므로, ->는 문법적 설탕이라고 할 수 있다.[27] 컬렉션(Collection)의 이터레이터를 확장해서 처리할 수 있는 개념으로, 이터레이터의 원소를 필터링해서 원하는 원소만 뽑거나, 원소갯수를 줄여버리고, 이렇게 다시 뽑혀진 원소들로 갖가지 처리를 만드는 등 '함수적인(functional)' 기능을 제공한다.[28] 정작 람다 표현식의 추가는 Java 진영 내에서 논란이 있다. 람다 식이 뒤늦게 추가된 것도 코드 리딩이 어려워진다고 싫어하는 개발자가 많아서였다.[29] 멀리 갈 것 없이, C언어의 stdio.h와 자바의 System.out을 비교해보자. Java는 직관적으로 '시스템'에서 뭔가가 '나온다'는 것을 쉽게 인식할 수 있지만, stdio.h를 봤을 때 직관적으로 뭘 떠올릴까? 저걸 처음 보고 STanDard Input and Output을 떠올릴 사람이 얼마나 있을까?[30] 실제로 Java에서 기본 제공하는 정렬 기능은 Collections 클래스의 정적 메소드인 sort(array)를 호출하도록 작성되어 있다.[31] JSP의 목적이 HTML 페이지를 동적으로 만들어내는 것이다. JSP 소스는 Java 서블릿 코드로 변환되어 서버에서 실행되고, 서버는 이 HTML 결과를 브라우저에 보여준다. JSP 페이지는 HTML 페이지에 Java 코드가 포함되어 있는 식으로 되어 있는 경우가 많고, 이 점은 PHP, ASP.NET 등과 비슷한 편이다. 반면 Java 서블릿은 서버 쪽에서 하는 일에 관심이 많지만 출력에 대한 관심은 적다. 필요하다면 브라우저에 출력을 전혀 안 보낼 수도 있다. 최근에는 Server side script language로 HTML 페이지를 동적으로 만드는 식으로는 프로그래밍을 하지 않는다. JSP, PHP와 같은 Server side script language로는 서버에 있는 자원의 접근을 주로 하고(DB 연산, File 연산 등등) 화면에 보여주는 UI는 HTML/CSS/JavaScript로만 한다. 따라서 Client side와 Server side 간에 통신이 필요한데 이는 XHR(XML HTTP Request)를 이용한다. 이러한 프로그래밍 기법을 나타내는 표현이 REST 내지는 Open API이다.[32] Java는 현용 프로그래밍 언어 중에서는 가장 Verbose한(장황한) 언어로 꼽힌다. 즉, 같은 의미인데 많은 타이핑이 필요하다.[33] Java는 버전 10에서 와서야 이와 같은 타입 추론 기능이 가능해졌다.[34] 안드로이드의 Java 라이선스 무단 사용으로 구글이 오라클과 법정 싸움을 한 여파로 보인다.[35] 기초적인 C-문법의 일부인 if문, while문 등을 제외하면 공통점이 많지 않다.[ES6] ECMAScript 6에서 Class가 생겼다! 그래도 여전히 Java의 클래스와는 겉보기에만 비슷할 뿐 열어보면 다르다. ES6에서 나온 클래스는 기존에 있던 prototype 객체지향 프로그래밍을 조금 더 쉽게 하게 해주는 문법적 설탕이다.[36] 다만 인도네시아의 어원은 인도와 관련이 있다. 인도네시아라는 이름은 '인도양의 섬'들이라는 그리스어·라틴어식 표현이기 때문. 이런 인도네시아와 인도의 관계는, JavaScript가 Java와 별 관련은 없어도 그 이름을 빌려 왔다는 점에서 왠지 흡사하다.[37] 각 언어 프로그래머들의 자신의 언어에 대한 자부심은 가히 종교의 신앙과 비견할 만한 것이다.[38] 원래 아파치 소프트웨어 재단이 '자카르타'라는 이름의 Java 오픈 소스 프로젝트(현재는 종료)를 소유하고 있었으나, 해당 명칭을 사용해도 된다고 허가하였다.[39] Java가 안드로이드의 기반이 되는 언어라는 점을 생각하면 아이러니...[40] 사실 애플은 독자적인 JDK를 제공하는지라 Java 개발자들을 매우 피곤하게 하는 회사이기도 하다.[41] 단지 징역을 살지는 않고 FBI에서 1년 근무하는 것으로 퉁쳤다.[42] 이 부분은 대학의 교육용 언어로서의 이야기다. 산업용으로서는 같은 기능을 개발하기 위한 언어는 쉬우면 쉬울수록 좋은 것이 당연하다. 물론 성능과 생산성 사이에서 적절한 균형을 잡아야 하겠지만.[43] Java 상임 위원회에는 인텔, 오라클, JetBrains, 레드햇, ARM Holdings 등이 속해 있다. 모두 각자의 분야에서 내로라하는 기업들이다.[44] '.'은 Java 클래스 파일이 위치한 해당 디렉토리를 의미한다.[45] CAFEDEAD를 0xCA 0xFE 0xDE 0xAD로 바꿨을 때의 얘기인 듯하다.[46] 그때 필요한 매직넘버는 2개였다. 하나는 오브젝트 파일이고, 또 다른 하나는 클래스 파일 매직넘버였다.