S-JIS[2017-09-22/2019-09-22] 変更履歴

Javaバージョン

Javaのバージョンについて。


概要

自分が初めて使ったJavaはたぶんJDK(Java Development Kit)1.3、バージョンを意識し始めたのはJDK1.4からなので、昔の事は知らないんだけど。

JDK1.2でJDK1.1より大幅に改善されたらしく、宣伝(マーケティング)の都合でJava2と名付けられ、Java2 Standard Edition→J2SEと表記されていた。
JDK1.5からは「2」が取れてJava 5.0という名称になったが、SEはJ2SE 5.0だったと思う。
JDK1.6からは「.0」が取れてJavaSE6という名称になった。
JDK1.7はJavaSE7あるいはJava7と呼ばれ、JDK1.8はJava8と言われることが多い。

この間、javaコマンドで表示されるバージョン等は1.8.0という感じだったので、自分はほぼ一貫して「JDK1.n」と表記してきた。
しかしJava9でバージョン体系が変わり、JDK9(Java SE Development Kit 9)が正式となった。


Javaバージョン

javaコマンドの「--version」オプションはJava9から使えるようになった。

javacコマンドの「-version」オプションはJDK1.5から使えるようになった。
Java9(JDK9)から「--version」オプションも使えるようになった。
また、Java8までは標準エラーに出力されたが、Java9から標準出力になったようだ。

Java9からバージョンの形式が大幅に変わったので、もし判定に使っているなら注意が必要。

Javaのバージョン表記の例
  java -version java --version java -fullversion java --full-version
JDK 1.4 java version "1.4.2_19" 標準エラー × × ×
JDK 1.5 java version "1.5.0_22" × × ×
JDK 1.6 java version "1.6.0_45" × × ×
JDK 1.7 java version "1.7.0_40" × × ×
JDK 1.8 java version "1.8.0_112" × × ×
JDK 9 java version "9" java 9 標準出力 java full version "9+181" 標準エラー java 9+181 標準出力
JDK 10 java version "10.0.1" 2018-04-17 java 10.0.1 2018-04-17 java full version "10.0.1+10" java 10.0.1+10
JDK 11 java version "11" 2018-09-25 java 11 2018-09-25 java full version "11+28" java 11+28
  ディレクトリー名 javac -version javac --version 更新日
JDK 1.4 j2sdk1.4.2_19 × ×  
JDK 1.5 jdk1.5.0_22 javac 1.5.0_22 標準エラー ×  
JDK 1.6 jdk1.6.0_45 javac 1.6.0_45 ×  
JDK 1.7 jdk1.7.0_40 javac 1.7.0_40 ×  
JDK 1.8 jdk1.8.0_112 javac 1.8.0_112 ×  
JDK 9 jdk-9 javac 9 標準出力 同左  
JDK 10 jdk-10.0.1 javac 10.0.1 同左 2018-04-30
JDK 11 jdk-11 javac 11 同左 2018-10-01

システムプロパティーで取得できるバージョン

システムプロパティーでも実行中のJavaVMのバージョン情報が保持されている。[/2017-09-22]

システムプロパティー 値の例 内容 備考
Java6 Java7 Java9
java.class.version 50.0 51.0 53.0 “Javaクラスの形式”のバージョン 実行可能なclassファイルのバージョンと思われる
java.specification.name Java Platform API Specification Java Platform API Specification Java Platform API Specification JREの仕様バージョン 実行可能な仕様を示すバージョン
java.specification.version 1.6 1.7 9
java.specification.vendor Sun Microsystems Inc. Oracle Corporation Oracle Corporation
java.version 1.6.0_02 1.7.0 9    
java.vendor Sun Microsystems Inc. Oracle Corporation Oracle Corporation
java.vendor.url http://java.sun.com/ http://java.oracle.com/ http://java.oracle.com/
java.vm.name Java HotSpot(TM) Client VM Java HotSpot(TM) Client VM Java HotSpot(TM) 64-Bit Server VM JavaVMのバージョン  
java.vm.version 1.6.0_02-b06
11.3-b02
21.0-b17 9+181
java.vm.vendor Sun Microsystems Inc. Oracle Corporation Oracle Corporation
java.runtime.name Java(TM) SE Runtime Environment Java(TM) SE Runtime Environment Java(TM) SE Runtime Environment JREのバージョン JavaVMの詳細なバージョン
java.runtime.version 1.6.0_13-b03 1.7.0-b147 9+181
java.vm.specification.name Java Virtual Machine Specification Java Virtual Machine Specification Java Virtual Machine Specification JavaVMの仕様バージョン  
java.vm.specification.version 1.0 1.7 9
java.vm.specification.vendor Sun Microsystems Inc. Oracle Corporation Oracle Corporation
java.vm.info mixed mode, sharing mixed mode, sharing mixed mode    
java.home C:\Program Files\Java\jre1.6.0_02 C:\Program Files\Java\jdk1.7.0\jre C:\Program Files\Java\jdk-9 Javaのインストール先ディレクトリー  

1.6とかのjavaのバージョンと、それがサポートしている50.0とかの数値との対応を(実際に試す以外に)どうやって知るのかは不明…。


classバージョン

javacコマンドでコンパイルするとclassファイルが作られるが、classファイルの中には「どのバージョンのJavaVMで実行できるか」という“Javaクラスの形式”のバージョンが書かれる。[2007-05-15]
JavaVM(javaコマンド)では実行できるバージョンが限られており、自分より新しいバージョンで作られたclassファイルは実行することが出来ない(古すぎてもダメ)。
(実行しようとすると、「java.lang.UnsupportedClassVersionError: クラス名 (Unsupported major.minor version Mj.Mi)」の例外が発生する。Mj.Miは、 対象クラスのメジャーバージョンとマイナーバージョン。→native2asciiの例

JavaVMのバージョン
JRE(JavaVM)
仕様バージョン
VMがサポートしている
Javaクラスの形式
のバージョン

(メジャーバージョン.
マイナーバージョン)
更新日
1.4 48.0  
1.5 49.0  
1.6 50.0  
1.7 51.0  
1.8 52.0  
9 53.0 2017-09-22
10 54.0 2018-04-30
11 55.0 2018-10-01
12
12 preview
56.0
56.65535
2019-03-31
13
13 preview
57.0
57.65535
2019-09-22

JDK1.5以上のjavapを使えば、classファイルの実行可能バージョンを表示することが出来る。

>javap -v Test		…Test.classを表示する例。-vは-verboseのことらしい。
Compiled from "Test.java"
public class Test extends java.lang.Object
SourceFile: "Test.java"
minor version: 0
major version: 50

50.0だと、50.0に対応しているJavaVM(つまりJRE1.6のjavaコマンド)で実行できる、ということになる。
ちなみに、JDK1.4.0のjavapではバージョンは表示されず、JDK1.4.2_13では正しい値が表示されない(メジャーバージョンの箇所にマイナーバージョンの値がそのまま出てた(爆))

UNIXの場合は、fileコマンドでもclassファイルのバージョンを知ることが出来る。

なお、classファイルの中をバイナリーエディターで見てみると、 先頭部分が以下のようになっている。

00000000 : CA FE BA BE 00 00 00 32  00 1D 0A 00 06 00 0F 09
                       ~~~~~ ~~~~~
                       ↑    ↑メジャーバージョン:十六進数の0032十進数の50
                       ↑マイナーバージョン:0000

classファイルのメジャーバージョン/マイナーバージョンは、javacの-target(JDK9は--release)で指定した対象JavaVMバージョンの値によって異なってくる。
-targetを省略した場合は-sourceの値に左右される。
-targetで指定するのは1.4とか1.5とか1.6というJREの仕様バージョンだが、classファイル内に保持されている値は48.0とか49.0とか50.0という数字(Javaクラスの形式のバージョン)。

生成されるバージョンの対応表(試行結果)[/2018-04-30]
-sourceの指定 -targetの指定 JDK(javac)のバージョン
1.4.0 1.4.2 1.5.0 1.6.0 1.7.0 1.8.0 9 10 11
なし なし 46.0 46.0 49.0 50.0 51.0 52.0 53.0 54.0 55.0
1.2以下 1.2 × 46.0 46.0 46.0 46.0 46.0△ × ×  
1.3以下 1.3 47.0 47.0 47.0 47.0 47.0 47.0△ × ×  
1.4以下 1.4 48.0 48.0 48.0 48.0 48.0 48.0△ × ×  
1.5以下 1.5 × × 49.0 49.0 49.0 49.0△ × × ×
1.6以下 1.6 × × × 50.0 50.0 50.0 50.0△ 50.0△ 50.0△
1.7以下 1.7         51.0 51.0 51.0 51.0 51.0
1.8 1.8           52.0 52.0 52.0 52.0
1.9 or 9 1.9 or 9             53.0 53.0 53.0
1.10 or 10 1.10 or 10               54.0 54.0
11 11                 55.0
1.1 なし × × × × × × × ×  
1.2 なし × 46.0 48.0 48.0 48.0 48.0△ × ×  
1.3 なし 46.0 46.0 48.0 48.0 48.0 48.0△ × ×  
1.4 なし 48.0 48.0 48.0 48.0 48.0 48.0△ × ×  
1.5 なし × × 49.0 50.0 51.0 52.0△ × × ×
1.6 なし × × × 50.0 51.0 52.0 53.0△ 54.0△ 55.0△
1.7 なし         51.0 52.0 53.0 54.0 55.0
1.8 なし           52.0 53.0 54.0 55.0
1.9 or 9 なし             53.0 54.0 55.0
1.10 or 10 なし               54.0 55.0
11 なし                 55.0

つまり、-targetを指定すれば、当然そのターゲットJavaVM向けのバージョンになる。
-sourceのみを指定した場合は、そのバージョンで動く(その時点での)なるべく最新のバージョンになる。
何も指定しなかった場合は、(Sunがサポートしても良いと思っている最古の?/Sunが推奨しようと思っている?)デフォルトのバージョンになる。
(JDK1.4までは「なるべく古いJREでも動くように」。JDK1.5からは「なるべく新しいJREでも動くように」という考えっぽい?)
のかな?

ターゲットのバージョンによってはclassファイルの中身(仕様・フォーマット)が違ったりするようで、新しく増えた命令とかがあったりするみたい。バージョンにそぐわない命令があったり、変な状況(ftpに失敗してclassファイルが壊れたり)で実行したりするとjava.lang.ClassFormatErrorが出るらしい。


Java目次へ戻る / 新機能へ戻る / 技術メモへ戻る
メールの送信先:ひしだま