13
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

1.3 Javaの概要~新Java Basic編 / AI対応版

13
Last updated at Posted at 2023-02-04

はじめに

自己紹介

皆さん、こんにちは、Udemy講師の斉藤賢哉です。私はこれまで、約30年にわたって企業システムの開発に携わってきました。現在も現役のアーキテクトとして、重要システムの技術設計やソリューションの選定を担当しています。直近では、システム開発へのAI適用(AI駆動開発)という全社的な施策でリーダーを務めています。
セミナーでの登壇や雑誌への技術記事の寄稿を行ってきたほか、以下の書籍も執筆しています。

Udemy講座のご紹介

この記事の内容は、私が講師を務めるUdemy講座『新 Java Basic編 / AI対応版』の一部の範囲をカバーしたものです。『新 Java Basic編 / AI対応版』はこちらのリンクから購入できます。

この講座は、以下のような皆様にお薦めします。

  • AIが書いたJavaのコードを読んで、正しさと設計の良し悪しを判断できるようになりたい方
  • 新人のシステムエンジニアとして、Javaの基礎を仕組みから身に付けたい方
  • AIを前提とした開発へ学び直し(リスキリング)をしたい方
  • 「Oracle認定Javaプログラマ」の取得を目指し、Javaの基礎を固めたい方

AIとチャットできるオールインワンの学習環境をリリースしました

Udemy講座の演習を動かすための学習環境として、Windows向けのデスクトップアプリ「Codinable(コーディナブル)」をリリースしました。
エディタ、実行結果、テスト結果、SQL、Webブラウザ、そしてAIチャットを1つの画面にまとめた、オールインワンの学習環境です。

Codinableの画面構成

学習に必要なものは、すべてCodinableの中で完結します。

  • 演習の実行環境(Java 25、Gradle、Bashなど)が一式同梱されており、JDKのインストールや環境変数の設定は不要です
  • インストールして「新規コース開始・再開」からコースを選ぶだけで、講座のすべての演習がそのまま動きます
  • 書き換えて動かなくなっても、「初期化」で配布時の状態に戻せます
  • 開いている演習のファイルと実行結果を踏まえて、AIに質問したり(Askモード)、ファイルの書き換えを指示したり(Agentモード)できます

AIに書き換えを指示し、差分を確かめてから実行する、というAI駆動開発の基本の流れを、Codinableの中だけで安全に体験できます。

AIチャットに書き換えを指示し、差分を確かめて実行する

AIチャットは、受講者ご自身が生成AIサービス(Anthropic、OpenAI、Googleのいずれか)のAPIキーを登録して使うBYOK(Bring Your Own Key)方式です。利用料金は各社から直接請求されます。APIキーを登録しなくても、AIチャット以外の機能はすべて使えます。

Codinableのインストーラは、以下のGitHubのReleasesページからダウンロードできます(64ビット版のWindows 10/11、管理者権限は不要)。

この記事を含むシリーズ全体像

この記事はJava SEの一部の機能・仕様を取り上げたものですが、一連のシリーズになっており、シリーズ全体でJava SEを網羅しています。また認定資格である「Oracle認定Javaプログラマ」(Silver、Gold)の範囲もカバーしています。シリーズの全体像および「Oracle認定Javaプログラマ」の範囲との対応関係については、以下を参照ください。

1.3 Javaの概要

チャプターの概要

本チャプターでは、Javaという技術の位置付けと、Javaのプログラムを動かす土台であるJava Virtual Machine(JVM)の仕組み、Javaの言語としての特性を取り上げます。ここで押さえる「バイトコード」「JVM」「ヒープとガベージコレクション」「静的型付け」は、AIが書いたコードを読むときに、そのコードが「いつ」「どこで」誤りを見せるのかを判断する土台になります。

1.3.1 Javaの位置付けと歴史

本レッスンでは、Javaがどのような仕組みで標準化され、どのように進化してきたかを整理します。

仕様と実装の関係

Javaとは、プラットフォーム(OSやハードウェアの種類)に依存しない、オブジェクト指向型のプログラミング言語です。広い意味では、開発環境と実行環境、言語本体に同梱されたクラスライブラリまでを含めてJavaと呼びます。Javaの仕様は、Java Community Process(JCP)という仕組みの中で、様々な企業やコミュニティの意見を取り込んで決定されます。仕様、実装、配布物の関係を図で整理します。

Javaの仕様・実装・配布物の関係

  • 最上段に「Javaの仕様(JCPで決定)」がある
  • 仕様から下へ線が伸び、中段の「OpenJDK(オープンソースの実装)」につながる
  • OpenJDKから下へ3本の線が伸び、下段の「Oracle JDK」「Eclipse Temurin」「その他のディストリビューション」につながる
  • Eclipse Temurinの横に「Codinableが同梱」というラベルが付く
  • 下段のどのJDKも同じ仕様に準拠するため、プログラムの動作は変わらない

特定のベンダーに支配されない標準的な技術であるため、Javaは企業の分散システムやWebサービス、Androidのアプリケーションなど、長く保守されるシステムで広く使われています。AIエージェントが書くコードの量が増えても、それを読んで判断できる人の需要は変わりません。

Javaの歩み

Javaは、1995年にSun Microsystems社によって発表されました。2010年に同社がOracle社に買収された後も、OpenJDKのコミュニティを中心に開発が続いています。主な出来事を図で整理します。

Javaの歩み

  • 左から右へ時間が進む年表である
  • 1995年「Javaの発表(Sun Microsystems社)」
  • 2004年「Java 5: 総称型、列挙型、アノテーション」
  • 2014年「Java 8: ラムダ式、ストリームAPI」
  • 2017年「Java 9: 以降は半年ごとのリリースへ」
  • 2025年9月「Java 25: 本コースの前提(LTS)」

バージョンごとの主な機能は、チャプター1.5参照。

1.3.2 Java Virtual Machineの仕組み

本レッスンでは、Javaのプログラムが様々なOSで動く仕組みと、JVMがメモリーを管理する仕組みを整理します。

一般的なコンパイル型言語の制約

コンピューターが直接実行できるのは、CPUが理解できる機械語だけです。ソースコードを機械語に翻訳することをコンパイルと呼びます。一般的なコンパイル型言語では、機械語がOSやCPUの種類ごとに異なるため、実行するOSに合わせてコンパイルする必要があります。

一般的なコンパイル型言語におけるOSごとのコンパイル

  • ソースコードを、Linux用のコンパイラでコンパイルする
  • コンパイラは、Linux用の機械語のバイナリファイルを生成する
  • Linux用のバイナリファイルは、Linuxでは動作するが、WindowsやmacOSでは動作しない

バイトコードとJVM

JVM(Java Virtual Machine)とは、様々なOSの上で動作する、Javaプログラムの仮想的な実行環境です。Javaのソースコード(.javaファイル)は、特定のOSの機械語ではなく、バイトコードと呼ばれる中間コードにコンパイルされます。バイトコードを格納したファイルをクラスファイル(.classファイル)と呼び、クラスファイルは各OSのJVMの上で実行されます。

Javaのバイトコードと各OSのJVMによる実行

  • ソースファイル(.java)は、1つのJavaコンパイラでコンパイルされる
  • コンパイルの結果は、バイトコードを収めたクラスファイル(.class)になる
  • 1つのクラスファイルが、Windows上・macOS上・Linux上のJVMでそれぞれ動作する
  • この性質を「Write Once, Run Anywhere(一度書けば、どこでも動く)」と表現する

JVMは、クラスファイルを読み込み、バイトコードを機械語に変換しながら実行します。JVMの中の流れを図で整理します。

JVMの中でバイトコードが実行される流れ

  • 左端の「クラスファイル(.class)」から、JVMの枠の中へ矢印が入る
  • JVMの枠の中には、左から「クラスの読み込み」「バイトコードの検証」「インタープリタによる実行」が並ぶ
  • 「インタープリタによる実行」の下に「JITコンパイラ」があり、「頻繁に実行される部分を機械語にコンパイルする」と書かれている
  • JVMの枠の右端から「OSとCPU」へ矢印が出る

JIT(Just-In-Time)コンパイラによって、頻繁に実行される部分は実行中に機械語へコンパイルされるため、Javaは移植性と処理性能を両立しています。

ヒープとガベージコレクション

クラスから生成されたインスタンス(オブジェクト)は、JVMが管理するヒープと呼ばれるメモリー領域に置かれます。どこからも参照されなくなったオブジェクトは、ガベージコレクション(GC)によって自動的に解放されます。C言語のようにメモリーの解放をプログラムで明示する必要がないため、解放の漏れや二重の解放といった不具合が起きにくくなります。

ヒープとガベージコレクション

  • 左に「変数」の枠があり、変数aと変数bが並ぶ
  • 右に「ヒープ」の枠があり、オブジェクトX、オブジェクトY、オブジェクトZが並ぶ
  • 変数aからオブジェクトXへ、変数bからオブジェクトYへ、参照の矢印が伸びる
  • オブジェクトZにはどこからも矢印が届いておらず、「GCの回収対象」というラベルが付く
  • 参照が残っているオブジェクトXとYは回収されない

ただし、GCが回収するのは「どこからも参照されなくなった」オブジェクトだけです。不要になったオブジェクトをコレクションに入れたまま参照し続けると、GCは回収できず、メモリーを使い続けます。参照の仕組みはチャプター5.2参照。

レビューの観点

  • ファイルのパスの区切り文字(\)やOS固有のコマンドを文字列で直接書き、JVMによる移植性を損なっていないか
  • 不要になったオブジェクトを、スタティックなコレクションなどに入れたまま参照し続けていないか
  • メモリーの解放のつもりでSystem.gc()を呼び出していないか(GCの実行の時期はJVMが決める)

1.3.3 Javaの言語特性

本レッスンでは、Javaの言語特性のうち、AIが書いたコードの誤りがどの段階で見つかるかに関わるものを整理します。

6つの言語特性

Javaの言語としての特性を表にまとめます。

【表】Javaの6つの言語特性

特性 内容
オブジェクト指向型 手続き(メソッド)とデータ(フィールド)をクラスにまとめ、クラスの連携で処理を組み立てる
コンパイル型 実行前にソースコードをバイトコードへコンパイルする
静的型付け 変数の型を宣言し、コンパイルの時点で型を検査する
堅牢で安全 メモリーへ直接アクセスできず、メモリー管理はJVMが行う。例外を捕捉して回復できる(チャプター19.1参照)
多様なAPI 文字列や数値からネットワーク、並行処理まで、クラスライブラリがAPIとして同梱される
豊富な外部ライブラリ データベース接続、ログ出力などのライブラリがコミュニティやベンダーから提供される(本コースのスコープ外)

手続き型とオブジェクト指向型

手続き型プログラミングでは、手続きとデータが分離されており、処理の流れが複雑に絡み合った「スパゲッティコード」が生じやすくなります。オブジェクト指向型プログラミングでは、手続きとデータをクラスという単位に統合し、クラスとクラスの連携で処理を組み立てます。

手続き型とオブジェクト指向型のプログラムの構成

  • 手続き型では、手続き1・手続き2・手続き3が、別に置かれたデータ(構造体)にそれぞれアクセスする
  • オブジェクト指向型では、クラスAとクラスBが、それぞれデータと手続き(メソッド)を1つにまとめて持つ
  • クラスAはクラスBを呼び出し、クラス同士の連携で処理を組み立てる

AIに大きな処理を一度に書かせると、1つのクラスに手続きを並べただけの、手続き型に近いコードになることがあります。クラスの責務の分け方はチャプター7.1以降で取り上げます。

誤りが見つかる段階

Javaは静的型付けのコンパイル型言語であるため、文法や型の誤りはコンパイルの時点で見つかり、誤りがある状態ではプログラムを実行できません。この性質を型安全(タイプセーフ)と呼びます。一方で、コンパイルが通っても、実行して初めて分かる誤りがあります。誤りが見つかる段階を図で整理します。

誤りが見つかる段階

  • 左から右へ「コンパイル時」「実行時」「結果の確認時」の3つの段階が並ぶ
  • 「コンパイル時」の下に「文法の誤り」「型の誤り」があり、「javacが検出する」と書かれている
  • 「実行時」の下に「nullの参照」「配列の範囲外」があり、「例外として現れる」と書かれている
  • 「結果の確認時」の下に「仕様と異なる計算」があり、「実行結果と期待を比べて初めて分かる」と書かれている
  • 左から右へ進むほど、見つけるのに人の確認が要ることを示す帯がある

【表】コンパイル型言語とインタープリタ型言語

観点 コンパイル型言語 インタープリタ型言語
翻訳のタイミング 実行前に一括して翻訳する 実行しながら一命令ずつ翻訳する
型の検査 静的型付けが多く、コンパイル時に検査する 動的型付けが多く、実行時に検査する
代表的な言語 Java、C言語 JavaScript、Python

レビューの観点

  • 「コンパイルが通った」ことを「正しく動く」ことと取り違えていないか。実行時と結果の確認時の誤りは、実行して確かめる
  • 型で表せる制約(数値、日付など)を、文字列やObject型で受け渡して、コンパイル時の検査を逃がしていないか
  • 1つのクラスに無関係な処理を並べた、手続き型に近い構造になっていないか

このチャプターで学んだこと

本チャプターでは、以下を取り上げました。

  1. Javaの仕様はJCPで決まり、OpenJDKを基にした複数のJDKが同じ仕様に準拠していること
  2. ソースコードをバイトコードにコンパイルし、各OSのJVMで実行することで高い移植性を実現する仕組み
  3. オブジェクトはヒープに置かれ、どこからも参照されなくなったものだけがガベージコレクションで回収されること
  4. 静的型付けによって文法と型の誤りはコンパイル時に見つかるが、実行時と結果の確認時の誤りは実行して確かめる必要があること
13
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?