1 /*
  2  * Copyright (c) 2022, 2023, 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     /**
 54      * The original version.
 55      *
 56      * The format described in <cite>The Java Virtual Specification,
 57      * First Edition</cite>.
 58      */
 59     RELEASE_0(45),
 60 
 61     /**
 62      * The version recognized by the Java Platform 1.1.
 63      *
 64      * @apiNote
 65      * While {@code RELEASE_0} and {@code RELEASE_1} have the same
 66      * {@linkplain #major() major version}, several additional
 67      * attributes were defined for {@code RELEASE_1} (JVMS {@jvms
 68      * 4.7}).
 69      *
 70      */
 71     RELEASE_1(45),
 72 
 73     /**
 74      * The version introduced by the Java 2 Platform, Standard Edition,
 75      * v 1.2.
 76      *
 77      * The format described in <cite>The Java Virtual Machine
 78      * Specification, Second Edition</cite>, which includes the {@link
 79      * AccessFlag#STRICT ACC_STRICT} access flag.
 80      */
 81     RELEASE_2(46),
 82 
 83     /**
 84      * The version introduced by the Java 2 Platform, Standard Edition,
 85      * v 1.3.
 86      */
 87     RELEASE_3(47),
 88 
 89     /**
 90      * The version introduced by the Java 2 Platform, Standard Edition,
 91      * v 1.4.
 92      */
 93     RELEASE_4(48),
 94 
 95     /**
 96      * The version introduced by the Java 2 Platform, Standard
 97      * Edition 5.0.
 98      *
 99      * @see <a
100      * href="https://jcp.org/aboutJava/communityprocess/maintenance/jsr924/index.html">
101      * <cite>The Java Virtual Machine Specification, Second Edition updated for Java SE 5.0</cite></a>
102      * @see <a href="https://jcp.org/en/jsr/detail?id=14">
103      * JSR 14: Add Generic Types To The Java&trade; Programming Language</a>
104      * @see <a href="https://jcp.org/en/jsr/detail?id=175">
105      * JSR 175: A Metadata Facility for the Java&trade; Programming Language</a>
106      */
107     RELEASE_5(49),
108 
109     /**
110      * The version introduced by the Java Platform, Standard Edition
111      * 6.
112      *
113      * @see <a
114      * href="https://jcp.org/aboutJava/communityprocess/maintenance/jsr924/index2.html">
115      * <cite>The Java Virtual Machine Specification, Java SE, Second Edition updated for Java SE 6</cite></a>
116      */
117     RELEASE_6(50),
118 
119     /**
120      * The version introduced by the Java Platform, Standard Edition
121      * 7.
122      *
123      * @see <a
124      * href="https://docs.oracle.com/javase/specs/jvms/se7/html/index.html">
125      * <cite>The Java Virtual Machine Specification, Java SE 7 Edition</cite></a>
126      */
127     RELEASE_7(51),
128 
129     /**
130      * The version introduced by the Java Platform, Standard Edition
131      * 8.
132      *
133      * @see <a
134      * href="https://docs.oracle.com/javase/specs/jvms/se8/html/index.html">
135      * <cite>The Java Virtual Machine Specification, Java SE 8 Edition</cite></a>
136      * @see <a href="https://jcp.org/en/jsr/detail?id=335">
137      * JSR 335: Lambda Expressions for the Java&trade; Programming Language</a>
138      */
139     RELEASE_8(52),
140 
141     /**
142      * The version introduced by the Java Platform, Standard Edition
143      * 9.
144      *
145      * @see <a
146      * href="https://docs.oracle.com/javase/specs/jvms/se9/html/index.html">
147      * <cite>The Java Virtual Machine Specification, Java SE 9 Edition</cite></a>
148      * @see <a href="https://jcp.org/en/jsr/detail?id=376">
149      * JSR 376: Java&trade; Platform Module System</a>
150      */
151      RELEASE_9(53),
152 
153     /**
154      * The version introduced by the Java Platform, Standard Edition
155      * 10.
156      *
157      * @see <a
158      * href="https://docs.oracle.com/javase/specs/jvms/se10/html/index.html">
159      * <cite>The Java Virtual Machine Specification, Java SE 10 Edition</cite></a>
160      */
161     RELEASE_10(54),
162 
163     /**
164      * The version introduced by the Java Platform, Standard Edition
165      * 11.
166      *
167      * @see <a
168      * href="https://docs.oracle.com/javase/specs/jvms/se11/html/index.html">
169      * <cite>The Java Virtual Machine Specification, Java SE 11 Edition</cite></a>
170      * @see <a href="https://openjdk.org/jeps/181">
171      * JEP 181: Nest-Based Access Control</a>
172      */
173     RELEASE_11(55),
174 
175     /**
176      * The version introduced by the Java Platform, Standard Edition
177      * 12.
178      *
179      * @see <a
180      * href="https://docs.oracle.com/javase/specs/jvms/se12/html/index.html">
181      * <cite>The Java Virtual Machine Specification, Java SE 12 Edition</cite></a>
182      */
183     RELEASE_12(56),
184 
185     /**
186      * The version introduced by the Java Platform, Standard Edition
187      * 13.
188      *
189      * @see <a
190      * href="https://docs.oracle.com/javase/specs/jvms/se13/html/index.html">
191      * <cite>The Java Virtual Machine Specification, Java SE 13 Edition</cite></a>
192      */
193     RELEASE_13(57),
194 
195     /**
196      * The version introduced by the Java Platform, Standard Edition
197      * 14.
198      *
199      * @see <a
200      * href="https://docs.oracle.com/javase/specs/jvms/se14/html/index.html">
201      * <cite>The Java Virtual Machine Specification, Java SE 14 Edition</cite></a>
202      */
203     RELEASE_14(58),
204 
205     /**
206      * The version introduced by the Java Platform, Standard Edition
207      * 15.
208      *
209      * @see <a
210      * href="https://docs.oracle.com/javase/specs/jvms/se15/html/index.html">
211      * <cite>The Java Virtual Machine Specification, Java SE 15 Edition</cite></a>
212      * @see <a href="https://openjdk.org/jeps/371">
213      * JEP 371: Hidden Classes</a>
214      */
215     RELEASE_15(59),
216 
217     /**
218      * The version introduced by the Java Platform, Standard Edition
219      * 16.
220      *
221      * @see <a
222      * href="https://docs.oracle.com/javase/specs/jvms/se16/html/index.html">
223      * <cite>The Java Virtual Machine Specification, Java SE 16 Edition</cite></a>
224      */
225     RELEASE_16(60),
226 
227     /**
228      * The version introduced by the Java Platform, Standard Edition
229      * 17.
230      *
231      * Additions in this release include sealed classes and
232      * restoration of always-strict floating-point semantics.
233      *
234      * @see <a
235      * href="https://docs.oracle.com/javase/specs/jvms/se17/html/index.html">
236      * <cite>The Java Virtual Machine Specification, Java SE 17 Edition</cite></a>
237      * @see <a href="https://openjdk.org/jeps/306">
238      * JEP 306: Restore Always-Strict Floating-Point Semantics</a>
239      * @see <a href="https://openjdk.org/jeps/409">
240      * JEP 409: Sealed Classes</a>
241      */
242     RELEASE_17(61),
243 
244     /**
245      * The version introduced by the Java Platform, Standard Edition
246      * 18.
247      *
248      * @see <a
249      * href="https://docs.oracle.com/javase/specs/jvms/se18/html/index.html">
250      * <cite>The Java Virtual Machine Specification, Java SE 18 Edition</cite></a>
251      */
252     RELEASE_18(62),
253 
254     /**
255      * The version introduced by the Java Platform, Standard Edition
256      * 19.
257      *
258      * @see <a
259      * href="https://docs.oracle.com/javase/specs/jvms/se19/html/index.html">
260      * <cite>The Java Virtual Machine Specification, Java SE 19 Edition</cite></a>
261      */
262     RELEASE_19(63),
263 
264     /**
265      * The version introduced by the Java Platform, Standard Edition
266      * 20.
267      *
268      * @see <a
269      * href="https://docs.oracle.com/javase/specs/jvms/se20/html/index.html">
270      * <cite>The Java Virtual Machine Specification, Java SE 20 Edition</cite></a>
271      */
272     RELEASE_20(64),
273 
274     /**
275      * The version introduced by the Java Platform, Standard Edition
276      * 21.
277      *
278      * @since 21
279      *
280      * @see <a
281      * href="https://docs.oracle.com/javase/specs/jvms/se21/html/index.html">
282      * <cite>The Java Virtual Machine Specification, Java SE 21 Edition</cite></a>
283      */
284     RELEASE_21(65),
285 
286     /**
287      * The version introduced by the Java Platform, Standard Edition
288      * 22.
289      *
290      * @since 22
291      *
292      * @see <a
293      * href="https://docs.oracle.com/javase/specs/jvms/se22/html/index.html">
294      * <cite>The Java Virtual Machine Specification, Java SE 22 Edition</cite></a>
295      */
296     RELEASE_22(66),
297 
298     /**
299      * The version introduced by the Java Platform, Standard Edition
300      * 23.
301      *
302      * @since 23
303      *
304      * @see <a
305      * href="https://docs.oracle.com/javase/specs/jvms/se23/html/index.html">
306      * <cite>The Java Virtual Machine Specification, Java SE 23 Edition</cite></a>
307      */
308     RELEASE_23(67),
309     ; // Reduce code churn when appending new constants
310 
311     // Note to maintainers: when adding constants for newer releases,
312     // the implementation of latest() must be updated too.
313 
314     private final int major;
315 
316     private ClassFileFormatVersion(int major) {
317         this.major = major;
318     }
319 
320     /**
321      * {@return the latest class file format version}
322      */
323     public static ClassFileFormatVersion latest() {
324         return RELEASE_22;
325     }
326 
327     /**
328      * {@return the major class file version as an integer}
329      * @jvms 4.1 The {@code ClassFile} Structure
330      */
331     public int major() {
332         return major;
333     }
334 
335     /**
336      * {@return the latest class file format version that is usable
337      * under the runtime version argument} If the runtime version's
338      * {@linkplain Runtime.Version#feature() feature} is greater than
339      * the feature of the {@linkplain #runtimeVersion() runtime
340      * version} of the {@linkplain #latest() latest class file format
341      * version}, an {@code IllegalArgumentException} is thrown.
342      *
343      * <p>Because the class file format versions of the Java platform
344      * have so far followed a linear progression, only the feature
345      * component of a runtime version is queried to determine the
346      * mapping to a class file format version. If that linearity
347      * changes in the future, other components of the runtime version
348      * may influence the result.
349      *
350      * @apiNote
351      * An expression to convert from a string value, for example
352      * {@code "17"}, to the corresponding class file format version,
353      * {@code RELEASE_17}, is:
354      *
355      * {@snippet lang="java" :
356      * ClassFileFormatVersion.valueOf(Runtime.Version.parse("17"))}
357      *
358      * @param rv runtime version to map to a class file format version
359      * @throws IllegalArgumentException if the feature of version
360      * argument is greater than the feature of the platform version.
361      */
362     public static ClassFileFormatVersion valueOf(Runtime.Version rv) {
363         // Could also implement this as a switch where a case was
364         // added with each new release.
365         return valueOf("RELEASE_" + rv.feature());
366     }
367 
368     /**
369      * {@return the least runtime version that supports this class
370      * file format version; otherwise {@code null}} The returned
371      * runtime version has a {@linkplain Runtime.Version#feature()
372      * feature} large enough to support this class file format version
373      * and has no other elements set.
374      *
375      * Class file format versions greater than or equal to {@link
376      * RELEASE_6} have non-{@code null} results.
377      */
378     public Runtime.Version runtimeVersion() {
379         // Starting with Java SE 6, the leading digit was the primary
380         // way of identifying the platform version.
381         if (this.compareTo(RELEASE_6) >= 0) {
382             return Runtime.Version.parse(Integer.toString(ordinal()));
383         } else {
384             return null;
385         }
386     }
387 
388     /**
389      * {@return the latest class file format version whose major class
390      * file version matches the argument}
391      * @param major the major class file version as an integer
392      * @throws IllegalArgumentException if the argument is outside of
393      * the range of major class file versions
394      */
395     public static ClassFileFormatVersion fromMajor(int major) {
396         if (major < 45  // RELEASE_0.major()
397             || major > latest().major()) {
398             throw new IllegalArgumentException("Out of range major class file version "
399                                                + major);
400         }
401         // RELEASE_0 and RELEASE_1 both have a major version of 45;
402         // return RELEASE_1 for an argument of 45.
403         return values()[major-44];
404     }
405 }