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     ; // Reduce code churn when appending new constants
298 
299     // Note to maintainers: when adding constants for newer releases,
300     // the implementation of latest() must be updated too.
301 
302     private final int major;
303 
304     private ClassFileFormatVersion(int major) {
305         this.major = major;
306     }
307 
308     /**
309      * {@return the latest class file format version}
310      */
311     public static ClassFileFormatVersion latest() {
312         return RELEASE_22;
313     }
314 
315     /**
316      * {@return the major class file version as an integer}
317      * @jvms 4.1 The {@code ClassFile} Structure
318      */
319     public int major() {
320         return major;
321     }
322 
323     /**
324      * {@return the latest class file format version that is usable
325      * under the runtime version argument} If the runtime version's
326      * {@linkplain Runtime.Version#feature() feature} is greater than
327      * the feature of the {@linkplain #runtimeVersion() runtime
328      * version} of the {@linkplain #latest() latest class file format
329      * version}, an {@code IllegalArgumentException} is thrown.
330      *
331      * <p>Because the class file format versions of the Java platform
332      * have so far followed a linear progression, only the feature
333      * component of a runtime version is queried to determine the
334      * mapping to a class file format version. If that linearity
335      * changes in the future, other components of the runtime version
336      * may influence the result.
337      *
338      * @apiNote
339      * An expression to convert from a string value, for example
340      * {@code "17"}, to the corresponding class file format version,
341      * {@code RELEASE_17}, is:
342      *
343      * {@snippet lang="java" :
344      * ClassFileFormatVersion.valueOf(Runtime.Version.parse("17"))}
345      *
346      * @param rv runtime version to map to a class file format version
347      * @throws IllegalArgumentException if the feature of version
348      * argument is greater than the feature of the platform version.
349      */
350     public static ClassFileFormatVersion valueOf(Runtime.Version rv) {
351         // Could also implement this as a switch where a case was
352         // added with each new release.
353         return valueOf("RELEASE_" + rv.feature());
354     }
355 
356     /**
357      * {@return the least runtime version that supports this class
358      * file format version; otherwise {@code null}} The returned
359      * runtime version has a {@linkplain Runtime.Version#feature()
360      * feature} large enough to support this class file format version
361      * and has no other elements set.
362      *
363      * Class file format versions greater than or equal to {@link
364      * RELEASE_6} have non-{@code null} results.
365      */
366     public Runtime.Version runtimeVersion() {
367         // Starting with Java SE 6, the leading digit was the primary
368         // way of identifying the platform version.
369         if (this.compareTo(RELEASE_6) >= 0) {
370             return Runtime.Version.parse(Integer.toString(ordinal()));
371         } else {
372             return null;
373         }
374     }
375 
376     /**
377      * {@return the latest class file format version whose major class
378      * file version matches the argument}
379      * @param major the major class file version as an integer
380      * @throws IllegalArgumentException if the argument is outside of
381      * the range of major class file versions
382      */
383     public static ClassFileFormatVersion fromMajor(int major) {
384         if (major < 45  // RELEASE_0.major()
385             || major > latest().major()) {
386             throw new IllegalArgumentException("Out of range major class file version "
387                                                + major);
388         }
389         // RELEASE_0 and RELEASE_1 both have a major version of 45;
390         // return RELEASE_1 for an argument of 45.
391         return values()[major-44];
392     }
393 }