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&trade; Programming Language</a>
149      * @see <a href="https://jcp.org/en/jsr/detail?id=175">
150      * JSR 175: A Metadata Facility for the Java&trade; 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&trade; 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&trade; 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 }