Javaに対する批判
Javaはガベージコレクションによるメモリ管理機能を備える。これによって、完全ではないもののプログラマがメモリリークを起こすようなプログラムを作ってしまう危険性を減らした。Javaではオブジェクトは常にヒープ領域に(JITコンパイラによって最適化されてスタックやレジスタに割り当てられない限り)確保される。ローカル変数はスタックやレジスタに確保される。C++ではオブジェクトをヒープ領域に割り当てるかスタック領域に割り当てるかをプログラマが選択することができたが、Javaではそれが不可能になっている。
オブジェクトはガベージコレクションによって管理されるが、Javaはプログラマにガベージコレクションがいつ起こるかを保証しない。プログラマはガベージコレクションを阻止することができないし、たとえSystem.gc()を用いても任意のオブジェクトを任意のタイミングで解放することはできない。これはプログラミングを簡易にしメモリリークの可能性を軽減するが、決定論的でより効果的なメモリ処理を行うための柔軟性が犠牲になっている。C言語やアセンブリ言語のような低水準言語はこの柔軟性を提供する。
C++などで書かれた多くのプログラムはメモリリークの犠牲になりがちだが、問題はメモリリークだけではない。ファイルハンドルやデータベース、ネットワーク接続のような他のリソースのリークは特に例外が投げられたときに常に起こりうる。C++ではRAIIと呼ばれるイディオムによっていずれの問題も克服することができるが、Javaプログラマは忘れずにfinally節でリソースを解放する必要があり、Javaが何を解放するかということとプログラマは何を解放しなければならないのかということをきちんと理解する必要がある。
Javaプログラムを実行する際、すべてのサードパーティーのライブラリはクラスパスに存在する必要がある。これは移植性の障壁となる。なぜならばクラスパスの文法はプラットフォームに依存するからである。例えばWindowsベースのシステムはサブディレクトリを区切るためにバックスラッシュ "\" を使用し、パス区切りにセミコロン ";" を使用している。だが一方、他の多くのプラットフォームではサブディレクトリ区切りにスラッシュ "/" を使用し、パス区切りにコロン ":" を使用している。
各々の.jarや.zipアーカイブはクラスパスにおいて明示的に名前がつけられる必要がある。この抜け道としてアスタリスク(*)で終わるクラスパスを指定することで、そのディレクトリにある.jarや.JARで終わるすべてのファイル名にマッチさせることができる。しかしながら、.zipや.classファイルのようなものはマッチしない。