1 /*
2 * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package java.lang.reflect;
27
28 import java.lang.classfile.ClassFile;
29
30 /**
31 * Class file format versions of the Java virtual machine.
32 *
33 * See the appropriate edition of <cite>The Java Virtual Machine
34 * Specification</cite> for information about a particular class file
35 * format version.
36 *
37 * <p>Note that additional class file format version constants will be
38 * added to model future releases of the Java Virtual Machine
39 * Specification.
40 *
41 * @apiNote
42 * The complete version used in a class file includes a major version
43 * and a minor version; this enum only models the major version. A
44 * Java virtual machine implementation is required to support a range
45 * of major versions; see the corresponding edition of the <cite>The
46 * Java Virtual Machine Specification</cite> for details.
47 *
48 * @since 20
49 * @see System#getProperties System property {@code java.class.version}
50 * @see java.compiler/javax.lang.model.SourceVersion
51 */
52 @SuppressWarnings("doclint:reference") // cross-module links
53 public enum ClassFileFormatVersion {
54 /*
55 * Summary of class file format evolution; previews are listed for
56 * convenience, but they are not modeled by this enum.
57 * 1.1: InnerClasses, Synthetic, Deprecated attributes
58 * 1.2: ACC_STRICT modifier
59 * 1.3: no changes
60 * 1.4: no changes
61 * 1.5: Annotations (Runtime(Inv/V)isible(Parameter)Annotations attributes);
62 * Generics (Signature, LocalVariableTypeTable attributes);
63 * EnclosingMethod attribute
64 * 1.6: Verification by type checking (StackMapTable attribute)
65 * 1.7: Verification by type checking enforced (jsr and ret opcodes
66 * obsolete); java.lang.invoke support (JSR 292) (CONSTANT_MethodHandle,
67 * CONSTANT_MethodType, CONSTANT_InvokeDynamic constant pool entries,
68 * BoostrapMethods attribute); <clinit> method must be ACC_STATIC
69 * 1.8: private, static, and non-abstract (default) methods in interfaces;
70 * Type Annotations (JEP 104) (Runtime(Inv/V)isibleTypeAnnotations
71 * attribute); MethodParameters attribute
72 * 9: JSR 376 - modules (JSR 376, JEP 261) (Module, ModuleMainClass,
73 * ModulePackages attributes, CONSTANT_Module, CONSTANT_Package
74 * constant pool entries, ACC_MODULE modifier)
75 * 10: minor tweak to requires_flags in Module attribute
76 * 11: Nest mates (JEP 181) (NestHost, NestMembers attributes);
77 * CONSTANT_Dynamic (JEP 309) constant pool entry
78 * 12: Preview Features (JEP 12) (minor version must be 0 or 65535)
79 * 13: no changes
80 * 14: no changes; (JEP 359 Records in Preview)
81 * 15: no changes; (JEP 384 Records in 2nd Preview, JEP 360 Sealed Classes
82 * in Preview)
83 * 16: Records (JEP 395) (Record attribute); (JEP 397 Sealed Classes in 2nd
84 * Preview)
85 * 17: Sealed Classes (JEP 409) (PermittedSubclasses attribute); ACC_STRICT
86 * modifier obsolete (JEP 306)
87 * 18: no changes
88 * 19: no changes
89 * 20: no changes
90 * 21: no changes
91 * 22: no changes
92 * 23: no changes
93 * 24: no changes
94 */
95
96 /**
97 * The original version.
98 *
99 * The format described in <cite>The Java Virtual Specification,
100 * First Edition</cite>.
101 */
102 RELEASE_0(45),
103
104 /**
105 * The version recognized by the Java Platform 1.1.
106 *
107 * @apiNote
108 * While {@code RELEASE_0} and {@code RELEASE_1} have the same
109 * {@linkplain #major() major version}, several additional
110 * attributes were defined for {@code RELEASE_1} (JVMS {@jvms
111 * 4.7}).
112 *
113 */
114 RELEASE_1(45),
115
116 /**
117 * The version introduced by the Java 2 Platform, Standard Edition,
118 * v 1.2.
119 *
120 * The format described in <cite>The Java Virtual Machine
121 * Specification, Second Edition</cite>, which includes the {@link
122 * AccessFlag#STRICT ACC_STRICT} access flag.
123 */
124 RELEASE_2(46),
125
126 /**
127 * The version introduced by the Java 2 Platform, Standard Edition,
128 * v 1.3.
129 */
130 RELEASE_3(47),
131
132 /**
133 * The version introduced by the Java 2 Platform, Standard Edition,
134 * v 1.4.
135 */
136 RELEASE_4(48),
137
138 /**
139 * The version introduced by the Java 2 Platform, Standard
140 * Edition 5.0.
141 *
142 * @see <a
143 * href="https://jcp.org/aboutJava/communityprocess/maintenance/jsr924/index.html">
144 * <cite>The Java Virtual Machine Specification, Second Edition updated for Java SE 5.0</cite></a>
145 * @see <a href="https://jcp.org/en/jsr/detail?id=14">
146 * JSR 14: Add Generic Types To The Java™ Programming Language</a>
147 * @see <a href="https://jcp.org/en/jsr/detail?id=175">
148 * JSR 175: A Metadata Facility for the Java™ Programming Language</a>
149 */
150 RELEASE_5(49),
151
152 /**
153 * The version introduced by the Java Platform, Standard Edition
154 * 6.
155 *
156 * @see <a
157 * href="https://jcp.org/aboutJava/communityprocess/maintenance/jsr924/index2.html">
158 * <cite>The Java Virtual Machine Specification, Java SE, Second Edition updated for Java SE 6</cite></a>
159 */
160 RELEASE_6(50),
161
162 /**
163 * The version introduced by the Java Platform, Standard Edition
164 * 7.
165 *
166 * @see <a
167 * href="https://docs.oracle.com/javase/specs/jvms/se7/html/index.html">
168 * <cite>The Java Virtual Machine Specification, Java SE 7 Edition</cite></a>
169 */
170 RELEASE_7(51),
171
172 /**
173 * The version introduced by the Java Platform, Standard Edition
174 * 8.
175 *
176 * @see <a
177 * href="https://docs.oracle.com/javase/specs/jvms/se8/html/index.html">
178 * <cite>The Java Virtual Machine Specification, Java SE 8 Edition</cite></a>
179 * @see <a href="https://jcp.org/en/jsr/detail?id=335">
180 * JSR 335: Lambda Expressions for the Java™ Programming Language</a>
181 */
182 RELEASE_8(52),
183
184 /**
185 * The version introduced by the Java Platform, Standard Edition
186 * 9.
187 *
188 * @see <a
189 * href="https://docs.oracle.com/javase/specs/jvms/se9/html/index.html">
190 * <cite>The Java Virtual Machine Specification, Java SE 9 Edition</cite></a>
191 * @see <a href="https://jcp.org/en/jsr/detail?id=376">
192 * JSR 376: Java™ Platform Module System</a>
193 */
194 RELEASE_9(53),
195
196 /**
197 * The version introduced by the Java Platform, Standard Edition
198 * 10.
199 *
200 * @see <a
201 * href="https://docs.oracle.com/javase/specs/jvms/se10/html/index.html">
202 * <cite>The Java Virtual Machine Specification, Java SE 10 Edition</cite></a>
203 */
204 RELEASE_10(54),
205
206 /**
207 * The version introduced by the Java Platform, Standard Edition
208 * 11.
209 *
210 * @see <a
211 * href="https://docs.oracle.com/javase/specs/jvms/se11/html/index.html">
212 * <cite>The Java Virtual Machine Specification, Java SE 11 Edition</cite></a>
213 * @see <a href="https://openjdk.org/jeps/181">
214 * JEP 181: Nest-Based Access Control</a>
215 */
216 RELEASE_11(55),
217
218 /**
219 * The version introduced by the Java Platform, Standard Edition
220 * 12.
221 *
222 * @see <a
223 * href="https://docs.oracle.com/javase/specs/jvms/se12/html/index.html">
224 * <cite>The Java Virtual Machine Specification, Java SE 12 Edition</cite></a>
225 */
226 RELEASE_12(56),
227
228 /**
229 * The version introduced by the Java Platform, Standard Edition
230 * 13.
231 *
232 * @see <a
233 * href="https://docs.oracle.com/javase/specs/jvms/se13/html/index.html">
234 * <cite>The Java Virtual Machine Specification, Java SE 13 Edition</cite></a>
235 */
236 RELEASE_13(57),
237
238 /**
239 * The version introduced by the Java Platform, Standard Edition
240 * 14.
241 *
242 * @see <a
243 * href="https://docs.oracle.com/javase/specs/jvms/se14/html/index.html">
244 * <cite>The Java Virtual Machine Specification, Java SE 14 Edition</cite></a>
245 */
246 RELEASE_14(58),
247
248 /**
249 * The version introduced by the Java Platform, Standard Edition
250 * 15.
251 *
252 * @see <a
253 * href="https://docs.oracle.com/javase/specs/jvms/se15/html/index.html">
254 * <cite>The Java Virtual Machine Specification, Java SE 15 Edition</cite></a>
255 * @see <a href="https://openjdk.org/jeps/371">
256 * JEP 371: Hidden Classes</a>
257 */
258 RELEASE_15(59),
259
260 /**
261 * The version introduced by the Java Platform, Standard Edition
262 * 16.
263 *
264 * @see <a
265 * href="https://docs.oracle.com/javase/specs/jvms/se16/html/index.html">
266 * <cite>The Java Virtual Machine Specification, Java SE 16 Edition</cite></a>
267 */
268 RELEASE_16(60),
269
270 /**
271 * The version introduced by the Java Platform, Standard Edition
272 * 17.
273 *
274 * Additions in this release include sealed classes and
275 * restoration of always-strict floating-point semantics.
276 *
277 * @see <a
278 * href="https://docs.oracle.com/javase/specs/jvms/se17/html/index.html">
279 * <cite>The Java Virtual Machine Specification, Java SE 17 Edition</cite></a>
280 * @see <a href="https://openjdk.org/jeps/306">
281 * JEP 306: Restore Always-Strict Floating-Point Semantics</a>
282 * @see <a href="https://openjdk.org/jeps/409">
283 * JEP 409: Sealed Classes</a>
284 */
285 RELEASE_17(61),
286
287 /**
288 * The version introduced by the Java Platform, Standard Edition
289 * 18.
290 *
291 * @see <a
292 * href="https://docs.oracle.com/javase/specs/jvms/se18/html/index.html">
293 * <cite>The Java Virtual Machine Specification, Java SE 18 Edition</cite></a>
294 */
295 RELEASE_18(62),
296
297 /**
298 * The version introduced by the Java Platform, Standard Edition
299 * 19.
300 *
301 * @see <a
302 * href="https://docs.oracle.com/javase/specs/jvms/se19/html/index.html">
303 * <cite>The Java Virtual Machine Specification, Java SE 19 Edition</cite></a>
304 */
305 RELEASE_19(63),
306
307 /**
308 * The version introduced by the Java Platform, Standard Edition
309 * 20.
310 *
311 * @see <a
312 * href="https://docs.oracle.com/javase/specs/jvms/se20/html/index.html">
313 * <cite>The Java Virtual Machine Specification, Java SE 20 Edition</cite></a>
314 */
315 RELEASE_20(64),
316
317 /**
318 * The version introduced by the Java Platform, Standard Edition
319 * 21.
320 *
321 * @since 21
322 *
323 * @see <a
324 * href="https://docs.oracle.com/javase/specs/jvms/se21/html/index.html">
325 * <cite>The Java Virtual Machine Specification, Java SE 21 Edition</cite></a>
326 */
327 RELEASE_21(65),
328
329 /**
330 * The version introduced by the Java Platform, Standard Edition
331 * 22.
332 *
333 * @since 22
334 *
335 * @see <a
336 * href="https://docs.oracle.com/javase/specs/jvms/se22/html/index.html">
337 * <cite>The Java Virtual Machine Specification, Java SE 22 Edition</cite></a>
338 */
339 RELEASE_22(66),
340
341 /**
342 * The version introduced by the Java Platform, Standard Edition
343 * 23.
344 *
345 * @since 23
346 *
347 * @see <a
348 * href="https://docs.oracle.com/javase/specs/jvms/se23/html/index.html">
349 * <cite>The Java Virtual Machine Specification, Java SE 23 Edition</cite></a>
350 */
351 RELEASE_23(67),
352
353 /**
354 * The version introduced by the Java Platform, Standard Edition
355 * 24.
356 *
357 * @since 24
358 *
359 * @see <a
360 * href="https://docs.oracle.com/javase/specs/jvms/se24/html/index.html">
361 * <cite>The Java Virtual Machine Specification, Java SE 24 Edition</cite></a>
362 */
363 RELEASE_24(68),
364
365 /**
366 * The version introduced by the Java Platform, Standard Edition
367 * 25.
368 *
369 * @since 25
370 *
371 * @see <a
372 * href="https://docs.oracle.com/javase/specs/jvms/se25/html/index.html">
373 * <cite>The Java Virtual Machine Specification, Java SE 25 Edition</cite></a>
374 */
375 RELEASE_25(69),
376
377 /**
378 * The version introduced by the Java Platform, Standard Edition
379 * 26.
380 *
381 * @since 26
382 *
383 * @see <a
384 * href="https://docs.oracle.com/javase/specs/jvms/se26/html/index.html">
385 * <cite>The Java Virtual Machine Specification, Java SE 26 Edition</cite></a>
386 */
387 RELEASE_26(70),
388
389 // Reduce code churn when appending new constants
390
391 // Note to maintainers: when adding constants for newer releases,
392 // the implementation of latest() must be updated too.
393
394 /// The preview features of Valhalla.
395 /// @since 26
396 CURRENT_PREVIEW_FEATURES(ClassFile.latestMajorVersion());
397
398 private final int major;
399
400 private ClassFileFormatVersion(int major) {
401 this.major = major;
402 }
403
404 /**
405 * {@return the latest class file format version}
406 */
407 public static ClassFileFormatVersion latest() {
408 return RELEASE_26;
409 }
410
411 /**
412 * {@return the major class file version as an integer}
413 * @jvms 4.1 The {@code ClassFile} Structure
414 */
415 public int major() {
416 return major;
417 }
418
419 /**
420 * {@return the latest class file format version that is usable
421 * under the runtime version argument} If the runtime version's
422 * {@linkplain Runtime.Version#feature() feature} is greater than
423 * the feature of the {@linkplain #runtimeVersion() runtime
424 * version} of the {@linkplain #latest() latest class file format
425 * version}, an {@code IllegalArgumentException} is thrown.
426 *
427 * <p>Because the class file format versions of the Java platform
428 * have so far followed a linear progression, only the feature
429 * component of a runtime version is queried to determine the
430 * mapping to a class file format version. If that linearity
431 * changes in the future, other components of the runtime version
432 * may influence the result.
433 *
434 * @apiNote
435 * An expression to convert from a string value, for example
436 * {@code "17"}, to the corresponding class file format version,
437 * {@code RELEASE_17}, is:
438 *
439 * {@snippet lang="java" :
440 * ClassFileFormatVersion.valueOf(Runtime.Version.parse("17"))}
441 *
442 * @param rv runtime version to map to a class file format version
443 * @throws IllegalArgumentException if the feature of version
444 * argument is greater than the feature of the platform version.
445 */
446 public static ClassFileFormatVersion valueOf(Runtime.Version rv) {
447 // Could also implement this as a switch where a case was
448 // added with each new release.
449 return valueOf("RELEASE_" + rv.feature());
450 }
451
452 /**
453 * {@return the least runtime version that supports this class
454 * file format version; otherwise {@code null}} The returned
455 * runtime version has a {@linkplain Runtime.Version#feature()
456 * feature} large enough to support this class file format version
457 * and has no other elements set.
458 *
459 * Class file format versions greater than or equal to {@link
460 * RELEASE_6} have non-{@code null} results.
461 */
462 public Runtime.Version runtimeVersion() {
463 // Starting with Java SE 6, the leading digit was the primary
464 // way of identifying the platform version.
465 if (this.compareTo(RELEASE_6) >= 0) {
466 return Runtime.Version.parse(Integer.toString(ordinal()));
467 } else {
468 return null;
469 }
470 }
471
472 /**
473 * {@return the latest class file format version whose major class
474 * file version matches the argument}
475 * @param major the major class file version as an integer
476 * @throws IllegalArgumentException if the argument is outside of
477 * the range of major class file versions
478 */
479 public static ClassFileFormatVersion fromMajor(int major) {
480 if (major < 45 // RELEASE_0.major()
481 || major > latest().major()) {
482 throw new IllegalArgumentException("Out of range major class file version "
483 + major);
484 }
485 // RELEASE_0 and RELEASE_1 both have a major version of 45;
486 // return RELEASE_1 for an argument of 45.
487 return values()[major-44];
488 }
489 }