Java 12 中引入 JVM 常量 API,用來更容易地對關鍵類文件 (key class-file) 和運行時構件(artefact)的名義描述
(nominal description) 進行建模,特別是對那些從常量池加載的常量,這是一項很是技術性的變化,可以以更簡
單、標準的方式處理可加載常量。
具體來講就是java.base模塊新增了java.lang.constant包(而非 java.lang.invoke.constant )。包中定義了一系列基於值的符號引用(JVMS 5.1)類型,它們可以描述每種可加載常量。html
官方api連接地址: http://cr.openjdk.java.net/~iris/se/12/latestSpec/api/java.base/java/lang/constant/pack age-summary.html Java SE > Java SE Specifications > Java Virtual Machine Specification下的第5章: Chapter 5. Loading, Linking, and Initializing https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-5.html
引入了ConstantDesc接口( ClassDesc、MethodTypeDesc、MethodHandleDesc這幾個接口直接繼承了ConstantDesc接口)以及Constable接口;ConstantDesc接口定義了resolveConstantDesc方法,Constable接口定義了describeConstable方法;String、Integer、Long、Float、Double均實現了這兩個接口,而EnumDesc實現了ConstantDesc接口。java
符號引用以純 nominal 形式描述可加載常量,與類加載或可訪問性上下文區分開。有些類能夠做爲本身的符號引用(例如 String)。而對於可連接常量,另外定義了一系列符號引用類型,具體包括: ClassDesc (Class 的可加載常量標稱描述符) ,MethodTypeDesc(方法類型常量標稱描述符) ,MethodHandleDesc (方法句柄常量標稱描述符) 和DynamicConstantDesc (動態常量標稱描述符) ,它們包含描述這些常量的 nominal 信息。此 API 對於操做類和方法的工具頗有幫助。api
public final class String implements java.io.Serializable, Comparable<String>, CharSequence,Constable, ConstantDesc {
java.lang.constant.Constable接口定義了抽象方法:antd
public interface Constable { Optional<? extends ConstantDesc> describeConstable(); }
Java 12 String 的實現源碼:oracle
@Override public Optional<String> describeConstable() { return Optional.of(this); }
很簡單,其實就是調用 Optional.of 方法返回一個 Optional 類型。jvm
新引入的接口java.lang.constant.Constable - 它用於標記constable類型,這意味着這類型的值是常量,能夠在JVMS 4.4常量池中定義。ide
Java SE > Java SE Specifications > Java Virtual Machine Specification下的第4章:
Chapter 4. The class File Format工具
String的源碼:this
/** * Returns an {@link Optional} containing the nominal descriptor for this * instance, which is the instance itself. * * @return an {@link Optional} describing the {@linkplain String} instance * @since 12 */ @Override public Optional<String> describeConstable() { return Optional.of(this); } /** * Resolves this instance as a {@link ConstantDesc}, the result of which is * the instance itself. * * @param lookup ignored * @return the {@linkplain String} instance * @since 12 */ @Override public String resolveConstantDesc(MethodHandles.Lookup lookup) { return this; }
private static void testDescribeConstable() { System.out.println("======test java 12 describeConstable======"); String name = "Java高級工程師"; Optional<String> optional = name.describeConstable(); System.out.println(optional.get()); }