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