/* * Copyright (c) 2017, 2020, 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 java.lang.invoke; import java.util.List; import java.util.NoSuchElementException; import java.util.function.IntFunction; /** * An ordered sequence of constants, some of which may not yet * be present. This type is used by {@link BootstrapCallInfo} * to represent the sequence of bootstrap arguments associated * with a bootstrap method, without forcing their immediate * resolution. *
* If you use the * {@linkplain ConstantGroup#get(int) simple get method}, * the constant will be resolved, if this has not already * happened. An occasional side effect of resolution is a * {@code LinkageError}, which happens if the system * could not resolve the constant in question. *
* In order to peek at a constant without necessarily * resolving it, use the * {@linkplain ConstantGroup#get(int,Object) * non-throwing get method}. * This method will never throw a resolution error. * Instead, if the resolution would result in an error, * or if the implementation elects not to attempt * resolution at this point, then the method will * return the user-supplied sentinel value. *
* To iterate through the constants, resolving as you go, * use the iterator provided on the {@link List}-typed view. * If you supply a sentinel, resolution will be suppressed. *
* Typically the constant is drawn from a constant pool entry * in the virtual machine. Constant pool entries undergo a * one-time state transition from unresolved to resolved, * with a permanently recorded result. Usually that result * is the desired constant value, but it may also be an error. * In any case, the results displayed by a {@code ConstantGroup} * are stable in the same way. If a query to a particular * constant in a {@code ConstantGroup} throws an exception once, * it will throw the same kind of exception forever after. * If the query returns a constant value once, it will return * the same value forever after. *
* The only possible change in the status of a constant is * from the unresolved to the resolved state, and that * happens exactly once. A constant will never revert to * an unlinked state. However, from the point of view of * this interface, constants may appear to spontaneously * resolve. This is so because constant pools are global * structures shared across threads, and because * prefetching of some constants may occur, there are no * strong guarantees when the virtual machine may resolve * constants. *
* When choosing sentinel values, be aware that a constant * pool which has {@code CONSTANT_Dynamic} entries * can contain potentially any representable value, * and arbitrary implementations of {@code ConstantGroup} * are also free to produce arbitrary values. * This means some obvious choices for sentinel values, * such as {@code null}, may sometimes fail to distinguish * a resolved from an unresolved constant in the group. * The most reliable sentinel is a privately created object, * or perhaps the {@code ConstantGroup} itself. * @since 1.10 */ // public interface ConstantGroup { /// Access /** * Returns the number of constants in this group. * This value never changes, for any particular group. * @return the number of constants in this group */ int size(); /** * Returns the selected constant, resolving it if necessary. * Throws a linkage error if resolution proves impossible. * @param index which constant to select * @return the selected constant * @throws LinkageError if the selected constant needs resolution and cannot be resolved */ Object get(int index) throws LinkageError; /** * Returns the selected constant, * or the given sentinel value if there is none available. * If the constant cannot be resolved, the sentinel will be returned. * If the constant can (perhaps) be resolved, but has not yet been resolved, * then the sentinel may be returned, at the implementation's discretion. * To force resolution (and a possible exception), call {@link #get(int)}. * @param index the selected constant * @param ifNotPresent the sentinel value to return if the constant is not present * @return the selected constant, if available, else the sentinel value */ Object get(int index, Object ifNotPresent); /** * Returns an indication of whether a constant may be available. * If it returns {@code true}, it will always return true in the future, * and a call to {@link #get(int)} will never throw an exception. *
* After a normal return from {@link #get(int)} or a present * value is reported from {@link #get(int,Object)}, this method * must always return true. *
* If this method returns {@code false}, nothing in particular * can be inferred, since the query only concerns the internal * logic of the {@code ConstantGroup} object which ensures that * a successful query to a constant will always remain successful. * The only way to force a permanent decision about whether * a constant is available is to call {@link #get(int)} and * be ready for an exception if the constant is unavailable. * @param index the selected constant * @return {@code true} if the selected constant is known by * this object to be present, {@code false} if it is known * not to be present or */ boolean isPresent(int index); /// Views /** * Create a view on this group as a {@link List} view. * Any request for a constant through this view will * force resolution. * @return a {@code List} view on this group which will force resolution */ default List