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