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