io.github.dmlloyd.classfile.extras.reflect.ClassFileFormatVersion Maven / Gradle / Ivy
/*
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package io.github.dmlloyd.classfile.extras.reflect;
/**
* Class file format versions of the Java virtual machine.
*
* See the appropriate edition of The Java Virtual Machine
* Specification for information about a particular class file
* format version.
*
* Note that additional class file format version constants will be
* added to model future releases of the Java Virtual Machine
* Specification.
*
* @apiNote
* The complete version used in a class file includes a major version
* and a minor version; this enum only models the major version. A
* Java virtual machine implementation is required to support a range
* of major versions; see the corresponding edition of the The
* Java Virtual Machine Specification for details.
*
* @since 20
* @see System#getProperties System property {@code java.class.version}
*/
@SuppressWarnings("doclint:reference") // cross-module links
public enum ClassFileFormatVersion {
/**
* The original version.
*
* The format described in The Java Virtual Specification,
* First Edition.
*/
RELEASE_0(45),
/**
* The version recognized by the Java Platform 1.1.
*
* @apiNote
* While {@code RELEASE_0} and {@code RELEASE_1} have the same
* {@linkplain #major() major version}, several additional
* attributes were defined for {@code RELEASE_1} (JVMS {@jvms
* 4.7}).
*
*/
RELEASE_1(45),
/**
* The version introduced by the Java 2 Platform, Standard Edition,
* v 1.2.
*
* The format described in The Java Virtual Machine
* Specification, Second Edition, which includes the {@link
* AccessFlag#STRICT ACC_STRICT} access flag.
*/
RELEASE_2(46),
/**
* The version introduced by the Java 2 Platform, Standard Edition,
* v 1.3.
*/
RELEASE_3(47),
/**
* The version introduced by the Java 2 Platform, Standard Edition,
* v 1.4.
*/
RELEASE_4(48),
/**
* The version introduced by the Java 2 Platform, Standard
* Edition 5.0.
*
* @see
* The Java Virtual Machine Specification, Second Edition updated for Java SE 5.0
* @see
* JSR 14: Add Generic Types To The Java™ Programming Language
* @see
* JSR 175: A Metadata Facility for the Java™ Programming Language
*/
RELEASE_5(49),
/**
* The version introduced by the Java Platform, Standard Edition
* 6.
*
* @see
* The Java Virtual Machine Specification, Java SE, Second Edition updated for Java SE 6
*/
RELEASE_6(50),
/**
* The version introduced by the Java Platform, Standard Edition
* 7.
*
* @see
* The Java Virtual Machine Specification, Java SE 7 Edition
*/
RELEASE_7(51),
/**
* The version introduced by the Java Platform, Standard Edition
* 8.
*
* @see
* The Java Virtual Machine Specification, Java SE 8 Edition
* @see
* JSR 335: Lambda Expressions for the Java™ Programming Language
*/
RELEASE_8(52),
/**
* The version introduced by the Java Platform, Standard Edition
* 9.
*
* @see
* The Java Virtual Machine Specification, Java SE 9 Edition
* @see
* JSR 376: Java™ Platform Module System
*/
RELEASE_9(53),
/**
* The version introduced by the Java Platform, Standard Edition
* 10.
*
* @see
* The Java Virtual Machine Specification, Java SE 10 Edition
*/
RELEASE_10(54),
/**
* The version introduced by the Java Platform, Standard Edition
* 11.
*
* @see
* The Java Virtual Machine Specification, Java SE 11 Edition
* @see
* JEP 181: Nest-Based Access Control
*/
RELEASE_11(55),
/**
* The version introduced by the Java Platform, Standard Edition
* 12.
*
* @see
* The Java Virtual Machine Specification, Java SE 12 Edition
*/
RELEASE_12(56),
/**
* The version introduced by the Java Platform, Standard Edition
* 13.
*
* @see
* The Java Virtual Machine Specification, Java SE 13 Edition
*/
RELEASE_13(57),
/**
* The version introduced by the Java Platform, Standard Edition
* 14.
*
* @see
* The Java Virtual Machine Specification, Java SE 14 Edition
*/
RELEASE_14(58),
/**
* The version introduced by the Java Platform, Standard Edition
* 15.
*
* @see
* The Java Virtual Machine Specification, Java SE 15 Edition
* @see
* JEP 371: Hidden Classes
*/
RELEASE_15(59),
/**
* The version introduced by the Java Platform, Standard Edition
* 16.
*
* @see
* The Java Virtual Machine Specification, Java SE 16 Edition
*/
RELEASE_16(60),
/**
* The version introduced by the Java Platform, Standard Edition
* 17.
*
* Additions in this release include sealed classes and
* restoration of always-strict floating-point semantics.
*
* @see
* The Java Virtual Machine Specification, Java SE 17 Edition
* @see
* JEP 306: Restore Always-Strict Floating-Point Semantics
* @see
* JEP 409: Sealed Classes
*/
RELEASE_17(61),
/**
* The version introduced by the Java Platform, Standard Edition
* 18.
*
* @see
* The Java Virtual Machine Specification, Java SE 18 Edition
*/
RELEASE_18(62),
/**
* The version introduced by the Java Platform, Standard Edition
* 19.
*
* @see
* The Java Virtual Machine Specification, Java SE 19 Edition
*/
RELEASE_19(63),
/**
* The version introduced by the Java Platform, Standard Edition
* 20.
*
* @see
* The Java Virtual Machine Specification, Java SE 20 Edition
*/
RELEASE_20(64),
/**
* The version introduced by the Java Platform, Standard Edition
* 21.
*
* @since 21
*
* @see
* The Java Virtual Machine Specification, Java SE 21 Edition
*/
RELEASE_21(65),
/**
* The version introduced by the Java Platform, Standard Edition
* 22.
*
* @since 22
*
* @see
* The Java Virtual Machine Specification, Java SE 22 Edition
*/
RELEASE_22(66),
/**
* The version introduced by the Java Platform, Standard Edition
* 23.
*
* @since 23
*
* @see
* The Java Virtual Machine Specification, Java SE 23 Edition
*/
RELEASE_23(67),
/**
* The version introduced by the Java Platform, Standard Edition
* 24.
*
* @since 24
*
* @see
* The Java Virtual Machine Specification, Java SE 24 Edition
*/
RELEASE_24(68),
; // Reduce code churn when appending new constants
// Note to maintainers: when adding constants for newer releases,
// the implementation of latest() must be updated too.
private final int major;
private ClassFileFormatVersion(int major) {
this.major = major;
}
/**
* {@return the latest class file format version}
*/
public static ClassFileFormatVersion latest() {
return RELEASE_24;
}
/**
* {@return the major class file version as an integer}
* @jvms 4.1 The {@code ClassFile} Structure
*/
public int major() {
return major;
}
/**
* {@return the latest class file format version that is usable
* under the runtime version argument} If the runtime version's
* {@linkplain Runtime.Version#feature() feature} is greater than
* the feature of the {@linkplain #runtimeVersion() runtime
* version} of the {@linkplain #latest() latest class file format
* version}, an {@code IllegalArgumentException} is thrown.
*
*
Because the class file format versions of the Java platform
* have so far followed a linear progression, only the feature
* component of a runtime version is queried to determine the
* mapping to a class file format version. If that linearity
* changes in the future, other components of the runtime version
* may influence the result.
*
* @apiNote
* An expression to convert from a string value, for example
* {@code "17"}, to the corresponding class file format version,
* {@code RELEASE_17}, is:
*
* {@snippet lang="java" :
* ClassFileFormatVersion.valueOf(Runtime.Version.parse("17"))}
*
* @param rv runtime version to map to a class file format version
* @throws IllegalArgumentException if the feature of version
* argument is greater than the feature of the platform version.
*/
public static ClassFileFormatVersion valueOf(Runtime.Version rv) {
// Could also implement this as a switch where a case was
// added with each new release.
return valueOf("RELEASE_" + rv.feature());
}
/**
* {@return the least runtime version that supports this class
* file format version; otherwise {@code null}} The returned
* runtime version has a {@linkplain Runtime.Version#feature()
* feature} large enough to support this class file format version
* and has no other elements set.
*
* Class file format versions greater than or equal to {@link
* #RELEASE_6} have non-{@code null} results.
*/
public Runtime.Version runtimeVersion() {
// Starting with Java SE 6, the leading digit was the primary
// way of identifying the platform version.
if (this.compareTo(RELEASE_6) >= 0) {
return Runtime.Version.parse(Integer.toString(ordinal()));
} else {
return null;
}
}
/**
* {@return the latest class file format version whose major class
* file version matches the argument}
* @param major the major class file version as an integer
* @throws IllegalArgumentException if the argument is outside of
* the range of major class file versions
*/
public static ClassFileFormatVersion fromMajor(int major) {
if (major < 45 // RELEASE_0.major()
|| major > latest().major()) {
throw new IllegalArgumentException("Out of range major class file version "
+ major);
}
// RELEASE_0 and RELEASE_1 both have a major version of 45;
// return RELEASE_1 for an argument of 45.
return values()[major-44];
}
}