Automatic sources dropoff on 2020-06-10 18:32:38.095721
The change is generated with prebuilt drop tool.
Change-Id: I24cbf6ba6db262a1ae1445db1427a08fee35b3b4
diff --git a/java/lang/AbstractMethodError.java b/java/lang/AbstractMethodError.java
new file mode 100644
index 0000000..e266107
--- /dev/null
+++ b/java/lang/AbstractMethodError.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1994, 2008, 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;
+
+/**
+ * Thrown when an application tries to call an abstract method.
+ * Normally, this error is caught by the compiler; this error can
+ * only occur at run time if the definition of some class has
+ * incompatibly changed since the currently executing method was last
+ * compiled.
+ *
+ * @author unascribed
+ * @since JDK1.0
+ */
+public
+class AbstractMethodError extends IncompatibleClassChangeError {
+ private static final long serialVersionUID = -1654391082989018462L;
+
+ /**
+ * Constructs an <code>AbstractMethodError</code> with no detail message.
+ */
+ public AbstractMethodError() {
+ super();
+ }
+
+ /**
+ * Constructs an <code>AbstractMethodError</code> with the specified
+ * detail message.
+ *
+ * @param s the detail message.
+ */
+ public AbstractMethodError(String s) {
+ super(s);
+ }
+}
diff --git a/java/lang/AbstractStringBuilder.java b/java/lang/AbstractStringBuilder.java
new file mode 100644
index 0000000..4c31e23
--- /dev/null
+++ b/java/lang/AbstractStringBuilder.java
@@ -0,0 +1,1466 @@
+/*
+ * Copyright (c) 2003, 2016, 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;
+
+import sun.misc.FloatingDecimal;
+import java.util.Arrays;
+
+/**
+ * A mutable sequence of characters.
+ * <p>
+ * Implements a modifiable string. At any point in time it contains some
+ * particular sequence of characters, but the length and content of the
+ * sequence can be changed through certain method calls.
+ *
+ * <p>Unless otherwise noted, passing a {@code null} argument to a constructor
+ * or method in this class will cause a {@link NullPointerException} to be
+ * thrown.
+ *
+ * @author Michael McCloskey
+ * @author Martin Buchholz
+ * @author Ulf Zibis
+ * @since 1.5
+ */
+abstract class AbstractStringBuilder implements Appendable, CharSequence {
+ /**
+ * The value is used for character storage.
+ */
+ char[] value;
+
+ /**
+ * The count is the number of characters used.
+ */
+ int count;
+
+ /**
+ * This no-arg constructor is necessary for serialization of subclasses.
+ */
+ AbstractStringBuilder() {
+ }
+
+ /**
+ * Creates an AbstractStringBuilder of the specified capacity.
+ */
+ AbstractStringBuilder(int capacity) {
+ value = new char[capacity];
+ }
+
+ /**
+ * Returns the length (character count).
+ *
+ * @return the length of the sequence of characters currently
+ * represented by this object
+ */
+ @Override
+ public int length() {
+ return count;
+ }
+
+ /**
+ * Returns the current capacity. The capacity is the amount of storage
+ * available for newly inserted characters, beyond which an allocation
+ * will occur.
+ *
+ * @return the current capacity
+ */
+ public int capacity() {
+ return value.length;
+ }
+
+ /**
+ * Ensures that the capacity is at least equal to the specified minimum.
+ * If the current capacity is less than the argument, then a new internal
+ * array is allocated with greater capacity. The new capacity is the
+ * larger of:
+ * <ul>
+ * <li>The {@code minimumCapacity} argument.
+ * <li>Twice the old capacity, plus {@code 2}.
+ * </ul>
+ * If the {@code minimumCapacity} argument is nonpositive, this
+ * method takes no action and simply returns.
+ * Note that subsequent operations on this object can reduce the
+ * actual capacity below that requested here.
+ *
+ * @param minimumCapacity the minimum desired capacity.
+ */
+ public void ensureCapacity(int minimumCapacity) {
+ if (minimumCapacity > 0)
+ ensureCapacityInternal(minimumCapacity);
+ }
+
+ /**
+ * For positive values of {@code minimumCapacity}, this method
+ * behaves like {@code ensureCapacity}, however it is never
+ * synchronized.
+ * If {@code minimumCapacity} is non positive due to numeric
+ * overflow, this method throws {@code OutOfMemoryError}.
+ */
+ private void ensureCapacityInternal(int minimumCapacity) {
+ // overflow-conscious code
+ if (minimumCapacity - value.length > 0) {
+ value = Arrays.copyOf(value,
+ newCapacity(minimumCapacity));
+ }
+ }
+
+ /**
+ * The maximum size of array to allocate (unless necessary).
+ * Some VMs reserve some header words in an array.
+ * Attempts to allocate larger arrays may result in
+ * OutOfMemoryError: Requested array size exceeds VM limit
+ */
+ private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
+
+ /**
+ * Returns a capacity at least as large as the given minimum capacity.
+ * Returns the current capacity increased by the same amount + 2 if
+ * that suffices.
+ * Will not return a capacity greater than {@code MAX_ARRAY_SIZE}
+ * unless the given minimum capacity is greater than that.
+ *
+ * @param minCapacity the desired minimum capacity
+ * @throws OutOfMemoryError if minCapacity is less than zero or
+ * greater than Integer.MAX_VALUE
+ */
+ private int newCapacity(int minCapacity) {
+ // overflow-conscious code
+ int newCapacity = (value.length << 1) + 2;
+ if (newCapacity - minCapacity < 0) {
+ newCapacity = minCapacity;
+ }
+ return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0)
+ ? hugeCapacity(minCapacity)
+ : newCapacity;
+ }
+
+ private int hugeCapacity(int minCapacity) {
+ if (Integer.MAX_VALUE - minCapacity < 0) { // overflow
+ throw new OutOfMemoryError();
+ }
+ return (minCapacity > MAX_ARRAY_SIZE)
+ ? minCapacity : MAX_ARRAY_SIZE;
+ }
+
+ /**
+ * Attempts to reduce storage used for the character sequence.
+ * If the buffer is larger than necessary to hold its current sequence of
+ * characters, then it may be resized to become more space efficient.
+ * Calling this method may, but is not required to, affect the value
+ * returned by a subsequent call to the {@link #capacity()} method.
+ */
+ public void trimToSize() {
+ if (count < value.length) {
+ value = Arrays.copyOf(value, count);
+ }
+ }
+
+ /**
+ * Sets the length of the character sequence.
+ * The sequence is changed to a new character sequence
+ * whose length is specified by the argument. For every nonnegative
+ * index <i>k</i> less than {@code newLength}, the character at
+ * index <i>k</i> in the new character sequence is the same as the
+ * character at index <i>k</i> in the old sequence if <i>k</i> is less
+ * than the length of the old character sequence; otherwise, it is the
+ * null character {@code '\u005Cu0000'}.
+ *
+ * In other words, if the {@code newLength} argument is less than
+ * the current length, the length is changed to the specified length.
+ * <p>
+ * If the {@code newLength} argument is greater than or equal
+ * to the current length, sufficient null characters
+ * ({@code '\u005Cu0000'}) are appended so that
+ * length becomes the {@code newLength} argument.
+ * <p>
+ * The {@code newLength} argument must be greater than or equal
+ * to {@code 0}.
+ *
+ * @param newLength the new length
+ * @throws IndexOutOfBoundsException if the
+ * {@code newLength} argument is negative.
+ */
+ public void setLength(int newLength) {
+ if (newLength < 0)
+ throw new StringIndexOutOfBoundsException(newLength);
+ ensureCapacityInternal(newLength);
+
+ if (count < newLength) {
+ Arrays.fill(value, count, newLength, '\0');
+ }
+
+ count = newLength;
+ }
+
+ /**
+ * Returns the {@code char} value in this sequence at the specified index.
+ * The first {@code char} value is at index {@code 0}, the next at index
+ * {@code 1}, and so on, as in array indexing.
+ * <p>
+ * The index argument must be greater than or equal to
+ * {@code 0}, and less than the length of this sequence.
+ *
+ * <p>If the {@code char} value specified by the index is a
+ * <a href="Character.html#unicode">surrogate</a>, the surrogate
+ * value is returned.
+ *
+ * @param index the index of the desired {@code char} value.
+ * @return the {@code char} value at the specified index.
+ * @throws IndexOutOfBoundsException if {@code index} is
+ * negative or greater than or equal to {@code length()}.
+ */
+ @Override
+ public char charAt(int index) {
+ if ((index < 0) || (index >= count))
+ throw new StringIndexOutOfBoundsException(index);
+ return value[index];
+ }
+
+ /**
+ * Returns the character (Unicode code point) at the specified
+ * index. The index refers to {@code char} values
+ * (Unicode code units) and ranges from {@code 0} to
+ * {@link #length()}{@code - 1}.
+ *
+ * <p> If the {@code char} value specified at the given index
+ * is in the high-surrogate range, the following index is less
+ * than the length of this sequence, and the
+ * {@code char} value at the following index is in the
+ * low-surrogate range, then the supplementary code point
+ * corresponding to this surrogate pair is returned. Otherwise,
+ * the {@code char} value at the given index is returned.
+ *
+ * @param index the index to the {@code char} values
+ * @return the code point value of the character at the
+ * {@code index}
+ * @exception IndexOutOfBoundsException if the {@code index}
+ * argument is negative or not less than the length of this
+ * sequence.
+ */
+ public int codePointAt(int index) {
+ if ((index < 0) || (index >= count)) {
+ throw new StringIndexOutOfBoundsException(index);
+ }
+ return Character.codePointAtImpl(value, index, count);
+ }
+
+ /**
+ * Returns the character (Unicode code point) before the specified
+ * index. The index refers to {@code char} values
+ * (Unicode code units) and ranges from {@code 1} to {@link
+ * #length()}.
+ *
+ * <p> If the {@code char} value at {@code (index - 1)}
+ * is in the low-surrogate range, {@code (index - 2)} is not
+ * negative, and the {@code char} value at {@code (index -
+ * 2)} is in the high-surrogate range, then the
+ * supplementary code point value of the surrogate pair is
+ * returned. If the {@code char} value at {@code index -
+ * 1} is an unpaired low-surrogate or a high-surrogate, the
+ * surrogate value is returned.
+ *
+ * @param index the index following the code point that should be returned
+ * @return the Unicode code point value before the given index.
+ * @exception IndexOutOfBoundsException if the {@code index}
+ * argument is less than 1 or greater than the length
+ * of this sequence.
+ */
+ public int codePointBefore(int index) {
+ int i = index - 1;
+ if ((i < 0) || (i >= count)) {
+ throw new StringIndexOutOfBoundsException(index);
+ }
+ return Character.codePointBeforeImpl(value, index, 0);
+ }
+
+ /**
+ * Returns the number of Unicode code points in the specified text
+ * range of this sequence. The text range begins at the specified
+ * {@code beginIndex} and extends to the {@code char} at
+ * index {@code endIndex - 1}. Thus the length (in
+ * {@code char}s) of the text range is
+ * {@code endIndex-beginIndex}. Unpaired surrogates within
+ * this sequence count as one code point each.
+ *
+ * @param beginIndex the index to the first {@code char} of
+ * the text range.
+ * @param endIndex the index after the last {@code char} of
+ * the text range.
+ * @return the number of Unicode code points in the specified text
+ * range
+ * @exception IndexOutOfBoundsException if the
+ * {@code beginIndex} is negative, or {@code endIndex}
+ * is larger than the length of this sequence, or
+ * {@code beginIndex} is larger than {@code endIndex}.
+ */
+ public int codePointCount(int beginIndex, int endIndex) {
+ if (beginIndex < 0 || endIndex > count || beginIndex > endIndex) {
+ throw new IndexOutOfBoundsException();
+ }
+ return Character.codePointCountImpl(value, beginIndex, endIndex-beginIndex);
+ }
+
+ /**
+ * Returns the index within this sequence that is offset from the
+ * given {@code index} by {@code codePointOffset} code
+ * points. Unpaired surrogates within the text range given by
+ * {@code index} and {@code codePointOffset} count as
+ * one code point each.
+ *
+ * @param index the index to be offset
+ * @param codePointOffset the offset in code points
+ * @return the index within this sequence
+ * @exception IndexOutOfBoundsException if {@code index}
+ * is negative or larger then the length of this sequence,
+ * or if {@code codePointOffset} is positive and the subsequence
+ * starting with {@code index} has fewer than
+ * {@code codePointOffset} code points,
+ * or if {@code codePointOffset} is negative and the subsequence
+ * before {@code index} has fewer than the absolute value of
+ * {@code codePointOffset} code points.
+ */
+ public int offsetByCodePoints(int index, int codePointOffset) {
+ if (index < 0 || index > count) {
+ throw new IndexOutOfBoundsException();
+ }
+ return Character.offsetByCodePointsImpl(value, 0, count,
+ index, codePointOffset);
+ }
+
+ /**
+ * Characters are copied from this sequence into the
+ * destination character array {@code dst}. The first character to
+ * be copied is at index {@code srcBegin}; the last character to
+ * be copied is at index {@code srcEnd-1}. The total number of
+ * characters to be copied is {@code srcEnd-srcBegin}. The
+ * characters are copied into the subarray of {@code dst} starting
+ * at index {@code dstBegin} and ending at index:
+ * <pre>{@code
+ * dstbegin + (srcEnd-srcBegin) - 1
+ * }</pre>
+ *
+ * @param srcBegin start copying at this offset.
+ * @param srcEnd stop copying at this offset.
+ * @param dst the array to copy the data into.
+ * @param dstBegin offset into {@code dst}.
+ * @throws IndexOutOfBoundsException if any of the following is true:
+ * <ul>
+ * <li>{@code srcBegin} is negative
+ * <li>{@code dstBegin} is negative
+ * <li>the {@code srcBegin} argument is greater than
+ * the {@code srcEnd} argument.
+ * <li>{@code srcEnd} is greater than
+ * {@code this.length()}.
+ * <li>{@code dstBegin+srcEnd-srcBegin} is greater than
+ * {@code dst.length}
+ * </ul>
+ */
+ public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
+ {
+ if (srcBegin < 0)
+ throw new StringIndexOutOfBoundsException(srcBegin);
+ if ((srcEnd < 0) || (srcEnd > count))
+ throw new StringIndexOutOfBoundsException(srcEnd);
+ if (srcBegin > srcEnd)
+ throw new StringIndexOutOfBoundsException("srcBegin > srcEnd");
+ System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
+ }
+
+ /**
+ * The character at the specified index is set to {@code ch}. This
+ * sequence is altered to represent a new character sequence that is
+ * identical to the old character sequence, except that it contains the
+ * character {@code ch} at position {@code index}.
+ * <p>
+ * The index argument must be greater than or equal to
+ * {@code 0}, and less than the length of this sequence.
+ *
+ * @param index the index of the character to modify.
+ * @param ch the new character.
+ * @throws IndexOutOfBoundsException if {@code index} is
+ * negative or greater than or equal to {@code length()}.
+ */
+ public void setCharAt(int index, char ch) {
+ if ((index < 0) || (index >= count))
+ throw new StringIndexOutOfBoundsException(index);
+ value[index] = ch;
+ }
+
+ /**
+ * Appends the string representation of the {@code Object} argument.
+ * <p>
+ * The overall effect is exactly as if the argument were converted
+ * to a string by the method {@link String#valueOf(Object)},
+ * and the characters of that string were then
+ * {@link #append(String) appended} to this character sequence.
+ *
+ * @param obj an {@code Object}.
+ * @return a reference to this object.
+ */
+ public AbstractStringBuilder append(Object obj) {
+ return append(String.valueOf(obj));
+ }
+
+ /**
+ * Appends the specified string to this character sequence.
+ * <p>
+ * The characters of the {@code String} argument are appended, in
+ * order, increasing the length of this sequence by the length of the
+ * argument. If {@code str} is {@code null}, then the four
+ * characters {@code "null"} are appended.
+ * <p>
+ * Let <i>n</i> be the length of this character sequence just prior to
+ * execution of the {@code append} method. Then the character at
+ * index <i>k</i> in the new character sequence is equal to the character
+ * at index <i>k</i> in the old character sequence, if <i>k</i> is less
+ * than <i>n</i>; otherwise, it is equal to the character at index
+ * <i>k-n</i> in the argument {@code str}.
+ *
+ * @param str a string.
+ * @return a reference to this object.
+ */
+ public AbstractStringBuilder append(String str) {
+ if (str == null)
+ return appendNull();
+ int len = str.length();
+ ensureCapacityInternal(count + len);
+ str.getChars(0, len, value, count);
+ count += len;
+ return this;
+ }
+
+ // Documentation in subclasses because of synchro difference
+ public AbstractStringBuilder append(StringBuffer sb) {
+ if (sb == null)
+ return appendNull();
+ int len = sb.length();
+ ensureCapacityInternal(count + len);
+ sb.getChars(0, len, value, count);
+ count += len;
+ return this;
+ }
+
+ /**
+ * @since 1.8
+ */
+ AbstractStringBuilder append(AbstractStringBuilder asb) {
+ if (asb == null)
+ return appendNull();
+ int len = asb.length();
+ ensureCapacityInternal(count + len);
+ asb.getChars(0, len, value, count);
+ count += len;
+ return this;
+ }
+
+ // Documentation in subclasses because of synchro difference
+ @Override
+ public AbstractStringBuilder append(CharSequence s) {
+ if (s == null)
+ return appendNull();
+ if (s instanceof String)
+ return this.append((String)s);
+ if (s instanceof AbstractStringBuilder)
+ return this.append((AbstractStringBuilder)s);
+
+ return this.append(s, 0, s.length());
+ }
+
+ private AbstractStringBuilder appendNull() {
+ int c = count;
+ ensureCapacityInternal(c + 4);
+ final char[] value = this.value;
+ value[c++] = 'n';
+ value[c++] = 'u';
+ value[c++] = 'l';
+ value[c++] = 'l';
+ count = c;
+ return this;
+ }
+
+ /**
+ * Appends a subsequence of the specified {@code CharSequence} to this
+ * sequence.
+ * <p>
+ * Characters of the argument {@code s}, starting at
+ * index {@code start}, are appended, in order, to the contents of
+ * this sequence up to the (exclusive) index {@code end}. The length
+ * of this sequence is increased by the value of {@code end - start}.
+ * <p>
+ * Let <i>n</i> be the length of this character sequence just prior to
+ * execution of the {@code append} method. Then the character at
+ * index <i>k</i> in this character sequence becomes equal to the
+ * character at index <i>k</i> in this sequence, if <i>k</i> is less than
+ * <i>n</i>; otherwise, it is equal to the character at index
+ * <i>k+start-n</i> in the argument {@code s}.
+ * <p>
+ * If {@code s} is {@code null}, then this method appends
+ * characters as if the s parameter was a sequence containing the four
+ * characters {@code "null"}.
+ *
+ * @param s the sequence to append.
+ * @param start the starting index of the subsequence to be appended.
+ * @param end the end index of the subsequence to be appended.
+ * @return a reference to this object.
+ * @throws IndexOutOfBoundsException if
+ * {@code start} is negative, or
+ * {@code start} is greater than {@code end} or
+ * {@code end} is greater than {@code s.length()}
+ */
+ @Override
+ public AbstractStringBuilder append(CharSequence s, int start, int end) {
+ if (s == null)
+ s = "null";
+ if ((start < 0) || (start > end) || (end > s.length()))
+ throw new IndexOutOfBoundsException(
+ "start " + start + ", end " + end + ", s.length() "
+ + s.length());
+ int len = end - start;
+ ensureCapacityInternal(count + len);
+ for (int i = start, j = count; i < end; i++, j++)
+ value[j] = s.charAt(i);
+ count += len;
+ return this;
+ }
+
+ /**
+ * Appends the string representation of the {@code char} array
+ * argument to this sequence.
+ * <p>
+ * The characters of the array argument are appended, in order, to
+ * the contents of this sequence. The length of this sequence
+ * increases by the length of the argument.
+ * <p>
+ * The overall effect is exactly as if the argument were converted
+ * to a string by the method {@link String#valueOf(char[])},
+ * and the characters of that string were then
+ * {@link #append(String) appended} to this character sequence.
+ *
+ * @param str the characters to be appended.
+ * @return a reference to this object.
+ */
+ public AbstractStringBuilder append(char[] str) {
+ int len = str.length;
+ ensureCapacityInternal(count + len);
+ System.arraycopy(str, 0, value, count, len);
+ count += len;
+ return this;
+ }
+
+ /**
+ * Appends the string representation of a subarray of the
+ * {@code char} array argument to this sequence.
+ * <p>
+ * Characters of the {@code char} array {@code str}, starting at
+ * index {@code offset}, are appended, in order, to the contents
+ * of this sequence. The length of this sequence increases
+ * by the value of {@code len}.
+ * <p>
+ * The overall effect is exactly as if the arguments were converted
+ * to a string by the method {@link String#valueOf(char[],int,int)},
+ * and the characters of that string were then
+ * {@link #append(String) appended} to this character sequence.
+ *
+ * @param str the characters to be appended.
+ * @param offset the index of the first {@code char} to append.
+ * @param len the number of {@code char}s to append.
+ * @return a reference to this object.
+ * @throws IndexOutOfBoundsException
+ * if {@code offset < 0} or {@code len < 0}
+ * or {@code offset+len > str.length}
+ */
+ public AbstractStringBuilder append(char str[], int offset, int len) {
+ if (len > 0) // let arraycopy report AIOOBE for len < 0
+ ensureCapacityInternal(count + len);
+ System.arraycopy(str, offset, value, count, len);
+ count += len;
+ return this;
+ }
+
+ /**
+ * Appends the string representation of the {@code boolean}
+ * argument to the sequence.
+ * <p>
+ * The overall effect is exactly as if the argument were converted
+ * to a string by the method {@link String#valueOf(boolean)},
+ * and the characters of that string were then
+ * {@link #append(String) appended} to this character sequence.
+ *
+ * @param b a {@code boolean}.
+ * @return a reference to this object.
+ */
+ public AbstractStringBuilder append(boolean b) {
+ if (b) {
+ ensureCapacityInternal(count + 4);
+ value[count++] = 't';
+ value[count++] = 'r';
+ value[count++] = 'u';
+ value[count++] = 'e';
+ } else {
+ ensureCapacityInternal(count + 5);
+ value[count++] = 'f';
+ value[count++] = 'a';
+ value[count++] = 'l';
+ value[count++] = 's';
+ value[count++] = 'e';
+ }
+ return this;
+ }
+
+ /**
+ * Appends the string representation of the {@code char}
+ * argument to this sequence.
+ * <p>
+ * The argument is appended to the contents of this sequence.
+ * The length of this sequence increases by {@code 1}.
+ * <p>
+ * The overall effect is exactly as if the argument were converted
+ * to a string by the method {@link String#valueOf(char)},
+ * and the character in that string were then
+ * {@link #append(String) appended} to this character sequence.
+ *
+ * @param c a {@code char}.
+ * @return a reference to this object.
+ */
+ @Override
+ public AbstractStringBuilder append(char c) {
+ ensureCapacityInternal(count + 1);
+ value[count++] = c;
+ return this;
+ }
+
+ /**
+ * Appends the string representation of the {@code int}
+ * argument to this sequence.
+ * <p>
+ * The overall effect is exactly as if the argument were converted
+ * to a string by the method {@link String#valueOf(int)},
+ * and the characters of that string were then
+ * {@link #append(String) appended} to this character sequence.
+ *
+ * @param i an {@code int}.
+ * @return a reference to this object.
+ */
+ public AbstractStringBuilder append(int i) {
+ if (i == Integer.MIN_VALUE) {
+ append("-2147483648");
+ return this;
+ }
+ int appendedLength = (i < 0) ? Integer.stringSize(-i) + 1
+ : Integer.stringSize(i);
+ int spaceNeeded = count + appendedLength;
+ ensureCapacityInternal(spaceNeeded);
+ Integer.getChars(i, spaceNeeded, value);
+ count = spaceNeeded;
+ return this;
+ }
+
+ /**
+ * Appends the string representation of the {@code long}
+ * argument to this sequence.
+ * <p>
+ * The overall effect is exactly as if the argument were converted
+ * to a string by the method {@link String#valueOf(long)},
+ * and the characters of that string were then
+ * {@link #append(String) appended} to this character sequence.
+ *
+ * @param l a {@code long}.
+ * @return a reference to this object.
+ */
+ public AbstractStringBuilder append(long l) {
+ if (l == Long.MIN_VALUE) {
+ append("-9223372036854775808");
+ return this;
+ }
+ int appendedLength = (l < 0) ? Long.stringSize(-l) + 1
+ : Long.stringSize(l);
+ int spaceNeeded = count + appendedLength;
+ ensureCapacityInternal(spaceNeeded);
+ Long.getChars(l, spaceNeeded, value);
+ count = spaceNeeded;
+ return this;
+ }
+
+ /**
+ * Appends the string representation of the {@code float}
+ * argument to this sequence.
+ * <p>
+ * The overall effect is exactly as if the argument were converted
+ * to a string by the method {@link String#valueOf(float)},
+ * and the characters of that string were then
+ * {@link #append(String) appended} to this character sequence.
+ *
+ * @param f a {@code float}.
+ * @return a reference to this object.
+ */
+ public AbstractStringBuilder append(float f) {
+ FloatingDecimal.appendTo(f,this);
+ return this;
+ }
+
+ /**
+ * Appends the string representation of the {@code double}
+ * argument to this sequence.
+ * <p>
+ * The overall effect is exactly as if the argument were converted
+ * to a string by the method {@link String#valueOf(double)},
+ * and the characters of that string were then
+ * {@link #append(String) appended} to this character sequence.
+ *
+ * @param d a {@code double}.
+ * @return a reference to this object.
+ */
+ public AbstractStringBuilder append(double d) {
+ FloatingDecimal.appendTo(d,this);
+ return this;
+ }
+
+ /**
+ * Removes the characters in a substring of this sequence.
+ * The substring begins at the specified {@code start} and extends to
+ * the character at index {@code end - 1} or to the end of the
+ * sequence if no such character exists. If
+ * {@code start} is equal to {@code end}, no changes are made.
+ *
+ * @param start The beginning index, inclusive.
+ * @param end The ending index, exclusive.
+ * @return This object.
+ * @throws StringIndexOutOfBoundsException if {@code start}
+ * is negative, greater than {@code length()}, or
+ * greater than {@code end}.
+ */
+ public AbstractStringBuilder delete(int start, int end) {
+ if (start < 0)
+ throw new StringIndexOutOfBoundsException(start);
+ if (end > count)
+ end = count;
+ if (start > end)
+ throw new StringIndexOutOfBoundsException();
+ int len = end - start;
+ if (len > 0) {
+ System.arraycopy(value, start+len, value, start, count-end);
+ count -= len;
+ }
+ return this;
+ }
+
+ /**
+ * Appends the string representation of the {@code codePoint}
+ * argument to this sequence.
+ *
+ * <p> The argument is appended to the contents of this sequence.
+ * The length of this sequence increases by
+ * {@link Character#charCount(int) Character.charCount(codePoint)}.
+ *
+ * <p> The overall effect is exactly as if the argument were
+ * converted to a {@code char} array by the method
+ * {@link Character#toChars(int)} and the character in that array
+ * were then {@link #append(char[]) appended} to this character
+ * sequence.
+ *
+ * @param codePoint a Unicode code point
+ * @return a reference to this object.
+ * @exception IllegalArgumentException if the specified
+ * {@code codePoint} isn't a valid Unicode code point
+ */
+ public AbstractStringBuilder appendCodePoint(int codePoint) {
+ final int count = this.count;
+
+ if (Character.isBmpCodePoint(codePoint)) {
+ ensureCapacityInternal(count + 1);
+ value[count] = (char) codePoint;
+ this.count = count + 1;
+ } else if (Character.isValidCodePoint(codePoint)) {
+ ensureCapacityInternal(count + 2);
+ Character.toSurrogates(codePoint, value, count);
+ this.count = count + 2;
+ } else {
+ throw new IllegalArgumentException();
+ }
+ return this;
+ }
+
+ /**
+ * Removes the {@code char} at the specified position in this
+ * sequence. This sequence is shortened by one {@code char}.
+ *
+ * <p>Note: If the character at the given index is a supplementary
+ * character, this method does not remove the entire character. If
+ * correct handling of supplementary characters is required,
+ * determine the number of {@code char}s to remove by calling
+ * {@code Character.charCount(thisSequence.codePointAt(index))},
+ * where {@code thisSequence} is this sequence.
+ *
+ * @param index Index of {@code char} to remove
+ * @return This object.
+ * @throws StringIndexOutOfBoundsException if the {@code index}
+ * is negative or greater than or equal to
+ * {@code length()}.
+ */
+ public AbstractStringBuilder deleteCharAt(int index) {
+ if ((index < 0) || (index >= count))
+ throw new StringIndexOutOfBoundsException(index);
+ System.arraycopy(value, index+1, value, index, count-index-1);
+ count--;
+ return this;
+ }
+
+ /**
+ * Replaces the characters in a substring of this sequence
+ * with characters in the specified {@code String}. The substring
+ * begins at the specified {@code start} and extends to the character
+ * at index {@code end - 1} or to the end of the
+ * sequence if no such character exists. First the
+ * characters in the substring are removed and then the specified
+ * {@code String} is inserted at {@code start}. (This
+ * sequence will be lengthened to accommodate the
+ * specified String if necessary.)
+ *
+ * @param start The beginning index, inclusive.
+ * @param end The ending index, exclusive.
+ * @param str String that will replace previous contents.
+ * @return This object.
+ * @throws StringIndexOutOfBoundsException if {@code start}
+ * is negative, greater than {@code length()}, or
+ * greater than {@code end}.
+ */
+ public AbstractStringBuilder replace(int start, int end, String str) {
+ if (start < 0)
+ throw new StringIndexOutOfBoundsException(start);
+ if (start > count)
+ throw new StringIndexOutOfBoundsException("start > length()");
+ if (start > end)
+ throw new StringIndexOutOfBoundsException("start > end");
+
+ if (end > count)
+ end = count;
+ int len = str.length();
+ int newCount = count + len - (end - start);
+ ensureCapacityInternal(newCount);
+
+ System.arraycopy(value, end, value, start + len, count - end);
+ str.getChars(value, start);
+ count = newCount;
+ return this;
+ }
+
+ /**
+ * Returns a new {@code String} that contains a subsequence of
+ * characters currently contained in this character sequence. The
+ * substring begins at the specified index and extends to the end of
+ * this sequence.
+ *
+ * @param start The beginning index, inclusive.
+ * @return The new string.
+ * @throws StringIndexOutOfBoundsException if {@code start} is
+ * less than zero, or greater than the length of this object.
+ */
+ public String substring(int start) {
+ return substring(start, count);
+ }
+
+ /**
+ * Returns a new character sequence that is a subsequence of this sequence.
+ *
+ * <p> An invocation of this method of the form
+ *
+ * <pre>{@code
+ * sb.subSequence(begin, end)}</pre>
+ *
+ * behaves in exactly the same way as the invocation
+ *
+ * <pre>{@code
+ * sb.substring(begin, end)}</pre>
+ *
+ * This method is provided so that this class can
+ * implement the {@link CharSequence} interface.
+ *
+ * @param start the start index, inclusive.
+ * @param end the end index, exclusive.
+ * @return the specified subsequence.
+ *
+ * @throws IndexOutOfBoundsException
+ * if {@code start} or {@code end} are negative,
+ * if {@code end} is greater than {@code length()},
+ * or if {@code start} is greater than {@code end}
+ * @spec JSR-51
+ */
+ @Override
+ public CharSequence subSequence(int start, int end) {
+ return substring(start, end);
+ }
+
+ /**
+ * Returns a new {@code String} that contains a subsequence of
+ * characters currently contained in this sequence. The
+ * substring begins at the specified {@code start} and
+ * extends to the character at index {@code end - 1}.
+ *
+ * @param start The beginning index, inclusive.
+ * @param end The ending index, exclusive.
+ * @return The new string.
+ * @throws StringIndexOutOfBoundsException if {@code start}
+ * or {@code end} are negative or greater than
+ * {@code length()}, or {@code start} is
+ * greater than {@code end}.
+ */
+ public String substring(int start, int end) {
+ if (start < 0)
+ throw new StringIndexOutOfBoundsException(start);
+ if (end > count)
+ throw new StringIndexOutOfBoundsException(end);
+ if (start > end)
+ throw new StringIndexOutOfBoundsException(end - start);
+ return new String(value, start, end - start);
+ }
+
+ /**
+ * Inserts the string representation of a subarray of the {@code str}
+ * array argument into this sequence. The subarray begins at the
+ * specified {@code offset} and extends {@code len} {@code char}s.
+ * The characters of the subarray are inserted into this sequence at
+ * the position indicated by {@code index}. The length of this
+ * sequence increases by {@code len} {@code char}s.
+ *
+ * @param index position at which to insert subarray.
+ * @param str A {@code char} array.
+ * @param offset the index of the first {@code char} in subarray to
+ * be inserted.
+ * @param len the number of {@code char}s in the subarray to
+ * be inserted.
+ * @return This object
+ * @throws StringIndexOutOfBoundsException if {@code index}
+ * is negative or greater than {@code length()}, or
+ * {@code offset} or {@code len} are negative, or
+ * {@code (offset+len)} is greater than
+ * {@code str.length}.
+ */
+ public AbstractStringBuilder insert(int index, char[] str, int offset,
+ int len)
+ {
+ if ((index < 0) || (index > length()))
+ throw new StringIndexOutOfBoundsException(index);
+ if ((offset < 0) || (len < 0) || (offset > str.length - len))
+ throw new StringIndexOutOfBoundsException(
+ "offset " + offset + ", len " + len + ", str.length "
+ + str.length);
+ ensureCapacityInternal(count + len);
+ System.arraycopy(value, index, value, index + len, count - index);
+ System.arraycopy(str, offset, value, index, len);
+ count += len;
+ return this;
+ }
+
+ /**
+ * Inserts the string representation of the {@code Object}
+ * argument into this character sequence.
+ * <p>
+ * The overall effect is exactly as if the second argument were
+ * converted to a string by the method {@link String#valueOf(Object)},
+ * and the characters of that string were then
+ * {@link #insert(int,String) inserted} into this character
+ * sequence at the indicated offset.
+ * <p>
+ * The {@code offset} argument must be greater than or equal to
+ * {@code 0}, and less than or equal to the {@linkplain #length() length}
+ * of this sequence.
+ *
+ * @param offset the offset.
+ * @param obj an {@code Object}.
+ * @return a reference to this object.
+ * @throws StringIndexOutOfBoundsException if the offset is invalid.
+ */
+ public AbstractStringBuilder insert(int offset, Object obj) {
+ return insert(offset, String.valueOf(obj));
+ }
+
+ /**
+ * Inserts the string into this character sequence.
+ * <p>
+ * The characters of the {@code String} argument are inserted, in
+ * order, into this sequence at the indicated offset, moving up any
+ * characters originally above that position and increasing the length
+ * of this sequence by the length of the argument. If
+ * {@code str} is {@code null}, then the four characters
+ * {@code "null"} are inserted into this sequence.
+ * <p>
+ * The character at index <i>k</i> in the new character sequence is
+ * equal to:
+ * <ul>
+ * <li>the character at index <i>k</i> in the old character sequence, if
+ * <i>k</i> is less than {@code offset}
+ * <li>the character at index <i>k</i>{@code -offset} in the
+ * argument {@code str}, if <i>k</i> is not less than
+ * {@code offset} but is less than {@code offset+str.length()}
+ * <li>the character at index <i>k</i>{@code -str.length()} in the
+ * old character sequence, if <i>k</i> is not less than
+ * {@code offset+str.length()}
+ * </ul><p>
+ * The {@code offset} argument must be greater than or equal to
+ * {@code 0}, and less than or equal to the {@linkplain #length() length}
+ * of this sequence.
+ *
+ * @param offset the offset.
+ * @param str a string.
+ * @return a reference to this object.
+ * @throws StringIndexOutOfBoundsException if the offset is invalid.
+ */
+ public AbstractStringBuilder insert(int offset, String str) {
+ if ((offset < 0) || (offset > length()))
+ throw new StringIndexOutOfBoundsException(offset);
+ if (str == null)
+ str = "null";
+ int len = str.length();
+ ensureCapacityInternal(count + len);
+ System.arraycopy(value, offset, value, offset + len, count - offset);
+ str.getChars(value, offset);
+ count += len;
+ return this;
+ }
+
+ /**
+ * Inserts the string representation of the {@code char} array
+ * argument into this sequence.
+ * <p>
+ * The characters of the array argument are inserted into the
+ * contents of this sequence at the position indicated by
+ * {@code offset}. The length of this sequence increases by
+ * the length of the argument.
+ * <p>
+ * The overall effect is exactly as if the second argument were
+ * converted to a string by the method {@link String#valueOf(char[])},
+ * and the characters of that string were then
+ * {@link #insert(int,String) inserted} into this character
+ * sequence at the indicated offset.
+ * <p>
+ * The {@code offset} argument must be greater than or equal to
+ * {@code 0}, and less than or equal to the {@linkplain #length() length}
+ * of this sequence.
+ *
+ * @param offset the offset.
+ * @param str a character array.
+ * @return a reference to this object.
+ * @throws StringIndexOutOfBoundsException if the offset is invalid.
+ */
+ public AbstractStringBuilder insert(int offset, char[] str) {
+ if ((offset < 0) || (offset > length()))
+ throw new StringIndexOutOfBoundsException(offset);
+ int len = str.length;
+ ensureCapacityInternal(count + len);
+ System.arraycopy(value, offset, value, offset + len, count - offset);
+ System.arraycopy(str, 0, value, offset, len);
+ count += len;
+ return this;
+ }
+
+ /**
+ * Inserts the specified {@code CharSequence} into this sequence.
+ * <p>
+ * The characters of the {@code CharSequence} argument are inserted,
+ * in order, into this sequence at the indicated offset, moving up
+ * any characters originally above that position and increasing the length
+ * of this sequence by the length of the argument s.
+ * <p>
+ * The result of this method is exactly the same as if it were an
+ * invocation of this object's
+ * {@link #insert(int,CharSequence,int,int) insert}(dstOffset, s, 0, s.length())
+ * method.
+ *
+ * <p>If {@code s} is {@code null}, then the four characters
+ * {@code "null"} are inserted into this sequence.
+ *
+ * @param dstOffset the offset.
+ * @param s the sequence to be inserted
+ * @return a reference to this object.
+ * @throws IndexOutOfBoundsException if the offset is invalid.
+ */
+ public AbstractStringBuilder insert(int dstOffset, CharSequence s) {
+ if (s == null)
+ s = "null";
+ if (s instanceof String)
+ return this.insert(dstOffset, (String)s);
+ return this.insert(dstOffset, s, 0, s.length());
+ }
+
+ /**
+ * Inserts a subsequence of the specified {@code CharSequence} into
+ * this sequence.
+ * <p>
+ * The subsequence of the argument {@code s} specified by
+ * {@code start} and {@code end} are inserted,
+ * in order, into this sequence at the specified destination offset, moving
+ * up any characters originally above that position. The length of this
+ * sequence is increased by {@code end - start}.
+ * <p>
+ * The character at index <i>k</i> in this sequence becomes equal to:
+ * <ul>
+ * <li>the character at index <i>k</i> in this sequence, if
+ * <i>k</i> is less than {@code dstOffset}
+ * <li>the character at index <i>k</i>{@code +start-dstOffset} in
+ * the argument {@code s}, if <i>k</i> is greater than or equal to
+ * {@code dstOffset} but is less than {@code dstOffset+end-start}
+ * <li>the character at index <i>k</i>{@code -(end-start)} in this
+ * sequence, if <i>k</i> is greater than or equal to
+ * {@code dstOffset+end-start}
+ * </ul><p>
+ * The {@code dstOffset} argument must be greater than or equal to
+ * {@code 0}, and less than or equal to the {@linkplain #length() length}
+ * of this sequence.
+ * <p>The start argument must be nonnegative, and not greater than
+ * {@code end}.
+ * <p>The end argument must be greater than or equal to
+ * {@code start}, and less than or equal to the length of s.
+ *
+ * <p>If {@code s} is {@code null}, then this method inserts
+ * characters as if the s parameter was a sequence containing the four
+ * characters {@code "null"}.
+ *
+ * @param dstOffset the offset in this sequence.
+ * @param s the sequence to be inserted.
+ * @param start the starting index of the subsequence to be inserted.
+ * @param end the end index of the subsequence to be inserted.
+ * @return a reference to this object.
+ * @throws IndexOutOfBoundsException if {@code dstOffset}
+ * is negative or greater than {@code this.length()}, or
+ * {@code start} or {@code end} are negative, or
+ * {@code start} is greater than {@code end} or
+ * {@code end} is greater than {@code s.length()}
+ */
+ public AbstractStringBuilder insert(int dstOffset, CharSequence s,
+ int start, int end) {
+ if (s == null)
+ s = "null";
+ if ((dstOffset < 0) || (dstOffset > this.length()))
+ throw new IndexOutOfBoundsException("dstOffset "+dstOffset);
+ if ((start < 0) || (end < 0) || (start > end) || (end > s.length()))
+ throw new IndexOutOfBoundsException(
+ "start " + start + ", end " + end + ", s.length() "
+ + s.length());
+ int len = end - start;
+ ensureCapacityInternal(count + len);
+ System.arraycopy(value, dstOffset, value, dstOffset + len,
+ count - dstOffset);
+ for (int i=start; i<end; i++)
+ value[dstOffset++] = s.charAt(i);
+ count += len;
+ return this;
+ }
+
+ /**
+ * Inserts the string representation of the {@code boolean}
+ * argument into this sequence.
+ * <p>
+ * The overall effect is exactly as if the second argument were
+ * converted to a string by the method {@link String#valueOf(boolean)},
+ * and the characters of that string were then
+ * {@link #insert(int,String) inserted} into this character
+ * sequence at the indicated offset.
+ * <p>
+ * The {@code offset} argument must be greater than or equal to
+ * {@code 0}, and less than or equal to the {@linkplain #length() length}
+ * of this sequence.
+ *
+ * @param offset the offset.
+ * @param b a {@code boolean}.
+ * @return a reference to this object.
+ * @throws StringIndexOutOfBoundsException if the offset is invalid.
+ */
+ public AbstractStringBuilder insert(int offset, boolean b) {
+ return insert(offset, String.valueOf(b));
+ }
+
+ /**
+ * Inserts the string representation of the {@code char}
+ * argument into this sequence.
+ * <p>
+ * The overall effect is exactly as if the second argument were
+ * converted to a string by the method {@link String#valueOf(char)},
+ * and the character in that string were then
+ * {@link #insert(int,String) inserted} into this character
+ * sequence at the indicated offset.
+ * <p>
+ * The {@code offset} argument must be greater than or equal to
+ * {@code 0}, and less than or equal to the {@linkplain #length() length}
+ * of this sequence.
+ *
+ * @param offset the offset.
+ * @param c a {@code char}.
+ * @return a reference to this object.
+ * @throws IndexOutOfBoundsException if the offset is invalid.
+ */
+ public AbstractStringBuilder insert(int offset, char c) {
+ ensureCapacityInternal(count + 1);
+ System.arraycopy(value, offset, value, offset + 1, count - offset);
+ value[offset] = c;
+ count += 1;
+ return this;
+ }
+
+ /**
+ * Inserts the string representation of the second {@code int}
+ * argument into this sequence.
+ * <p>
+ * The overall effect is exactly as if the second argument were
+ * converted to a string by the method {@link String#valueOf(int)},
+ * and the characters of that string were then
+ * {@link #insert(int,String) inserted} into this character
+ * sequence at the indicated offset.
+ * <p>
+ * The {@code offset} argument must be greater than or equal to
+ * {@code 0}, and less than or equal to the {@linkplain #length() length}
+ * of this sequence.
+ *
+ * @param offset the offset.
+ * @param i an {@code int}.
+ * @return a reference to this object.
+ * @throws StringIndexOutOfBoundsException if the offset is invalid.
+ */
+ public AbstractStringBuilder insert(int offset, int i) {
+ return insert(offset, String.valueOf(i));
+ }
+
+ /**
+ * Inserts the string representation of the {@code long}
+ * argument into this sequence.
+ * <p>
+ * The overall effect is exactly as if the second argument were
+ * converted to a string by the method {@link String#valueOf(long)},
+ * and the characters of that string were then
+ * {@link #insert(int,String) inserted} into this character
+ * sequence at the indicated offset.
+ * <p>
+ * The {@code offset} argument must be greater than or equal to
+ * {@code 0}, and less than or equal to the {@linkplain #length() length}
+ * of this sequence.
+ *
+ * @param offset the offset.
+ * @param l a {@code long}.
+ * @return a reference to this object.
+ * @throws StringIndexOutOfBoundsException if the offset is invalid.
+ */
+ public AbstractStringBuilder insert(int offset, long l) {
+ return insert(offset, String.valueOf(l));
+ }
+
+ /**
+ * Inserts the string representation of the {@code float}
+ * argument into this sequence.
+ * <p>
+ * The overall effect is exactly as if the second argument were
+ * converted to a string by the method {@link String#valueOf(float)},
+ * and the characters of that string were then
+ * {@link #insert(int,String) inserted} into this character
+ * sequence at the indicated offset.
+ * <p>
+ * The {@code offset} argument must be greater than or equal to
+ * {@code 0}, and less than or equal to the {@linkplain #length() length}
+ * of this sequence.
+ *
+ * @param offset the offset.
+ * @param f a {@code float}.
+ * @return a reference to this object.
+ * @throws StringIndexOutOfBoundsException if the offset is invalid.
+ */
+ public AbstractStringBuilder insert(int offset, float f) {
+ return insert(offset, String.valueOf(f));
+ }
+
+ /**
+ * Inserts the string representation of the {@code double}
+ * argument into this sequence.
+ * <p>
+ * The overall effect is exactly as if the second argument were
+ * converted to a string by the method {@link String#valueOf(double)},
+ * and the characters of that string were then
+ * {@link #insert(int,String) inserted} into this character
+ * sequence at the indicated offset.
+ * <p>
+ * The {@code offset} argument must be greater than or equal to
+ * {@code 0}, and less than or equal to the {@linkplain #length() length}
+ * of this sequence.
+ *
+ * @param offset the offset.
+ * @param d a {@code double}.
+ * @return a reference to this object.
+ * @throws StringIndexOutOfBoundsException if the offset is invalid.
+ */
+ public AbstractStringBuilder insert(int offset, double d) {
+ return insert(offset, String.valueOf(d));
+ }
+
+ /**
+ * Returns the index within this string of the first occurrence of the
+ * specified substring. The integer returned is the smallest value
+ * <i>k</i> such that:
+ * <pre>{@code
+ * this.toString().startsWith(str, <i>k</i>)
+ * }</pre>
+ * is {@code true}.
+ *
+ * @param str any string.
+ * @return if the string argument occurs as a substring within this
+ * object, then the index of the first character of the first
+ * such substring is returned; if it does not occur as a
+ * substring, {@code -1} is returned.
+ */
+ public int indexOf(String str) {
+ return indexOf(str, 0);
+ }
+
+ /**
+ * Returns the index within this string of the first occurrence of the
+ * specified substring, starting at the specified index. The integer
+ * returned is the smallest value {@code k} for which:
+ * <pre>{@code
+ * k >= Math.min(fromIndex, this.length()) &&
+ * this.toString().startsWith(str, k)
+ * }</pre>
+ * If no such value of <i>k</i> exists, then -1 is returned.
+ *
+ * @param str the substring for which to search.
+ * @param fromIndex the index from which to start the search.
+ * @return the index within this string of the first occurrence of the
+ * specified substring, starting at the specified index.
+ */
+ public int indexOf(String str, int fromIndex) {
+ return String.indexOf(value, 0, count, str, fromIndex);
+ }
+
+ /**
+ * Returns the index within this string of the rightmost occurrence
+ * of the specified substring. The rightmost empty string "" is
+ * considered to occur at the index value {@code this.length()}.
+ * The returned index is the largest value <i>k</i> such that
+ * <pre>{@code
+ * this.toString().startsWith(str, k)
+ * }</pre>
+ * is true.
+ *
+ * @param str the substring to search for.
+ * @return if the string argument occurs one or more times as a substring
+ * within this object, then the index of the first character of
+ * the last such substring is returned. If it does not occur as
+ * a substring, {@code -1} is returned.
+ */
+ public int lastIndexOf(String str) {
+ return lastIndexOf(str, count);
+ }
+
+ /**
+ * Returns the index within this string of the last occurrence of the
+ * specified substring. The integer returned is the largest value <i>k</i>
+ * such that:
+ * <pre>{@code
+ * k <= Math.min(fromIndex, this.length()) &&
+ * this.toString().startsWith(str, k)
+ * }</pre>
+ * If no such value of <i>k</i> exists, then -1 is returned.
+ *
+ * @param str the substring to search for.
+ * @param fromIndex the index to start the search from.
+ * @return the index within this sequence of the last occurrence of the
+ * specified substring.
+ */
+ public int lastIndexOf(String str, int fromIndex) {
+ return String.lastIndexOf(value, 0, count, str, fromIndex);
+ }
+
+ /**
+ * Causes this character sequence to be replaced by the reverse of
+ * the sequence. If there are any surrogate pairs included in the
+ * sequence, these are treated as single characters for the
+ * reverse operation. Thus, the order of the high-low surrogates
+ * is never reversed.
+ *
+ * Let <i>n</i> be the character length of this character sequence
+ * (not the length in {@code char} values) just prior to
+ * execution of the {@code reverse} method. Then the
+ * character at index <i>k</i> in the new character sequence is
+ * equal to the character at index <i>n-k-1</i> in the old
+ * character sequence.
+ *
+ * <p>Note that the reverse operation may result in producing
+ * surrogate pairs that were unpaired low-surrogates and
+ * high-surrogates before the operation. For example, reversing
+ * "\u005CuDC00\u005CuD800" produces "\u005CuD800\u005CuDC00" which is
+ * a valid surrogate pair.
+ *
+ * @return a reference to this object.
+ */
+ public AbstractStringBuilder reverse() {
+ boolean hasSurrogates = false;
+ int n = count - 1;
+ for (int j = (n-1) >> 1; j >= 0; j--) {
+ int k = n - j;
+ char cj = value[j];
+ char ck = value[k];
+ value[j] = ck;
+ value[k] = cj;
+ if (Character.isSurrogate(cj) ||
+ Character.isSurrogate(ck)) {
+ hasSurrogates = true;
+ }
+ }
+ if (hasSurrogates) {
+ reverseAllValidSurrogatePairs();
+ }
+ return this;
+ }
+
+ /** Outlined helper method for reverse() */
+ private void reverseAllValidSurrogatePairs() {
+ for (int i = 0; i < count - 1; i++) {
+ char c2 = value[i];
+ if (Character.isLowSurrogate(c2)) {
+ char c1 = value[i + 1];
+ if (Character.isHighSurrogate(c1)) {
+ value[i++] = c1;
+ value[i] = c2;
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns a string representing the data in this sequence.
+ * A new {@code String} object is allocated and initialized to
+ * contain the character sequence currently represented by this
+ * object. This {@code String} is then returned. Subsequent
+ * changes to this sequence do not affect the contents of the
+ * {@code String}.
+ *
+ * @return a string representation of this sequence of characters.
+ */
+ @Override
+ public abstract String toString();
+
+ /**
+ * Needed by {@code String} for the contentEquals method.
+ */
+ final char[] getValue() {
+ return value;
+ }
+
+}
diff --git a/java/lang/AndroidHardcodedSystemProperties.java b/java/lang/AndroidHardcodedSystemProperties.java
new file mode 100644
index 0000000..931994f
--- /dev/null
+++ b/java/lang/AndroidHardcodedSystemProperties.java
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.lang;
+
+import java.util.Properties;
+
+/**
+ * A class encoding all hardcoded system property values on Android. A compiler may
+ * take advantage of these properties. Changing them at load-time (-D) or runtime
+ * may not have any effect.
+ *
+ * @hide
+ */
+public final class AndroidHardcodedSystemProperties {
+
+ // This value is shared with sun.misc.Version. It is defined here so that the compiler
+ // can use it.
+ public final static String JAVA_VERSION = "0";
+
+ final static String[][] STATIC_PROPERTIES = {
+ // None of these four are meaningful on Android, but these keys are guaranteed
+ // to be present for System.getProperty. For java.class.version, we use the maximum
+ // class file version that dx currently supports.
+ { "java.class.version", "50.0" },
+ { "java.version", JAVA_VERSION },
+ { "java.compiler", "" },
+ { "java.ext.dirs", "" },
+
+ { "java.specification.name", "Dalvik Core Library" },
+ { "java.specification.vendor", "The Android Project" },
+ { "java.specification.version", "0.9" },
+
+ { "java.vendor", "The Android Project" },
+ { "java.vendor.url", "http://www.android.com/" },
+ { "java.vm.name", "Dalvik" },
+ { "java.vm.specification.name", "Dalvik Virtual Machine Specification" },
+ { "java.vm.specification.vendor", "The Android Project" },
+ { "java.vm.specification.version", "0.9" },
+ { "java.vm.vendor", "The Android Project" },
+
+ { "java.vm.vendor.url", "http://www.android.com/" },
+
+ { "java.net.preferIPv6Addresses", "false" },
+
+ { "file.encoding", "UTF-8" },
+
+ { "file.separator", "/" },
+ { "line.separator", "\n" },
+ { "path.separator", ":" },
+
+ // Turn off ICU debugging. This allows compile-time initialization of a range of
+ // classes. b/28039175
+ { "ICUDebug", null },
+
+ // Hardcode DecimalFormat parsing flag to be default. b/27265238
+ { "android.icu.text.DecimalFormat.SkipExtendedSeparatorParsing", null },
+ // Hardcode MessagePattern apostrophe mode to be default. b/27265238
+ { "android.icu.text.MessagePattern.ApostropheMode", null },
+
+ // Hardcode "sun.io.useCanonCaches" to use the default (off). b/28174137, b/62301183
+ { "sun.io.useCanonCaches", null },
+ { "sun.io.useCanonPrefixCache", null },
+
+ // Hardcode some http properties to use the default. b/28174137
+ { "http.keepAlive", null },
+ { "http.keepAliveDuration", null },
+ { "http.maxConnections", null },
+
+ // Turn off javax.net debugging. This allows compile-time initialization of a range
+ // of classes. b/28174137
+ { "javax.net.debug", null },
+
+ // Hardcode default value for AVA. b/28174137
+ { "com.sun.security.preserveOldDCEncoding", null },
+
+ // Hardcode default value for LogManager. b/28174137
+ { "java.util.logging.manager", null },
+ };
+}
diff --git a/java/lang/Appendable.annotated.java b/java/lang/Appendable.annotated.java
new file mode 100644
index 0000000..0ef58db
--- /dev/null
+++ b/java/lang/Appendable.annotated.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2003, 2004, 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;
+
+import java.io.IOException;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface Appendable {
+
[email protected] public java.lang.Appendable append(@libcore.util.Nullable java.lang.CharSequence csq) throws java.io.IOException;
+
[email protected] public java.lang.Appendable append(@libcore.util.Nullable java.lang.CharSequence csq, int start, int end) throws java.io.IOException;
+
[email protected] public java.lang.Appendable append(char c) throws java.io.IOException;
+}
+
diff --git a/java/lang/Appendable.java b/java/lang/Appendable.java
new file mode 100644
index 0000000..46fd78d
--- /dev/null
+++ b/java/lang/Appendable.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2003, 2004, 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;
+
+import java.io.IOException;
+
+/**
+ * An object to which <tt>char</tt> sequences and values can be appended. The
+ * <tt>Appendable</tt> interface must be implemented by any class whose
+ * instances are intended to receive formatted output from a {@link
+ * java.util.Formatter}.
+ *
+ * <p> The characters to be appended should be valid Unicode characters as
+ * described in <a href="Character.html#unicode">Unicode Character
+ * Representation</a>. Note that supplementary characters may be composed of
+ * multiple 16-bit <tt>char</tt> values.
+ *
+ * <p> Appendables are not necessarily safe for multithreaded access. Thread
+ * safety is the responsibility of classes that extend and implement this
+ * interface.
+ *
+ * <p> Since this interface may be implemented by existing classes
+ * with different styles of error handling there is no guarantee that
+ * errors will be propagated to the invoker.
+ *
+ * @since 1.5
+ */
+public interface Appendable {
+
+ /**
+ * Appends the specified character sequence to this <tt>Appendable</tt>.
+ *
+ * <p> Depending on which class implements the character sequence
+ * <tt>csq</tt>, the entire sequence may not be appended. For
+ * instance, if <tt>csq</tt> is a {@link java.nio.CharBuffer} then
+ * the subsequence to append is defined by the buffer's position and limit.
+ *
+ * @param csq
+ * The character sequence to append. If <tt>csq</tt> is
+ * <tt>null</tt>, then the four characters <tt>"null"</tt> are
+ * appended to this Appendable.
+ *
+ * @return A reference to this <tt>Appendable</tt>
+ *
+ * @throws IOException
+ * If an I/O error occurs
+ */
+ Appendable append(CharSequence csq) throws IOException;
+
+ /**
+ * Appends a subsequence of the specified character sequence to this
+ * <tt>Appendable</tt>.
+ *
+ * <p> An invocation of this method of the form <tt>out.append(csq, start,
+ * end)</tt> when <tt>csq</tt> is not <tt>null</tt>, behaves in
+ * exactly the same way as the invocation
+ *
+ * <pre>
+ * out.append(csq.subSequence(start, end)) </pre>
+ *
+ * @param csq
+ * The character sequence from which a subsequence will be
+ * appended. If <tt>csq</tt> is <tt>null</tt>, then characters
+ * will be appended as if <tt>csq</tt> contained the four
+ * characters <tt>"null"</tt>.
+ *
+ * @param start
+ * The index of the first character in the subsequence
+ *
+ * @param end
+ * The index of the character following the last character in the
+ * subsequence
+ *
+ * @return A reference to this <tt>Appendable</tt>
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>start</tt> or <tt>end</tt> are negative, <tt>start</tt>
+ * is greater than <tt>end</tt>, or <tt>end</tt> is greater than
+ * <tt>csq.length()</tt>
+ *
+ * @throws IOException
+ * If an I/O error occurs
+ */
+ Appendable append(CharSequence csq, int start, int end) throws IOException;
+
+ /**
+ * Appends the specified character to this <tt>Appendable</tt>.
+ *
+ * @param c
+ * The character to append
+ *
+ * @return A reference to this <tt>Appendable</tt>
+ *
+ * @throws IOException
+ * If an I/O error occurs
+ */
+ Appendable append(char c) throws IOException;
+}
diff --git a/java/lang/ArithmeticException.java b/java/lang/ArithmeticException.java
new file mode 100644
index 0000000..af00777
--- /dev/null
+++ b/java/lang/ArithmeticException.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 1994, 2011, 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;
+
+/**
+ * Thrown when an exceptional arithmetic condition has occurred. For
+ * example, an integer "divide by zero" throws an
+ * instance of this class.
+ *
+ * {@code ArithmeticException} objects may be constructed by the
+ * virtual machine as if {@linkplain Throwable#Throwable(String,
+ * Throwable, boolean, boolean) suppression were disabled and/or the
+ * stack trace was not writable}.
+ *
+ * @author unascribed
+ * @since JDK1.0
+ */
+public class ArithmeticException extends RuntimeException {
+ private static final long serialVersionUID = 2256477558314496007L;
+
+ /**
+ * Constructs an {@code ArithmeticException} with no detail
+ * message.
+ */
+ public ArithmeticException() {
+ super();
+ }
+
+ /**
+ * Constructs an {@code ArithmeticException} with the specified
+ * detail message.
+ *
+ * @param s the detail message.
+ */
+ public ArithmeticException(String s) {
+ super(s);
+ }
+}
diff --git a/java/lang/ArrayIndexOutOfBoundsException.java b/java/lang/ArrayIndexOutOfBoundsException.java
new file mode 100644
index 0000000..d07a4b2
--- /dev/null
+++ b/java/lang/ArrayIndexOutOfBoundsException.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 2008, 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;
+
+/**
+ * Thrown to indicate that an array has been accessed with an
+ * illegal index. The index is either negative or greater than or
+ * equal to the size of the array.
+ *
+ * @author unascribed
+ * @since JDK1.0
+ */
+public
+class ArrayIndexOutOfBoundsException extends IndexOutOfBoundsException {
+ private static final long serialVersionUID = -5116101128118950844L;
+
+ /**
+ * Constructs an <code>ArrayIndexOutOfBoundsException</code> with no
+ * detail message.
+ */
+ public ArrayIndexOutOfBoundsException() {
+ super();
+ }
+
+ /**
+ * Constructs a new <code>ArrayIndexOutOfBoundsException</code>
+ * class with an argument indicating the illegal index.
+ *
+ * @param index the illegal index.
+ */
+ public ArrayIndexOutOfBoundsException(int index) {
+ super("Array index out of range: " + index);
+ }
+
+ /**
+ * Constructs an <code>ArrayIndexOutOfBoundsException</code> class
+ * with the specified detail message.
+ *
+ * @param s the detail message.
+ */
+ public ArrayIndexOutOfBoundsException(String s) {
+ super(s);
+ }
+}
diff --git a/java/lang/ArrayStoreException.java b/java/lang/ArrayStoreException.java
new file mode 100644
index 0000000..5ea0aa9
--- /dev/null
+++ b/java/lang/ArrayStoreException.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 1995, 2013, 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;
+
+/**
+ * Thrown to indicate that an attempt has been made to store the
+ * wrong type of object into an array of objects. For example, the
+ * following code generates an <code>ArrayStoreException</code>:
+ * <blockquote><pre>
+ * Object x[] = new String[3];
+ * x[0] = new Integer(0);
+ * </pre></blockquote>
+ *
+ * @author unascribed
+ * @since JDK1.0
+ */
+public
+class ArrayStoreException extends RuntimeException {
+ private static final long serialVersionUID = -4522193890499838241L;
+
+ /**
+ * Constructs an <code>ArrayStoreException</code> with no detail message.
+ */
+ public ArrayStoreException() {
+ super();
+ }
+
+ /**
+ * Constructs an <code>ArrayStoreException</code> with the specified
+ * detail message.
+ *
+ * @param s the detail message.
+ */
+ public ArrayStoreException(String s) {
+ super(s);
+ }
+}
diff --git a/java/lang/AssertionError.java b/java/lang/AssertionError.java
new file mode 100644
index 0000000..a560af5
--- /dev/null
+++ b/java/lang/AssertionError.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2000, 2011, 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;
+
+/**
+ * Thrown to indicate that an assertion has failed.
+ *
+ * <p>The seven one-argument public constructors provided by this
+ * class ensure that the assertion error returned by the invocation:
+ * <pre>
+ * new AssertionError(<i>expression</i>)
+ * </pre>
+ * has as its detail message the <i>string conversion</i> of
+ * <i>expression</i> (as defined in section 15.18.1.1 of
+ * <cite>The Java™ Language Specification</cite>),
+ * regardless of the type of <i>expression</i>.
+ *
+ * @since 1.4
+ */
+public class AssertionError extends Error {
+ private static final long serialVersionUID = -5013299493970297370L;
+
+ /**
+ * Constructs an AssertionError with no detail message.
+ */
+ public AssertionError() {
+ }
+
+ /**
+ * This internal constructor does no processing on its string argument,
+ * even if it is a null reference. The public constructors will
+ * never call this constructor with a null argument.
+ */
+ private AssertionError(String detailMessage) {
+ super(detailMessage);
+ }
+
+ /**
+ * Constructs an AssertionError with its detail message derived
+ * from the specified object, which is converted to a string as
+ * defined in section 15.18.1.1 of
+ * <cite>The Java™ Language Specification</cite>.
+ *<p>
+ * If the specified object is an instance of {@code Throwable}, it
+ * becomes the <i>cause</i> of the newly constructed assertion error.
+ *
+ * @param detailMessage value to be used in constructing detail message
+ * @see Throwable#getCause()
+ */
+ public AssertionError(Object detailMessage) {
+ this(String.valueOf(detailMessage));
+ if (detailMessage instanceof Throwable)
+ initCause((Throwable) detailMessage);
+ }
+
+ /**
+ * Constructs an AssertionError with its detail message derived
+ * from the specified <code>boolean</code>, which is converted to
+ * a string as defined in section 15.18.1.1 of
+ * <cite>The Java™ Language Specification</cite>.
+ *
+ * @param detailMessage value to be used in constructing detail message
+ */
+ public AssertionError(boolean detailMessage) {
+ this(String.valueOf(detailMessage));
+ }
+
+ /**
+ * Constructs an AssertionError with its detail message derived
+ * from the specified <code>char</code>, which is converted to a
+ * string as defined in section 15.18.1.1 of
+ * <cite>The Java™ Language Specification</cite>.
+ *
+ * @param detailMessage value to be used in constructing detail message
+ */
+ public AssertionError(char detailMessage) {
+ this(String.valueOf(detailMessage));
+ }
+
+ /**
+ * Constructs an AssertionError with its detail message derived
+ * from the specified <code>int</code>, which is converted to a
+ * string as defined in section 15.18.1.1 of
+ * <cite>The Java™ Language Specification</cite>.
+ *
+ * @param detailMessage value to be used in constructing detail message
+ */
+ public AssertionError(int detailMessage) {
+ this(String.valueOf(detailMessage));
+ }
+
+ /**
+ * Constructs an AssertionError with its detail message derived
+ * from the specified <code>long</code>, which is converted to a
+ * string as defined in section 15.18.1.1 of
+ * <cite>The Java™ Language Specification</cite>.
+ *
+ * @param detailMessage value to be used in constructing detail message
+ */
+ public AssertionError(long detailMessage) {
+ this(String.valueOf(detailMessage));
+ }
+
+ /**
+ * Constructs an AssertionError with its detail message derived
+ * from the specified <code>float</code>, which is converted to a
+ * string as defined in section 15.18.1.1 of
+ * <cite>The Java™ Language Specification</cite>.
+ *
+ * @param detailMessage value to be used in constructing detail message
+ */
+ public AssertionError(float detailMessage) {
+ this(String.valueOf(detailMessage));
+ }
+
+ /**
+ * Constructs an AssertionError with its detail message derived
+ * from the specified <code>double</code>, which is converted to a
+ * string as defined in section 15.18.1.1 of
+ * <cite>The Java™ Language Specification</cite>.
+ *
+ * @param detailMessage value to be used in constructing detail message
+ */
+ public AssertionError(double detailMessage) {
+ this(String.valueOf(detailMessage));
+ }
+
+ /**
+ * Constructs a new {@code AssertionError} with the specified
+ * detail message and cause.
+ *
+ * <p>Note that the detail message associated with
+ * {@code cause} is <i>not</i> automatically incorporated in
+ * this error's detail message.
+ *
+ * @param message the detail message, may be {@code null}
+ * @param cause the cause, may be {@code null}
+ *
+ * @since 1.7
+ */
+ public AssertionError(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/java/lang/AutoCloseable.java b/java/lang/AutoCloseable.java
new file mode 100644
index 0000000..135d9fe
--- /dev/null
+++ b/java/lang/AutoCloseable.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2009, 2013, 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;
+
+/**
+ * An object that may hold resources (such as file or socket handles)
+ * until it is closed. The {@link #close()} method of an {@code AutoCloseable}
+ * object is called automatically when exiting a {@code
+ * try}-with-resources block for which the object has been declared in
+ * the resource specification header. This construction ensures prompt
+ * release, avoiding resource exhaustion exceptions and errors that
+ * may otherwise occur.
+ *
+ * @apiNote
+ * <p>It is possible, and in fact common, for a base class to
+ * implement AutoCloseable even though not all of its subclasses or
+ * instances will hold releasable resources. For code that must operate
+ * in complete generality, or when it is known that the {@code AutoCloseable}
+ * instance requires resource release, it is recommended to use {@code
+ * try}-with-resources constructions. However, when using facilities such as
+ * {@link java.util.stream.Stream} that support both I/O-based and
+ * non-I/O-based forms, {@code try}-with-resources blocks are in
+ * general unnecessary when using non-I/O-based forms.
+ *
+ * @author Josh Bloch
+ * @since 1.7
+ */
+public interface AutoCloseable {
+ /**
+ * Closes this resource, relinquishing any underlying resources.
+ * This method is invoked automatically on objects managed by the
+ * {@code try}-with-resources statement.
+ *
+ * <p>While this interface method is declared to throw {@code
+ * Exception}, implementers are <em>strongly</em> encouraged to
+ * declare concrete implementations of the {@code close} method to
+ * throw more specific exceptions, or to throw no exception at all
+ * if the close operation cannot fail.
+ *
+ * <p> Cases where the close operation may fail require careful
+ * attention by implementers. It is strongly advised to relinquish
+ * the underlying resources and to internally <em>mark</em> the
+ * resource as closed, prior to throwing the exception. The {@code
+ * close} method is unlikely to be invoked more than once and so
+ * this ensures that the resources are released in a timely manner.
+ * Furthermore it reduces problems that could arise when the resource
+ * wraps, or is wrapped, by another resource.
+ *
+ * <p><em>Implementers of this interface are also strongly advised
+ * to not have the {@code close} method throw {@link
+ * InterruptedException}.</em>
+ *
+ * This exception interacts with a thread's interrupted status,
+ * and runtime misbehavior is likely to occur if an {@code
+ * InterruptedException} is {@linkplain Throwable#addSuppressed
+ * suppressed}.
+ *
+ * More generally, if it would cause problems for an
+ * exception to be suppressed, the {@code AutoCloseable.close}
+ * method should not throw it.
+ *
+ * <p>Note that unlike the {@link java.io.Closeable#close close}
+ * method of {@link java.io.Closeable}, this {@code close} method
+ * is <em>not</em> required to be idempotent. In other words,
+ * calling this {@code close} method more than once may have some
+ * visible side effect, unlike {@code Closeable.close} which is
+ * required to have no effect if called more than once.
+ *
+ * However, implementers of this interface are strongly encouraged
+ * to make their {@code close} methods idempotent.
+ *
+ * @throws Exception if this resource cannot be closed
+ */
+ void close() throws Exception;
+}
diff --git a/java/lang/Boolean.annotated.java b/java/lang/Boolean.annotated.java
new file mode 100644
index 0000000..8022814
--- /dev/null
+++ b/java/lang/Boolean.annotated.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 1994, 2013, 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;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Boolean implements java.io.Serializable, java.lang.Comparable<java.lang.Boolean> {
+
+public Boolean(boolean value) { throw new RuntimeException("Stub!"); }
+
+public Boolean(@libcore.util.Nullable java.lang.String s) { throw new RuntimeException("Stub!"); }
+
+public static boolean parseBoolean(@libcore.util.Nullable java.lang.String s) { throw new RuntimeException("Stub!"); }
+
+public boolean booleanValue() { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Boolean valueOf(boolean b) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Boolean valueOf(@libcore.util.Nullable java.lang.String s) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String toString(boolean b) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public static int hashCode(boolean value) { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public static boolean getBoolean(@libcore.util.NonNull java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+public int compareTo(@libcore.util.NonNull java.lang.Boolean b) { throw new RuntimeException("Stub!"); }
+
+public static int compare(boolean x, boolean y) { throw new RuntimeException("Stub!"); }
+
+public static boolean logicalAnd(boolean a, boolean b) { throw new RuntimeException("Stub!"); }
+
+public static boolean logicalOr(boolean a, boolean b) { throw new RuntimeException("Stub!"); }
+
+public static boolean logicalXor(boolean a, boolean b) { throw new RuntimeException("Stub!"); }
+
+public static final java.lang.Boolean FALSE;
+static { FALSE = null; }
+
+public static final java.lang.Boolean TRUE;
+static { TRUE = null; }
+
+public static final java.lang.Class<java.lang.Boolean> TYPE;
+static { TYPE = null; }
+}
diff --git a/java/lang/Boolean.java b/java/lang/Boolean.java
new file mode 100644
index 0000000..a9293ba
--- /dev/null
+++ b/java/lang/Boolean.java
@@ -0,0 +1,335 @@
+/*
+ * Copyright (c) 1994, 2013, 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;
+
+/**
+ * The Boolean class wraps a value of the primitive type
+ * {@code boolean} in an object. An object of type
+ * {@code Boolean} contains a single field whose type is
+ * {@code boolean}.
+ * <p>
+ * In addition, this class provides many methods for
+ * converting a {@code boolean} to a {@code String} and a
+ * {@code String} to a {@code boolean}, as well as other
+ * constants and methods useful when dealing with a
+ * {@code boolean}.
+ *
+ * @author Arthur van Hoff
+ * @since JDK1.0
+ */
+public final class Boolean implements java.io.Serializable,
+ Comparable<Boolean>
+{
+ /**
+ * The {@code Boolean} object corresponding to the primitive
+ * value {@code true}.
+ */
+ public static final Boolean TRUE = new Boolean(true);
+
+ /**
+ * The {@code Boolean} object corresponding to the primitive
+ * value {@code false}.
+ */
+ public static final Boolean FALSE = new Boolean(false);
+
+ /**
+ * The Class object representing the primitive type boolean.
+ *
+ * @since JDK1.1
+ */
+ @SuppressWarnings("unchecked")
+ public static final Class<Boolean> TYPE = (Class<Boolean>) Class.getPrimitiveClass("boolean");
+
+ /**
+ * The value of the Boolean.
+ *
+ * @serial
+ */
+ private final boolean value;
+
+ /** use serialVersionUID from JDK 1.0.2 for interoperability */
+ private static final long serialVersionUID = -3665804199014368530L;
+
+ /**
+ * Allocates a {@code Boolean} object representing the
+ * {@code value} argument.
+ *
+ * <p><b>Note: It is rarely appropriate to use this constructor.
+ * Unless a <i>new</i> instance is required, the static factory
+ * {@link #valueOf(boolean)} is generally a better choice. It is
+ * likely to yield significantly better space and time performance.</b>
+ *
+ * @param value the value of the {@code Boolean}.
+ */
+ public Boolean(boolean value) {
+ this.value = value;
+ }
+
+ /**
+ * Allocates a {@code Boolean} object representing the value
+ * {@code true} if the string argument is not {@code null}
+ * and is equal, ignoring case, to the string {@code "true"}.
+ * Otherwise, allocate a {@code Boolean} object representing the
+ * value {@code false}. Examples:<p>
+ * {@code new Boolean("True")} produces a {@code Boolean} object
+ * that represents {@code true}.<br>
+ * {@code new Boolean("yes")} produces a {@code Boolean} object
+ * that represents {@code false}.
+ *
+ * @param s the string to be converted to a {@code Boolean}.
+ */
+ public Boolean(String s) {
+ this(parseBoolean(s));
+ }
+
+ /**
+ * Parses the string argument as a boolean. The {@code boolean}
+ * returned represents the value {@code true} if the string argument
+ * is not {@code null} and is equal, ignoring case, to the string
+ * {@code "true"}. <p>
+ * Example: {@code Boolean.parseBoolean("True")} returns {@code true}.<br>
+ * Example: {@code Boolean.parseBoolean("yes")} returns {@code false}.
+ *
+ * @param s the {@code String} containing the boolean
+ * representation to be parsed
+ * @return the boolean represented by the string argument
+ * @since 1.5
+ */
+ public static boolean parseBoolean(String s) {
+ return ((s != null) && s.equalsIgnoreCase("true"));
+ }
+
+ /**
+ * Returns the value of this {@code Boolean} object as a boolean
+ * primitive.
+ *
+ * @return the primitive {@code boolean} value of this object.
+ */
+ public boolean booleanValue() {
+ return value;
+ }
+
+ /**
+ * Returns a {@code Boolean} instance representing the specified
+ * {@code boolean} value. If the specified {@code boolean} value
+ * is {@code true}, this method returns {@code Boolean.TRUE};
+ * if it is {@code false}, this method returns {@code Boolean.FALSE}.
+ * If a new {@code Boolean} instance is not required, this method
+ * should generally be used in preference to the constructor
+ * {@link #Boolean(boolean)}, as this method is likely to yield
+ * significantly better space and time performance.
+ *
+ * @param b a boolean value.
+ * @return a {@code Boolean} instance representing {@code b}.
+ * @since 1.4
+ */
+ public static Boolean valueOf(boolean b) {
+ return (b ? TRUE : FALSE);
+ }
+
+ /**
+ * Returns a {@code Boolean} with a value represented by the
+ * specified string. The {@code Boolean} returned represents a
+ * true value if the string argument is not {@code null}
+ * and is equal, ignoring case, to the string {@code "true"}.
+ *
+ * @param s a string.
+ * @return the {@code Boolean} value represented by the string.
+ */
+ public static Boolean valueOf(String s) {
+ return parseBoolean(s) ? TRUE : FALSE;
+ }
+
+ /**
+ * Returns a {@code String} object representing the specified
+ * boolean. If the specified boolean is {@code true}, then
+ * the string {@code "true"} will be returned, otherwise the
+ * string {@code "false"} will be returned.
+ *
+ * @param b the boolean to be converted
+ * @return the string representation of the specified {@code boolean}
+ * @since 1.4
+ */
+ public static String toString(boolean b) {
+ return b ? "true" : "false";
+ }
+
+ /**
+ * Returns a {@code String} object representing this Boolean's
+ * value. If this object represents the value {@code true},
+ * a string equal to {@code "true"} is returned. Otherwise, a
+ * string equal to {@code "false"} is returned.
+ *
+ * @return a string representation of this object.
+ */
+ public String toString() {
+ return value ? "true" : "false";
+ }
+
+ /**
+ * Returns a hash code for this {@code Boolean} object.
+ *
+ * @return the integer {@code 1231} if this object represents
+ * {@code true}; returns the integer {@code 1237} if this
+ * object represents {@code false}.
+ */
+ @Override
+ public int hashCode() {
+ return Boolean.hashCode(value);
+ }
+
+ /**
+ * Returns a hash code for a {@code boolean} value; compatible with
+ * {@code Boolean.hashCode()}.
+ *
+ * @param value the value to hash
+ * @return a hash code value for a {@code boolean} value.
+ * @since 1.8
+ */
+ public static int hashCode(boolean value) {
+ return value ? 1231 : 1237;
+ }
+
+ /**
+ * Returns {@code true} if and only if the argument is not
+ * {@code null} and is a {@code Boolean} object that
+ * represents the same {@code boolean} value as this object.
+ *
+ * @param obj the object to compare with.
+ * @return {@code true} if the Boolean objects represent the
+ * same value; {@code false} otherwise.
+ */
+ public boolean equals(Object obj) {
+ if (obj instanceof Boolean) {
+ return value == ((Boolean)obj).booleanValue();
+ }
+ return false;
+ }
+
+ /**
+ * Returns {@code true} if and only if the system property
+ * named by the argument exists and is equal to the string
+ * {@code "true"}. (Beginning with version 1.0.2 of the
+ * Java<small><sup>TM</sup></small> platform, the test of
+ * this string is case insensitive.) A system property is accessible
+ * through {@code getProperty}, a method defined by the
+ * {@code System} class.
+ * <p>
+ * If there is no property with the specified name, or if the specified
+ * name is empty or null, then {@code false} is returned.
+ *
+ * @param name the system property name.
+ * @return the {@code boolean} value of the system property.
+ * @throws SecurityException for the same reasons as
+ * {@link System#getProperty(String) System.getProperty}
+ * @see java.lang.System#getProperty(java.lang.String)
+ * @see java.lang.System#getProperty(java.lang.String, java.lang.String)
+ */
+ public static boolean getBoolean(String name) {
+ boolean result = false;
+ try {
+ result = parseBoolean(System.getProperty(name));
+ } catch (IllegalArgumentException | NullPointerException e) {
+ }
+ return result;
+ }
+
+ /**
+ * Compares this {@code Boolean} instance with another.
+ *
+ * @param b the {@code Boolean} instance to be compared
+ * @return zero if this object represents the same boolean value as the
+ * argument; a positive value if this object represents true
+ * and the argument represents false; and a negative value if
+ * this object represents false and the argument represents true
+ * @throws NullPointerException if the argument is {@code null}
+ * @see Comparable
+ * @since 1.5
+ */
+ public int compareTo(Boolean b) {
+ return compare(this.value, b.value);
+ }
+
+ /**
+ * Compares two {@code boolean} values.
+ * The value returned is identical to what would be returned by:
+ * <pre>
+ * Boolean.valueOf(x).compareTo(Boolean.valueOf(y))
+ * </pre>
+ *
+ * @param x the first {@code boolean} to compare
+ * @param y the second {@code boolean} to compare
+ * @return the value {@code 0} if {@code x == y};
+ * a value less than {@code 0} if {@code !x && y}; and
+ * a value greater than {@code 0} if {@code x && !y}
+ * @since 1.7
+ */
+ public static int compare(boolean x, boolean y) {
+ return (x == y) ? 0 : (x ? 1 : -1);
+ }
+
+ /**
+ * Returns the result of applying the logical AND operator to the
+ * specified {@code boolean} operands.
+ *
+ * @param a the first operand
+ * @param b the second operand
+ * @return the logical AND of {@code a} and {@code b}
+ * @see java.util.function.BinaryOperator
+ * @since 1.8
+ */
+ public static boolean logicalAnd(boolean a, boolean b) {
+ return a && b;
+ }
+
+ /**
+ * Returns the result of applying the logical OR operator to the
+ * specified {@code boolean} operands.
+ *
+ * @param a the first operand
+ * @param b the second operand
+ * @return the logical OR of {@code a} and {@code b}
+ * @see java.util.function.BinaryOperator
+ * @since 1.8
+ */
+ public static boolean logicalOr(boolean a, boolean b) {
+ return a || b;
+ }
+
+ /**
+ * Returns the result of applying the logical XOR operator to the
+ * specified {@code boolean} operands.
+ *
+ * @param a the first operand
+ * @param b the second operand
+ * @return the logical XOR of {@code a} and {@code b}
+ * @see java.util.function.BinaryOperator
+ * @since 1.8
+ */
+ public static boolean logicalXor(boolean a, boolean b) {
+ return a ^ b;
+ }
+}
diff --git a/java/lang/BootstrapMethodError.java b/java/lang/BootstrapMethodError.java
new file mode 100644
index 0000000..a1509a0
--- /dev/null
+++ b/java/lang/BootstrapMethodError.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2008, 2011, 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;
+
+/**
+ * Thrown to indicate that an {@code invokedynamic} instruction has
+ * failed to find its bootstrap method,
+ * or the bootstrap method has failed to provide a
+ * {@linkplain java.lang.invoke.CallSite call site} with a {@linkplain java.lang.invoke.CallSite#getTarget target}
+ * of the correct {@linkplain java.lang.invoke.MethodHandle#type method type}.
+ *
+ * @author John Rose, JSR 292 EG
+ * @since 1.7
+ */
+public class BootstrapMethodError extends LinkageError {
+ private static final long serialVersionUID = 292L;
+
+ /**
+ * Constructs a {@code BootstrapMethodError} with no detail message.
+ */
+ public BootstrapMethodError() {
+ super();
+ }
+
+ /**
+ * Constructs a {@code BootstrapMethodError} with the specified
+ * detail message.
+ *
+ * @param s the detail message.
+ */
+ public BootstrapMethodError(String s) {
+ super(s);
+ }
+
+ /**
+ * Constructs a {@code BootstrapMethodError} with the specified
+ * detail message and cause.
+ *
+ * @param s the detail message.
+ * @param cause the cause, may be {@code null}.
+ */
+ public BootstrapMethodError(String s, Throwable cause) {
+ super(s, cause);
+ }
+
+ /**
+ * Constructs a {@code BootstrapMethodError} with the specified
+ * cause.
+ *
+ * @param cause the cause, may be {@code null}.
+ */
+ public BootstrapMethodError(Throwable cause) {
+ // cf. Throwable(Throwable cause) constructor.
+ super(cause == null ? null : cause.toString());
+ initCause(cause);
+ }
+}
diff --git a/java/lang/Byte.annotated.java b/java/lang/Byte.annotated.java
new file mode 100644
index 0000000..b64ca1e
--- /dev/null
+++ b/java/lang/Byte.annotated.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 1996, 2013, 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;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Byte extends java.lang.Number implements java.lang.Comparable<java.lang.Byte> {
+
+public Byte(byte value) { throw new RuntimeException("Stub!"); }
+
+public Byte(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String toString(byte b) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Byte valueOf(byte b) { throw new RuntimeException("Stub!"); }
+
+public static byte parseByte(@libcore.util.NonNull java.lang.String s, int radix) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public static byte parseByte(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Byte valueOf(@libcore.util.NonNull java.lang.String s, int radix) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Byte valueOf(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Byte decode(@libcore.util.NonNull java.lang.String nm) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public byte byteValue() { throw new RuntimeException("Stub!"); }
+
+public short shortValue() { throw new RuntimeException("Stub!"); }
+
+public int intValue() { throw new RuntimeException("Stub!"); }
+
+public long longValue() { throw new RuntimeException("Stub!"); }
+
+public float floatValue() { throw new RuntimeException("Stub!"); }
+
+public double doubleValue() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public static int hashCode(byte value) { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public int compareTo(@libcore.util.NonNull java.lang.Byte anotherByte) { throw new RuntimeException("Stub!"); }
+
+public static int compare(byte x, byte y) { throw new RuntimeException("Stub!"); }
+
+public static int toUnsignedInt(byte x) { throw new RuntimeException("Stub!"); }
+
+public static long toUnsignedLong(byte x) { throw new RuntimeException("Stub!"); }
+
+public static final int BYTES = 1; // 0x1
+
+public static final byte MAX_VALUE = 127; // 0x7f
+
+public static final byte MIN_VALUE = -128; // 0xffffff80
+
+public static final int SIZE = 8; // 0x8
+
+public static final java.lang.Class<java.lang.Byte> TYPE;
+static { TYPE = null; }
+}
+
diff --git a/java/lang/Byte.java b/java/lang/Byte.java
new file mode 100644
index 0000000..deb4ecb
--- /dev/null
+++ b/java/lang/Byte.java
@@ -0,0 +1,532 @@
+/*
+ * Copyright (c) 1996, 2013, 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;
+
+import libcore.util.HexEncoding;
+
+/**
+ *
+ * The {@code Byte} class wraps a value of primitive type {@code byte}
+ * in an object. An object of type {@code Byte} contains a single
+ * field whose type is {@code byte}.
+ *
+ * <p>In addition, this class provides several methods for converting
+ * a {@code byte} to a {@code String} and a {@code String} to a {@code
+ * byte}, as well as other constants and methods useful when dealing
+ * with a {@code byte}.
+ *
+ * @author Nakul Saraiya
+ * @author Joseph D. Darcy
+ * @see java.lang.Number
+ * @since JDK1.1
+ */
+public final class Byte extends Number implements Comparable<Byte> {
+
+ /**
+ * A constant holding the minimum value a {@code byte} can
+ * have, -2<sup>7</sup>.
+ */
+ public static final byte MIN_VALUE = -128;
+
+ /**
+ * A constant holding the maximum value a {@code byte} can
+ * have, 2<sup>7</sup>-1.
+ */
+ public static final byte MAX_VALUE = 127;
+
+ /**
+ * The {@code Class} instance representing the primitive type
+ * {@code byte}.
+ */
+ @SuppressWarnings("unchecked")
+ public static final Class<Byte> TYPE = (Class<Byte>) Class.getPrimitiveClass("byte");
+
+ /**
+ * Returns a new {@code String} object representing the
+ * specified {@code byte}. The radix is assumed to be 10.
+ *
+ * @param b the {@code byte} to be converted
+ * @return the string representation of the specified {@code byte}
+ * @see java.lang.Integer#toString(int)
+ */
+ public static String toString(byte b) {
+ return Integer.toString((int)b, 10);
+ }
+
+ private static class ByteCache {
+ private ByteCache(){}
+
+ static final Byte cache[] = new Byte[-(-128) + 127 + 1];
+
+ static {
+ for(int i = 0; i < cache.length; i++)
+ cache[i] = new Byte((byte)(i - 128));
+ }
+ }
+
+ /**
+ * Returns a {@code Byte} instance representing the specified
+ * {@code byte} value.
+ * If a new {@code Byte} instance is not required, this method
+ * should generally be used in preference to the constructor
+ * {@link #Byte(byte)}, as this method is likely to yield
+ * significantly better space and time performance since
+ * all byte values are cached.
+ *
+ * @param b a byte value.
+ * @return a {@code Byte} instance representing {@code b}.
+ * @since 1.5
+ */
+ public static Byte valueOf(byte b) {
+ final int offset = 128;
+ return ByteCache.cache[(int)b + offset];
+ }
+
+ /**
+ * Parses the string argument as a signed {@code byte} in the
+ * radix specified by the second argument. The characters in the
+ * string must all be digits, of the specified radix (as
+ * determined by whether {@link java.lang.Character#digit(char,
+ * int)} returns a nonnegative value) except that the first
+ * character may be an ASCII minus sign {@code '-'}
+ * ({@code '\u005Cu002D'}) to indicate a negative value or an
+ * ASCII plus sign {@code '+'} ({@code '\u005Cu002B'}) to
+ * indicate a positive value. The resulting {@code byte} value is
+ * returned.
+ *
+ * <p>An exception of type {@code NumberFormatException} is
+ * thrown if any of the following situations occurs:
+ * <ul>
+ * <li> The first argument is {@code null} or is a string of
+ * length zero.
+ *
+ * <li> The radix is either smaller than {@link
+ * java.lang.Character#MIN_RADIX} or larger than {@link
+ * java.lang.Character#MAX_RADIX}.
+ *
+ * <li> Any character of the string is not a digit of the
+ * specified radix, except that the first character may be a minus
+ * sign {@code '-'} ({@code '\u005Cu002D'}) or plus sign
+ * {@code '+'} ({@code '\u005Cu002B'}) provided that the
+ * string is longer than length 1.
+ *
+ * <li> The value represented by the string is not a value of type
+ * {@code byte}.
+ * </ul>
+ *
+ * @param s the {@code String} containing the
+ * {@code byte}
+ * representation to be parsed
+ * @param radix the radix to be used while parsing {@code s}
+ * @return the {@code byte} value represented by the string
+ * argument in the specified radix
+ * @throws NumberFormatException If the string does
+ * not contain a parsable {@code byte}.
+ */
+ public static byte parseByte(String s, int radix)
+ throws NumberFormatException {
+ int i = Integer.parseInt(s, radix);
+ if (i < MIN_VALUE || i > MAX_VALUE)
+ throw new NumberFormatException(
+ "Value out of range. Value:\"" + s + "\" Radix:" + radix);
+ return (byte)i;
+ }
+
+ /**
+ * Parses the string argument as a signed decimal {@code
+ * byte}. The characters in the string must all be decimal digits,
+ * except that the first character may be an ASCII minus sign
+ * {@code '-'} ({@code '\u005Cu002D'}) to indicate a negative
+ * value or an ASCII plus sign {@code '+'}
+ * ({@code '\u005Cu002B'}) to indicate a positive value. The
+ * resulting {@code byte} value is returned, exactly as if the
+ * argument and the radix 10 were given as arguments to the {@link
+ * #parseByte(java.lang.String, int)} method.
+ *
+ * @param s a {@code String} containing the
+ * {@code byte} representation to be parsed
+ * @return the {@code byte} value represented by the
+ * argument in decimal
+ * @throws NumberFormatException if the string does not
+ * contain a parsable {@code byte}.
+ */
+ public static byte parseByte(String s) throws NumberFormatException {
+ return parseByte(s, 10);
+ }
+
+ /**
+ * Returns a {@code Byte} object holding the value
+ * extracted from the specified {@code String} when parsed
+ * with the radix given by the second argument. The first argument
+ * is interpreted as representing a signed {@code byte} in
+ * the radix specified by the second argument, exactly as if the
+ * argument were given to the {@link #parseByte(java.lang.String,
+ * int)} method. The result is a {@code Byte} object that
+ * represents the {@code byte} value specified by the string.
+ *
+ * <p> In other words, this method returns a {@code Byte} object
+ * equal to the value of:
+ *
+ * <blockquote>
+ * {@code new Byte(Byte.parseByte(s, radix))}
+ * </blockquote>
+ *
+ * @param s the string to be parsed
+ * @param radix the radix to be used in interpreting {@code s}
+ * @return a {@code Byte} object holding the value
+ * represented by the string argument in the
+ * specified radix.
+ * @throws NumberFormatException If the {@code String} does
+ * not contain a parsable {@code byte}.
+ */
+ public static Byte valueOf(String s, int radix)
+ throws NumberFormatException {
+ return valueOf(parseByte(s, radix));
+ }
+
+ /**
+ * Returns a {@code Byte} object holding the value
+ * given by the specified {@code String}. The argument is
+ * interpreted as representing a signed decimal {@code byte},
+ * exactly as if the argument were given to the {@link
+ * #parseByte(java.lang.String)} method. The result is a
+ * {@code Byte} object that represents the {@code byte}
+ * value specified by the string.
+ *
+ * <p> In other words, this method returns a {@code Byte} object
+ * equal to the value of:
+ *
+ * <blockquote>
+ * {@code new Byte(Byte.parseByte(s))}
+ * </blockquote>
+ *
+ * @param s the string to be parsed
+ * @return a {@code Byte} object holding the value
+ * represented by the string argument
+ * @throws NumberFormatException If the {@code String} does
+ * not contain a parsable {@code byte}.
+ */
+ public static Byte valueOf(String s) throws NumberFormatException {
+ return valueOf(s, 10);
+ }
+
+ /**
+ * Decodes a {@code String} into a {@code Byte}.
+ * Accepts decimal, hexadecimal, and octal numbers given by
+ * the following grammar:
+ *
+ * <blockquote>
+ * <dl>
+ * <dt><i>DecodableString:</i>
+ * <dd><i>Sign<sub>opt</sub> DecimalNumeral</i>
+ * <dd><i>Sign<sub>opt</sub></i> {@code 0x} <i>HexDigits</i>
+ * <dd><i>Sign<sub>opt</sub></i> {@code 0X} <i>HexDigits</i>
+ * <dd><i>Sign<sub>opt</sub></i> {@code #} <i>HexDigits</i>
+ * <dd><i>Sign<sub>opt</sub></i> {@code 0} <i>OctalDigits</i>
+ *
+ * <dt><i>Sign:</i>
+ * <dd>{@code -}
+ * <dd>{@code +}
+ * </dl>
+ * </blockquote>
+ *
+ * <i>DecimalNumeral</i>, <i>HexDigits</i>, and <i>OctalDigits</i>
+ * are as defined in section 3.10.1 of
+ * <cite>The Java™ Language Specification</cite>,
+ * except that underscores are not accepted between digits.
+ *
+ * <p>The sequence of characters following an optional
+ * sign and/or radix specifier ("{@code 0x}", "{@code 0X}",
+ * "{@code #}", or leading zero) is parsed as by the {@code
+ * Byte.parseByte} method with the indicated radix (10, 16, or 8).
+ * This sequence of characters must represent a positive value or
+ * a {@link NumberFormatException} will be thrown. The result is
+ * negated if first character of the specified {@code String} is
+ * the minus sign. No whitespace characters are permitted in the
+ * {@code String}.
+ *
+ * @param nm the {@code String} to decode.
+ * @return a {@code Byte} object holding the {@code byte}
+ * value represented by {@code nm}
+ * @throws NumberFormatException if the {@code String} does not
+ * contain a parsable {@code byte}.
+ * @see java.lang.Byte#parseByte(java.lang.String, int)
+ */
+ public static Byte decode(String nm) throws NumberFormatException {
+ int i = Integer.decode(nm);
+ if (i < MIN_VALUE || i > MAX_VALUE)
+ throw new NumberFormatException(
+ "Value " + i + " out of range from input " + nm);
+ return valueOf((byte)i);
+ }
+
+ /**
+ * The value of the {@code Byte}.
+ *
+ * @serial
+ */
+ private final byte value;
+
+ /**
+ * Constructs a newly allocated {@code Byte} object that
+ * represents the specified {@code byte} value.
+ *
+ * @param value the value to be represented by the
+ * {@code Byte}.
+ */
+ public Byte(byte value) {
+ this.value = value;
+ }
+
+ /**
+ * Constructs a newly allocated {@code Byte} object that
+ * represents the {@code byte} value indicated by the
+ * {@code String} parameter. The string is converted to a
+ * {@code byte} value in exactly the manner used by the
+ * {@code parseByte} method for radix 10.
+ *
+ * @param s the {@code String} to be converted to a
+ * {@code Byte}
+ * @throws NumberFormatException If the {@code String}
+ * does not contain a parsable {@code byte}.
+ * @see java.lang.Byte#parseByte(java.lang.String, int)
+ */
+ public Byte(String s) throws NumberFormatException {
+ this.value = parseByte(s, 10);
+ }
+
+ /**
+ * Returns the value of this {@code Byte} as a
+ * {@code byte}.
+ */
+ public byte byteValue() {
+ return value;
+ }
+
+ /**
+ * Returns the value of this {@code Byte} as a {@code short} after
+ * a widening primitive conversion.
+ * @jls 5.1.2 Widening Primitive Conversions
+ */
+ public short shortValue() {
+ return (short)value;
+ }
+
+ /**
+ * Returns the value of this {@code Byte} as an {@code int} after
+ * a widening primitive conversion.
+ * @jls 5.1.2 Widening Primitive Conversions
+ */
+ public int intValue() {
+ return (int)value;
+ }
+
+ /**
+ * Returns the value of this {@code Byte} as a {@code long} after
+ * a widening primitive conversion.
+ * @jls 5.1.2 Widening Primitive Conversions
+ */
+ public long longValue() {
+ return (long)value;
+ }
+
+ /**
+ * Returns the value of this {@code Byte} as a {@code float} after
+ * a widening primitive conversion.
+ * @jls 5.1.2 Widening Primitive Conversions
+ */
+ public float floatValue() {
+ return (float)value;
+ }
+
+ /**
+ * Returns the value of this {@code Byte} as a {@code double}
+ * after a widening primitive conversion.
+ * @jls 5.1.2 Widening Primitive Conversions
+ */
+ public double doubleValue() {
+ return (double)value;
+ }
+
+ /**
+ * Returns a {@code String} object representing this
+ * {@code Byte}'s value. The value is converted to signed
+ * decimal representation and returned as a string, exactly as if
+ * the {@code byte} value were given as an argument to the
+ * {@link java.lang.Byte#toString(byte)} method.
+ *
+ * @return a string representation of the value of this object in
+ * base 10.
+ */
+ public String toString() {
+ return Integer.toString((int)value);
+ }
+
+ /**
+ * Returns a hash code for this {@code Byte}; equal to the result
+ * of invoking {@code intValue()}.
+ *
+ * @return a hash code value for this {@code Byte}
+ */
+ @Override
+ public int hashCode() {
+ return Byte.hashCode(value);
+ }
+
+ /**
+ * Returns a hash code for a {@code byte} value; compatible with
+ * {@code Byte.hashCode()}.
+ *
+ * @param value the value to hash
+ * @return a hash code value for a {@code byte} value.
+ * @since 1.8
+ */
+ public static int hashCode(byte value) {
+ return (int)value;
+ }
+
+ /**
+ * Compares this object to the specified object. The result is
+ * {@code true} if and only if the argument is not
+ * {@code null} and is a {@code Byte} object that
+ * contains the same {@code byte} value as this object.
+ *
+ * @param obj the object to compare with
+ * @return {@code true} if the objects are the same;
+ * {@code false} otherwise.
+ */
+ public boolean equals(Object obj) {
+ if (obj instanceof Byte) {
+ return value == ((Byte)obj).byteValue();
+ }
+ return false;
+ }
+
+ /**
+ * Compares two {@code Byte} objects numerically.
+ *
+ * @param anotherByte the {@code Byte} to be compared.
+ * @return the value {@code 0} if this {@code Byte} is
+ * equal to the argument {@code Byte}; a value less than
+ * {@code 0} if this {@code Byte} is numerically less
+ * than the argument {@code Byte}; and a value greater than
+ * {@code 0} if this {@code Byte} is numerically
+ * greater than the argument {@code Byte} (signed
+ * comparison).
+ * @since 1.2
+ */
+ public int compareTo(Byte anotherByte) {
+ return compare(this.value, anotherByte.value);
+ }
+
+ /**
+ * Compares two {@code byte} values numerically.
+ * The value returned is identical to what would be returned by:
+ * <pre>
+ * Byte.valueOf(x).compareTo(Byte.valueOf(y))
+ * </pre>
+ *
+ * @param x the first {@code byte} to compare
+ * @param y the second {@code byte} to compare
+ * @return the value {@code 0} if {@code x == y};
+ * a value less than {@code 0} if {@code x < y}; and
+ * a value greater than {@code 0} if {@code x > y}
+ * @since 1.7
+ */
+ public static int compare(byte x, byte y) {
+ return x - y;
+ }
+
+ /**
+ * Converts the argument to an {@code int} by an unsigned
+ * conversion. In an unsigned conversion to an {@code int}, the
+ * high-order 24 bits of the {@code int} are zero and the
+ * low-order 8 bits are equal to the bits of the {@code byte} argument.
+ *
+ * Consequently, zero and positive {@code byte} values are mapped
+ * to a numerically equal {@code int} value and negative {@code
+ * byte} values are mapped to an {@code int} value equal to the
+ * input plus 2<sup>8</sup>.
+ *
+ * @param x the value to convert to an unsigned {@code int}
+ * @return the argument converted to {@code int} by an unsigned
+ * conversion
+ * @since 1.8
+ */
+ public static int toUnsignedInt(byte x) {
+ return ((int) x) & 0xff;
+ }
+
+ /**
+ * Converts the argument to a {@code long} by an unsigned
+ * conversion. In an unsigned conversion to a {@code long}, the
+ * high-order 56 bits of the {@code long} are zero and the
+ * low-order 8 bits are equal to the bits of the {@code byte} argument.
+ *
+ * Consequently, zero and positive {@code byte} values are mapped
+ * to a numerically equal {@code long} value and negative {@code
+ * byte} values are mapped to a {@code long} value equal to the
+ * input plus 2<sup>8</sup>.
+ *
+ * @param x the value to convert to an unsigned {@code long}
+ * @return the argument converted to {@code long} by an unsigned
+ * conversion
+ * @since 1.8
+ */
+ public static long toUnsignedLong(byte x) {
+ return ((long) x) & 0xffL;
+ }
+
+
+ /**
+ * The number of bits used to represent a {@code byte} value in two's
+ * complement binary form.
+ *
+ * @since 1.5
+ */
+ public static final int SIZE = 8;
+
+ /**
+ * The number of bytes used to represent a {@code byte} value in two's
+ * complement binary form.
+ *
+ * @since 1.8
+ */
+ public static final int BYTES = SIZE / Byte.SIZE;
+
+ /** use serialVersionUID from JDK 1.1. for interoperability */
+ private static final long serialVersionUID = -7183698231559129828L;
+
+ // BEGIN Android-added: toHexString() for internal use.
+ /**
+ * @hide
+ */
+ public static String toHexString(byte b, boolean upperCase) {
+ // This method currently retained because it is marked @UnsupportedAppUsage.
+ return HexEncoding.encodeToString(b, upperCase);
+ }
+ // END Android-added: toHexString() for internal use.
+}
diff --git a/java/lang/CaseMapper.java b/java/lang/CaseMapper.java
new file mode 100644
index 0000000..04eef09
--- /dev/null
+++ b/java/lang/CaseMapper.java
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.lang;
+
+import android.icu.text.Transliterator;
+import com.android.icu.util.CaseMapperNative;
+import java.util.Locale;
+
+/**
+ * Performs case operations as described by http://unicode.org/reports/tr21/tr21-5.html.
+ */
+class CaseMapper {
+ private static final char[] upperValues = "SS\u0000\u02bcN\u0000J\u030c\u0000\u0399\u0308\u0301\u03a5\u0308\u0301\u0535\u0552\u0000H\u0331\u0000T\u0308\u0000W\u030a\u0000Y\u030a\u0000A\u02be\u0000\u03a5\u0313\u0000\u03a5\u0313\u0300\u03a5\u0313\u0301\u03a5\u0313\u0342\u1f08\u0399\u0000\u1f09\u0399\u0000\u1f0a\u0399\u0000\u1f0b\u0399\u0000\u1f0c\u0399\u0000\u1f0d\u0399\u0000\u1f0e\u0399\u0000\u1f0f\u0399\u0000\u1f08\u0399\u0000\u1f09\u0399\u0000\u1f0a\u0399\u0000\u1f0b\u0399\u0000\u1f0c\u0399\u0000\u1f0d\u0399\u0000\u1f0e\u0399\u0000\u1f0f\u0399\u0000\u1f28\u0399\u0000\u1f29\u0399\u0000\u1f2a\u0399\u0000\u1f2b\u0399\u0000\u1f2c\u0399\u0000\u1f2d\u0399\u0000\u1f2e\u0399\u0000\u1f2f\u0399\u0000\u1f28\u0399\u0000\u1f29\u0399\u0000\u1f2a\u0399\u0000\u1f2b\u0399\u0000\u1f2c\u0399\u0000\u1f2d\u0399\u0000\u1f2e\u0399\u0000\u1f2f\u0399\u0000\u1f68\u0399\u0000\u1f69\u0399\u0000\u1f6a\u0399\u0000\u1f6b\u0399\u0000\u1f6c\u0399\u0000\u1f6d\u0399\u0000\u1f6e\u0399\u0000\u1f6f\u0399\u0000\u1f68\u0399\u0000\u1f69\u0399\u0000\u1f6a\u0399\u0000\u1f6b\u0399\u0000\u1f6c\u0399\u0000\u1f6d\u0399\u0000\u1f6e\u0399\u0000\u1f6f\u0399\u0000\u1fba\u0399\u0000\u0391\u0399\u0000\u0386\u0399\u0000\u0391\u0342\u0000\u0391\u0342\u0399\u0391\u0399\u0000\u1fca\u0399\u0000\u0397\u0399\u0000\u0389\u0399\u0000\u0397\u0342\u0000\u0397\u0342\u0399\u0397\u0399\u0000\u0399\u0308\u0300\u0399\u0308\u0301\u0399\u0342\u0000\u0399\u0308\u0342\u03a5\u0308\u0300\u03a5\u0308\u0301\u03a1\u0313\u0000\u03a5\u0342\u0000\u03a5\u0308\u0342\u1ffa\u0399\u0000\u03a9\u0399\u0000\u038f\u0399\u0000\u03a9\u0342\u0000\u03a9\u0342\u0399\u03a9\u0399\u0000FF\u0000FI\u0000FL\u0000FFIFFLST\u0000ST\u0000\u0544\u0546\u0000\u0544\u0535\u0000\u0544\u053b\u0000\u054e\u0546\u0000\u0544\u053d\u0000".toCharArray();
+ private static final char[] upperValues2 = "\u000b\u0000\f\u0000\r\u0000\u000e\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>\u0000\u0000?@A\u0000BC\u0000\u0000\u0000\u0000D\u0000\u0000\u0000\u0000\u0000EFG\u0000HI\u0000\u0000\u0000\u0000J\u0000\u0000\u0000\u0000\u0000KL\u0000\u0000MN\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000OPQ\u0000RS\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000TUV\u0000WX\u0000\u0000\u0000\u0000Y".toCharArray();
+
+ private static final char LATIN_CAPITAL_I_WITH_DOT = '\u0130';
+ private static final char GREEK_CAPITAL_SIGMA = '\u03a3';
+ private static final char GREEK_SMALL_FINAL_SIGMA = '\u03c2';
+
+ /**
+ * Our current GC makes short-lived objects more expensive than we'd like. When that's fixed,
+ * this class should be changed so that you instantiate it with the String and its value,
+ * and count fields.
+ */
+ private CaseMapper() {
+ }
+
+ /**
+ * Implements String.toLowerCase. The original String instance is returned if nothing changes.
+ */
+ public static String toLowerCase(Locale locale, String s) {
+ // Punt hard cases to ICU4C.
+ // Note that Greek isn't a particularly hard case for toLowerCase, only toUpperCase.
+ String languageCode = locale.getLanguage();
+ if (languageCode.equals("tr") || languageCode.equals("az") || languageCode.equals("lt")) {
+ return CaseMapperNative.toLowerCase(s, locale);
+ }
+
+ char[] newValue = null;
+ for (int i = 0, end = s.length(); i < end; ++i) {
+ char ch = s.charAt(i);
+ char newCh;
+ if (ch == LATIN_CAPITAL_I_WITH_DOT || Character.isHighSurrogate(ch)) {
+ // Punt these hard cases.
+ return CaseMapperNative.toLowerCase(s, locale);
+ } else if (ch == GREEK_CAPITAL_SIGMA && isFinalSigma(s, i)) {
+ newCh = GREEK_SMALL_FINAL_SIGMA;
+ } else {
+ newCh = Character.toLowerCase(ch);
+ }
+ if (ch != newCh) {
+ if (newValue == null) {
+ newValue = new char[end];
+ s.getCharsNoCheck(0, end, newValue, 0);
+ }
+ newValue[i] = newCh;
+ }
+ }
+ return newValue != null ? new String(newValue) : s;
+ }
+
+ /**
+ * True if 'index' is preceded by a sequence consisting of a cased letter and a case-ignorable
+ * sequence, and 'index' is not followed by a sequence consisting of an ignorable sequence and
+ * then a cased letter.
+ */
+ private static boolean isFinalSigma(String s, int index) {
+ // TODO: we don't skip case-ignorable sequences like we should.
+ // TODO: we should add a more direct way to test for a cased letter.
+ if (index <= 0) {
+ return false;
+ }
+ char previous = s.charAt(index - 1);
+ if (!(Character.isLowerCase(previous) || Character.isUpperCase(previous) || Character.isTitleCase(previous))) {
+ return false;
+ }
+ if (index + 1 >= s.length()) {
+ return true;
+ }
+ char next = s.charAt(index + 1);
+ if (Character.isLowerCase(next) || Character.isUpperCase(next) || Character.isTitleCase(next)) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Return the index of the specified character into the upperValues table.
+ * The upperValues table contains three entries at each position. These
+ * three characters are the upper case conversion. If only two characters
+ * are used, the third character in the table is \u0000.
+ * @return the index into the upperValues table, or -1
+ */
+ private static int upperIndex(int ch) {
+ int index = -1;
+ if (ch >= 0xdf) {
+ if (ch <= 0x587) {
+ switch (ch) {
+ case 0xdf: return 0;
+ case 0x149: return 1;
+ case 0x1f0: return 2;
+ case 0x390: return 3;
+ case 0x3b0: return 4;
+ case 0x587: return 5;
+ }
+ } else if (ch >= 0x1e96) {
+ if (ch <= 0x1e9a) {
+ index = 6 + ch - 0x1e96;
+ } else if (ch >= 0x1f50 && ch <= 0x1ffc) {
+ index = upperValues2[ch - 0x1f50];
+ if (index == 0) {
+ index = -1;
+ }
+ } else if (ch >= 0xfb00) {
+ if (ch <= 0xfb06) {
+ index = 90 + ch - 0xfb00;
+ } else if (ch >= 0xfb13 && ch <= 0xfb17) {
+ index = 97 + ch - 0xfb13;
+ }
+ }
+ }
+ }
+ return index;
+ }
+
+ private static final ThreadLocal<Transliterator> EL_UPPER = new ThreadLocal<Transliterator>() {
+ @Override protected Transliterator initialValue() {
+ return Transliterator.getInstance("el-Upper");
+ }
+ };
+
+ public static String toUpperCase(Locale locale, String s, int count) {
+ String languageCode = locale.getLanguage();
+ if (languageCode.equals("tr") || languageCode.equals("az") || languageCode.equals("lt")) {
+ return CaseMapperNative.toUpperCase(s, locale);
+ }
+ if (languageCode.equals("el")) {
+ return EL_UPPER.get().transliterate(s);
+ }
+
+ char[] output = null;
+ int i = 0;
+ for (int o = 0; o < count; o++) {
+ char ch = s.charAt(o);
+ if (Character.isHighSurrogate(ch)) {
+ return CaseMapperNative.toUpperCase(s, locale);
+ }
+ int index = upperIndex(ch);
+ if (index == -1) {
+ if (output != null && i >= output.length) {
+ char[] newoutput = new char[output.length + (count / 6) + 2];
+ System.arraycopy(output, 0, newoutput, 0, output.length);
+ output = newoutput;
+ }
+ char upch = Character.toUpperCase(ch);
+ if (output != null) {
+ output[i++] = upch;
+ } else if (ch != upch) {
+ output = new char[count];
+ i = o;
+ s.getCharsNoCheck(0, i, output, 0);
+ output[i++] = upch;
+ }
+ } else {
+ int target = index * 3;
+ char val3 = upperValues[target + 2];
+ if (output == null) {
+ output = new char[count + (count / 6) + 2];
+ i = o;
+ s.getCharsNoCheck(0, i, output, 0);
+ } else if (i + (val3 == 0 ? 1 : 2) >= output.length) {
+ char[] newoutput = new char[output.length + (count / 6) + 3];
+ System.arraycopy(output, 0, newoutput, 0, output.length);
+ output = newoutput;
+ }
+
+ char val = upperValues[target];
+ output[i++] = val;
+ val = upperValues[target + 1];
+ output[i++] = val;
+ if (val3 != 0) {
+ output[i++] = val3;
+ }
+ }
+ }
+ if (output == null) {
+ return s;
+ }
+ return output.length == i || output.length - i < 8 ? new String(0, i, output) : new String(output, 0, i);
+ }
+}
diff --git a/java/lang/CharSequence.annotated.java b/java/lang/CharSequence.annotated.java
new file mode 100644
index 0000000..e61d5d4
--- /dev/null
+++ b/java/lang/CharSequence.annotated.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2000, 2013, 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;
+
+import java.util.stream.IntStream;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface CharSequence {
+
+public int length();
+
+public char charAt(int index);
+
[email protected] public java.lang.CharSequence subSequence(int start, int end);
+
[email protected] public java.lang.String toString();
+
[email protected] public default java.util.stream.IntStream chars() { throw new RuntimeException("Stub!"); }
+
[email protected] public default java.util.stream.IntStream codePoints() { throw new RuntimeException("Stub!"); }
+}
diff --git a/java/lang/CharSequence.java b/java/lang/CharSequence.java
new file mode 100644
index 0000000..4d9ab3f
--- /dev/null
+++ b/java/lang/CharSequence.java
@@ -0,0 +1,234 @@
+/*
+ * Copyright (c) 2000, 2013, 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;
+
+import java.util.NoSuchElementException;
+import java.util.PrimitiveIterator;
+import java.util.Spliterator;
+import java.util.Spliterators;
+import java.util.function.IntConsumer;
+import java.util.stream.IntStream;
+import java.util.stream.StreamSupport;
+
+/**
+ * A <tt>CharSequence</tt> is a readable sequence of <code>char</code> values. This
+ * interface provides uniform, read-only access to many different kinds of
+ * <code>char</code> sequences.
+ * A <code>char</code> value represents a character in the <i>Basic
+ * Multilingual Plane (BMP)</i> or a surrogate. Refer to <a
+ * href="Character.html#unicode">Unicode Character Representation</a> for details.
+ *
+ * <p> This interface does not refine the general contracts of the {@link
+ * java.lang.Object#equals(java.lang.Object) equals} and {@link
+ * java.lang.Object#hashCode() hashCode} methods. The result of comparing two
+ * objects that implement <tt>CharSequence</tt> is therefore, in general,
+ * undefined. Each object may be implemented by a different class, and there
+ * is no guarantee that each class will be capable of testing its instances
+ * for equality with those of the other. It is therefore inappropriate to use
+ * arbitrary <tt>CharSequence</tt> instances as elements in a set or as keys in
+ * a map. </p>
+ *
+ * @author Mike McCloskey
+ * @since 1.4
+ * @spec JSR-51
+ */
+
+public interface CharSequence {
+
+ /**
+ * Returns the length of this character sequence. The length is the number
+ * of 16-bit <code>char</code>s in the sequence.
+ *
+ * @return the number of <code>char</code>s in this sequence
+ */
+ int length();
+
+ /**
+ * Returns the <code>char</code> value at the specified index. An index ranges from zero
+ * to <tt>length() - 1</tt>. The first <code>char</code> value of the sequence is at
+ * index zero, the next at index one, and so on, as for array
+ * indexing.
+ *
+ * <p>If the <code>char</code> value specified by the index is a
+ * <a href="{@docRoot}/java/lang/Character.html#unicode">surrogate</a>, the surrogate
+ * value is returned.
+ *
+ * @param index the index of the <code>char</code> value to be returned
+ *
+ * @return the specified <code>char</code> value
+ *
+ * @throws IndexOutOfBoundsException
+ * if the <tt>index</tt> argument is negative or not less than
+ * <tt>length()</tt>
+ */
+ char charAt(int index);
+
+ /**
+ * Returns a <code>CharSequence</code> that is a subsequence of this sequence.
+ * The subsequence starts with the <code>char</code> value at the specified index and
+ * ends with the <code>char</code> value at index <tt>end - 1</tt>. The length
+ * (in <code>char</code>s) of the
+ * returned sequence is <tt>end - start</tt>, so if <tt>start == end</tt>
+ * then an empty sequence is returned.
+ *
+ * @param start the start index, inclusive
+ * @param end the end index, exclusive
+ *
+ * @return the specified subsequence
+ *
+ * @throws IndexOutOfBoundsException
+ * if <tt>start</tt> or <tt>end</tt> are negative,
+ * if <tt>end</tt> is greater than <tt>length()</tt>,
+ * or if <tt>start</tt> is greater than <tt>end</tt>
+ */
+ CharSequence subSequence(int start, int end);
+
+ /**
+ * Returns a string containing the characters in this sequence in the same
+ * order as this sequence. The length of the string will be the length of
+ * this sequence.
+ *
+ * @return a string consisting of exactly this sequence of characters
+ */
+ public String toString();
+
+ /**
+ * Returns a stream of {@code int} zero-extending the {@code char} values
+ * from this sequence. Any char which maps to a <a
+ * href="{@docRoot}/java/lang/Character.html#unicode">surrogate code
+ * point</a> is passed through uninterpreted.
+ *
+ * <p>If the sequence is mutated while the stream is being read, the
+ * result is undefined.
+ *
+ * @return an IntStream of char values from this sequence
+ * @since 1.8
+ */
+ public default IntStream chars() {
+ class CharIterator implements PrimitiveIterator.OfInt {
+ int cur = 0;
+
+ public boolean hasNext() {
+ return cur < length();
+ }
+
+ public int nextInt() {
+ if (hasNext()) {
+ return charAt(cur++);
+ } else {
+ throw new NoSuchElementException();
+ }
+ }
+
+ @Override
+ public void forEachRemaining(IntConsumer block) {
+ for (; cur < length(); cur++) {
+ block.accept(charAt(cur));
+ }
+ }
+ }
+
+ return StreamSupport.intStream(() ->
+ Spliterators.spliterator(
+ new CharIterator(),
+ length(),
+ Spliterator.ORDERED),
+ Spliterator.SUBSIZED | Spliterator.SIZED | Spliterator.ORDERED,
+ false);
+ }
+
+ /**
+ * Returns a stream of code point values from this sequence. Any surrogate
+ * pairs encountered in the sequence are combined as if by {@linkplain
+ * Character#toCodePoint Character.toCodePoint} and the result is passed
+ * to the stream. Any other code units, including ordinary BMP characters,
+ * unpaired surrogates, and undefined code units, are zero-extended to
+ * {@code int} values which are then passed to the stream.
+ *
+ * <p>If the sequence is mutated while the stream is being read, the result
+ * is undefined.
+ *
+ * @return an IntStream of Unicode code points from this sequence
+ * @since 1.8
+ */
+ public default IntStream codePoints() {
+ class CodePointIterator implements PrimitiveIterator.OfInt {
+ int cur = 0;
+
+ @Override
+ public void forEachRemaining(IntConsumer block) {
+ final int length = length();
+ int i = cur;
+ try {
+ while (i < length) {
+ char c1 = charAt(i++);
+ if (!Character.isHighSurrogate(c1) || i >= length) {
+ block.accept(c1);
+ } else {
+ char c2 = charAt(i);
+ if (Character.isLowSurrogate(c2)) {
+ i++;
+ block.accept(Character.toCodePoint(c1, c2));
+ } else {
+ block.accept(c1);
+ }
+ }
+ }
+ } finally {
+ cur = i;
+ }
+ }
+
+ public boolean hasNext() {
+ return cur < length();
+ }
+
+ public int nextInt() {
+ final int length = length();
+
+ if (cur >= length) {
+ throw new NoSuchElementException();
+ }
+ char c1 = charAt(cur++);
+ if (Character.isHighSurrogate(c1) && cur < length) {
+ char c2 = charAt(cur);
+ if (Character.isLowSurrogate(c2)) {
+ cur++;
+ return Character.toCodePoint(c1, c2);
+ }
+ }
+ return c1;
+ }
+ }
+
+ return StreamSupport.intStream(() ->
+ Spliterators.spliteratorUnknownSize(
+ new CodePointIterator(),
+ Spliterator.ORDERED),
+ Spliterator.ORDERED,
+ false);
+ }
+}
diff --git a/java/lang/Character.annotated.java b/java/lang/Character.annotated.java
new file mode 100644
index 0000000..d50474f
--- /dev/null
+++ b/java/lang/Character.annotated.java
@@ -0,0 +1,1140 @@
+/*
+ * Copyright (c) 2002, 2013, 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;
+
+import java.util.Locale;
+import java.util.Map;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Character implements java.io.Serializable, java.lang.Comparable<java.lang.Character> {
+
+public Character(char value) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Character valueOf(char c) { throw new RuntimeException("Stub!"); }
+
+public char charValue() { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public static int hashCode(char value) { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String toString(char c) { throw new RuntimeException("Stub!"); }
+
+public static boolean isValidCodePoint(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isBmpCodePoint(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isSupplementaryCodePoint(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isHighSurrogate(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isLowSurrogate(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isSurrogate(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isSurrogatePair(char high, char low) { throw new RuntimeException("Stub!"); }
+
+public static int charCount(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static int toCodePoint(char high, char low) { throw new RuntimeException("Stub!"); }
+
+public static int codePointAt(@libcore.util.NonNull java.lang.CharSequence seq, int index) { throw new RuntimeException("Stub!"); }
+
+public static int codePointAt(char[] a, int index) { throw new RuntimeException("Stub!"); }
+
+public static int codePointAt(char[] a, int index, int limit) { throw new RuntimeException("Stub!"); }
+
+public static int codePointBefore(@libcore.util.NonNull java.lang.CharSequence seq, int index) { throw new RuntimeException("Stub!"); }
+
+public static int codePointBefore(char[] a, int index) { throw new RuntimeException("Stub!"); }
+
+public static int codePointBefore(char[] a, int index, int start) { throw new RuntimeException("Stub!"); }
+
+public static char highSurrogate(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static char lowSurrogate(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static int toChars(int codePoint, char[] dst, int dstIndex) { throw new RuntimeException("Stub!"); }
+
+public static char[] toChars(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static int codePointCount(@libcore.util.NonNull java.lang.CharSequence seq, int beginIndex, int endIndex) { throw new RuntimeException("Stub!"); }
+
+public static int codePointCount(char[] a, int offset, int count) { throw new RuntimeException("Stub!"); }
+
+public static int offsetByCodePoints(@libcore.util.NonNull java.lang.CharSequence seq, int index, int codePointOffset) { throw new RuntimeException("Stub!"); }
+
+public static int offsetByCodePoints(char[] a, int start, int count, int index, int codePointOffset) { throw new RuntimeException("Stub!"); }
+
+public static boolean isLowerCase(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isLowerCase(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isUpperCase(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isUpperCase(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isTitleCase(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isTitleCase(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isDigit(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isDigit(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isDefined(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isDefined(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isLetter(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isLetter(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isLetterOrDigit(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isLetterOrDigit(int codePoint) { throw new RuntimeException("Stub!"); }
+
+@Deprecated public static boolean isJavaLetter(char ch) { throw new RuntimeException("Stub!"); }
+
+@Deprecated public static boolean isJavaLetterOrDigit(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isAlphabetic(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isIdeographic(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isJavaIdentifierStart(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isJavaIdentifierStart(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isJavaIdentifierPart(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isJavaIdentifierPart(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isUnicodeIdentifierStart(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isUnicodeIdentifierStart(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isUnicodeIdentifierPart(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isUnicodeIdentifierPart(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isIdentifierIgnorable(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isIdentifierIgnorable(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static char toLowerCase(char ch) { throw new RuntimeException("Stub!"); }
+
+public static int toLowerCase(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static char toUpperCase(char ch) { throw new RuntimeException("Stub!"); }
+
+public static int toUpperCase(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static char toTitleCase(char ch) { throw new RuntimeException("Stub!"); }
+
+public static int toTitleCase(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static int digit(char ch, int radix) { throw new RuntimeException("Stub!"); }
+
+public static int digit(int codePoint, int radix) { throw new RuntimeException("Stub!"); }
+
+public static int getNumericValue(char ch) { throw new RuntimeException("Stub!"); }
+
+public static int getNumericValue(int codePoint) { throw new RuntimeException("Stub!"); }
+
+@Deprecated public static boolean isSpace(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isSpaceChar(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isSpaceChar(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isWhitespace(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isWhitespace(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isISOControl(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isISOControl(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static int getType(char ch) { throw new RuntimeException("Stub!"); }
+
+public static int getType(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static char forDigit(int digit, int radix) { throw new RuntimeException("Stub!"); }
+
+public static byte getDirectionality(char ch) { throw new RuntimeException("Stub!"); }
+
+public static byte getDirectionality(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static boolean isMirrored(char ch) { throw new RuntimeException("Stub!"); }
+
+public static boolean isMirrored(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public int compareTo(@libcore.util.NonNull java.lang.Character anotherCharacter) { throw new RuntimeException("Stub!"); }
+
+public static int compare(char x, char y) { throw new RuntimeException("Stub!"); }
+
+public static char reverseBytes(char ch) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String getName(int codePoint) { throw new RuntimeException("Stub!"); }
+
+public static final int BYTES = 2; // 0x2
+
+public static final byte COMBINING_SPACING_MARK = 8; // 0x8
+
+public static final byte CONNECTOR_PUNCTUATION = 23; // 0x17
+
+public static final byte CONTROL = 15; // 0xf
+
+public static final byte CURRENCY_SYMBOL = 26; // 0x1a
+
+public static final byte DASH_PUNCTUATION = 20; // 0x14
+
+public static final byte DECIMAL_DIGIT_NUMBER = 9; // 0x9
+
+public static final byte DIRECTIONALITY_ARABIC_NUMBER = 6; // 0x6
+
+public static final byte DIRECTIONALITY_BOUNDARY_NEUTRAL = 9; // 0x9
+
+public static final byte DIRECTIONALITY_COMMON_NUMBER_SEPARATOR = 7; // 0x7
+
+public static final byte DIRECTIONALITY_EUROPEAN_NUMBER = 3; // 0x3
+
+public static final byte DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR = 4; // 0x4
+
+public static final byte DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR = 5; // 0x5
+
+public static final byte DIRECTIONALITY_LEFT_TO_RIGHT = 0; // 0x0
+
+public static final byte DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING = 14; // 0xe
+
+public static final byte DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE = 15; // 0xf
+
+public static final byte DIRECTIONALITY_NONSPACING_MARK = 8; // 0x8
+
+public static final byte DIRECTIONALITY_OTHER_NEUTRALS = 13; // 0xd
+
+public static final byte DIRECTIONALITY_PARAGRAPH_SEPARATOR = 10; // 0xa
+
+public static final byte DIRECTIONALITY_POP_DIRECTIONAL_FORMAT = 18; // 0x12
+
+public static final byte DIRECTIONALITY_RIGHT_TO_LEFT = 1; // 0x1
+
+public static final byte DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC = 2; // 0x2
+
+public static final byte DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING = 16; // 0x10
+
+public static final byte DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE = 17; // 0x11
+
+public static final byte DIRECTIONALITY_SEGMENT_SEPARATOR = 11; // 0xb
+
+public static final byte DIRECTIONALITY_UNDEFINED = -1; // 0xffffffff
+
+public static final byte DIRECTIONALITY_WHITESPACE = 12; // 0xc
+
+public static final byte ENCLOSING_MARK = 7; // 0x7
+
+public static final byte END_PUNCTUATION = 22; // 0x16
+
+public static final byte FINAL_QUOTE_PUNCTUATION = 30; // 0x1e
+
+public static final byte FORMAT = 16; // 0x10
+
+public static final byte INITIAL_QUOTE_PUNCTUATION = 29; // 0x1d
+
+public static final byte LETTER_NUMBER = 10; // 0xa
+
+public static final byte LINE_SEPARATOR = 13; // 0xd
+
+public static final byte LOWERCASE_LETTER = 2; // 0x2
+
+public static final byte MATH_SYMBOL = 25; // 0x19
+
+public static final int MAX_CODE_POINT = 1114111; // 0x10ffff
+
+public static final char MAX_HIGH_SURROGATE = 56319; // 0xdbff '\udbff'
+
+public static final char MAX_LOW_SURROGATE = 57343; // 0xdfff '\udfff'
+
+public static final int MAX_RADIX = 36; // 0x24
+
+public static final char MAX_SURROGATE = 57343; // 0xdfff '\udfff'
+
+public static final char MAX_VALUE = 65535; // 0xffff '\uffff'
+
+public static final int MIN_CODE_POINT = 0; // 0x0
+
+public static final char MIN_HIGH_SURROGATE = 55296; // 0xd800 '\ud800'
+
+public static final char MIN_LOW_SURROGATE = 56320; // 0xdc00 '\udc00'
+
+public static final int MIN_RADIX = 2; // 0x2
+
+public static final int MIN_SUPPLEMENTARY_CODE_POINT = 65536; // 0x10000
+
+public static final char MIN_SURROGATE = 55296; // 0xd800 '\ud800'
+
+public static final char MIN_VALUE = 0; // 0x0000 '\u0000'
+
+public static final byte MODIFIER_LETTER = 4; // 0x4
+
+public static final byte MODIFIER_SYMBOL = 27; // 0x1b
+
+public static final byte NON_SPACING_MARK = 6; // 0x6
+
+public static final byte OTHER_LETTER = 5; // 0x5
+
+public static final byte OTHER_NUMBER = 11; // 0xb
+
+public static final byte OTHER_PUNCTUATION = 24; // 0x18
+
+public static final byte OTHER_SYMBOL = 28; // 0x1c
+
+public static final byte PARAGRAPH_SEPARATOR = 14; // 0xe
+
+public static final byte PRIVATE_USE = 18; // 0x12
+
+public static final int SIZE = 16; // 0x10
+
+public static final byte SPACE_SEPARATOR = 12; // 0xc
+
+public static final byte START_PUNCTUATION = 21; // 0x15
+
+public static final byte SURROGATE = 19; // 0x13
+
+public static final byte TITLECASE_LETTER = 3; // 0x3
+
+public static final java.lang.Class<java.lang.Character> TYPE;
+static { TYPE = null; }
+
+public static final byte UNASSIGNED = 0; // 0x0
+
+public static final byte UPPERCASE_LETTER = 1; // 0x1
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public static class Subset {
+
+protected Subset(@libcore.util.NonNull java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+public final boolean equals(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public final int hashCode() { throw new RuntimeException("Stub!"); }
+
[email protected] public final java.lang.String toString() { throw new RuntimeException("Stub!"); }
+}
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public static final class UnicodeBlock extends java.lang.Character.Subset {
+
+UnicodeBlock(java.lang.String idName) { super(null); throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Character.UnicodeBlock of(char c) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Character.UnicodeBlock of(int codePoint) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Character.UnicodeBlock forName(@libcore.util.NonNull java.lang.String blockName) { throw new RuntimeException("Stub!"); }
+
+public static final java.lang.Character.UnicodeBlock AEGEAN_NUMBERS;
+static { AEGEAN_NUMBERS = null; }
+
+public static final java.lang.Character.UnicodeBlock ALCHEMICAL_SYMBOLS;
+static { ALCHEMICAL_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock ALPHABETIC_PRESENTATION_FORMS;
+static { ALPHABETIC_PRESENTATION_FORMS = null; }
+
+public static final java.lang.Character.UnicodeBlock ANCIENT_GREEK_MUSICAL_NOTATION;
+static { ANCIENT_GREEK_MUSICAL_NOTATION = null; }
+
+public static final java.lang.Character.UnicodeBlock ANCIENT_GREEK_NUMBERS;
+static { ANCIENT_GREEK_NUMBERS = null; }
+
+public static final java.lang.Character.UnicodeBlock ANCIENT_SYMBOLS;
+static { ANCIENT_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock ARABIC;
+static { ARABIC = null; }
+
+public static final java.lang.Character.UnicodeBlock ARABIC_EXTENDED_A;
+static { ARABIC_EXTENDED_A = null; }
+
+public static final java.lang.Character.UnicodeBlock ARABIC_MATHEMATICAL_ALPHABETIC_SYMBOLS;
+static { ARABIC_MATHEMATICAL_ALPHABETIC_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock ARABIC_PRESENTATION_FORMS_A;
+static { ARABIC_PRESENTATION_FORMS_A = null; }
+
+public static final java.lang.Character.UnicodeBlock ARABIC_PRESENTATION_FORMS_B;
+static { ARABIC_PRESENTATION_FORMS_B = null; }
+
+public static final java.lang.Character.UnicodeBlock ARABIC_SUPPLEMENT;
+static { ARABIC_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock ARMENIAN;
+static { ARMENIAN = null; }
+
+public static final java.lang.Character.UnicodeBlock ARROWS;
+static { ARROWS = null; }
+
+public static final java.lang.Character.UnicodeBlock AVESTAN;
+static { AVESTAN = null; }
+
+public static final java.lang.Character.UnicodeBlock BALINESE;
+static { BALINESE = null; }
+
+public static final java.lang.Character.UnicodeBlock BAMUM;
+static { BAMUM = null; }
+
+public static final java.lang.Character.UnicodeBlock BAMUM_SUPPLEMENT;
+static { BAMUM_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock BASIC_LATIN;
+static { BASIC_LATIN = null; }
+
+public static final java.lang.Character.UnicodeBlock BATAK;
+static { BATAK = null; }
+
+public static final java.lang.Character.UnicodeBlock BENGALI;
+static { BENGALI = null; }
+
+public static final java.lang.Character.UnicodeBlock BLOCK_ELEMENTS;
+static { BLOCK_ELEMENTS = null; }
+
+public static final java.lang.Character.UnicodeBlock BOPOMOFO;
+static { BOPOMOFO = null; }
+
+public static final java.lang.Character.UnicodeBlock BOPOMOFO_EXTENDED;
+static { BOPOMOFO_EXTENDED = null; }
+
+public static final java.lang.Character.UnicodeBlock BOX_DRAWING;
+static { BOX_DRAWING = null; }
+
+public static final java.lang.Character.UnicodeBlock BRAHMI;
+static { BRAHMI = null; }
+
+public static final java.lang.Character.UnicodeBlock BRAILLE_PATTERNS;
+static { BRAILLE_PATTERNS = null; }
+
+public static final java.lang.Character.UnicodeBlock BUGINESE;
+static { BUGINESE = null; }
+
+public static final java.lang.Character.UnicodeBlock BUHID;
+static { BUHID = null; }
+
+public static final java.lang.Character.UnicodeBlock BYZANTINE_MUSICAL_SYMBOLS;
+static { BYZANTINE_MUSICAL_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock CARIAN;
+static { CARIAN = null; }
+
+public static final java.lang.Character.UnicodeBlock CHAKMA;
+static { CHAKMA = null; }
+
+public static final java.lang.Character.UnicodeBlock CHAM;
+static { CHAM = null; }
+
+public static final java.lang.Character.UnicodeBlock CHEROKEE;
+static { CHEROKEE = null; }
+
+public static final java.lang.Character.UnicodeBlock CJK_COMPATIBILITY;
+static { CJK_COMPATIBILITY = null; }
+
+public static final java.lang.Character.UnicodeBlock CJK_COMPATIBILITY_FORMS;
+static { CJK_COMPATIBILITY_FORMS = null; }
+
+public static final java.lang.Character.UnicodeBlock CJK_COMPATIBILITY_IDEOGRAPHS;
+static { CJK_COMPATIBILITY_IDEOGRAPHS = null; }
+
+public static final java.lang.Character.UnicodeBlock CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT;
+static { CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock CJK_RADICALS_SUPPLEMENT;
+static { CJK_RADICALS_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock CJK_STROKES;
+static { CJK_STROKES = null; }
+
+public static final java.lang.Character.UnicodeBlock CJK_SYMBOLS_AND_PUNCTUATION;
+static { CJK_SYMBOLS_AND_PUNCTUATION = null; }
+
+public static final java.lang.Character.UnicodeBlock CJK_UNIFIED_IDEOGRAPHS;
+static { CJK_UNIFIED_IDEOGRAPHS = null; }
+
+public static final java.lang.Character.UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A;
+static { CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A = null; }
+
+public static final java.lang.Character.UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B;
+static { CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B = null; }
+
+public static final java.lang.Character.UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_C;
+static { CJK_UNIFIED_IDEOGRAPHS_EXTENSION_C = null; }
+
+public static final java.lang.Character.UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_D;
+static { CJK_UNIFIED_IDEOGRAPHS_EXTENSION_D = null; }
+
+public static final java.lang.Character.UnicodeBlock COMBINING_DIACRITICAL_MARKS;
+static { COMBINING_DIACRITICAL_MARKS = null; }
+
+public static final java.lang.Character.UnicodeBlock COMBINING_DIACRITICAL_MARKS_SUPPLEMENT;
+static { COMBINING_DIACRITICAL_MARKS_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock COMBINING_HALF_MARKS;
+static { COMBINING_HALF_MARKS = null; }
+
+public static final java.lang.Character.UnicodeBlock COMBINING_MARKS_FOR_SYMBOLS;
+static { COMBINING_MARKS_FOR_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock COMMON_INDIC_NUMBER_FORMS;
+static { COMMON_INDIC_NUMBER_FORMS = null; }
+
+public static final java.lang.Character.UnicodeBlock CONTROL_PICTURES;
+static { CONTROL_PICTURES = null; }
+
+public static final java.lang.Character.UnicodeBlock COPTIC;
+static { COPTIC = null; }
+
+public static final java.lang.Character.UnicodeBlock COUNTING_ROD_NUMERALS;
+static { COUNTING_ROD_NUMERALS = null; }
+
+public static final java.lang.Character.UnicodeBlock CUNEIFORM;
+static { CUNEIFORM = null; }
+
+public static final java.lang.Character.UnicodeBlock CUNEIFORM_NUMBERS_AND_PUNCTUATION;
+static { CUNEIFORM_NUMBERS_AND_PUNCTUATION = null; }
+
+public static final java.lang.Character.UnicodeBlock CURRENCY_SYMBOLS;
+static { CURRENCY_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock CYPRIOT_SYLLABARY;
+static { CYPRIOT_SYLLABARY = null; }
+
+public static final java.lang.Character.UnicodeBlock CYRILLIC;
+static { CYRILLIC = null; }
+
+public static final java.lang.Character.UnicodeBlock CYRILLIC_EXTENDED_A;
+static { CYRILLIC_EXTENDED_A = null; }
+
+public static final java.lang.Character.UnicodeBlock CYRILLIC_EXTENDED_B;
+static { CYRILLIC_EXTENDED_B = null; }
+
+public static final java.lang.Character.UnicodeBlock CYRILLIC_SUPPLEMENTARY;
+static { CYRILLIC_SUPPLEMENTARY = null; }
+
+public static final java.lang.Character.UnicodeBlock DESERET;
+static { DESERET = null; }
+
+public static final java.lang.Character.UnicodeBlock DEVANAGARI;
+static { DEVANAGARI = null; }
+
+public static final java.lang.Character.UnicodeBlock DEVANAGARI_EXTENDED;
+static { DEVANAGARI_EXTENDED = null; }
+
+public static final java.lang.Character.UnicodeBlock DINGBATS;
+static { DINGBATS = null; }
+
+public static final java.lang.Character.UnicodeBlock DOMINO_TILES;
+static { DOMINO_TILES = null; }
+
+public static final java.lang.Character.UnicodeBlock EGYPTIAN_HIEROGLYPHS;
+static { EGYPTIAN_HIEROGLYPHS = null; }
+
+public static final java.lang.Character.UnicodeBlock EMOTICONS;
+static { EMOTICONS = null; }
+
+public static final java.lang.Character.UnicodeBlock ENCLOSED_ALPHANUMERICS;
+static { ENCLOSED_ALPHANUMERICS = null; }
+
+public static final java.lang.Character.UnicodeBlock ENCLOSED_ALPHANUMERIC_SUPPLEMENT;
+static { ENCLOSED_ALPHANUMERIC_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock ENCLOSED_CJK_LETTERS_AND_MONTHS;
+static { ENCLOSED_CJK_LETTERS_AND_MONTHS = null; }
+
+public static final java.lang.Character.UnicodeBlock ENCLOSED_IDEOGRAPHIC_SUPPLEMENT;
+static { ENCLOSED_IDEOGRAPHIC_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock ETHIOPIC;
+static { ETHIOPIC = null; }
+
+public static final java.lang.Character.UnicodeBlock ETHIOPIC_EXTENDED;
+static { ETHIOPIC_EXTENDED = null; }
+
+public static final java.lang.Character.UnicodeBlock ETHIOPIC_EXTENDED_A;
+static { ETHIOPIC_EXTENDED_A = null; }
+
+public static final java.lang.Character.UnicodeBlock ETHIOPIC_SUPPLEMENT;
+static { ETHIOPIC_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock GENERAL_PUNCTUATION;
+static { GENERAL_PUNCTUATION = null; }
+
+public static final java.lang.Character.UnicodeBlock GEOMETRIC_SHAPES;
+static { GEOMETRIC_SHAPES = null; }
+
+public static final java.lang.Character.UnicodeBlock GEORGIAN;
+static { GEORGIAN = null; }
+
+public static final java.lang.Character.UnicodeBlock GEORGIAN_SUPPLEMENT;
+static { GEORGIAN_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock GLAGOLITIC;
+static { GLAGOLITIC = null; }
+
+public static final java.lang.Character.UnicodeBlock GOTHIC;
+static { GOTHIC = null; }
+
+public static final java.lang.Character.UnicodeBlock GREEK;
+static { GREEK = null; }
+
+public static final java.lang.Character.UnicodeBlock GREEK_EXTENDED;
+static { GREEK_EXTENDED = null; }
+
+public static final java.lang.Character.UnicodeBlock GUJARATI;
+static { GUJARATI = null; }
+
+public static final java.lang.Character.UnicodeBlock GURMUKHI;
+static { GURMUKHI = null; }
+
+public static final java.lang.Character.UnicodeBlock HALFWIDTH_AND_FULLWIDTH_FORMS;
+static { HALFWIDTH_AND_FULLWIDTH_FORMS = null; }
+
+public static final java.lang.Character.UnicodeBlock HANGUL_COMPATIBILITY_JAMO;
+static { HANGUL_COMPATIBILITY_JAMO = null; }
+
+public static final java.lang.Character.UnicodeBlock HANGUL_JAMO;
+static { HANGUL_JAMO = null; }
+
+public static final java.lang.Character.UnicodeBlock HANGUL_JAMO_EXTENDED_A;
+static { HANGUL_JAMO_EXTENDED_A = null; }
+
+public static final java.lang.Character.UnicodeBlock HANGUL_JAMO_EXTENDED_B;
+static { HANGUL_JAMO_EXTENDED_B = null; }
+
+public static final java.lang.Character.UnicodeBlock HANGUL_SYLLABLES;
+static { HANGUL_SYLLABLES = null; }
+
+public static final java.lang.Character.UnicodeBlock HANUNOO;
+static { HANUNOO = null; }
+
+public static final java.lang.Character.UnicodeBlock HEBREW;
+static { HEBREW = null; }
+
+public static final java.lang.Character.UnicodeBlock HIGH_PRIVATE_USE_SURROGATES;
+static { HIGH_PRIVATE_USE_SURROGATES = null; }
+
+public static final java.lang.Character.UnicodeBlock HIGH_SURROGATES;
+static { HIGH_SURROGATES = null; }
+
+public static final java.lang.Character.UnicodeBlock HIRAGANA;
+static { HIRAGANA = null; }
+
+public static final java.lang.Character.UnicodeBlock IDEOGRAPHIC_DESCRIPTION_CHARACTERS;
+static { IDEOGRAPHIC_DESCRIPTION_CHARACTERS = null; }
+
+public static final java.lang.Character.UnicodeBlock IMPERIAL_ARAMAIC;
+static { IMPERIAL_ARAMAIC = null; }
+
+public static final java.lang.Character.UnicodeBlock INSCRIPTIONAL_PAHLAVI;
+static { INSCRIPTIONAL_PAHLAVI = null; }
+
+public static final java.lang.Character.UnicodeBlock INSCRIPTIONAL_PARTHIAN;
+static { INSCRIPTIONAL_PARTHIAN = null; }
+
+public static final java.lang.Character.UnicodeBlock IPA_EXTENSIONS;
+static { IPA_EXTENSIONS = null; }
+
+public static final java.lang.Character.UnicodeBlock JAVANESE;
+static { JAVANESE = null; }
+
+public static final java.lang.Character.UnicodeBlock KAITHI;
+static { KAITHI = null; }
+
+public static final java.lang.Character.UnicodeBlock KANA_SUPPLEMENT;
+static { KANA_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock KANBUN;
+static { KANBUN = null; }
+
+public static final java.lang.Character.UnicodeBlock KANGXI_RADICALS;
+static { KANGXI_RADICALS = null; }
+
+public static final java.lang.Character.UnicodeBlock KANNADA;
+static { KANNADA = null; }
+
+public static final java.lang.Character.UnicodeBlock KATAKANA;
+static { KATAKANA = null; }
+
+public static final java.lang.Character.UnicodeBlock KATAKANA_PHONETIC_EXTENSIONS;
+static { KATAKANA_PHONETIC_EXTENSIONS = null; }
+
+public static final java.lang.Character.UnicodeBlock KAYAH_LI;
+static { KAYAH_LI = null; }
+
+public static final java.lang.Character.UnicodeBlock KHAROSHTHI;
+static { KHAROSHTHI = null; }
+
+public static final java.lang.Character.UnicodeBlock KHMER;
+static { KHMER = null; }
+
+public static final java.lang.Character.UnicodeBlock KHMER_SYMBOLS;
+static { KHMER_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock LAO;
+static { LAO = null; }
+
+public static final java.lang.Character.UnicodeBlock LATIN_1_SUPPLEMENT;
+static { LATIN_1_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock LATIN_EXTENDED_A;
+static { LATIN_EXTENDED_A = null; }
+
+public static final java.lang.Character.UnicodeBlock LATIN_EXTENDED_ADDITIONAL;
+static { LATIN_EXTENDED_ADDITIONAL = null; }
+
+public static final java.lang.Character.UnicodeBlock LATIN_EXTENDED_B;
+static { LATIN_EXTENDED_B = null; }
+
+public static final java.lang.Character.UnicodeBlock LATIN_EXTENDED_C;
+static { LATIN_EXTENDED_C = null; }
+
+public static final java.lang.Character.UnicodeBlock LATIN_EXTENDED_D;
+static { LATIN_EXTENDED_D = null; }
+
+public static final java.lang.Character.UnicodeBlock LEPCHA;
+static { LEPCHA = null; }
+
+public static final java.lang.Character.UnicodeBlock LETTERLIKE_SYMBOLS;
+static { LETTERLIKE_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock LIMBU;
+static { LIMBU = null; }
+
+public static final java.lang.Character.UnicodeBlock LINEAR_B_IDEOGRAMS;
+static { LINEAR_B_IDEOGRAMS = null; }
+
+public static final java.lang.Character.UnicodeBlock LINEAR_B_SYLLABARY;
+static { LINEAR_B_SYLLABARY = null; }
+
+public static final java.lang.Character.UnicodeBlock LISU;
+static { LISU = null; }
+
+public static final java.lang.Character.UnicodeBlock LOW_SURROGATES;
+static { LOW_SURROGATES = null; }
+
+public static final java.lang.Character.UnicodeBlock LYCIAN;
+static { LYCIAN = null; }
+
+public static final java.lang.Character.UnicodeBlock LYDIAN;
+static { LYDIAN = null; }
+
+public static final java.lang.Character.UnicodeBlock MAHJONG_TILES;
+static { MAHJONG_TILES = null; }
+
+public static final java.lang.Character.UnicodeBlock MALAYALAM;
+static { MALAYALAM = null; }
+
+public static final java.lang.Character.UnicodeBlock MANDAIC;
+static { MANDAIC = null; }
+
+public static final java.lang.Character.UnicodeBlock MATHEMATICAL_ALPHANUMERIC_SYMBOLS;
+static { MATHEMATICAL_ALPHANUMERIC_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock MATHEMATICAL_OPERATORS;
+static { MATHEMATICAL_OPERATORS = null; }
+
+public static final java.lang.Character.UnicodeBlock MEETEI_MAYEK;
+static { MEETEI_MAYEK = null; }
+
+public static final java.lang.Character.UnicodeBlock MEETEI_MAYEK_EXTENSIONS;
+static { MEETEI_MAYEK_EXTENSIONS = null; }
+
+public static final java.lang.Character.UnicodeBlock MEROITIC_CURSIVE;
+static { MEROITIC_CURSIVE = null; }
+
+public static final java.lang.Character.UnicodeBlock MEROITIC_HIEROGLYPHS;
+static { MEROITIC_HIEROGLYPHS = null; }
+
+public static final java.lang.Character.UnicodeBlock MIAO;
+static { MIAO = null; }
+
+public static final java.lang.Character.UnicodeBlock MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A;
+static { MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A = null; }
+
+public static final java.lang.Character.UnicodeBlock MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B;
+static { MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B = null; }
+
+public static final java.lang.Character.UnicodeBlock MISCELLANEOUS_SYMBOLS;
+static { MISCELLANEOUS_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock MISCELLANEOUS_SYMBOLS_AND_ARROWS;
+static { MISCELLANEOUS_SYMBOLS_AND_ARROWS = null; }
+
+public static final java.lang.Character.UnicodeBlock MISCELLANEOUS_SYMBOLS_AND_PICTOGRAPHS;
+static { MISCELLANEOUS_SYMBOLS_AND_PICTOGRAPHS = null; }
+
+public static final java.lang.Character.UnicodeBlock MISCELLANEOUS_TECHNICAL;
+static { MISCELLANEOUS_TECHNICAL = null; }
+
+public static final java.lang.Character.UnicodeBlock MODIFIER_TONE_LETTERS;
+static { MODIFIER_TONE_LETTERS = null; }
+
+public static final java.lang.Character.UnicodeBlock MONGOLIAN;
+static { MONGOLIAN = null; }
+
+public static final java.lang.Character.UnicodeBlock MUSICAL_SYMBOLS;
+static { MUSICAL_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock MYANMAR;
+static { MYANMAR = null; }
+
+public static final java.lang.Character.UnicodeBlock MYANMAR_EXTENDED_A;
+static { MYANMAR_EXTENDED_A = null; }
+
+public static final java.lang.Character.UnicodeBlock NEW_TAI_LUE;
+static { NEW_TAI_LUE = null; }
+
+public static final java.lang.Character.UnicodeBlock NKO;
+static { NKO = null; }
+
+public static final java.lang.Character.UnicodeBlock NUMBER_FORMS;
+static { NUMBER_FORMS = null; }
+
+public static final java.lang.Character.UnicodeBlock OGHAM;
+static { OGHAM = null; }
+
+public static final java.lang.Character.UnicodeBlock OLD_ITALIC;
+static { OLD_ITALIC = null; }
+
+public static final java.lang.Character.UnicodeBlock OLD_PERSIAN;
+static { OLD_PERSIAN = null; }
+
+public static final java.lang.Character.UnicodeBlock OLD_SOUTH_ARABIAN;
+static { OLD_SOUTH_ARABIAN = null; }
+
+public static final java.lang.Character.UnicodeBlock OLD_TURKIC;
+static { OLD_TURKIC = null; }
+
+public static final java.lang.Character.UnicodeBlock OL_CHIKI;
+static { OL_CHIKI = null; }
+
+public static final java.lang.Character.UnicodeBlock OPTICAL_CHARACTER_RECOGNITION;
+static { OPTICAL_CHARACTER_RECOGNITION = null; }
+
+public static final java.lang.Character.UnicodeBlock ORIYA;
+static { ORIYA = null; }
+
+public static final java.lang.Character.UnicodeBlock OSMANYA;
+static { OSMANYA = null; }
+
+public static final java.lang.Character.UnicodeBlock PHAGS_PA;
+static { PHAGS_PA = null; }
+
+public static final java.lang.Character.UnicodeBlock PHAISTOS_DISC;
+static { PHAISTOS_DISC = null; }
+
+public static final java.lang.Character.UnicodeBlock PHOENICIAN;
+static { PHOENICIAN = null; }
+
+public static final java.lang.Character.UnicodeBlock PHONETIC_EXTENSIONS;
+static { PHONETIC_EXTENSIONS = null; }
+
+public static final java.lang.Character.UnicodeBlock PHONETIC_EXTENSIONS_SUPPLEMENT;
+static { PHONETIC_EXTENSIONS_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock PLAYING_CARDS;
+static { PLAYING_CARDS = null; }
+
+public static final java.lang.Character.UnicodeBlock PRIVATE_USE_AREA;
+static { PRIVATE_USE_AREA = null; }
+
+public static final java.lang.Character.UnicodeBlock REJANG;
+static { REJANG = null; }
+
+public static final java.lang.Character.UnicodeBlock RUMI_NUMERAL_SYMBOLS;
+static { RUMI_NUMERAL_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock RUNIC;
+static { RUNIC = null; }
+
+public static final java.lang.Character.UnicodeBlock SAMARITAN;
+static { SAMARITAN = null; }
+
+public static final java.lang.Character.UnicodeBlock SAURASHTRA;
+static { SAURASHTRA = null; }
+
+public static final java.lang.Character.UnicodeBlock SHARADA;
+static { SHARADA = null; }
+
+public static final java.lang.Character.UnicodeBlock SHAVIAN;
+static { SHAVIAN = null; }
+
+public static final java.lang.Character.UnicodeBlock SINHALA;
+static { SINHALA = null; }
+
+public static final java.lang.Character.UnicodeBlock SMALL_FORM_VARIANTS;
+static { SMALL_FORM_VARIANTS = null; }
+
+public static final java.lang.Character.UnicodeBlock SORA_SOMPENG;
+static { SORA_SOMPENG = null; }
+
+public static final java.lang.Character.UnicodeBlock SPACING_MODIFIER_LETTERS;
+static { SPACING_MODIFIER_LETTERS = null; }
+
+public static final java.lang.Character.UnicodeBlock SPECIALS;
+static { SPECIALS = null; }
+
+public static final java.lang.Character.UnicodeBlock SUNDANESE;
+static { SUNDANESE = null; }
+
+public static final java.lang.Character.UnicodeBlock SUNDANESE_SUPPLEMENT;
+static { SUNDANESE_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock SUPERSCRIPTS_AND_SUBSCRIPTS;
+static { SUPERSCRIPTS_AND_SUBSCRIPTS = null; }
+
+public static final java.lang.Character.UnicodeBlock SUPPLEMENTAL_ARROWS_A;
+static { SUPPLEMENTAL_ARROWS_A = null; }
+
+public static final java.lang.Character.UnicodeBlock SUPPLEMENTAL_ARROWS_B;
+static { SUPPLEMENTAL_ARROWS_B = null; }
+
+public static final java.lang.Character.UnicodeBlock SUPPLEMENTAL_MATHEMATICAL_OPERATORS;
+static { SUPPLEMENTAL_MATHEMATICAL_OPERATORS = null; }
+
+public static final java.lang.Character.UnicodeBlock SUPPLEMENTAL_PUNCTUATION;
+static { SUPPLEMENTAL_PUNCTUATION = null; }
+
+public static final java.lang.Character.UnicodeBlock SUPPLEMENTARY_PRIVATE_USE_AREA_A;
+static { SUPPLEMENTARY_PRIVATE_USE_AREA_A = null; }
+
+public static final java.lang.Character.UnicodeBlock SUPPLEMENTARY_PRIVATE_USE_AREA_B;
+static { SUPPLEMENTARY_PRIVATE_USE_AREA_B = null; }
+
+@Deprecated public static final java.lang.Character.UnicodeBlock SURROGATES_AREA;
+static { SURROGATES_AREA = null; }
+
+public static final java.lang.Character.UnicodeBlock SYLOTI_NAGRI;
+static { SYLOTI_NAGRI = null; }
+
+public static final java.lang.Character.UnicodeBlock SYRIAC;
+static { SYRIAC = null; }
+
+public static final java.lang.Character.UnicodeBlock TAGALOG;
+static { TAGALOG = null; }
+
+public static final java.lang.Character.UnicodeBlock TAGBANWA;
+static { TAGBANWA = null; }
+
+public static final java.lang.Character.UnicodeBlock TAGS;
+static { TAGS = null; }
+
+public static final java.lang.Character.UnicodeBlock TAI_LE;
+static { TAI_LE = null; }
+
+public static final java.lang.Character.UnicodeBlock TAI_THAM;
+static { TAI_THAM = null; }
+
+public static final java.lang.Character.UnicodeBlock TAI_VIET;
+static { TAI_VIET = null; }
+
+public static final java.lang.Character.UnicodeBlock TAI_XUAN_JING_SYMBOLS;
+static { TAI_XUAN_JING_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock TAKRI;
+static { TAKRI = null; }
+
+public static final java.lang.Character.UnicodeBlock TAMIL;
+static { TAMIL = null; }
+
+public static final java.lang.Character.UnicodeBlock TELUGU;
+static { TELUGU = null; }
+
+public static final java.lang.Character.UnicodeBlock THAANA;
+static { THAANA = null; }
+
+public static final java.lang.Character.UnicodeBlock THAI;
+static { THAI = null; }
+
+public static final java.lang.Character.UnicodeBlock TIBETAN;
+static { TIBETAN = null; }
+
+public static final java.lang.Character.UnicodeBlock TIFINAGH;
+static { TIFINAGH = null; }
+
+public static final java.lang.Character.UnicodeBlock TRANSPORT_AND_MAP_SYMBOLS;
+static { TRANSPORT_AND_MAP_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock UGARITIC;
+static { UGARITIC = null; }
+
+public static final java.lang.Character.UnicodeBlock UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS;
+static { UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS = null; }
+
+public static final java.lang.Character.UnicodeBlock UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS_EXTENDED;
+static { UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS_EXTENDED = null; }
+
+public static final java.lang.Character.UnicodeBlock VAI;
+static { VAI = null; }
+
+public static final java.lang.Character.UnicodeBlock VARIATION_SELECTORS;
+static { VARIATION_SELECTORS = null; }
+
+public static final java.lang.Character.UnicodeBlock VARIATION_SELECTORS_SUPPLEMENT;
+static { VARIATION_SELECTORS_SUPPLEMENT = null; }
+
+public static final java.lang.Character.UnicodeBlock VEDIC_EXTENSIONS;
+static { VEDIC_EXTENSIONS = null; }
+
+public static final java.lang.Character.UnicodeBlock VERTICAL_FORMS;
+static { VERTICAL_FORMS = null; }
+
+public static final java.lang.Character.UnicodeBlock YIJING_HEXAGRAM_SYMBOLS;
+static { YIJING_HEXAGRAM_SYMBOLS = null; }
+
+public static final java.lang.Character.UnicodeBlock YI_RADICALS;
+static { YI_RADICALS = null; }
+
+public static final java.lang.Character.UnicodeBlock YI_SYLLABLES;
+static { YI_SYLLABLES = null; }
+}
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public static enum UnicodeScript {
+COMMON,
+LATIN,
+GREEK,
+CYRILLIC,
+ARMENIAN,
+HEBREW,
+ARABIC,
+SYRIAC,
+THAANA,
+DEVANAGARI,
+BENGALI,
+GURMUKHI,
+GUJARATI,
+ORIYA,
+TAMIL,
+TELUGU,
+KANNADA,
+MALAYALAM,
+SINHALA,
+THAI,
+LAO,
+TIBETAN,
+MYANMAR,
+GEORGIAN,
+HANGUL,
+ETHIOPIC,
+CHEROKEE,
+CANADIAN_ABORIGINAL,
+OGHAM,
+RUNIC,
+KHMER,
+MONGOLIAN,
+HIRAGANA,
+KATAKANA,
+BOPOMOFO,
+HAN,
+YI,
+OLD_ITALIC,
+GOTHIC,
+DESERET,
+INHERITED,
+TAGALOG,
+HANUNOO,
+BUHID,
+TAGBANWA,
+LIMBU,
+TAI_LE,
+LINEAR_B,
+UGARITIC,
+SHAVIAN,
+OSMANYA,
+CYPRIOT,
+BRAILLE,
+BUGINESE,
+COPTIC,
+NEW_TAI_LUE,
+GLAGOLITIC,
+TIFINAGH,
+SYLOTI_NAGRI,
+OLD_PERSIAN,
+KHAROSHTHI,
+BALINESE,
+CUNEIFORM,
+PHOENICIAN,
+PHAGS_PA,
+NKO,
+SUNDANESE,
+BATAK,
+LEPCHA,
+OL_CHIKI,
+VAI,
+SAURASHTRA,
+KAYAH_LI,
+REJANG,
+LYCIAN,
+CARIAN,
+LYDIAN,
+CHAM,
+TAI_THAM,
+TAI_VIET,
+AVESTAN,
+EGYPTIAN_HIEROGLYPHS,
+SAMARITAN,
+MANDAIC,
+LISU,
+BAMUM,
+JAVANESE,
+MEETEI_MAYEK,
+IMPERIAL_ARAMAIC,
+OLD_SOUTH_ARABIAN,
+INSCRIPTIONAL_PARTHIAN,
+INSCRIPTIONAL_PAHLAVI,
+OLD_TURKIC,
+BRAHMI,
+KAITHI,
+MEROITIC_HIEROGLYPHS,
+MEROITIC_CURSIVE,
+SORA_SOMPENG,
+CHAKMA,
+SHARADA,
+TAKRI,
+MIAO,
+UNKNOWN;
+
[email protected] public static java.lang.Character.UnicodeScript of(int codePoint) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Character.UnicodeScript forName(@libcore.util.NonNull java.lang.String scriptName) { throw new RuntimeException("Stub!"); }
+}
+
+}
+
diff --git a/java/lang/Character.java b/java/lang/Character.java
new file mode 100644
index 0000000..8b1635d
--- /dev/null
+++ b/java/lang/Character.java
@@ -0,0 +1,7659 @@
+/*
+ * Copyright (c) 2002, 2013, 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;
+
+import dalvik.annotation.optimization.FastNative;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+// Android-changed: Remove reference to a specific unicode standard version
+/**
+ * The {@code Character} class wraps a value of the primitive
+ * type {@code char} in an object. An object of type
+ * {@code Character} contains a single field whose type is
+ * {@code char}.
+ * <p>
+ * In addition, this class provides several methods for determining
+ * a character's category (lowercase letter, digit, etc.) and for converting
+ * characters from uppercase to lowercase and vice versa.
+ * <p>
+ * Character information is based on the Unicode Standard
+ * <p>
+ * The methods and data of class {@code Character} are defined by
+ * the information in the <i>UnicodeData</i> file that is part of the
+ * Unicode Character Database maintained by the Unicode
+ * Consortium. This file specifies various properties including name
+ * and general category for every defined Unicode code point or
+ * character range.
+ * <p>
+ * The file and its description are available from the Unicode Consortium at:
+ * <ul>
+ * <li><a href="http://www.unicode.org">http://www.unicode.org</a>
+ * </ul>
+ *
+ * <h3><a name="unicode">Unicode Character Representations</a></h3>
+ *
+ * <p>The {@code char} data type (and therefore the value that a
+ * {@code Character} object encapsulates) are based on the
+ * original Unicode specification, which defined characters as
+ * fixed-width 16-bit entities. The Unicode Standard has since been
+ * changed to allow for characters whose representation requires more
+ * than 16 bits. The range of legal <em>code point</em>s is now
+ * U+0000 to U+10FFFF, known as <em>Unicode scalar value</em>.
+ * (Refer to the <a
+ * href="http://www.unicode.org/reports/tr27/#notation"><i>
+ * definition</i></a> of the U+<i>n</i> notation in the Unicode
+ * Standard.)
+ *
+ * <p><a name="BMP">The set of characters from U+0000 to U+FFFF</a> is
+ * sometimes referred to as the <em>Basic Multilingual Plane (BMP)</em>.
+ * <a name="supplementary">Characters</a> whose code points are greater
+ * than U+FFFF are called <em>supplementary character</em>s. The Java
+ * platform uses the UTF-16 representation in {@code char} arrays and
+ * in the {@code String} and {@code StringBuffer} classes. In
+ * this representation, supplementary characters are represented as a pair
+ * of {@code char} values, the first from the <em>high-surrogates</em>
+ * range, (\uD800-\uDBFF), the second from the
+ * <em>low-surrogates</em> range (\uDC00-\uDFFF).
+ *
+ * <p>A {@code char} value, therefore, represents Basic
+ * Multilingual Plane (BMP) code points, including the surrogate
+ * code points, or code units of the UTF-16 encoding. An
+ * {@code int} value represents all Unicode code points,
+ * including supplementary code points. The lower (least significant)
+ * 21 bits of {@code int} are used to represent Unicode code
+ * points and the upper (most significant) 11 bits must be zero.
+ * Unless otherwise specified, the behavior with respect to
+ * supplementary characters and surrogate {@code char} values is
+ * as follows:
+ *
+ * <ul>
+ * <li>The methods that only accept a {@code char} value cannot support
+ * supplementary characters. They treat {@code char} values from the
+ * surrogate ranges as undefined characters. For example,
+ * {@code Character.isLetter('\u005CuD840')} returns {@code false}, even though
+ * this specific value if followed by any low-surrogate value in a string
+ * would represent a letter.
+ *
+ * <li>The methods that accept an {@code int} value support all
+ * Unicode characters, including supplementary characters. For
+ * example, {@code Character.isLetter(0x2F81A)} returns
+ * {@code true} because the code point value represents a letter
+ * (a CJK ideograph).
+ * </ul>
+ *
+ * <p>In the Java SE API documentation, <em>Unicode code point</em> is
+ * used for character values in the range between U+0000 and U+10FFFF,
+ * and <em>Unicode code unit</em> is used for 16-bit
+ * {@code char} values that are code units of the <em>UTF-16</em>
+ * encoding. For more information on Unicode terminology, refer to the
+ * <a href="http://www.unicode.org/glossary/">Unicode Glossary</a>.
+ *
+ * @author Lee Boynton
+ * @author Guy Steele
+ * @author Akira Tanaka
+ * @author Martin Buchholz
+ * @author Ulf Zibis
+ * @since 1.0
+ */
+public final
+class Character implements java.io.Serializable, Comparable<Character> {
+ /**
+ * The minimum radix available for conversion to and from strings.
+ * The constant value of this field is the smallest value permitted
+ * for the radix argument in radix-conversion methods such as the
+ * {@code digit} method, the {@code forDigit} method, and the
+ * {@code toString} method of class {@code Integer}.
+ *
+ * @see Character#digit(char, int)
+ * @see Character#forDigit(int, int)
+ * @see Integer#toString(int, int)
+ * @see Integer#valueOf(String)
+ */
+ public static final int MIN_RADIX = 2;
+
+ /**
+ * The maximum radix available for conversion to and from strings.
+ * The constant value of this field is the largest value permitted
+ * for the radix argument in radix-conversion methods such as the
+ * {@code digit} method, the {@code forDigit} method, and the
+ * {@code toString} method of class {@code Integer}.
+ *
+ * @see Character#digit(char, int)
+ * @see Character#forDigit(int, int)
+ * @see Integer#toString(int, int)
+ * @see Integer#valueOf(String)
+ */
+ public static final int MAX_RADIX = 36;
+
+ /**
+ * The constant value of this field is the smallest value of type
+ * {@code char}, {@code '\u005Cu0000'}.
+ *
+ * @since 1.0.2
+ */
+ public static final char MIN_VALUE = '\u0000';
+
+ /**
+ * The constant value of this field is the largest value of type
+ * {@code char}, {@code '\u005CuFFFF'}.
+ *
+ * @since 1.0.2
+ */
+ public static final char MAX_VALUE = '\uFFFF';
+
+ /**
+ * The {@code Class} instance representing the primitive type
+ * {@code char}.
+ *
+ * @since 1.1
+ */
+ @SuppressWarnings("unchecked")
+ public static final Class<Character> TYPE = (Class<Character>) Class.getPrimitiveClass("char");
+
+ /*
+ * Normative general types
+ */
+
+ /*
+ * General character types
+ */
+
+ /**
+ * General category "Cn" in the Unicode specification.
+ * @since 1.1
+ */
+ public static final byte UNASSIGNED = 0;
+
+ /**
+ * General category "Lu" in the Unicode specification.
+ * @since 1.1
+ */
+ public static final byte UPPERCASE_LETTER = 1;
+
+ /**
+ * General category "Ll" in the Unicode specification.
+ * @since 1.1
+ */
+ public static final byte LOWERCASE_LETTER = 2;
+
+ /**
+ * General category "Lt" in the Unicode specification.
+ * @since 1.1
+ */
+ public static final byte TITLECASE_LETTER = 3;
+
+ /**
+ * General category "Lm" in the Unicode specification.
+ * @since 1.1
+ */
+ public static final byte MODIFIER_LETTER = 4;
+
+ /**
+ * General category "Lo" in the Unicode specification.
+ * @since 1.1
+ */
+ public static final byte OTHER_LETTER = 5;
+
+ /**
+ * General category "Mn" in the Unicode specification.
+ * @since 1.1
+ */
+ public static final byte NON_SPACING_MARK = 6;
+
+ /**
+ * General category "Me" in the Unicode specification.
+ * @since 1.1
+ */
+ public static final byte ENCLOSING_MARK = 7;
+
+ /**
+ * General category "Mc" in the Unicode specification.
+ * @since 1.1
+ */
+ public static final byte COMBINING_SPACING_MARK = 8;
+
+ /**
+ * General category "Nd" in the Unicode specification.
+ * @since 1.1
+ */
+ public static final byte DECIMAL_DIGIT_NUMBER = 9;
+
+ /**
+ * General category "Nl" in the Unicode specification.
+ * @since 1.1
+ */
+ public static final byte LETTER_NUMBER = 10;
+
+ /**
+ * General category "No" in the Unicode specification.
+ * @since 1.1
+ */
+ public static final byte OTHER_NUMBER = 11;
+
+ /**
+ * General category "Zs" in the Unicode specification.
+ * @since 1.1
+ */
+ public static final byte SPACE_SEPARATOR = 12;
+
+ /**
+ * General category "Zl" in the Unicode specification.
+ * @since 1.1
+ */
+ public static final byte LINE_SEPARATOR = 13;
+
+ /**
+ * General category "Zp" in the Unicode specification.
+ * @since 1.1
+ */
+ public static final byte PARAGRAPH_SEPARATOR = 14;
+
+ /**
+ * General category "Cc" in the Unicode specification.
+ * @since 1.1
+ */
+ public static final byte CONTROL = 15;
+
+ /**
+ * General category "Cf" in the Unicode specification.
+ * @since 1.1
+ */
+ public static final byte FORMAT = 16;
+
+ /**
+ * General category "Co" in the Unicode specification.
+ * @since 1.1
+ */
+ public static final byte PRIVATE_USE = 18;
+
+ /**
+ * General category "Cs" in the Unicode specification.
+ * @since 1.1
+ */
+ public static final byte SURROGATE = 19;
+
+ /**
+ * General category "Pd" in the Unicode specification.
+ * @since 1.1
+ */
+ public static final byte DASH_PUNCTUATION = 20;
+
+ /**
+ * General category "Ps" in the Unicode specification.
+ * @since 1.1
+ */
+ public static final byte START_PUNCTUATION = 21;
+
+ /**
+ * General category "Pe" in the Unicode specification.
+ * @since 1.1
+ */
+ public static final byte END_PUNCTUATION = 22;
+
+ /**
+ * General category "Pc" in the Unicode specification.
+ * @since 1.1
+ */
+ public static final byte CONNECTOR_PUNCTUATION = 23;
+
+ /**
+ * General category "Po" in the Unicode specification.
+ * @since 1.1
+ */
+ public static final byte OTHER_PUNCTUATION = 24;
+
+ /**
+ * General category "Sm" in the Unicode specification.
+ * @since 1.1
+ */
+ public static final byte MATH_SYMBOL = 25;
+
+ /**
+ * General category "Sc" in the Unicode specification.
+ * @since 1.1
+ */
+ public static final byte CURRENCY_SYMBOL = 26;
+
+ /**
+ * General category "Sk" in the Unicode specification.
+ * @since 1.1
+ */
+ public static final byte MODIFIER_SYMBOL = 27;
+
+ /**
+ * General category "So" in the Unicode specification.
+ * @since 1.1
+ */
+ public static final byte OTHER_SYMBOL = 28;
+
+ /**
+ * General category "Pi" in the Unicode specification.
+ * @since 1.4
+ */
+ public static final byte INITIAL_QUOTE_PUNCTUATION = 29;
+
+ /**
+ * General category "Pf" in the Unicode specification.
+ * @since 1.4
+ */
+ public static final byte FINAL_QUOTE_PUNCTUATION = 30;
+
+ /**
+ * Error flag. Use int (code point) to avoid confusion with U+FFFF.
+ */
+ static final int ERROR = 0xFFFFFFFF;
+
+
+ /**
+ * Undefined bidirectional character type. Undefined {@code char}
+ * values have undefined directionality in the Unicode specification.
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_UNDEFINED = -1;
+
+ /**
+ * Strong bidirectional character type "L" in the Unicode specification.
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_LEFT_TO_RIGHT = 0;
+
+ /**
+ * Strong bidirectional character type "R" in the Unicode specification.
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_RIGHT_TO_LEFT = 1;
+
+ /**
+ * Strong bidirectional character type "AL" in the Unicode specification.
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC = 2;
+
+ /**
+ * Weak bidirectional character type "EN" in the Unicode specification.
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_EUROPEAN_NUMBER = 3;
+
+ /**
+ * Weak bidirectional character type "ES" in the Unicode specification.
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR = 4;
+
+ /**
+ * Weak bidirectional character type "ET" in the Unicode specification.
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR = 5;
+
+ /**
+ * Weak bidirectional character type "AN" in the Unicode specification.
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_ARABIC_NUMBER = 6;
+
+ /**
+ * Weak bidirectional character type "CS" in the Unicode specification.
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_COMMON_NUMBER_SEPARATOR = 7;
+
+ /**
+ * Weak bidirectional character type "NSM" in the Unicode specification.
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_NONSPACING_MARK = 8;
+
+ /**
+ * Weak bidirectional character type "BN" in the Unicode specification.
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_BOUNDARY_NEUTRAL = 9;
+
+ /**
+ * Neutral bidirectional character type "B" in the Unicode specification.
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_PARAGRAPH_SEPARATOR = 10;
+
+ /**
+ * Neutral bidirectional character type "S" in the Unicode specification.
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_SEGMENT_SEPARATOR = 11;
+
+ /**
+ * Neutral bidirectional character type "WS" in the Unicode specification.
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_WHITESPACE = 12;
+
+ /**
+ * Neutral bidirectional character type "ON" in the Unicode specification.
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_OTHER_NEUTRALS = 13;
+
+ /**
+ * Strong bidirectional character type "LRE" in the Unicode specification.
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING = 14;
+
+ /**
+ * Strong bidirectional character type "LRO" in the Unicode specification.
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE = 15;
+
+ /**
+ * Strong bidirectional character type "RLE" in the Unicode specification.
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING = 16;
+
+ /**
+ * Strong bidirectional character type "RLO" in the Unicode specification.
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE = 17;
+
+ /**
+ * Weak bidirectional character type "PDF" in the Unicode specification.
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_POP_DIRECTIONAL_FORMAT = 18;
+
+ /**
+ * The minimum value of a
+ * <a href="http://www.unicode.org/glossary/#high_surrogate_code_unit">
+ * Unicode high-surrogate code unit</a>
+ * in the UTF-16 encoding, constant {@code '\u005CuD800'}.
+ * A high-surrogate is also known as a <i>leading-surrogate</i>.
+ *
+ * @since 1.5
+ */
+ public static final char MIN_HIGH_SURROGATE = '\uD800';
+
+ /**
+ * The maximum value of a
+ * <a href="http://www.unicode.org/glossary/#high_surrogate_code_unit">
+ * Unicode high-surrogate code unit</a>
+ * in the UTF-16 encoding, constant {@code '\u005CuDBFF'}.
+ * A high-surrogate is also known as a <i>leading-surrogate</i>.
+ *
+ * @since 1.5
+ */
+ public static final char MAX_HIGH_SURROGATE = '\uDBFF';
+
+ /**
+ * The minimum value of a
+ * <a href="http://www.unicode.org/glossary/#low_surrogate_code_unit">
+ * Unicode low-surrogate code unit</a>
+ * in the UTF-16 encoding, constant {@code '\u005CuDC00'}.
+ * A low-surrogate is also known as a <i>trailing-surrogate</i>.
+ *
+ * @since 1.5
+ */
+ public static final char MIN_LOW_SURROGATE = '\uDC00';
+
+ /**
+ * The maximum value of a
+ * <a href="http://www.unicode.org/glossary/#low_surrogate_code_unit">
+ * Unicode low-surrogate code unit</a>
+ * in the UTF-16 encoding, constant {@code '\u005CuDFFF'}.
+ * A low-surrogate is also known as a <i>trailing-surrogate</i>.
+ *
+ * @since 1.5
+ */
+ public static final char MAX_LOW_SURROGATE = '\uDFFF';
+
+ /**
+ * The minimum value of a Unicode surrogate code unit in the
+ * UTF-16 encoding, constant {@code '\u005CuD800'}.
+ *
+ * @since 1.5
+ */
+ public static final char MIN_SURROGATE = MIN_HIGH_SURROGATE;
+
+ /**
+ * The maximum value of a Unicode surrogate code unit in the
+ * UTF-16 encoding, constant {@code '\u005CuDFFF'}.
+ *
+ * @since 1.5
+ */
+ public static final char MAX_SURROGATE = MAX_LOW_SURROGATE;
+
+ /**
+ * The minimum value of a
+ * <a href="http://www.unicode.org/glossary/#supplementary_code_point">
+ * Unicode supplementary code point</a>, constant {@code U+10000}.
+ *
+ * @since 1.5
+ */
+ public static final int MIN_SUPPLEMENTARY_CODE_POINT = 0x010000;
+
+ /**
+ * The minimum value of a
+ * <a href="http://www.unicode.org/glossary/#code_point">
+ * Unicode code point</a>, constant {@code U+0000}.
+ *
+ * @since 1.5
+ */
+ public static final int MIN_CODE_POINT = 0x000000;
+
+ /**
+ * The maximum value of a
+ * <a href="http://www.unicode.org/glossary/#code_point">
+ * Unicode code point</a>, constant {@code U+10FFFF}.
+ *
+ * @since 1.5
+ */
+ public static final int MAX_CODE_POINT = 0X10FFFF;
+
+ // BEGIN Android-added: Use ICU.
+ // The indices in int[] DIRECTIONALITY are based on icu4c's u_charDirection(),
+ // accessed via getDirectionalityImpl(), implemented in Character.cpp.
+ private static final byte[] DIRECTIONALITY = new byte[] {
+ DIRECTIONALITY_LEFT_TO_RIGHT, DIRECTIONALITY_RIGHT_TO_LEFT,
+ DIRECTIONALITY_EUROPEAN_NUMBER,
+ DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR,
+ DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR,
+ DIRECTIONALITY_ARABIC_NUMBER,
+ DIRECTIONALITY_COMMON_NUMBER_SEPARATOR,
+ DIRECTIONALITY_PARAGRAPH_SEPARATOR,
+ DIRECTIONALITY_SEGMENT_SEPARATOR, DIRECTIONALITY_WHITESPACE,
+ DIRECTIONALITY_OTHER_NEUTRALS,
+ DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING,
+ DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE,
+ DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC,
+ DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING,
+ DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE,
+ DIRECTIONALITY_POP_DIRECTIONAL_FORMAT,
+ DIRECTIONALITY_NONSPACING_MARK, DIRECTIONALITY_BOUNDARY_NEUTRAL };
+ // END Android-added: Use ICU.
+
+ /**
+ * Instances of this class represent particular subsets of the Unicode
+ * character set. The only family of subsets defined in the
+ * {@code Character} class is {@link Character.UnicodeBlock}.
+ * Other portions of the Java API may define other subsets for their
+ * own purposes.
+ *
+ * @since 1.2
+ */
+ public static class Subset {
+
+ private String name;
+
+ /**
+ * Constructs a new {@code Subset} instance.
+ *
+ * @param name The name of this subset
+ * @exception NullPointerException if name is {@code null}
+ */
+ protected Subset(String name) {
+ if (name == null) {
+ throw new NullPointerException("name");
+ }
+ this.name = name;
+ }
+
+ /**
+ * Compares two {@code Subset} objects for equality.
+ * This method returns {@code true} if and only if
+ * {@code this} and the argument refer to the same
+ * object; since this method is {@code final}, this
+ * guarantee holds for all subclasses.
+ */
+ public final boolean equals(Object obj) {
+ return (this == obj);
+ }
+
+ /**
+ * Returns the standard hash code as defined by the
+ * {@link Object#hashCode} method. This method
+ * is {@code final} in order to ensure that the
+ * {@code equals} and {@code hashCode} methods will
+ * be consistent in all subclasses.
+ */
+ public final int hashCode() {
+ return super.hashCode();
+ }
+
+ /**
+ * Returns the name of this subset.
+ */
+ public final String toString() {
+ return name;
+ }
+ }
+
+ // See http://www.unicode.org/Public/UNIDATA/Blocks.txt
+ // for the latest specification of Unicode Blocks.
+
+ /**
+ * A family of character subsets representing the character blocks in the
+ * Unicode specification. Character blocks generally define characters
+ * used for a specific script or purpose. A character is contained by
+ * at most one Unicode block.
+ *
+ * @since 1.2
+ */
+ public static final class UnicodeBlock extends Subset {
+
+ private static Map<String, UnicodeBlock> map = new HashMap<>(256);
+
+ /**
+ * Creates a UnicodeBlock with the given identifier name.
+ * This name must be the same as the block identifier.
+ */
+ private UnicodeBlock(String idName) {
+ super(idName);
+ map.put(idName, this);
+ }
+
+ // BEGIN Android-added: ICU consistency: Don't map deprecated SURROGATES_AREA. b/26140229
+ // Add a (String, boolean) constructor for use by SURROGATES_AREA.
+ private UnicodeBlock(String idName, boolean isMap) {
+ super(idName);
+ if (isMap) {
+ map.put(idName, this);
+ }
+ }
+ // END Android-added: ICU consistency: Don't map deprecated SURROGATES_AREA. b/26140229
+
+ /**
+ * Creates a UnicodeBlock with the given identifier name and
+ * alias name.
+ */
+ private UnicodeBlock(String idName, String alias) {
+ this(idName);
+ map.put(alias, this);
+ }
+
+ /**
+ * Creates a UnicodeBlock with the given identifier name and
+ * alias names.
+ */
+ private UnicodeBlock(String idName, String... aliases) {
+ this(idName);
+ for (String alias : aliases)
+ map.put(alias, this);
+ }
+
+ /**
+ * Constant for the "Basic Latin" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock BASIC_LATIN =
+ new UnicodeBlock("BASIC_LATIN",
+ "BASIC LATIN",
+ "BASICLATIN");
+
+ /**
+ * Constant for the "Latin-1 Supplement" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock LATIN_1_SUPPLEMENT =
+ new UnicodeBlock("LATIN_1_SUPPLEMENT",
+ "LATIN-1 SUPPLEMENT",
+ "LATIN-1SUPPLEMENT");
+
+ /**
+ * Constant for the "Latin Extended-A" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock LATIN_EXTENDED_A =
+ new UnicodeBlock("LATIN_EXTENDED_A",
+ "LATIN EXTENDED-A",
+ "LATINEXTENDED-A");
+
+ /**
+ * Constant for the "Latin Extended-B" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock LATIN_EXTENDED_B =
+ new UnicodeBlock("LATIN_EXTENDED_B",
+ "LATIN EXTENDED-B",
+ "LATINEXTENDED-B");
+
+ /**
+ * Constant for the "IPA Extensions" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock IPA_EXTENSIONS =
+ new UnicodeBlock("IPA_EXTENSIONS",
+ "IPA EXTENSIONS",
+ "IPAEXTENSIONS");
+
+ /**
+ * Constant for the "Spacing Modifier Letters" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock SPACING_MODIFIER_LETTERS =
+ new UnicodeBlock("SPACING_MODIFIER_LETTERS",
+ "SPACING MODIFIER LETTERS",
+ "SPACINGMODIFIERLETTERS");
+
+ /**
+ * Constant for the "Combining Diacritical Marks" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock COMBINING_DIACRITICAL_MARKS =
+ new UnicodeBlock("COMBINING_DIACRITICAL_MARKS",
+ "COMBINING DIACRITICAL MARKS",
+ "COMBININGDIACRITICALMARKS");
+
+ /**
+ * Constant for the "Greek and Coptic" Unicode character block.
+ * <p>
+ * This block was previously known as the "Greek" block.
+ *
+ * @since 1.2
+ */
+ public static final UnicodeBlock GREEK =
+ new UnicodeBlock("GREEK",
+ "GREEK AND COPTIC",
+ "GREEKANDCOPTIC");
+
+ /**
+ * Constant for the "Cyrillic" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock CYRILLIC =
+ new UnicodeBlock("CYRILLIC");
+
+ /**
+ * Constant for the "Armenian" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock ARMENIAN =
+ new UnicodeBlock("ARMENIAN");
+
+ /**
+ * Constant for the "Hebrew" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock HEBREW =
+ new UnicodeBlock("HEBREW");
+
+ /**
+ * Constant for the "Arabic" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock ARABIC =
+ new UnicodeBlock("ARABIC");
+
+ /**
+ * Constant for the "Devanagari" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock DEVANAGARI =
+ new UnicodeBlock("DEVANAGARI");
+
+ /**
+ * Constant for the "Bengali" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock BENGALI =
+ new UnicodeBlock("BENGALI");
+
+ /**
+ * Constant for the "Gurmukhi" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock GURMUKHI =
+ new UnicodeBlock("GURMUKHI");
+
+ /**
+ * Constant for the "Gujarati" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock GUJARATI =
+ new UnicodeBlock("GUJARATI");
+
+ /**
+ * Constant for the "Oriya" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock ORIYA =
+ new UnicodeBlock("ORIYA");
+
+ /**
+ * Constant for the "Tamil" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock TAMIL =
+ new UnicodeBlock("TAMIL");
+
+ /**
+ * Constant for the "Telugu" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock TELUGU =
+ new UnicodeBlock("TELUGU");
+
+ /**
+ * Constant for the "Kannada" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock KANNADA =
+ new UnicodeBlock("KANNADA");
+
+ /**
+ * Constant for the "Malayalam" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock MALAYALAM =
+ new UnicodeBlock("MALAYALAM");
+
+ /**
+ * Constant for the "Thai" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock THAI =
+ new UnicodeBlock("THAI");
+
+ /**
+ * Constant for the "Lao" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock LAO =
+ new UnicodeBlock("LAO");
+
+ /**
+ * Constant for the "Tibetan" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock TIBETAN =
+ new UnicodeBlock("TIBETAN");
+
+ /**
+ * Constant for the "Georgian" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock GEORGIAN =
+ new UnicodeBlock("GEORGIAN");
+
+ /**
+ * Constant for the "Hangul Jamo" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock HANGUL_JAMO =
+ new UnicodeBlock("HANGUL_JAMO",
+ "HANGUL JAMO",
+ "HANGULJAMO");
+
+ /**
+ * Constant for the "Latin Extended Additional" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock LATIN_EXTENDED_ADDITIONAL =
+ new UnicodeBlock("LATIN_EXTENDED_ADDITIONAL",
+ "LATIN EXTENDED ADDITIONAL",
+ "LATINEXTENDEDADDITIONAL");
+
+ /**
+ * Constant for the "Greek Extended" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock GREEK_EXTENDED =
+ new UnicodeBlock("GREEK_EXTENDED",
+ "GREEK EXTENDED",
+ "GREEKEXTENDED");
+
+ /**
+ * Constant for the "General Punctuation" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock GENERAL_PUNCTUATION =
+ new UnicodeBlock("GENERAL_PUNCTUATION",
+ "GENERAL PUNCTUATION",
+ "GENERALPUNCTUATION");
+
+ /**
+ * Constant for the "Superscripts and Subscripts" Unicode character
+ * block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock SUPERSCRIPTS_AND_SUBSCRIPTS =
+ new UnicodeBlock("SUPERSCRIPTS_AND_SUBSCRIPTS",
+ "SUPERSCRIPTS AND SUBSCRIPTS",
+ "SUPERSCRIPTSANDSUBSCRIPTS");
+
+ /**
+ * Constant for the "Currency Symbols" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock CURRENCY_SYMBOLS =
+ new UnicodeBlock("CURRENCY_SYMBOLS",
+ "CURRENCY SYMBOLS",
+ "CURRENCYSYMBOLS");
+
+ /**
+ * Constant for the "Combining Diacritical Marks for Symbols" Unicode
+ * character block.
+ * <p>
+ * This block was previously known as "Combining Marks for Symbols".
+ * @since 1.2
+ */
+ public static final UnicodeBlock COMBINING_MARKS_FOR_SYMBOLS =
+ new UnicodeBlock("COMBINING_MARKS_FOR_SYMBOLS",
+ "COMBINING DIACRITICAL MARKS FOR SYMBOLS",
+ "COMBININGDIACRITICALMARKSFORSYMBOLS",
+ "COMBINING MARKS FOR SYMBOLS",
+ "COMBININGMARKSFORSYMBOLS");
+
+ /**
+ * Constant for the "Letterlike Symbols" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock LETTERLIKE_SYMBOLS =
+ new UnicodeBlock("LETTERLIKE_SYMBOLS",
+ "LETTERLIKE SYMBOLS",
+ "LETTERLIKESYMBOLS");
+
+ /**
+ * Constant for the "Number Forms" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock NUMBER_FORMS =
+ new UnicodeBlock("NUMBER_FORMS",
+ "NUMBER FORMS",
+ "NUMBERFORMS");
+
+ /**
+ * Constant for the "Arrows" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock ARROWS =
+ new UnicodeBlock("ARROWS");
+
+ /**
+ * Constant for the "Mathematical Operators" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock MATHEMATICAL_OPERATORS =
+ new UnicodeBlock("MATHEMATICAL_OPERATORS",
+ "MATHEMATICAL OPERATORS",
+ "MATHEMATICALOPERATORS");
+
+ /**
+ * Constant for the "Miscellaneous Technical" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock MISCELLANEOUS_TECHNICAL =
+ new UnicodeBlock("MISCELLANEOUS_TECHNICAL",
+ "MISCELLANEOUS TECHNICAL",
+ "MISCELLANEOUSTECHNICAL");
+
+ /**
+ * Constant for the "Control Pictures" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock CONTROL_PICTURES =
+ new UnicodeBlock("CONTROL_PICTURES",
+ "CONTROL PICTURES",
+ "CONTROLPICTURES");
+
+ /**
+ * Constant for the "Optical Character Recognition" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock OPTICAL_CHARACTER_RECOGNITION =
+ new UnicodeBlock("OPTICAL_CHARACTER_RECOGNITION",
+ "OPTICAL CHARACTER RECOGNITION",
+ "OPTICALCHARACTERRECOGNITION");
+
+ /**
+ * Constant for the "Enclosed Alphanumerics" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock ENCLOSED_ALPHANUMERICS =
+ new UnicodeBlock("ENCLOSED_ALPHANUMERICS",
+ "ENCLOSED ALPHANUMERICS",
+ "ENCLOSEDALPHANUMERICS");
+
+ /**
+ * Constant for the "Box Drawing" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock BOX_DRAWING =
+ new UnicodeBlock("BOX_DRAWING",
+ "BOX DRAWING",
+ "BOXDRAWING");
+
+ /**
+ * Constant for the "Block Elements" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock BLOCK_ELEMENTS =
+ new UnicodeBlock("BLOCK_ELEMENTS",
+ "BLOCK ELEMENTS",
+ "BLOCKELEMENTS");
+
+ /**
+ * Constant for the "Geometric Shapes" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock GEOMETRIC_SHAPES =
+ new UnicodeBlock("GEOMETRIC_SHAPES",
+ "GEOMETRIC SHAPES",
+ "GEOMETRICSHAPES");
+
+ /**
+ * Constant for the "Miscellaneous Symbols" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock MISCELLANEOUS_SYMBOLS =
+ new UnicodeBlock("MISCELLANEOUS_SYMBOLS",
+ "MISCELLANEOUS SYMBOLS",
+ "MISCELLANEOUSSYMBOLS");
+
+ /**
+ * Constant for the "Dingbats" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock DINGBATS =
+ new UnicodeBlock("DINGBATS");
+
+ /**
+ * Constant for the "CJK Symbols and Punctuation" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock CJK_SYMBOLS_AND_PUNCTUATION =
+ new UnicodeBlock("CJK_SYMBOLS_AND_PUNCTUATION",
+ "CJK SYMBOLS AND PUNCTUATION",
+ "CJKSYMBOLSANDPUNCTUATION");
+
+ /**
+ * Constant for the "Hiragana" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock HIRAGANA =
+ new UnicodeBlock("HIRAGANA");
+
+ /**
+ * Constant for the "Katakana" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock KATAKANA =
+ new UnicodeBlock("KATAKANA");
+
+ /**
+ * Constant for the "Bopomofo" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock BOPOMOFO =
+ new UnicodeBlock("BOPOMOFO");
+
+ /**
+ * Constant for the "Hangul Compatibility Jamo" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock HANGUL_COMPATIBILITY_JAMO =
+ new UnicodeBlock("HANGUL_COMPATIBILITY_JAMO",
+ "HANGUL COMPATIBILITY JAMO",
+ "HANGULCOMPATIBILITYJAMO");
+
+ /**
+ * Constant for the "Kanbun" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock KANBUN =
+ new UnicodeBlock("KANBUN");
+
+ /**
+ * Constant for the "Enclosed CJK Letters and Months" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock ENCLOSED_CJK_LETTERS_AND_MONTHS =
+ new UnicodeBlock("ENCLOSED_CJK_LETTERS_AND_MONTHS",
+ "ENCLOSED CJK LETTERS AND MONTHS",
+ "ENCLOSEDCJKLETTERSANDMONTHS");
+
+ /**
+ * Constant for the "CJK Compatibility" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock CJK_COMPATIBILITY =
+ new UnicodeBlock("CJK_COMPATIBILITY",
+ "CJK COMPATIBILITY",
+ "CJKCOMPATIBILITY");
+
+ /**
+ * Constant for the "CJK Unified Ideographs" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock CJK_UNIFIED_IDEOGRAPHS =
+ new UnicodeBlock("CJK_UNIFIED_IDEOGRAPHS",
+ "CJK UNIFIED IDEOGRAPHS",
+ "CJKUNIFIEDIDEOGRAPHS");
+
+ /**
+ * Constant for the "Hangul Syllables" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock HANGUL_SYLLABLES =
+ new UnicodeBlock("HANGUL_SYLLABLES",
+ "HANGUL SYLLABLES",
+ "HANGULSYLLABLES");
+
+ /**
+ * Constant for the "Private Use Area" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock PRIVATE_USE_AREA =
+ new UnicodeBlock("PRIVATE_USE_AREA",
+ "PRIVATE USE AREA",
+ "PRIVATEUSEAREA");
+
+ /**
+ * Constant for the "CJK Compatibility Ideographs" Unicode character
+ * block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock CJK_COMPATIBILITY_IDEOGRAPHS =
+ new UnicodeBlock("CJK_COMPATIBILITY_IDEOGRAPHS",
+ "CJK COMPATIBILITY IDEOGRAPHS",
+ "CJKCOMPATIBILITYIDEOGRAPHS");
+
+ /**
+ * Constant for the "Alphabetic Presentation Forms" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock ALPHABETIC_PRESENTATION_FORMS =
+ new UnicodeBlock("ALPHABETIC_PRESENTATION_FORMS",
+ "ALPHABETIC PRESENTATION FORMS",
+ "ALPHABETICPRESENTATIONFORMS");
+
+ /**
+ * Constant for the "Arabic Presentation Forms-A" Unicode character
+ * block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock ARABIC_PRESENTATION_FORMS_A =
+ new UnicodeBlock("ARABIC_PRESENTATION_FORMS_A",
+ "ARABIC PRESENTATION FORMS-A",
+ "ARABICPRESENTATIONFORMS-A");
+
+ /**
+ * Constant for the "Combining Half Marks" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock COMBINING_HALF_MARKS =
+ new UnicodeBlock("COMBINING_HALF_MARKS",
+ "COMBINING HALF MARKS",
+ "COMBININGHALFMARKS");
+
+ /**
+ * Constant for the "CJK Compatibility Forms" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock CJK_COMPATIBILITY_FORMS =
+ new UnicodeBlock("CJK_COMPATIBILITY_FORMS",
+ "CJK COMPATIBILITY FORMS",
+ "CJKCOMPATIBILITYFORMS");
+
+ /**
+ * Constant for the "Small Form Variants" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock SMALL_FORM_VARIANTS =
+ new UnicodeBlock("SMALL_FORM_VARIANTS",
+ "SMALL FORM VARIANTS",
+ "SMALLFORMVARIANTS");
+
+ /**
+ * Constant for the "Arabic Presentation Forms-B" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock ARABIC_PRESENTATION_FORMS_B =
+ new UnicodeBlock("ARABIC_PRESENTATION_FORMS_B",
+ "ARABIC PRESENTATION FORMS-B",
+ "ARABICPRESENTATIONFORMS-B");
+
+ /**
+ * Constant for the "Halfwidth and Fullwidth Forms" Unicode character
+ * block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock HALFWIDTH_AND_FULLWIDTH_FORMS =
+ new UnicodeBlock("HALFWIDTH_AND_FULLWIDTH_FORMS",
+ "HALFWIDTH AND FULLWIDTH FORMS",
+ "HALFWIDTHANDFULLWIDTHFORMS");
+
+ /**
+ * Constant for the "Specials" Unicode character block.
+ * @since 1.2
+ */
+ public static final UnicodeBlock SPECIALS =
+ new UnicodeBlock("SPECIALS");
+
+ /**
+ * @deprecated As of J2SE 5, use {@link #HIGH_SURROGATES},
+ * {@link #HIGH_PRIVATE_USE_SURROGATES}, and
+ * {@link #LOW_SURROGATES}. These new constants match
+ * the block definitions of the Unicode Standard.
+ * The {@link #of(char)} and {@link #of(int)} methods
+ * return the new constants, not SURROGATES_AREA.
+ */
+ @Deprecated
+ public static final UnicodeBlock SURROGATES_AREA =
+ // Android-changed: ICU consistency: Don't map deprecated SURROGATES_AREA. b/26140229
+ // new UnicodeBlock("SURROGATES_AREA");
+ new UnicodeBlock("SURROGATES_AREA", false);
+
+ /**
+ * Constant for the "Syriac" Unicode character block.
+ * @since 1.4
+ */
+ public static final UnicodeBlock SYRIAC =
+ new UnicodeBlock("SYRIAC");
+
+ /**
+ * Constant for the "Thaana" Unicode character block.
+ * @since 1.4
+ */
+ public static final UnicodeBlock THAANA =
+ new UnicodeBlock("THAANA");
+
+ /**
+ * Constant for the "Sinhala" Unicode character block.
+ * @since 1.4
+ */
+ public static final UnicodeBlock SINHALA =
+ new UnicodeBlock("SINHALA");
+
+ /**
+ * Constant for the "Myanmar" Unicode character block.
+ * @since 1.4
+ */
+ public static final UnicodeBlock MYANMAR =
+ new UnicodeBlock("MYANMAR");
+
+ /**
+ * Constant for the "Ethiopic" Unicode character block.
+ * @since 1.4
+ */
+ public static final UnicodeBlock ETHIOPIC =
+ new UnicodeBlock("ETHIOPIC");
+
+ /**
+ * Constant for the "Cherokee" Unicode character block.
+ * @since 1.4
+ */
+ public static final UnicodeBlock CHEROKEE =
+ new UnicodeBlock("CHEROKEE");
+
+ /**
+ * Constant for the "Unified Canadian Aboriginal Syllabics" Unicode character block.
+ * @since 1.4
+ */
+ public static final UnicodeBlock UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS =
+ new UnicodeBlock("UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS",
+ "UNIFIED CANADIAN ABORIGINAL SYLLABICS",
+ "UNIFIEDCANADIANABORIGINALSYLLABICS");
+
+ /**
+ * Constant for the "Ogham" Unicode character block.
+ * @since 1.4
+ */
+ public static final UnicodeBlock OGHAM =
+ new UnicodeBlock("OGHAM");
+
+ /**
+ * Constant for the "Runic" Unicode character block.
+ * @since 1.4
+ */
+ public static final UnicodeBlock RUNIC =
+ new UnicodeBlock("RUNIC");
+
+ /**
+ * Constant for the "Khmer" Unicode character block.
+ * @since 1.4
+ */
+ public static final UnicodeBlock KHMER =
+ new UnicodeBlock("KHMER");
+
+ /**
+ * Constant for the "Mongolian" Unicode character block.
+ * @since 1.4
+ */
+ public static final UnicodeBlock MONGOLIAN =
+ new UnicodeBlock("MONGOLIAN");
+
+ /**
+ * Constant for the "Braille Patterns" Unicode character block.
+ * @since 1.4
+ */
+ public static final UnicodeBlock BRAILLE_PATTERNS =
+ new UnicodeBlock("BRAILLE_PATTERNS",
+ "BRAILLE PATTERNS",
+ "BRAILLEPATTERNS");
+
+ /**
+ * Constant for the "CJK Radicals Supplement" Unicode character block.
+ * @since 1.4
+ */
+ public static final UnicodeBlock CJK_RADICALS_SUPPLEMENT =
+ new UnicodeBlock("CJK_RADICALS_SUPPLEMENT",
+ "CJK RADICALS SUPPLEMENT",
+ "CJKRADICALSSUPPLEMENT");
+
+ /**
+ * Constant for the "Kangxi Radicals" Unicode character block.
+ * @since 1.4
+ */
+ public static final UnicodeBlock KANGXI_RADICALS =
+ new UnicodeBlock("KANGXI_RADICALS",
+ "KANGXI RADICALS",
+ "KANGXIRADICALS");
+
+ /**
+ * Constant for the "Ideographic Description Characters" Unicode character block.
+ * @since 1.4
+ */
+ public static final UnicodeBlock IDEOGRAPHIC_DESCRIPTION_CHARACTERS =
+ new UnicodeBlock("IDEOGRAPHIC_DESCRIPTION_CHARACTERS",
+ "IDEOGRAPHIC DESCRIPTION CHARACTERS",
+ "IDEOGRAPHICDESCRIPTIONCHARACTERS");
+
+ /**
+ * Constant for the "Bopomofo Extended" Unicode character block.
+ * @since 1.4
+ */
+ public static final UnicodeBlock BOPOMOFO_EXTENDED =
+ new UnicodeBlock("BOPOMOFO_EXTENDED",
+ "BOPOMOFO EXTENDED",
+ "BOPOMOFOEXTENDED");
+
+ /**
+ * Constant for the "CJK Unified Ideographs Extension A" Unicode character block.
+ * @since 1.4
+ */
+ public static final UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A =
+ new UnicodeBlock("CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A",
+ "CJK UNIFIED IDEOGRAPHS EXTENSION A",
+ "CJKUNIFIEDIDEOGRAPHSEXTENSIONA");
+
+ /**
+ * Constant for the "Yi Syllables" Unicode character block.
+ * @since 1.4
+ */
+ public static final UnicodeBlock YI_SYLLABLES =
+ new UnicodeBlock("YI_SYLLABLES",
+ "YI SYLLABLES",
+ "YISYLLABLES");
+
+ /**
+ * Constant for the "Yi Radicals" Unicode character block.
+ * @since 1.4
+ */
+ public static final UnicodeBlock YI_RADICALS =
+ new UnicodeBlock("YI_RADICALS",
+ "YI RADICALS",
+ "YIRADICALS");
+
+ /**
+ * Constant for the "Cyrillic Supplementary" Unicode character block.
+ * @since 1.5
+ */
+ public static final UnicodeBlock CYRILLIC_SUPPLEMENTARY =
+ new UnicodeBlock("CYRILLIC_SUPPLEMENTARY",
+ "CYRILLIC SUPPLEMENTARY",
+ "CYRILLICSUPPLEMENTARY",
+ "CYRILLIC SUPPLEMENT",
+ "CYRILLICSUPPLEMENT");
+
+ /**
+ * Constant for the "Tagalog" Unicode character block.
+ * @since 1.5
+ */
+ public static final UnicodeBlock TAGALOG =
+ new UnicodeBlock("TAGALOG");
+
+ /**
+ * Constant for the "Hanunoo" Unicode character block.
+ * @since 1.5
+ */
+ public static final UnicodeBlock HANUNOO =
+ new UnicodeBlock("HANUNOO");
+
+ /**
+ * Constant for the "Buhid" Unicode character block.
+ * @since 1.5
+ */
+ public static final UnicodeBlock BUHID =
+ new UnicodeBlock("BUHID");
+
+ /**
+ * Constant for the "Tagbanwa" Unicode character block.
+ * @since 1.5
+ */
+ public static final UnicodeBlock TAGBANWA =
+ new UnicodeBlock("TAGBANWA");
+
+ /**
+ * Constant for the "Limbu" Unicode character block.
+ * @since 1.5
+ */
+ public static final UnicodeBlock LIMBU =
+ new UnicodeBlock("LIMBU");
+
+ /**
+ * Constant for the "Tai Le" Unicode character block.
+ * @since 1.5
+ */
+ public static final UnicodeBlock TAI_LE =
+ new UnicodeBlock("TAI_LE",
+ "TAI LE",
+ "TAILE");
+
+ /**
+ * Constant for the "Khmer Symbols" Unicode character block.
+ * @since 1.5
+ */
+ public static final UnicodeBlock KHMER_SYMBOLS =
+ new UnicodeBlock("KHMER_SYMBOLS",
+ "KHMER SYMBOLS",
+ "KHMERSYMBOLS");
+
+ /**
+ * Constant for the "Phonetic Extensions" Unicode character block.
+ * @since 1.5
+ */
+ public static final UnicodeBlock PHONETIC_EXTENSIONS =
+ new UnicodeBlock("PHONETIC_EXTENSIONS",
+ "PHONETIC EXTENSIONS",
+ "PHONETICEXTENSIONS");
+
+ /**
+ * Constant for the "Miscellaneous Mathematical Symbols-A" Unicode character block.
+ * @since 1.5
+ */
+ public static final UnicodeBlock MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A =
+ new UnicodeBlock("MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A",
+ "MISCELLANEOUS MATHEMATICAL SYMBOLS-A",
+ "MISCELLANEOUSMATHEMATICALSYMBOLS-A");
+
+ /**
+ * Constant for the "Supplemental Arrows-A" Unicode character block.
+ * @since 1.5
+ */
+ public static final UnicodeBlock SUPPLEMENTAL_ARROWS_A =
+ new UnicodeBlock("SUPPLEMENTAL_ARROWS_A",
+ "SUPPLEMENTAL ARROWS-A",
+ "SUPPLEMENTALARROWS-A");
+
+ /**
+ * Constant for the "Supplemental Arrows-B" Unicode character block.
+ * @since 1.5
+ */
+ public static final UnicodeBlock SUPPLEMENTAL_ARROWS_B =
+ new UnicodeBlock("SUPPLEMENTAL_ARROWS_B",
+ "SUPPLEMENTAL ARROWS-B",
+ "SUPPLEMENTALARROWS-B");
+
+ /**
+ * Constant for the "Miscellaneous Mathematical Symbols-B" Unicode
+ * character block.
+ * @since 1.5
+ */
+ public static final UnicodeBlock MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B =
+ new UnicodeBlock("MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B",
+ "MISCELLANEOUS MATHEMATICAL SYMBOLS-B",
+ "MISCELLANEOUSMATHEMATICALSYMBOLS-B");
+
+ /**
+ * Constant for the "Supplemental Mathematical Operators" Unicode
+ * character block.
+ * @since 1.5
+ */
+ public static final UnicodeBlock SUPPLEMENTAL_MATHEMATICAL_OPERATORS =
+ new UnicodeBlock("SUPPLEMENTAL_MATHEMATICAL_OPERATORS",
+ "SUPPLEMENTAL MATHEMATICAL OPERATORS",
+ "SUPPLEMENTALMATHEMATICALOPERATORS");
+
+ /**
+ * Constant for the "Miscellaneous Symbols and Arrows" Unicode character
+ * block.
+ * @since 1.5
+ */
+ public static final UnicodeBlock MISCELLANEOUS_SYMBOLS_AND_ARROWS =
+ new UnicodeBlock("MISCELLANEOUS_SYMBOLS_AND_ARROWS",
+ "MISCELLANEOUS SYMBOLS AND ARROWS",
+ "MISCELLANEOUSSYMBOLSANDARROWS");
+
+ /**
+ * Constant for the "Katakana Phonetic Extensions" Unicode character
+ * block.
+ * @since 1.5
+ */
+ public static final UnicodeBlock KATAKANA_PHONETIC_EXTENSIONS =
+ new UnicodeBlock("KATAKANA_PHONETIC_EXTENSIONS",
+ "KATAKANA PHONETIC EXTENSIONS",
+ "KATAKANAPHONETICEXTENSIONS");
+
+ /**
+ * Constant for the "Yijing Hexagram Symbols" Unicode character block.
+ * @since 1.5
+ */
+ public static final UnicodeBlock YIJING_HEXAGRAM_SYMBOLS =
+ new UnicodeBlock("YIJING_HEXAGRAM_SYMBOLS",
+ "YIJING HEXAGRAM SYMBOLS",
+ "YIJINGHEXAGRAMSYMBOLS");
+
+ /**
+ * Constant for the "Variation Selectors" Unicode character block.
+ * @since 1.5
+ */
+ public static final UnicodeBlock VARIATION_SELECTORS =
+ new UnicodeBlock("VARIATION_SELECTORS",
+ "VARIATION SELECTORS",
+ "VARIATIONSELECTORS");
+
+ /**
+ * Constant for the "Linear B Syllabary" Unicode character block.
+ * @since 1.5
+ */
+ public static final UnicodeBlock LINEAR_B_SYLLABARY =
+ new UnicodeBlock("LINEAR_B_SYLLABARY",
+ "LINEAR B SYLLABARY",
+ "LINEARBSYLLABARY");
+
+ /**
+ * Constant for the "Linear B Ideograms" Unicode character block.
+ * @since 1.5
+ */
+ public static final UnicodeBlock LINEAR_B_IDEOGRAMS =
+ new UnicodeBlock("LINEAR_B_IDEOGRAMS",
+ "LINEAR B IDEOGRAMS",
+ "LINEARBIDEOGRAMS");
+
+ /**
+ * Constant for the "Aegean Numbers" Unicode character block.
+ * @since 1.5
+ */
+ public static final UnicodeBlock AEGEAN_NUMBERS =
+ new UnicodeBlock("AEGEAN_NUMBERS",
+ "AEGEAN NUMBERS",
+ "AEGEANNUMBERS");
+
+ /**
+ * Constant for the "Old Italic" Unicode character block.
+ * @since 1.5
+ */
+ public static final UnicodeBlock OLD_ITALIC =
+ new UnicodeBlock("OLD_ITALIC",
+ "OLD ITALIC",
+ "OLDITALIC");
+
+ /**
+ * Constant for the "Gothic" Unicode character block.
+ * @since 1.5
+ */
+ public static final UnicodeBlock GOTHIC =
+ new UnicodeBlock("GOTHIC");
+
+ /**
+ * Constant for the "Ugaritic" Unicode character block.
+ * @since 1.5
+ */
+ public static final UnicodeBlock UGARITIC =
+ new UnicodeBlock("UGARITIC");
+
+ /**
+ * Constant for the "Deseret" Unicode character block.
+ * @since 1.5
+ */
+ public static final UnicodeBlock DESERET =
+ new UnicodeBlock("DESERET");
+
+ /**
+ * Constant for the "Shavian" Unicode character block.
+ * @since 1.5
+ */
+ public static final UnicodeBlock SHAVIAN =
+ new UnicodeBlock("SHAVIAN");
+
+ /**
+ * Constant for the "Osmanya" Unicode character block.
+ * @since 1.5
+ */
+ public static final UnicodeBlock OSMANYA =
+ new UnicodeBlock("OSMANYA");
+
+ /**
+ * Constant for the "Cypriot Syllabary" Unicode character block.
+ * @since 1.5
+ */
+ public static final UnicodeBlock CYPRIOT_SYLLABARY =
+ new UnicodeBlock("CYPRIOT_SYLLABARY",
+ "CYPRIOT SYLLABARY",
+ "CYPRIOTSYLLABARY");
+
+ /**
+ * Constant for the "Byzantine Musical Symbols" Unicode character block.
+ * @since 1.5
+ */
+ public static final UnicodeBlock BYZANTINE_MUSICAL_SYMBOLS =
+ new UnicodeBlock("BYZANTINE_MUSICAL_SYMBOLS",
+ "BYZANTINE MUSICAL SYMBOLS",
+ "BYZANTINEMUSICALSYMBOLS");
+
+ /**
+ * Constant for the "Musical Symbols" Unicode character block.
+ * @since 1.5
+ */
+ public static final UnicodeBlock MUSICAL_SYMBOLS =
+ new UnicodeBlock("MUSICAL_SYMBOLS",
+ "MUSICAL SYMBOLS",
+ "MUSICALSYMBOLS");
+
+ /**
+ * Constant for the "Tai Xuan Jing Symbols" Unicode character block.
+ * @since 1.5
+ */
+ public static final UnicodeBlock TAI_XUAN_JING_SYMBOLS =
+ new UnicodeBlock("TAI_XUAN_JING_SYMBOLS",
+ "TAI XUAN JING SYMBOLS",
+ "TAIXUANJINGSYMBOLS");
+
+ /**
+ * Constant for the "Mathematical Alphanumeric Symbols" Unicode
+ * character block.
+ * @since 1.5
+ */
+ public static final UnicodeBlock MATHEMATICAL_ALPHANUMERIC_SYMBOLS =
+ new UnicodeBlock("MATHEMATICAL_ALPHANUMERIC_SYMBOLS",
+ "MATHEMATICAL ALPHANUMERIC SYMBOLS",
+ "MATHEMATICALALPHANUMERICSYMBOLS");
+
+ /**
+ * Constant for the "CJK Unified Ideographs Extension B" Unicode
+ * character block.
+ * @since 1.5
+ */
+ public static final UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B =
+ new UnicodeBlock("CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B",
+ "CJK UNIFIED IDEOGRAPHS EXTENSION B",
+ "CJKUNIFIEDIDEOGRAPHSEXTENSIONB");
+
+ /**
+ * Constant for the "CJK Compatibility Ideographs Supplement" Unicode character block.
+ * @since 1.5
+ */
+ public static final UnicodeBlock CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT =
+ new UnicodeBlock("CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT",
+ "CJK COMPATIBILITY IDEOGRAPHS SUPPLEMENT",
+ "CJKCOMPATIBILITYIDEOGRAPHSSUPPLEMENT");
+
+ /**
+ * Constant for the "Tags" Unicode character block.
+ * @since 1.5
+ */
+ public static final UnicodeBlock TAGS =
+ new UnicodeBlock("TAGS");
+
+ /**
+ * Constant for the "Variation Selectors Supplement" Unicode character
+ * block.
+ * @since 1.5
+ */
+ public static final UnicodeBlock VARIATION_SELECTORS_SUPPLEMENT =
+ new UnicodeBlock("VARIATION_SELECTORS_SUPPLEMENT",
+ "VARIATION SELECTORS SUPPLEMENT",
+ "VARIATIONSELECTORSSUPPLEMENT");
+
+ /**
+ * Constant for the "Supplementary Private Use Area-A" Unicode character
+ * block.
+ * @since 1.5
+ */
+ public static final UnicodeBlock SUPPLEMENTARY_PRIVATE_USE_AREA_A =
+ new UnicodeBlock("SUPPLEMENTARY_PRIVATE_USE_AREA_A",
+ "SUPPLEMENTARY PRIVATE USE AREA-A",
+ "SUPPLEMENTARYPRIVATEUSEAREA-A");
+
+ /**
+ * Constant for the "Supplementary Private Use Area-B" Unicode character
+ * block.
+ * @since 1.5
+ */
+ public static final UnicodeBlock SUPPLEMENTARY_PRIVATE_USE_AREA_B =
+ new UnicodeBlock("SUPPLEMENTARY_PRIVATE_USE_AREA_B",
+ "SUPPLEMENTARY PRIVATE USE AREA-B",
+ "SUPPLEMENTARYPRIVATEUSEAREA-B");
+
+ /**
+ * Constant for the "High Surrogates" Unicode character block.
+ * This block represents codepoint values in the high surrogate
+ * range: U+D800 through U+DB7F
+ *
+ * @since 1.5
+ */
+ public static final UnicodeBlock HIGH_SURROGATES =
+ new UnicodeBlock("HIGH_SURROGATES",
+ "HIGH SURROGATES",
+ "HIGHSURROGATES");
+
+ /**
+ * Constant for the "High Private Use Surrogates" Unicode character
+ * block.
+ * This block represents codepoint values in the private use high
+ * surrogate range: U+DB80 through U+DBFF
+ *
+ * @since 1.5
+ */
+ public static final UnicodeBlock HIGH_PRIVATE_USE_SURROGATES =
+ new UnicodeBlock("HIGH_PRIVATE_USE_SURROGATES",
+ "HIGH PRIVATE USE SURROGATES",
+ "HIGHPRIVATEUSESURROGATES");
+
+ /**
+ * Constant for the "Low Surrogates" Unicode character block.
+ * This block represents codepoint values in the low surrogate
+ * range: U+DC00 through U+DFFF
+ *
+ * @since 1.5
+ */
+ public static final UnicodeBlock LOW_SURROGATES =
+ new UnicodeBlock("LOW_SURROGATES",
+ "LOW SURROGATES",
+ "LOWSURROGATES");
+
+ /**
+ * Constant for the "Arabic Supplement" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock ARABIC_SUPPLEMENT =
+ new UnicodeBlock("ARABIC_SUPPLEMENT",
+ "ARABIC SUPPLEMENT",
+ "ARABICSUPPLEMENT");
+
+ /**
+ * Constant for the "NKo" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock NKO =
+ new UnicodeBlock("NKO");
+
+ /**
+ * Constant for the "Samaritan" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock SAMARITAN =
+ new UnicodeBlock("SAMARITAN");
+
+ /**
+ * Constant for the "Mandaic" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock MANDAIC =
+ new UnicodeBlock("MANDAIC");
+
+ /**
+ * Constant for the "Ethiopic Supplement" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock ETHIOPIC_SUPPLEMENT =
+ new UnicodeBlock("ETHIOPIC_SUPPLEMENT",
+ "ETHIOPIC SUPPLEMENT",
+ "ETHIOPICSUPPLEMENT");
+
+ /**
+ * Constant for the "Unified Canadian Aboriginal Syllabics Extended"
+ * Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS_EXTENDED =
+ new UnicodeBlock("UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS_EXTENDED",
+ "UNIFIED CANADIAN ABORIGINAL SYLLABICS EXTENDED",
+ "UNIFIEDCANADIANABORIGINALSYLLABICSEXTENDED");
+
+ /**
+ * Constant for the "New Tai Lue" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock NEW_TAI_LUE =
+ new UnicodeBlock("NEW_TAI_LUE",
+ "NEW TAI LUE",
+ "NEWTAILUE");
+
+ /**
+ * Constant for the "Buginese" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock BUGINESE =
+ new UnicodeBlock("BUGINESE");
+
+ /**
+ * Constant for the "Tai Tham" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock TAI_THAM =
+ new UnicodeBlock("TAI_THAM",
+ "TAI THAM",
+ "TAITHAM");
+
+ /**
+ * Constant for the "Balinese" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock BALINESE =
+ new UnicodeBlock("BALINESE");
+
+ /**
+ * Constant for the "Sundanese" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock SUNDANESE =
+ new UnicodeBlock("SUNDANESE");
+
+ /**
+ * Constant for the "Batak" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock BATAK =
+ new UnicodeBlock("BATAK");
+
+ /**
+ * Constant for the "Lepcha" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock LEPCHA =
+ new UnicodeBlock("LEPCHA");
+
+ /**
+ * Constant for the "Ol Chiki" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock OL_CHIKI =
+ new UnicodeBlock("OL_CHIKI",
+ "OL CHIKI",
+ "OLCHIKI");
+
+ /**
+ * Constant for the "Vedic Extensions" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock VEDIC_EXTENSIONS =
+ new UnicodeBlock("VEDIC_EXTENSIONS",
+ "VEDIC EXTENSIONS",
+ "VEDICEXTENSIONS");
+
+ /**
+ * Constant for the "Phonetic Extensions Supplement" Unicode character
+ * block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock PHONETIC_EXTENSIONS_SUPPLEMENT =
+ new UnicodeBlock("PHONETIC_EXTENSIONS_SUPPLEMENT",
+ "PHONETIC EXTENSIONS SUPPLEMENT",
+ "PHONETICEXTENSIONSSUPPLEMENT");
+
+ /**
+ * Constant for the "Combining Diacritical Marks Supplement" Unicode
+ * character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock COMBINING_DIACRITICAL_MARKS_SUPPLEMENT =
+ new UnicodeBlock("COMBINING_DIACRITICAL_MARKS_SUPPLEMENT",
+ "COMBINING DIACRITICAL MARKS SUPPLEMENT",
+ "COMBININGDIACRITICALMARKSSUPPLEMENT");
+
+ /**
+ * Constant for the "Glagolitic" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock GLAGOLITIC =
+ new UnicodeBlock("GLAGOLITIC");
+
+ /**
+ * Constant for the "Latin Extended-C" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock LATIN_EXTENDED_C =
+ new UnicodeBlock("LATIN_EXTENDED_C",
+ "LATIN EXTENDED-C",
+ "LATINEXTENDED-C");
+
+ /**
+ * Constant for the "Coptic" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock COPTIC =
+ new UnicodeBlock("COPTIC");
+
+ /**
+ * Constant for the "Georgian Supplement" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock GEORGIAN_SUPPLEMENT =
+ new UnicodeBlock("GEORGIAN_SUPPLEMENT",
+ "GEORGIAN SUPPLEMENT",
+ "GEORGIANSUPPLEMENT");
+
+ /**
+ * Constant for the "Tifinagh" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock TIFINAGH =
+ new UnicodeBlock("TIFINAGH");
+
+ /**
+ * Constant for the "Ethiopic Extended" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock ETHIOPIC_EXTENDED =
+ new UnicodeBlock("ETHIOPIC_EXTENDED",
+ "ETHIOPIC EXTENDED",
+ "ETHIOPICEXTENDED");
+
+ /**
+ * Constant for the "Cyrillic Extended-A" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock CYRILLIC_EXTENDED_A =
+ new UnicodeBlock("CYRILLIC_EXTENDED_A",
+ "CYRILLIC EXTENDED-A",
+ "CYRILLICEXTENDED-A");
+
+ /**
+ * Constant for the "Supplemental Punctuation" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock SUPPLEMENTAL_PUNCTUATION =
+ new UnicodeBlock("SUPPLEMENTAL_PUNCTUATION",
+ "SUPPLEMENTAL PUNCTUATION",
+ "SUPPLEMENTALPUNCTUATION");
+
+ /**
+ * Constant for the "CJK Strokes" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock CJK_STROKES =
+ new UnicodeBlock("CJK_STROKES",
+ "CJK STROKES",
+ "CJKSTROKES");
+
+ /**
+ * Constant for the "Lisu" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock LISU =
+ new UnicodeBlock("LISU");
+
+ /**
+ * Constant for the "Vai" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock VAI =
+ new UnicodeBlock("VAI");
+
+ /**
+ * Constant for the "Cyrillic Extended-B" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock CYRILLIC_EXTENDED_B =
+ new UnicodeBlock("CYRILLIC_EXTENDED_B",
+ "CYRILLIC EXTENDED-B",
+ "CYRILLICEXTENDED-B");
+
+ /**
+ * Constant for the "Bamum" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock BAMUM =
+ new UnicodeBlock("BAMUM");
+
+ /**
+ * Constant for the "Modifier Tone Letters" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock MODIFIER_TONE_LETTERS =
+ new UnicodeBlock("MODIFIER_TONE_LETTERS",
+ "MODIFIER TONE LETTERS",
+ "MODIFIERTONELETTERS");
+
+ /**
+ * Constant for the "Latin Extended-D" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock LATIN_EXTENDED_D =
+ new UnicodeBlock("LATIN_EXTENDED_D",
+ "LATIN EXTENDED-D",
+ "LATINEXTENDED-D");
+
+ /**
+ * Constant for the "Syloti Nagri" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock SYLOTI_NAGRI =
+ new UnicodeBlock("SYLOTI_NAGRI",
+ "SYLOTI NAGRI",
+ "SYLOTINAGRI");
+
+ /**
+ * Constant for the "Common Indic Number Forms" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock COMMON_INDIC_NUMBER_FORMS =
+ new UnicodeBlock("COMMON_INDIC_NUMBER_FORMS",
+ "COMMON INDIC NUMBER FORMS",
+ "COMMONINDICNUMBERFORMS");
+
+ /**
+ * Constant for the "Phags-pa" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock PHAGS_PA =
+ new UnicodeBlock("PHAGS_PA",
+ "PHAGS-PA");
+
+ /**
+ * Constant for the "Saurashtra" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock SAURASHTRA =
+ new UnicodeBlock("SAURASHTRA");
+
+ /**
+ * Constant for the "Devanagari Extended" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock DEVANAGARI_EXTENDED =
+ new UnicodeBlock("DEVANAGARI_EXTENDED",
+ "DEVANAGARI EXTENDED",
+ "DEVANAGARIEXTENDED");
+
+ /**
+ * Constant for the "Kayah Li" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock KAYAH_LI =
+ new UnicodeBlock("KAYAH_LI",
+ "KAYAH LI",
+ "KAYAHLI");
+
+ /**
+ * Constant for the "Rejang" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock REJANG =
+ new UnicodeBlock("REJANG");
+
+ /**
+ * Constant for the "Hangul Jamo Extended-A" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock HANGUL_JAMO_EXTENDED_A =
+ new UnicodeBlock("HANGUL_JAMO_EXTENDED_A",
+ "HANGUL JAMO EXTENDED-A",
+ "HANGULJAMOEXTENDED-A");
+
+ /**
+ * Constant for the "Javanese" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock JAVANESE =
+ new UnicodeBlock("JAVANESE");
+
+ /**
+ * Constant for the "Cham" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock CHAM =
+ new UnicodeBlock("CHAM");
+
+ /**
+ * Constant for the "Myanmar Extended-A" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock MYANMAR_EXTENDED_A =
+ new UnicodeBlock("MYANMAR_EXTENDED_A",
+ "MYANMAR EXTENDED-A",
+ "MYANMAREXTENDED-A");
+
+ /**
+ * Constant for the "Tai Viet" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock TAI_VIET =
+ new UnicodeBlock("TAI_VIET",
+ "TAI VIET",
+ "TAIVIET");
+
+ /**
+ * Constant for the "Ethiopic Extended-A" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock ETHIOPIC_EXTENDED_A =
+ new UnicodeBlock("ETHIOPIC_EXTENDED_A",
+ "ETHIOPIC EXTENDED-A",
+ "ETHIOPICEXTENDED-A");
+
+ /**
+ * Constant for the "Meetei Mayek" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock MEETEI_MAYEK =
+ new UnicodeBlock("MEETEI_MAYEK",
+ "MEETEI MAYEK",
+ "MEETEIMAYEK");
+
+ /**
+ * Constant for the "Hangul Jamo Extended-B" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock HANGUL_JAMO_EXTENDED_B =
+ new UnicodeBlock("HANGUL_JAMO_EXTENDED_B",
+ "HANGUL JAMO EXTENDED-B",
+ "HANGULJAMOEXTENDED-B");
+
+ /**
+ * Constant for the "Vertical Forms" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock VERTICAL_FORMS =
+ new UnicodeBlock("VERTICAL_FORMS",
+ "VERTICAL FORMS",
+ "VERTICALFORMS");
+
+ /**
+ * Constant for the "Ancient Greek Numbers" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock ANCIENT_GREEK_NUMBERS =
+ new UnicodeBlock("ANCIENT_GREEK_NUMBERS",
+ "ANCIENT GREEK NUMBERS",
+ "ANCIENTGREEKNUMBERS");
+
+ /**
+ * Constant for the "Ancient Symbols" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock ANCIENT_SYMBOLS =
+ new UnicodeBlock("ANCIENT_SYMBOLS",
+ "ANCIENT SYMBOLS",
+ "ANCIENTSYMBOLS");
+
+ /**
+ * Constant for the "Phaistos Disc" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock PHAISTOS_DISC =
+ new UnicodeBlock("PHAISTOS_DISC",
+ "PHAISTOS DISC",
+ "PHAISTOSDISC");
+
+ /**
+ * Constant for the "Lycian" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock LYCIAN =
+ new UnicodeBlock("LYCIAN");
+
+ /**
+ * Constant for the "Carian" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock CARIAN =
+ new UnicodeBlock("CARIAN");
+
+ /**
+ * Constant for the "Old Persian" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock OLD_PERSIAN =
+ new UnicodeBlock("OLD_PERSIAN",
+ "OLD PERSIAN",
+ "OLDPERSIAN");
+
+ /**
+ * Constant for the "Imperial Aramaic" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock IMPERIAL_ARAMAIC =
+ new UnicodeBlock("IMPERIAL_ARAMAIC",
+ "IMPERIAL ARAMAIC",
+ "IMPERIALARAMAIC");
+
+ /**
+ * Constant for the "Phoenician" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock PHOENICIAN =
+ new UnicodeBlock("PHOENICIAN");
+
+ /**
+ * Constant for the "Lydian" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock LYDIAN =
+ new UnicodeBlock("LYDIAN");
+
+ /**
+ * Constant for the "Kharoshthi" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock KHAROSHTHI =
+ new UnicodeBlock("KHAROSHTHI");
+
+ /**
+ * Constant for the "Old South Arabian" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock OLD_SOUTH_ARABIAN =
+ new UnicodeBlock("OLD_SOUTH_ARABIAN",
+ "OLD SOUTH ARABIAN",
+ "OLDSOUTHARABIAN");
+
+ /**
+ * Constant for the "Avestan" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock AVESTAN =
+ new UnicodeBlock("AVESTAN");
+
+ /**
+ * Constant for the "Inscriptional Parthian" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock INSCRIPTIONAL_PARTHIAN =
+ new UnicodeBlock("INSCRIPTIONAL_PARTHIAN",
+ "INSCRIPTIONAL PARTHIAN",
+ "INSCRIPTIONALPARTHIAN");
+
+ /**
+ * Constant for the "Inscriptional Pahlavi" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock INSCRIPTIONAL_PAHLAVI =
+ new UnicodeBlock("INSCRIPTIONAL_PAHLAVI",
+ "INSCRIPTIONAL PAHLAVI",
+ "INSCRIPTIONALPAHLAVI");
+
+ /**
+ * Constant for the "Old Turkic" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock OLD_TURKIC =
+ new UnicodeBlock("OLD_TURKIC",
+ "OLD TURKIC",
+ "OLDTURKIC");
+
+ /**
+ * Constant for the "Rumi Numeral Symbols" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock RUMI_NUMERAL_SYMBOLS =
+ new UnicodeBlock("RUMI_NUMERAL_SYMBOLS",
+ "RUMI NUMERAL SYMBOLS",
+ "RUMINUMERALSYMBOLS");
+
+ /**
+ * Constant for the "Brahmi" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock BRAHMI =
+ new UnicodeBlock("BRAHMI");
+
+ /**
+ * Constant for the "Kaithi" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock KAITHI =
+ new UnicodeBlock("KAITHI");
+
+ /**
+ * Constant for the "Cuneiform" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock CUNEIFORM =
+ new UnicodeBlock("CUNEIFORM");
+
+ /**
+ * Constant for the "Cuneiform Numbers and Punctuation" Unicode
+ * character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock CUNEIFORM_NUMBERS_AND_PUNCTUATION =
+ new UnicodeBlock("CUNEIFORM_NUMBERS_AND_PUNCTUATION",
+ "CUNEIFORM NUMBERS AND PUNCTUATION",
+ "CUNEIFORMNUMBERSANDPUNCTUATION");
+
+ /**
+ * Constant for the "Egyptian Hieroglyphs" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock EGYPTIAN_HIEROGLYPHS =
+ new UnicodeBlock("EGYPTIAN_HIEROGLYPHS",
+ "EGYPTIAN HIEROGLYPHS",
+ "EGYPTIANHIEROGLYPHS");
+
+ /**
+ * Constant for the "Bamum Supplement" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock BAMUM_SUPPLEMENT =
+ new UnicodeBlock("BAMUM_SUPPLEMENT",
+ "BAMUM SUPPLEMENT",
+ "BAMUMSUPPLEMENT");
+
+ /**
+ * Constant for the "Kana Supplement" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock KANA_SUPPLEMENT =
+ new UnicodeBlock("KANA_SUPPLEMENT",
+ "KANA SUPPLEMENT",
+ "KANASUPPLEMENT");
+
+ /**
+ * Constant for the "Ancient Greek Musical Notation" Unicode character
+ * block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock ANCIENT_GREEK_MUSICAL_NOTATION =
+ new UnicodeBlock("ANCIENT_GREEK_MUSICAL_NOTATION",
+ "ANCIENT GREEK MUSICAL NOTATION",
+ "ANCIENTGREEKMUSICALNOTATION");
+
+ /**
+ * Constant for the "Counting Rod Numerals" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock COUNTING_ROD_NUMERALS =
+ new UnicodeBlock("COUNTING_ROD_NUMERALS",
+ "COUNTING ROD NUMERALS",
+ "COUNTINGRODNUMERALS");
+
+ /**
+ * Constant for the "Mahjong Tiles" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock MAHJONG_TILES =
+ new UnicodeBlock("MAHJONG_TILES",
+ "MAHJONG TILES",
+ "MAHJONGTILES");
+
+ /**
+ * Constant for the "Domino Tiles" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock DOMINO_TILES =
+ new UnicodeBlock("DOMINO_TILES",
+ "DOMINO TILES",
+ "DOMINOTILES");
+
+ /**
+ * Constant for the "Playing Cards" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock PLAYING_CARDS =
+ new UnicodeBlock("PLAYING_CARDS",
+ "PLAYING CARDS",
+ "PLAYINGCARDS");
+
+ /**
+ * Constant for the "Enclosed Alphanumeric Supplement" Unicode character
+ * block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock ENCLOSED_ALPHANUMERIC_SUPPLEMENT =
+ new UnicodeBlock("ENCLOSED_ALPHANUMERIC_SUPPLEMENT",
+ "ENCLOSED ALPHANUMERIC SUPPLEMENT",
+ "ENCLOSEDALPHANUMERICSUPPLEMENT");
+
+ /**
+ * Constant for the "Enclosed Ideographic Supplement" Unicode character
+ * block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock ENCLOSED_IDEOGRAPHIC_SUPPLEMENT =
+ new UnicodeBlock("ENCLOSED_IDEOGRAPHIC_SUPPLEMENT",
+ "ENCLOSED IDEOGRAPHIC SUPPLEMENT",
+ "ENCLOSEDIDEOGRAPHICSUPPLEMENT");
+
+ /**
+ * Constant for the "Miscellaneous Symbols And Pictographs" Unicode
+ * character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock MISCELLANEOUS_SYMBOLS_AND_PICTOGRAPHS =
+ new UnicodeBlock("MISCELLANEOUS_SYMBOLS_AND_PICTOGRAPHS",
+ "MISCELLANEOUS SYMBOLS AND PICTOGRAPHS",
+ "MISCELLANEOUSSYMBOLSANDPICTOGRAPHS");
+
+ /**
+ * Constant for the "Emoticons" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock EMOTICONS =
+ new UnicodeBlock("EMOTICONS");
+
+ /**
+ * Constant for the "Transport And Map Symbols" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock TRANSPORT_AND_MAP_SYMBOLS =
+ new UnicodeBlock("TRANSPORT_AND_MAP_SYMBOLS",
+ "TRANSPORT AND MAP SYMBOLS",
+ "TRANSPORTANDMAPSYMBOLS");
+
+ /**
+ * Constant for the "Alchemical Symbols" Unicode character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock ALCHEMICAL_SYMBOLS =
+ new UnicodeBlock("ALCHEMICAL_SYMBOLS",
+ "ALCHEMICAL SYMBOLS",
+ "ALCHEMICALSYMBOLS");
+
+ /**
+ * Constant for the "CJK Unified Ideographs Extension C" Unicode
+ * character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_C =
+ new UnicodeBlock("CJK_UNIFIED_IDEOGRAPHS_EXTENSION_C",
+ "CJK UNIFIED IDEOGRAPHS EXTENSION C",
+ "CJKUNIFIEDIDEOGRAPHSEXTENSIONC");
+
+ /**
+ * Constant for the "CJK Unified Ideographs Extension D" Unicode
+ * character block.
+ * @since 1.7
+ */
+ public static final UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_D =
+ new UnicodeBlock("CJK_UNIFIED_IDEOGRAPHS_EXTENSION_D",
+ "CJK UNIFIED IDEOGRAPHS EXTENSION D",
+ "CJKUNIFIEDIDEOGRAPHSEXTENSIOND");
+
+ /**
+ * Constant for the "Arabic Extended-A" Unicode character block.
+ * @since 1.8
+ */
+ public static final UnicodeBlock ARABIC_EXTENDED_A =
+ new UnicodeBlock("ARABIC_EXTENDED_A",
+ "ARABIC EXTENDED-A",
+ "ARABICEXTENDED-A");
+
+ /**
+ * Constant for the "Sundanese Supplement" Unicode character block.
+ * @since 1.8
+ */
+ public static final UnicodeBlock SUNDANESE_SUPPLEMENT =
+ new UnicodeBlock("SUNDANESE_SUPPLEMENT",
+ "SUNDANESE SUPPLEMENT",
+ "SUNDANESESUPPLEMENT");
+
+ /**
+ * Constant for the "Meetei Mayek Extensions" Unicode character block.
+ * @since 1.8
+ */
+ public static final UnicodeBlock MEETEI_MAYEK_EXTENSIONS =
+ new UnicodeBlock("MEETEI_MAYEK_EXTENSIONS",
+ "MEETEI MAYEK EXTENSIONS",
+ "MEETEIMAYEKEXTENSIONS");
+
+ /**
+ * Constant for the "Meroitic Hieroglyphs" Unicode character block.
+ * @since 1.8
+ */
+ public static final UnicodeBlock MEROITIC_HIEROGLYPHS =
+ new UnicodeBlock("MEROITIC_HIEROGLYPHS",
+ "MEROITIC HIEROGLYPHS",
+ "MEROITICHIEROGLYPHS");
+
+ /**
+ * Constant for the "Meroitic Cursive" Unicode character block.
+ * @since 1.8
+ */
+ public static final UnicodeBlock MEROITIC_CURSIVE =
+ new UnicodeBlock("MEROITIC_CURSIVE",
+ "MEROITIC CURSIVE",
+ "MEROITICCURSIVE");
+
+ /**
+ * Constant for the "Sora Sompeng" Unicode character block.
+ * @since 1.8
+ */
+ public static final UnicodeBlock SORA_SOMPENG =
+ new UnicodeBlock("SORA_SOMPENG",
+ "SORA SOMPENG",
+ "SORASOMPENG");
+
+ /**
+ * Constant for the "Chakma" Unicode character block.
+ * @since 1.8
+ */
+ public static final UnicodeBlock CHAKMA =
+ new UnicodeBlock("CHAKMA");
+
+ /**
+ * Constant for the "Sharada" Unicode character block.
+ * @since 1.8
+ */
+ public static final UnicodeBlock SHARADA =
+ new UnicodeBlock("SHARADA");
+
+ /**
+ * Constant for the "Takri" Unicode character block.
+ * @since 1.8
+ */
+ public static final UnicodeBlock TAKRI =
+ new UnicodeBlock("TAKRI");
+
+ /**
+ * Constant for the "Miao" Unicode character block.
+ * @since 1.8
+ */
+ public static final UnicodeBlock MIAO =
+ new UnicodeBlock("MIAO");
+
+ /**
+ * Constant for the "Arabic Mathematical Alphabetic Symbols" Unicode
+ * character block.
+ * @since 1.8
+ */
+ public static final UnicodeBlock ARABIC_MATHEMATICAL_ALPHABETIC_SYMBOLS =
+ new UnicodeBlock("ARABIC_MATHEMATICAL_ALPHABETIC_SYMBOLS",
+ "ARABIC MATHEMATICAL ALPHABETIC SYMBOLS",
+ "ARABICMATHEMATICALALPHABETICSYMBOLS");
+
+ private static final int blockStarts[] = {
+ 0x0000, // 0000..007F; Basic Latin
+ 0x0080, // 0080..00FF; Latin-1 Supplement
+ 0x0100, // 0100..017F; Latin Extended-A
+ 0x0180, // 0180..024F; Latin Extended-B
+ 0x0250, // 0250..02AF; IPA Extensions
+ 0x02B0, // 02B0..02FF; Spacing Modifier Letters
+ 0x0300, // 0300..036F; Combining Diacritical Marks
+ 0x0370, // 0370..03FF; Greek and Coptic
+ 0x0400, // 0400..04FF; Cyrillic
+ 0x0500, // 0500..052F; Cyrillic Supplement
+ 0x0530, // 0530..058F; Armenian
+ 0x0590, // 0590..05FF; Hebrew
+ 0x0600, // 0600..06FF; Arabic
+ 0x0700, // 0700..074F; Syriac
+ 0x0750, // 0750..077F; Arabic Supplement
+ 0x0780, // 0780..07BF; Thaana
+ 0x07C0, // 07C0..07FF; NKo
+ 0x0800, // 0800..083F; Samaritan
+ 0x0840, // 0840..085F; Mandaic
+ 0x0860, // unassigned
+ 0x08A0, // 08A0..08FF; Arabic Extended-A
+ 0x0900, // 0900..097F; Devanagari
+ 0x0980, // 0980..09FF; Bengali
+ 0x0A00, // 0A00..0A7F; Gurmukhi
+ 0x0A80, // 0A80..0AFF; Gujarati
+ 0x0B00, // 0B00..0B7F; Oriya
+ 0x0B80, // 0B80..0BFF; Tamil
+ 0x0C00, // 0C00..0C7F; Telugu
+ 0x0C80, // 0C80..0CFF; Kannada
+ 0x0D00, // 0D00..0D7F; Malayalam
+ 0x0D80, // 0D80..0DFF; Sinhala
+ 0x0E00, // 0E00..0E7F; Thai
+ 0x0E80, // 0E80..0EFF; Lao
+ 0x0F00, // 0F00..0FFF; Tibetan
+ 0x1000, // 1000..109F; Myanmar
+ 0x10A0, // 10A0..10FF; Georgian
+ 0x1100, // 1100..11FF; Hangul Jamo
+ 0x1200, // 1200..137F; Ethiopic
+ 0x1380, // 1380..139F; Ethiopic Supplement
+ 0x13A0, // 13A0..13FF; Cherokee
+ 0x1400, // 1400..167F; Unified Canadian Aboriginal Syllabics
+ 0x1680, // 1680..169F; Ogham
+ 0x16A0, // 16A0..16FF; Runic
+ 0x1700, // 1700..171F; Tagalog
+ 0x1720, // 1720..173F; Hanunoo
+ 0x1740, // 1740..175F; Buhid
+ 0x1760, // 1760..177F; Tagbanwa
+ 0x1780, // 1780..17FF; Khmer
+ 0x1800, // 1800..18AF; Mongolian
+ 0x18B0, // 18B0..18FF; Unified Canadian Aboriginal Syllabics Extended
+ 0x1900, // 1900..194F; Limbu
+ 0x1950, // 1950..197F; Tai Le
+ 0x1980, // 1980..19DF; New Tai Lue
+ 0x19E0, // 19E0..19FF; Khmer Symbols
+ 0x1A00, // 1A00..1A1F; Buginese
+ 0x1A20, // 1A20..1AAF; Tai Tham
+ 0x1AB0, // unassigned
+ 0x1B00, // 1B00..1B7F; Balinese
+ 0x1B80, // 1B80..1BBF; Sundanese
+ 0x1BC0, // 1BC0..1BFF; Batak
+ 0x1C00, // 1C00..1C4F; Lepcha
+ 0x1C50, // 1C50..1C7F; Ol Chiki
+ 0x1C80, // unassigned
+ 0x1CC0, // 1CC0..1CCF; Sundanese Supplement
+ 0x1CD0, // 1CD0..1CFF; Vedic Extensions
+ 0x1D00, // 1D00..1D7F; Phonetic Extensions
+ 0x1D80, // 1D80..1DBF; Phonetic Extensions Supplement
+ 0x1DC0, // 1DC0..1DFF; Combining Diacritical Marks Supplement
+ 0x1E00, // 1E00..1EFF; Latin Extended Additional
+ 0x1F00, // 1F00..1FFF; Greek Extended
+ 0x2000, // 2000..206F; General Punctuation
+ 0x2070, // 2070..209F; Superscripts and Subscripts
+ 0x20A0, // 20A0..20CF; Currency Symbols
+ 0x20D0, // 20D0..20FF; Combining Diacritical Marks for Symbols
+ 0x2100, // 2100..214F; Letterlike Symbols
+ 0x2150, // 2150..218F; Number Forms
+ 0x2190, // 2190..21FF; Arrows
+ 0x2200, // 2200..22FF; Mathematical Operators
+ 0x2300, // 2300..23FF; Miscellaneous Technical
+ 0x2400, // 2400..243F; Control Pictures
+ 0x2440, // 2440..245F; Optical Character Recognition
+ 0x2460, // 2460..24FF; Enclosed Alphanumerics
+ 0x2500, // 2500..257F; Box Drawing
+ 0x2580, // 2580..259F; Block Elements
+ 0x25A0, // 25A0..25FF; Geometric Shapes
+ 0x2600, // 2600..26FF; Miscellaneous Symbols
+ 0x2700, // 2700..27BF; Dingbats
+ 0x27C0, // 27C0..27EF; Miscellaneous Mathematical Symbols-A
+ 0x27F0, // 27F0..27FF; Supplemental Arrows-A
+ 0x2800, // 2800..28FF; Braille Patterns
+ 0x2900, // 2900..297F; Supplemental Arrows-B
+ 0x2980, // 2980..29FF; Miscellaneous Mathematical Symbols-B
+ 0x2A00, // 2A00..2AFF; Supplemental Mathematical Operators
+ 0x2B00, // 2B00..2BFF; Miscellaneous Symbols and Arrows
+ 0x2C00, // 2C00..2C5F; Glagolitic
+ 0x2C60, // 2C60..2C7F; Latin Extended-C
+ 0x2C80, // 2C80..2CFF; Coptic
+ 0x2D00, // 2D00..2D2F; Georgian Supplement
+ 0x2D30, // 2D30..2D7F; Tifinagh
+ 0x2D80, // 2D80..2DDF; Ethiopic Extended
+ 0x2DE0, // 2DE0..2DFF; Cyrillic Extended-A
+ 0x2E00, // 2E00..2E7F; Supplemental Punctuation
+ 0x2E80, // 2E80..2EFF; CJK Radicals Supplement
+ 0x2F00, // 2F00..2FDF; Kangxi Radicals
+ 0x2FE0, // unassigned
+ 0x2FF0, // 2FF0..2FFF; Ideographic Description Characters
+ 0x3000, // 3000..303F; CJK Symbols and Punctuation
+ 0x3040, // 3040..309F; Hiragana
+ 0x30A0, // 30A0..30FF; Katakana
+ 0x3100, // 3100..312F; Bopomofo
+ 0x3130, // 3130..318F; Hangul Compatibility Jamo
+ 0x3190, // 3190..319F; Kanbun
+ 0x31A0, // 31A0..31BF; Bopomofo Extended
+ 0x31C0, // 31C0..31EF; CJK Strokes
+ 0x31F0, // 31F0..31FF; Katakana Phonetic Extensions
+ 0x3200, // 3200..32FF; Enclosed CJK Letters and Months
+ 0x3300, // 3300..33FF; CJK Compatibility
+ 0x3400, // 3400..4DBF; CJK Unified Ideographs Extension A
+ 0x4DC0, // 4DC0..4DFF; Yijing Hexagram Symbols
+ 0x4E00, // 4E00..9FFF; CJK Unified Ideographs
+ 0xA000, // A000..A48F; Yi Syllables
+ 0xA490, // A490..A4CF; Yi Radicals
+ 0xA4D0, // A4D0..A4FF; Lisu
+ 0xA500, // A500..A63F; Vai
+ 0xA640, // A640..A69F; Cyrillic Extended-B
+ 0xA6A0, // A6A0..A6FF; Bamum
+ 0xA700, // A700..A71F; Modifier Tone Letters
+ 0xA720, // A720..A7FF; Latin Extended-D
+ 0xA800, // A800..A82F; Syloti Nagri
+ 0xA830, // A830..A83F; Common Indic Number Forms
+ 0xA840, // A840..A87F; Phags-pa
+ 0xA880, // A880..A8DF; Saurashtra
+ 0xA8E0, // A8E0..A8FF; Devanagari Extended
+ 0xA900, // A900..A92F; Kayah Li
+ 0xA930, // A930..A95F; Rejang
+ 0xA960, // A960..A97F; Hangul Jamo Extended-A
+ 0xA980, // A980..A9DF; Javanese
+ 0xA9E0, // unassigned
+ 0xAA00, // AA00..AA5F; Cham
+ 0xAA60, // AA60..AA7F; Myanmar Extended-A
+ 0xAA80, // AA80..AADF; Tai Viet
+ 0xAAE0, // AAE0..AAFF; Meetei Mayek Extensions
+ 0xAB00, // AB00..AB2F; Ethiopic Extended-A
+ 0xAB30, // unassigned
+ 0xABC0, // ABC0..ABFF; Meetei Mayek
+ 0xAC00, // AC00..D7AF; Hangul Syllables
+ 0xD7B0, // D7B0..D7FF; Hangul Jamo Extended-B
+ 0xD800, // D800..DB7F; High Surrogates
+ 0xDB80, // DB80..DBFF; High Private Use Surrogates
+ 0xDC00, // DC00..DFFF; Low Surrogates
+ 0xE000, // E000..F8FF; Private Use Area
+ 0xF900, // F900..FAFF; CJK Compatibility Ideographs
+ 0xFB00, // FB00..FB4F; Alphabetic Presentation Forms
+ 0xFB50, // FB50..FDFF; Arabic Presentation Forms-A
+ 0xFE00, // FE00..FE0F; Variation Selectors
+ 0xFE10, // FE10..FE1F; Vertical Forms
+ 0xFE20, // FE20..FE2F; Combining Half Marks
+ 0xFE30, // FE30..FE4F; CJK Compatibility Forms
+ 0xFE50, // FE50..FE6F; Small Form Variants
+ 0xFE70, // FE70..FEFF; Arabic Presentation Forms-B
+ 0xFF00, // FF00..FFEF; Halfwidth and Fullwidth Forms
+ 0xFFF0, // FFF0..FFFF; Specials
+ 0x10000, // 10000..1007F; Linear B Syllabary
+ 0x10080, // 10080..100FF; Linear B Ideograms
+ 0x10100, // 10100..1013F; Aegean Numbers
+ 0x10140, // 10140..1018F; Ancient Greek Numbers
+ 0x10190, // 10190..101CF; Ancient Symbols
+ 0x101D0, // 101D0..101FF; Phaistos Disc
+ 0x10200, // unassigned
+ 0x10280, // 10280..1029F; Lycian
+ 0x102A0, // 102A0..102DF; Carian
+ 0x102E0, // unassigned
+ 0x10300, // 10300..1032F; Old Italic
+ 0x10330, // 10330..1034F; Gothic
+ 0x10350, // unassigned
+ 0x10380, // 10380..1039F; Ugaritic
+ 0x103A0, // 103A0..103DF; Old Persian
+ 0x103E0, // unassigned
+ 0x10400, // 10400..1044F; Deseret
+ 0x10450, // 10450..1047F; Shavian
+ 0x10480, // 10480..104AF; Osmanya
+ 0x104B0, // unassigned
+ 0x10800, // 10800..1083F; Cypriot Syllabary
+ 0x10840, // 10840..1085F; Imperial Aramaic
+ 0x10860, // unassigned
+ 0x10900, // 10900..1091F; Phoenician
+ 0x10920, // 10920..1093F; Lydian
+ 0x10940, // unassigned
+ 0x10980, // 10980..1099F; Meroitic Hieroglyphs
+ 0x109A0, // 109A0..109FF; Meroitic Cursive
+ 0x10A00, // 10A00..10A5F; Kharoshthi
+ 0x10A60, // 10A60..10A7F; Old South Arabian
+ 0x10A80, // unassigned
+ 0x10B00, // 10B00..10B3F; Avestan
+ 0x10B40, // 10B40..10B5F; Inscriptional Parthian
+ 0x10B60, // 10B60..10B7F; Inscriptional Pahlavi
+ 0x10B80, // unassigned
+ 0x10C00, // 10C00..10C4F; Old Turkic
+ 0x10C50, // unassigned
+ 0x10E60, // 10E60..10E7F; Rumi Numeral Symbols
+ 0x10E80, // unassigned
+ 0x11000, // 11000..1107F; Brahmi
+ 0x11080, // 11080..110CF; Kaithi
+ 0x110D0, // 110D0..110FF; Sora Sompeng
+ 0x11100, // 11100..1114F; Chakma
+ 0x11150, // unassigned
+ 0x11180, // 11180..111DF; Sharada
+ 0x111E0, // unassigned
+ 0x11680, // 11680..116CF; Takri
+ 0x116D0, // unassigned
+ 0x12000, // 12000..123FF; Cuneiform
+ 0x12400, // 12400..1247F; Cuneiform Numbers and Punctuation
+ 0x12480, // unassigned
+ 0x13000, // 13000..1342F; Egyptian Hieroglyphs
+ 0x13430, // unassigned
+ 0x16800, // 16800..16A3F; Bamum Supplement
+ 0x16A40, // unassigned
+ 0x16F00, // 16F00..16F9F; Miao
+ 0x16FA0, // unassigned
+ 0x1B000, // 1B000..1B0FF; Kana Supplement
+ 0x1B100, // unassigned
+ 0x1D000, // 1D000..1D0FF; Byzantine Musical Symbols
+ 0x1D100, // 1D100..1D1FF; Musical Symbols
+ 0x1D200, // 1D200..1D24F; Ancient Greek Musical Notation
+ 0x1D250, // unassigned
+ 0x1D300, // 1D300..1D35F; Tai Xuan Jing Symbols
+ 0x1D360, // 1D360..1D37F; Counting Rod Numerals
+ 0x1D380, // unassigned
+ 0x1D400, // 1D400..1D7FF; Mathematical Alphanumeric Symbols
+ 0x1D800, // unassigned
+ 0x1EE00, // 1EE00..1EEFF; Arabic Mathematical Alphabetic Symbols
+ 0x1EF00, // unassigned
+ 0x1F000, // 1F000..1F02F; Mahjong Tiles
+ 0x1F030, // 1F030..1F09F; Domino Tiles
+ 0x1F0A0, // 1F0A0..1F0FF; Playing Cards
+ 0x1F100, // 1F100..1F1FF; Enclosed Alphanumeric Supplement
+ 0x1F200, // 1F200..1F2FF; Enclosed Ideographic Supplement
+ 0x1F300, // 1F300..1F5FF; Miscellaneous Symbols And Pictographs
+ 0x1F600, // 1F600..1F64F; Emoticons
+ 0x1F650, // unassigned
+ 0x1F680, // 1F680..1F6FF; Transport And Map Symbols
+ 0x1F700, // 1F700..1F77F; Alchemical Symbols
+ 0x1F780, // unassigned
+ 0x20000, // 20000..2A6DF; CJK Unified Ideographs Extension B
+ 0x2A6E0, // unassigned
+ 0x2A700, // 2A700..2B73F; CJK Unified Ideographs Extension C
+ 0x2B740, // 2B740..2B81F; CJK Unified Ideographs Extension D
+ 0x2B820, // unassigned
+ 0x2F800, // 2F800..2FA1F; CJK Compatibility Ideographs Supplement
+ 0x2FA20, // unassigned
+ 0xE0000, // E0000..E007F; Tags
+ 0xE0080, // unassigned
+ 0xE0100, // E0100..E01EF; Variation Selectors Supplement
+ 0xE01F0, // unassigned
+ 0xF0000, // F0000..FFFFF; Supplementary Private Use Area-A
+ 0x100000 // 100000..10FFFF; Supplementary Private Use Area-B
+ };
+
+ private static final UnicodeBlock[] blocks = {
+ BASIC_LATIN,
+ LATIN_1_SUPPLEMENT,
+ LATIN_EXTENDED_A,
+ LATIN_EXTENDED_B,
+ IPA_EXTENSIONS,
+ SPACING_MODIFIER_LETTERS,
+ COMBINING_DIACRITICAL_MARKS,
+ GREEK,
+ CYRILLIC,
+ CYRILLIC_SUPPLEMENTARY,
+ ARMENIAN,
+ HEBREW,
+ ARABIC,
+ SYRIAC,
+ ARABIC_SUPPLEMENT,
+ THAANA,
+ NKO,
+ SAMARITAN,
+ MANDAIC,
+ null,
+ ARABIC_EXTENDED_A,
+ DEVANAGARI,
+ BENGALI,
+ GURMUKHI,
+ GUJARATI,
+ ORIYA,
+ TAMIL,
+ TELUGU,
+ KANNADA,
+ MALAYALAM,
+ SINHALA,
+ THAI,
+ LAO,
+ TIBETAN,
+ MYANMAR,
+ GEORGIAN,
+ HANGUL_JAMO,
+ ETHIOPIC,
+ ETHIOPIC_SUPPLEMENT,
+ CHEROKEE,
+ UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS,
+ OGHAM,
+ RUNIC,
+ TAGALOG,
+ HANUNOO,
+ BUHID,
+ TAGBANWA,
+ KHMER,
+ MONGOLIAN,
+ UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS_EXTENDED,
+ LIMBU,
+ TAI_LE,
+ NEW_TAI_LUE,
+ KHMER_SYMBOLS,
+ BUGINESE,
+ TAI_THAM,
+ null,
+ BALINESE,
+ SUNDANESE,
+ BATAK,
+ LEPCHA,
+ OL_CHIKI,
+ null,
+ SUNDANESE_SUPPLEMENT,
+ VEDIC_EXTENSIONS,
+ PHONETIC_EXTENSIONS,
+ PHONETIC_EXTENSIONS_SUPPLEMENT,
+ COMBINING_DIACRITICAL_MARKS_SUPPLEMENT,
+ LATIN_EXTENDED_ADDITIONAL,
+ GREEK_EXTENDED,
+ GENERAL_PUNCTUATION,
+ SUPERSCRIPTS_AND_SUBSCRIPTS,
+ CURRENCY_SYMBOLS,
+ COMBINING_MARKS_FOR_SYMBOLS,
+ LETTERLIKE_SYMBOLS,
+ NUMBER_FORMS,
+ ARROWS,
+ MATHEMATICAL_OPERATORS,
+ MISCELLANEOUS_TECHNICAL,
+ CONTROL_PICTURES,
+ OPTICAL_CHARACTER_RECOGNITION,
+ ENCLOSED_ALPHANUMERICS,
+ BOX_DRAWING,
+ BLOCK_ELEMENTS,
+ GEOMETRIC_SHAPES,
+ MISCELLANEOUS_SYMBOLS,
+ DINGBATS,
+ MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A,
+ SUPPLEMENTAL_ARROWS_A,
+ BRAILLE_PATTERNS,
+ SUPPLEMENTAL_ARROWS_B,
+ MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B,
+ SUPPLEMENTAL_MATHEMATICAL_OPERATORS,
+ MISCELLANEOUS_SYMBOLS_AND_ARROWS,
+ GLAGOLITIC,
+ LATIN_EXTENDED_C,
+ COPTIC,
+ GEORGIAN_SUPPLEMENT,
+ TIFINAGH,
+ ETHIOPIC_EXTENDED,
+ CYRILLIC_EXTENDED_A,
+ SUPPLEMENTAL_PUNCTUATION,
+ CJK_RADICALS_SUPPLEMENT,
+ KANGXI_RADICALS,
+ null,
+ IDEOGRAPHIC_DESCRIPTION_CHARACTERS,
+ CJK_SYMBOLS_AND_PUNCTUATION,
+ HIRAGANA,
+ KATAKANA,
+ BOPOMOFO,
+ HANGUL_COMPATIBILITY_JAMO,
+ KANBUN,
+ BOPOMOFO_EXTENDED,
+ CJK_STROKES,
+ KATAKANA_PHONETIC_EXTENSIONS,
+ ENCLOSED_CJK_LETTERS_AND_MONTHS,
+ CJK_COMPATIBILITY,
+ CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A,
+ YIJING_HEXAGRAM_SYMBOLS,
+ CJK_UNIFIED_IDEOGRAPHS,
+ YI_SYLLABLES,
+ YI_RADICALS,
+ LISU,
+ VAI,
+ CYRILLIC_EXTENDED_B,
+ BAMUM,
+ MODIFIER_TONE_LETTERS,
+ LATIN_EXTENDED_D,
+ SYLOTI_NAGRI,
+ COMMON_INDIC_NUMBER_FORMS,
+ PHAGS_PA,
+ SAURASHTRA,
+ DEVANAGARI_EXTENDED,
+ KAYAH_LI,
+ REJANG,
+ HANGUL_JAMO_EXTENDED_A,
+ JAVANESE,
+ null,
+ CHAM,
+ MYANMAR_EXTENDED_A,
+ TAI_VIET,
+ MEETEI_MAYEK_EXTENSIONS,
+ ETHIOPIC_EXTENDED_A,
+ null,
+ MEETEI_MAYEK,
+ HANGUL_SYLLABLES,
+ HANGUL_JAMO_EXTENDED_B,
+ HIGH_SURROGATES,
+ HIGH_PRIVATE_USE_SURROGATES,
+ LOW_SURROGATES,
+ PRIVATE_USE_AREA,
+ CJK_COMPATIBILITY_IDEOGRAPHS,
+ ALPHABETIC_PRESENTATION_FORMS,
+ ARABIC_PRESENTATION_FORMS_A,
+ VARIATION_SELECTORS,
+ VERTICAL_FORMS,
+ COMBINING_HALF_MARKS,
+ CJK_COMPATIBILITY_FORMS,
+ SMALL_FORM_VARIANTS,
+ ARABIC_PRESENTATION_FORMS_B,
+ HALFWIDTH_AND_FULLWIDTH_FORMS,
+ SPECIALS,
+ LINEAR_B_SYLLABARY,
+ LINEAR_B_IDEOGRAMS,
+ AEGEAN_NUMBERS,
+ ANCIENT_GREEK_NUMBERS,
+ ANCIENT_SYMBOLS,
+ PHAISTOS_DISC,
+ null,
+ LYCIAN,
+ CARIAN,
+ null,
+ OLD_ITALIC,
+ GOTHIC,
+ null,
+ UGARITIC,
+ OLD_PERSIAN,
+ null,
+ DESERET,
+ SHAVIAN,
+ OSMANYA,
+ null,
+ CYPRIOT_SYLLABARY,
+ IMPERIAL_ARAMAIC,
+ null,
+ PHOENICIAN,
+ LYDIAN,
+ null,
+ MEROITIC_HIEROGLYPHS,
+ MEROITIC_CURSIVE,
+ KHAROSHTHI,
+ OLD_SOUTH_ARABIAN,
+ null,
+ AVESTAN,
+ INSCRIPTIONAL_PARTHIAN,
+ INSCRIPTIONAL_PAHLAVI,
+ null,
+ OLD_TURKIC,
+ null,
+ RUMI_NUMERAL_SYMBOLS,
+ null,
+ BRAHMI,
+ KAITHI,
+ SORA_SOMPENG,
+ CHAKMA,
+ null,
+ SHARADA,
+ null,
+ TAKRI,
+ null,
+ CUNEIFORM,
+ CUNEIFORM_NUMBERS_AND_PUNCTUATION,
+ null,
+ EGYPTIAN_HIEROGLYPHS,
+ null,
+ BAMUM_SUPPLEMENT,
+ null,
+ MIAO,
+ null,
+ KANA_SUPPLEMENT,
+ null,
+ BYZANTINE_MUSICAL_SYMBOLS,
+ MUSICAL_SYMBOLS,
+ ANCIENT_GREEK_MUSICAL_NOTATION,
+ null,
+ TAI_XUAN_JING_SYMBOLS,
+ COUNTING_ROD_NUMERALS,
+ null,
+ MATHEMATICAL_ALPHANUMERIC_SYMBOLS,
+ null,
+ ARABIC_MATHEMATICAL_ALPHABETIC_SYMBOLS,
+ null,
+ MAHJONG_TILES,
+ DOMINO_TILES,
+ PLAYING_CARDS,
+ ENCLOSED_ALPHANUMERIC_SUPPLEMENT,
+ ENCLOSED_IDEOGRAPHIC_SUPPLEMENT,
+ MISCELLANEOUS_SYMBOLS_AND_PICTOGRAPHS,
+ EMOTICONS,
+ null,
+ TRANSPORT_AND_MAP_SYMBOLS,
+ ALCHEMICAL_SYMBOLS,
+ null,
+ CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B,
+ null,
+ CJK_UNIFIED_IDEOGRAPHS_EXTENSION_C,
+ CJK_UNIFIED_IDEOGRAPHS_EXTENSION_D,
+ null,
+ CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT,
+ null,
+ TAGS,
+ null,
+ VARIATION_SELECTORS_SUPPLEMENT,
+ null,
+ SUPPLEMENTARY_PRIVATE_USE_AREA_A,
+ SUPPLEMENTARY_PRIVATE_USE_AREA_B
+ };
+
+
+ /**
+ * Returns the object representing the Unicode block containing the
+ * given character, or {@code null} if the character is not a
+ * member of a defined block.
+ *
+ * <p><b>Note:</b> This method cannot handle
+ * <a href="Character.html#supplementary"> supplementary
+ * characters</a>. To support all Unicode characters, including
+ * supplementary characters, use the {@link #of(int)} method.
+ *
+ * @param c The character in question
+ * @return The {@code UnicodeBlock} instance representing the
+ * Unicode block of which this character is a member, or
+ * {@code null} if the character is not a member of any
+ * Unicode block
+ */
+ public static UnicodeBlock of(char c) {
+ return of((int)c);
+ }
+
+ /**
+ * Returns the object representing the Unicode block
+ * containing the given character (Unicode code point), or
+ * {@code null} if the character is not a member of a
+ * defined block.
+ *
+ * @param codePoint the character (Unicode code point) in question.
+ * @return The {@code UnicodeBlock} instance representing the
+ * Unicode block of which this character is a member, or
+ * {@code null} if the character is not a member of any
+ * Unicode block
+ * @exception IllegalArgumentException if the specified
+ * {@code codePoint} is an invalid Unicode code point.
+ * @see Character#isValidCodePoint(int)
+ * @since 1.5
+ */
+ public static UnicodeBlock of(int codePoint) {
+ if (!isValidCodePoint(codePoint)) {
+ throw new IllegalArgumentException();
+ }
+
+ int top, bottom, current;
+ bottom = 0;
+ top = blockStarts.length;
+ current = top/2;
+
+ // invariant: top > current >= bottom && codePoint >= unicodeBlockStarts[bottom]
+ while (top - bottom > 1) {
+ if (codePoint >= blockStarts[current]) {
+ bottom = current;
+ } else {
+ top = current;
+ }
+ current = (top + bottom) / 2;
+ }
+ return blocks[current];
+ }
+
+ /**
+ * Returns the UnicodeBlock with the given name. Block
+ * names are determined by The Unicode Standard. The file
+ * Blocks-<version>.txt defines blocks for a particular
+ * version of the standard. The {@link Character} class specifies
+ * the version of the standard that it supports.
+ * <p>
+ * This method accepts block names in the following forms:
+ * <ol>
+ * <li> Canonical block names as defined by the Unicode Standard.
+ * For example, the standard defines a "Basic Latin" block. Therefore, this
+ * method accepts "Basic Latin" as a valid block name. The documentation of
+ * each UnicodeBlock provides the canonical name.
+ * <li>Canonical block names with all spaces removed. For example, "BasicLatin"
+ * is a valid block name for the "Basic Latin" block.
+ * <li>The text representation of each constant UnicodeBlock identifier.
+ * For example, this method will return the {@link #BASIC_LATIN} block if
+ * provided with the "BASIC_LATIN" name. This form replaces all spaces and
+ * hyphens in the canonical name with underscores.
+ * </ol>
+ * Finally, character case is ignored for all of the valid block name forms.
+ * For example, "BASIC_LATIN" and "basic_latin" are both valid block names.
+ * The en_US locale's case mapping rules are used to provide case-insensitive
+ * string comparisons for block name validation.
+ * <p>
+ * If the Unicode Standard changes block names, both the previous and
+ * current names will be accepted.
+ *
+ * @param blockName A {@code UnicodeBlock} name.
+ * @return The {@code UnicodeBlock} instance identified
+ * by {@code blockName}
+ * @throws IllegalArgumentException if {@code blockName} is an
+ * invalid name
+ * @throws NullPointerException if {@code blockName} is null
+ * @since 1.5
+ */
+ public static final UnicodeBlock forName(String blockName) {
+ UnicodeBlock block = map.get(blockName.toUpperCase(Locale.US));
+ if (block == null) {
+ throw new IllegalArgumentException();
+ }
+ return block;
+ }
+ }
+
+
+ /**
+ * A family of character subsets representing the character scripts
+ * defined in the <a href="http://www.unicode.org/reports/tr24/">
+ * <i>Unicode Standard Annex #24: Script Names</i></a>. Every Unicode
+ * character is assigned to a single Unicode script, either a specific
+ * script, such as {@link Character.UnicodeScript#LATIN Latin}, or
+ * one of the following three special values,
+ * {@link Character.UnicodeScript#INHERITED Inherited},
+ * {@link Character.UnicodeScript#COMMON Common} or
+ * {@link Character.UnicodeScript#UNKNOWN Unknown}.
+ *
+ * @since 1.7
+ */
+ public static enum UnicodeScript {
+ /**
+ * Unicode script "Common".
+ */
+ COMMON,
+
+ /**
+ * Unicode script "Latin".
+ */
+ LATIN,
+
+ /**
+ * Unicode script "Greek".
+ */
+ GREEK,
+
+ /**
+ * Unicode script "Cyrillic".
+ */
+ CYRILLIC,
+
+ /**
+ * Unicode script "Armenian".
+ */
+ ARMENIAN,
+
+ /**
+ * Unicode script "Hebrew".
+ */
+ HEBREW,
+
+ /**
+ * Unicode script "Arabic".
+ */
+ ARABIC,
+
+ /**
+ * Unicode script "Syriac".
+ */
+ SYRIAC,
+
+ /**
+ * Unicode script "Thaana".
+ */
+ THAANA,
+
+ /**
+ * Unicode script "Devanagari".
+ */
+ DEVANAGARI,
+
+ /**
+ * Unicode script "Bengali".
+ */
+ BENGALI,
+
+ /**
+ * Unicode script "Gurmukhi".
+ */
+ GURMUKHI,
+
+ /**
+ * Unicode script "Gujarati".
+ */
+ GUJARATI,
+
+ /**
+ * Unicode script "Oriya".
+ */
+ ORIYA,
+
+ /**
+ * Unicode script "Tamil".
+ */
+ TAMIL,
+
+ /**
+ * Unicode script "Telugu".
+ */
+ TELUGU,
+
+ /**
+ * Unicode script "Kannada".
+ */
+ KANNADA,
+
+ /**
+ * Unicode script "Malayalam".
+ */
+ MALAYALAM,
+
+ /**
+ * Unicode script "Sinhala".
+ */
+ SINHALA,
+
+ /**
+ * Unicode script "Thai".
+ */
+ THAI,
+
+ /**
+ * Unicode script "Lao".
+ */
+ LAO,
+
+ /**
+ * Unicode script "Tibetan".
+ */
+ TIBETAN,
+
+ /**
+ * Unicode script "Myanmar".
+ */
+ MYANMAR,
+
+ /**
+ * Unicode script "Georgian".
+ */
+ GEORGIAN,
+
+ /**
+ * Unicode script "Hangul".
+ */
+ HANGUL,
+
+ /**
+ * Unicode script "Ethiopic".
+ */
+ ETHIOPIC,
+
+ /**
+ * Unicode script "Cherokee".
+ */
+ CHEROKEE,
+
+ /**
+ * Unicode script "Canadian_Aboriginal".
+ */
+ CANADIAN_ABORIGINAL,
+
+ /**
+ * Unicode script "Ogham".
+ */
+ OGHAM,
+
+ /**
+ * Unicode script "Runic".
+ */
+ RUNIC,
+
+ /**
+ * Unicode script "Khmer".
+ */
+ KHMER,
+
+ /**
+ * Unicode script "Mongolian".
+ */
+ MONGOLIAN,
+
+ /**
+ * Unicode script "Hiragana".
+ */
+ HIRAGANA,
+
+ /**
+ * Unicode script "Katakana".
+ */
+ KATAKANA,
+
+ /**
+ * Unicode script "Bopomofo".
+ */
+ BOPOMOFO,
+
+ /**
+ * Unicode script "Han".
+ */
+ HAN,
+
+ /**
+ * Unicode script "Yi".
+ */
+ YI,
+
+ /**
+ * Unicode script "Old_Italic".
+ */
+ OLD_ITALIC,
+
+ /**
+ * Unicode script "Gothic".
+ */
+ GOTHIC,
+
+ /**
+ * Unicode script "Deseret".
+ */
+ DESERET,
+
+ /**
+ * Unicode script "Inherited".
+ */
+ INHERITED,
+
+ /**
+ * Unicode script "Tagalog".
+ */
+ TAGALOG,
+
+ /**
+ * Unicode script "Hanunoo".
+ */
+ HANUNOO,
+
+ /**
+ * Unicode script "Buhid".
+ */
+ BUHID,
+
+ /**
+ * Unicode script "Tagbanwa".
+ */
+ TAGBANWA,
+
+ /**
+ * Unicode script "Limbu".
+ */
+ LIMBU,
+
+ /**
+ * Unicode script "Tai_Le".
+ */
+ TAI_LE,
+
+ /**
+ * Unicode script "Linear_B".
+ */
+ LINEAR_B,
+
+ /**
+ * Unicode script "Ugaritic".
+ */
+ UGARITIC,
+
+ /**
+ * Unicode script "Shavian".
+ */
+ SHAVIAN,
+
+ /**
+ * Unicode script "Osmanya".
+ */
+ OSMANYA,
+
+ /**
+ * Unicode script "Cypriot".
+ */
+ CYPRIOT,
+
+ /**
+ * Unicode script "Braille".
+ */
+ BRAILLE,
+
+ /**
+ * Unicode script "Buginese".
+ */
+ BUGINESE,
+
+ /**
+ * Unicode script "Coptic".
+ */
+ COPTIC,
+
+ /**
+ * Unicode script "New_Tai_Lue".
+ */
+ NEW_TAI_LUE,
+
+ /**
+ * Unicode script "Glagolitic".
+ */
+ GLAGOLITIC,
+
+ /**
+ * Unicode script "Tifinagh".
+ */
+ TIFINAGH,
+
+ /**
+ * Unicode script "Syloti_Nagri".
+ */
+ SYLOTI_NAGRI,
+
+ /**
+ * Unicode script "Old_Persian".
+ */
+ OLD_PERSIAN,
+
+ /**
+ * Unicode script "Kharoshthi".
+ */
+ KHAROSHTHI,
+
+ /**
+ * Unicode script "Balinese".
+ */
+ BALINESE,
+
+ /**
+ * Unicode script "Cuneiform".
+ */
+ CUNEIFORM,
+
+ /**
+ * Unicode script "Phoenician".
+ */
+ PHOENICIAN,
+
+ /**
+ * Unicode script "Phags_Pa".
+ */
+ PHAGS_PA,
+
+ /**
+ * Unicode script "Nko".
+ */
+ NKO,
+
+ /**
+ * Unicode script "Sundanese".
+ */
+ SUNDANESE,
+
+ /**
+ * Unicode script "Batak".
+ */
+ BATAK,
+
+ /**
+ * Unicode script "Lepcha".
+ */
+ LEPCHA,
+
+ /**
+ * Unicode script "Ol_Chiki".
+ */
+ OL_CHIKI,
+
+ /**
+ * Unicode script "Vai".
+ */
+ VAI,
+
+ /**
+ * Unicode script "Saurashtra".
+ */
+ SAURASHTRA,
+
+ /**
+ * Unicode script "Kayah_Li".
+ */
+ KAYAH_LI,
+
+ /**
+ * Unicode script "Rejang".
+ */
+ REJANG,
+
+ /**
+ * Unicode script "Lycian".
+ */
+ LYCIAN,
+
+ /**
+ * Unicode script "Carian".
+ */
+ CARIAN,
+
+ /**
+ * Unicode script "Lydian".
+ */
+ LYDIAN,
+
+ /**
+ * Unicode script "Cham".
+ */
+ CHAM,
+
+ /**
+ * Unicode script "Tai_Tham".
+ */
+ TAI_THAM,
+
+ /**
+ * Unicode script "Tai_Viet".
+ */
+ TAI_VIET,
+
+ /**
+ * Unicode script "Avestan".
+ */
+ AVESTAN,
+
+ /**
+ * Unicode script "Egyptian_Hieroglyphs".
+ */
+ EGYPTIAN_HIEROGLYPHS,
+
+ /**
+ * Unicode script "Samaritan".
+ */
+ SAMARITAN,
+
+ /**
+ * Unicode script "Mandaic".
+ */
+ MANDAIC,
+
+ /**
+ * Unicode script "Lisu".
+ */
+ LISU,
+
+ /**
+ * Unicode script "Bamum".
+ */
+ BAMUM,
+
+ /**
+ * Unicode script "Javanese".
+ */
+ JAVANESE,
+
+ /**
+ * Unicode script "Meetei_Mayek".
+ */
+ MEETEI_MAYEK,
+
+ /**
+ * Unicode script "Imperial_Aramaic".
+ */
+ IMPERIAL_ARAMAIC,
+
+ /**
+ * Unicode script "Old_South_Arabian".
+ */
+ OLD_SOUTH_ARABIAN,
+
+ /**
+ * Unicode script "Inscriptional_Parthian".
+ */
+ INSCRIPTIONAL_PARTHIAN,
+
+ /**
+ * Unicode script "Inscriptional_Pahlavi".
+ */
+ INSCRIPTIONAL_PAHLAVI,
+
+ /**
+ * Unicode script "Old_Turkic".
+ */
+ OLD_TURKIC,
+
+ /**
+ * Unicode script "Brahmi".
+ */
+ BRAHMI,
+
+ /**
+ * Unicode script "Kaithi".
+ */
+ KAITHI,
+
+ /**
+ * Unicode script "Meroitic Hieroglyphs".
+ */
+ MEROITIC_HIEROGLYPHS,
+
+ /**
+ * Unicode script "Meroitic Cursive".
+ */
+ MEROITIC_CURSIVE,
+
+ /**
+ * Unicode script "Sora Sompeng".
+ */
+ SORA_SOMPENG,
+
+ /**
+ * Unicode script "Chakma".
+ */
+ CHAKMA,
+
+ /**
+ * Unicode script "Sharada".
+ */
+ SHARADA,
+
+ /**
+ * Unicode script "Takri".
+ */
+ TAKRI,
+
+ /**
+ * Unicode script "Miao".
+ */
+ MIAO,
+
+ /**
+ * Unicode script "Unknown".
+ */
+ UNKNOWN;
+
+ private static final int[] scriptStarts = {
+ 0x0000, // 0000..0040; COMMON
+ 0x0041, // 0041..005A; LATIN
+ 0x005B, // 005B..0060; COMMON
+ 0x0061, // 0061..007A; LATIN
+ 0x007B, // 007B..00A9; COMMON
+ 0x00AA, // 00AA..00AA; LATIN
+ 0x00AB, // 00AB..00B9; COMMON
+ 0x00BA, // 00BA..00BA; LATIN
+ 0x00BB, // 00BB..00BF; COMMON
+ 0x00C0, // 00C0..00D6; LATIN
+ 0x00D7, // 00D7..00D7; COMMON
+ 0x00D8, // 00D8..00F6; LATIN
+ 0x00F7, // 00F7..00F7; COMMON
+ 0x00F8, // 00F8..02B8; LATIN
+ 0x02B9, // 02B9..02DF; COMMON
+ 0x02E0, // 02E0..02E4; LATIN
+ 0x02E5, // 02E5..02E9; COMMON
+ 0x02EA, // 02EA..02EB; BOPOMOFO
+ 0x02EC, // 02EC..02FF; COMMON
+ 0x0300, // 0300..036F; INHERITED
+ 0x0370, // 0370..0373; GREEK
+ 0x0374, // 0374..0374; COMMON
+ 0x0375, // 0375..037D; GREEK
+ 0x037E, // 037E..0383; COMMON
+ 0x0384, // 0384..0384; GREEK
+ 0x0385, // 0385..0385; COMMON
+ 0x0386, // 0386..0386; GREEK
+ 0x0387, // 0387..0387; COMMON
+ 0x0388, // 0388..03E1; GREEK
+ 0x03E2, // 03E2..03EF; COPTIC
+ 0x03F0, // 03F0..03FF; GREEK
+ 0x0400, // 0400..0484; CYRILLIC
+ 0x0485, // 0485..0486; INHERITED
+ 0x0487, // 0487..0530; CYRILLIC
+ 0x0531, // 0531..0588; ARMENIAN
+ 0x0589, // 0589..0589; COMMON
+ 0x058A, // 058A..0590; ARMENIAN
+ 0x0591, // 0591..05FF; HEBREW
+ 0x0600, // 0600..060B; ARABIC
+ 0x060C, // 060C..060C; COMMON
+ 0x060D, // 060D..061A; ARABIC
+ 0x061B, // 061B..061D; COMMON
+ 0x061E, // 061E..061E; ARABIC
+ 0x061F, // 061F..061F; COMMON
+ 0x0620, // 0620..063F; ARABIC
+ 0x0640, // 0640..0640; COMMON
+ 0x0641, // 0641..064A; ARABIC
+ 0x064B, // 064B..0655; INHERITED
+ 0x0656, // 0656..065F; ARABIC
+ 0x0660, // 0660..0669; COMMON
+ 0x066A, // 066A..066F; ARABIC
+ 0x0670, // 0670..0670; INHERITED
+ 0x0671, // 0671..06DC; ARABIC
+ 0x06DD, // 06DD..06DD; COMMON
+ 0x06DE, // 06DE..06FF; ARABIC
+ 0x0700, // 0700..074F; SYRIAC
+ 0x0750, // 0750..077F; ARABIC
+ 0x0780, // 0780..07BF; THAANA
+ 0x07C0, // 07C0..07FF; NKO
+ 0x0800, // 0800..083F; SAMARITAN
+ 0x0840, // 0840..089F; MANDAIC
+ 0x08A0, // 08A0..08FF; ARABIC
+ 0x0900, // 0900..0950; DEVANAGARI
+ 0x0951, // 0951..0952; INHERITED
+ 0x0953, // 0953..0963; DEVANAGARI
+ 0x0964, // 0964..0965; COMMON
+ 0x0966, // 0966..0980; DEVANAGARI
+ 0x0981, // 0981..0A00; BENGALI
+ 0x0A01, // 0A01..0A80; GURMUKHI
+ 0x0A81, // 0A81..0B00; GUJARATI
+ 0x0B01, // 0B01..0B81; ORIYA
+ 0x0B82, // 0B82..0C00; TAMIL
+ 0x0C01, // 0C01..0C81; TELUGU
+ 0x0C82, // 0C82..0CF0; KANNADA
+ 0x0D02, // 0D02..0D81; MALAYALAM
+ 0x0D82, // 0D82..0E00; SINHALA
+ 0x0E01, // 0E01..0E3E; THAI
+ 0x0E3F, // 0E3F..0E3F; COMMON
+ 0x0E40, // 0E40..0E80; THAI
+ 0x0E81, // 0E81..0EFF; LAO
+ 0x0F00, // 0F00..0FD4; TIBETAN
+ 0x0FD5, // 0FD5..0FD8; COMMON
+ 0x0FD9, // 0FD9..0FFF; TIBETAN
+ 0x1000, // 1000..109F; MYANMAR
+ 0x10A0, // 10A0..10FA; GEORGIAN
+ 0x10FB, // 10FB..10FB; COMMON
+ 0x10FC, // 10FC..10FF; GEORGIAN
+ 0x1100, // 1100..11FF; HANGUL
+ 0x1200, // 1200..139F; ETHIOPIC
+ 0x13A0, // 13A0..13FF; CHEROKEE
+ 0x1400, // 1400..167F; CANADIAN_ABORIGINAL
+ 0x1680, // 1680..169F; OGHAM
+ 0x16A0, // 16A0..16EA; RUNIC
+ 0x16EB, // 16EB..16ED; COMMON
+ 0x16EE, // 16EE..16FF; RUNIC
+ 0x1700, // 1700..171F; TAGALOG
+ 0x1720, // 1720..1734; HANUNOO
+ 0x1735, // 1735..173F; COMMON
+ 0x1740, // 1740..175F; BUHID
+ 0x1760, // 1760..177F; TAGBANWA
+ 0x1780, // 1780..17FF; KHMER
+ 0x1800, // 1800..1801; MONGOLIAN
+ 0x1802, // 1802..1803; COMMON
+ 0x1804, // 1804..1804; MONGOLIAN
+ 0x1805, // 1805..1805; COMMON
+ 0x1806, // 1806..18AF; MONGOLIAN
+ 0x18B0, // 18B0..18FF; CANADIAN_ABORIGINAL
+ 0x1900, // 1900..194F; LIMBU
+ 0x1950, // 1950..197F; TAI_LE
+ 0x1980, // 1980..19DF; NEW_TAI_LUE
+ 0x19E0, // 19E0..19FF; KHMER
+ 0x1A00, // 1A00..1A1F; BUGINESE
+ 0x1A20, // 1A20..1AFF; TAI_THAM
+ 0x1B00, // 1B00..1B7F; BALINESE
+ 0x1B80, // 1B80..1BBF; SUNDANESE
+ 0x1BC0, // 1BC0..1BFF; BATAK
+ 0x1C00, // 1C00..1C4F; LEPCHA
+ 0x1C50, // 1C50..1CBF; OL_CHIKI
+ 0x1CC0, // 1CC0..1CCF; SUNDANESE
+ 0x1CD0, // 1CD0..1CD2; INHERITED
+ 0x1CD3, // 1CD3..1CD3; COMMON
+ 0x1CD4, // 1CD4..1CE0; INHERITED
+ 0x1CE1, // 1CE1..1CE1; COMMON
+ 0x1CE2, // 1CE2..1CE8; INHERITED
+ 0x1CE9, // 1CE9..1CEC; COMMON
+ 0x1CED, // 1CED..1CED; INHERITED
+ 0x1CEE, // 1CEE..1CF3; COMMON
+ 0x1CF4, // 1CF4..1CF4; INHERITED
+ 0x1CF5, // 1CF5..1CFF; COMMON
+ 0x1D00, // 1D00..1D25; LATIN
+ 0x1D26, // 1D26..1D2A; GREEK
+ 0x1D2B, // 1D2B..1D2B; CYRILLIC
+ 0x1D2C, // 1D2C..1D5C; LATIN
+ 0x1D5D, // 1D5D..1D61; GREEK
+ 0x1D62, // 1D62..1D65; LATIN
+ 0x1D66, // 1D66..1D6A; GREEK
+ 0x1D6B, // 1D6B..1D77; LATIN
+ 0x1D78, // 1D78..1D78; CYRILLIC
+ 0x1D79, // 1D79..1DBE; LATIN
+ 0x1DBF, // 1DBF..1DBF; GREEK
+ 0x1DC0, // 1DC0..1DFF; INHERITED
+ 0x1E00, // 1E00..1EFF; LATIN
+ 0x1F00, // 1F00..1FFF; GREEK
+ 0x2000, // 2000..200B; COMMON
+ 0x200C, // 200C..200D; INHERITED
+ 0x200E, // 200E..2070; COMMON
+ 0x2071, // 2071..2073; LATIN
+ 0x2074, // 2074..207E; COMMON
+ 0x207F, // 207F..207F; LATIN
+ 0x2080, // 2080..208F; COMMON
+ 0x2090, // 2090..209F; LATIN
+ 0x20A0, // 20A0..20CF; COMMON
+ 0x20D0, // 20D0..20FF; INHERITED
+ 0x2100, // 2100..2125; COMMON
+ 0x2126, // 2126..2126; GREEK
+ 0x2127, // 2127..2129; COMMON
+ 0x212A, // 212A..212B; LATIN
+ 0x212C, // 212C..2131; COMMON
+ 0x2132, // 2132..2132; LATIN
+ 0x2133, // 2133..214D; COMMON
+ 0x214E, // 214E..214E; LATIN
+ 0x214F, // 214F..215F; COMMON
+ 0x2160, // 2160..2188; LATIN
+ 0x2189, // 2189..27FF; COMMON
+ 0x2800, // 2800..28FF; BRAILLE
+ 0x2900, // 2900..2BFF; COMMON
+ 0x2C00, // 2C00..2C5F; GLAGOLITIC
+ 0x2C60, // 2C60..2C7F; LATIN
+ 0x2C80, // 2C80..2CFF; COPTIC
+ 0x2D00, // 2D00..2D2F; GEORGIAN
+ 0x2D30, // 2D30..2D7F; TIFINAGH
+ 0x2D80, // 2D80..2DDF; ETHIOPIC
+ 0x2DE0, // 2DE0..2DFF; CYRILLIC
+ 0x2E00, // 2E00..2E7F; COMMON
+ 0x2E80, // 2E80..2FEF; HAN
+ 0x2FF0, // 2FF0..3004; COMMON
+ 0x3005, // 3005..3005; HAN
+ 0x3006, // 3006..3006; COMMON
+ 0x3007, // 3007..3007; HAN
+ 0x3008, // 3008..3020; COMMON
+ 0x3021, // 3021..3029; HAN
+ 0x302A, // 302A..302D; INHERITED
+ 0x302E, // 302E..302F; HANGUL
+ 0x3030, // 3030..3037; COMMON
+ 0x3038, // 3038..303B; HAN
+ 0x303C, // 303C..3040; COMMON
+ 0x3041, // 3041..3098; HIRAGANA
+ 0x3099, // 3099..309A; INHERITED
+ 0x309B, // 309B..309C; COMMON
+ 0x309D, // 309D..309F; HIRAGANA
+ 0x30A0, // 30A0..30A0; COMMON
+ 0x30A1, // 30A1..30FA; KATAKANA
+ 0x30FB, // 30FB..30FC; COMMON
+ 0x30FD, // 30FD..3104; KATAKANA
+ 0x3105, // 3105..3130; BOPOMOFO
+ 0x3131, // 3131..318F; HANGUL
+ 0x3190, // 3190..319F; COMMON
+ 0x31A0, // 31A0..31BF; BOPOMOFO
+ 0x31C0, // 31C0..31EF; COMMON
+ 0x31F0, // 31F0..31FF; KATAKANA
+ 0x3200, // 3200..321F; HANGUL
+ 0x3220, // 3220..325F; COMMON
+ 0x3260, // 3260..327E; HANGUL
+ 0x327F, // 327F..32CF; COMMON
+ 0x32D0, // 32D0..3357; KATAKANA
+ 0x3358, // 3358..33FF; COMMON
+ 0x3400, // 3400..4DBF; HAN
+ 0x4DC0, // 4DC0..4DFF; COMMON
+ 0x4E00, // 4E00..9FFF; HAN
+ 0xA000, // A000..A4CF; YI
+ 0xA4D0, // A4D0..A4FF; LISU
+ 0xA500, // A500..A63F; VAI
+ 0xA640, // A640..A69F; CYRILLIC
+ 0xA6A0, // A6A0..A6FF; BAMUM
+ 0xA700, // A700..A721; COMMON
+ 0xA722, // A722..A787; LATIN
+ 0xA788, // A788..A78A; COMMON
+ 0xA78B, // A78B..A7FF; LATIN
+ 0xA800, // A800..A82F; SYLOTI_NAGRI
+ 0xA830, // A830..A83F; COMMON
+ 0xA840, // A840..A87F; PHAGS_PA
+ 0xA880, // A880..A8DF; SAURASHTRA
+ 0xA8E0, // A8E0..A8FF; DEVANAGARI
+ 0xA900, // A900..A92F; KAYAH_LI
+ 0xA930, // A930..A95F; REJANG
+ 0xA960, // A960..A97F; HANGUL
+ 0xA980, // A980..A9FF; JAVANESE
+ 0xAA00, // AA00..AA5F; CHAM
+ 0xAA60, // AA60..AA7F; MYANMAR
+ 0xAA80, // AA80..AADF; TAI_VIET
+ 0xAAE0, // AAE0..AB00; MEETEI_MAYEK
+ 0xAB01, // AB01..ABBF; ETHIOPIC
+ 0xABC0, // ABC0..ABFF; MEETEI_MAYEK
+ 0xAC00, // AC00..D7FB; HANGUL
+ 0xD7FC, // D7FC..F8FF; UNKNOWN
+ 0xF900, // F900..FAFF; HAN
+ 0xFB00, // FB00..FB12; LATIN
+ 0xFB13, // FB13..FB1C; ARMENIAN
+ 0xFB1D, // FB1D..FB4F; HEBREW
+ 0xFB50, // FB50..FD3D; ARABIC
+ 0xFD3E, // FD3E..FD4F; COMMON
+ 0xFD50, // FD50..FDFC; ARABIC
+ 0xFDFD, // FDFD..FDFF; COMMON
+ 0xFE00, // FE00..FE0F; INHERITED
+ 0xFE10, // FE10..FE1F; COMMON
+ 0xFE20, // FE20..FE2F; INHERITED
+ 0xFE30, // FE30..FE6F; COMMON
+ 0xFE70, // FE70..FEFE; ARABIC
+ 0xFEFF, // FEFF..FF20; COMMON
+ 0xFF21, // FF21..FF3A; LATIN
+ 0xFF3B, // FF3B..FF40; COMMON
+ 0xFF41, // FF41..FF5A; LATIN
+ 0xFF5B, // FF5B..FF65; COMMON
+ 0xFF66, // FF66..FF6F; KATAKANA
+ 0xFF70, // FF70..FF70; COMMON
+ 0xFF71, // FF71..FF9D; KATAKANA
+ 0xFF9E, // FF9E..FF9F; COMMON
+ 0xFFA0, // FFA0..FFDF; HANGUL
+ 0xFFE0, // FFE0..FFFF; COMMON
+ 0x10000, // 10000..100FF; LINEAR_B
+ 0x10100, // 10100..1013F; COMMON
+ 0x10140, // 10140..1018F; GREEK
+ 0x10190, // 10190..101FC; COMMON
+ 0x101FD, // 101FD..1027F; INHERITED
+ 0x10280, // 10280..1029F; LYCIAN
+ 0x102A0, // 102A0..102FF; CARIAN
+ 0x10300, // 10300..1032F; OLD_ITALIC
+ 0x10330, // 10330..1037F; GOTHIC
+ 0x10380, // 10380..1039F; UGARITIC
+ 0x103A0, // 103A0..103FF; OLD_PERSIAN
+ 0x10400, // 10400..1044F; DESERET
+ 0x10450, // 10450..1047F; SHAVIAN
+ 0x10480, // 10480..107FF; OSMANYA
+ 0x10800, // 10800..1083F; CYPRIOT
+ 0x10840, // 10840..108FF; IMPERIAL_ARAMAIC
+ 0x10900, // 10900..1091F; PHOENICIAN
+ 0x10920, // 10920..1097F; LYDIAN
+ 0x10980, // 10980..1099F; MEROITIC_HIEROGLYPHS
+ 0x109A0, // 109A0..109FF; MEROITIC_CURSIVE
+ 0x10A00, // 10A00..10A5F; KHAROSHTHI
+ 0x10A60, // 10A60..10AFF; OLD_SOUTH_ARABIAN
+ 0x10B00, // 10B00..10B3F; AVESTAN
+ 0x10B40, // 10B40..10B5F; INSCRIPTIONAL_PARTHIAN
+ 0x10B60, // 10B60..10BFF; INSCRIPTIONAL_PAHLAVI
+ 0x10C00, // 10C00..10E5F; OLD_TURKIC
+ 0x10E60, // 10E60..10FFF; ARABIC
+ 0x11000, // 11000..1107F; BRAHMI
+ 0x11080, // 11080..110CF; KAITHI
+ 0x110D0, // 110D0..110FF; SORA_SOMPENG
+ 0x11100, // 11100..1117F; CHAKMA
+ 0x11180, // 11180..1167F; SHARADA
+ 0x11680, // 11680..116CF; TAKRI
+ 0x12000, // 12000..12FFF; CUNEIFORM
+ 0x13000, // 13000..167FF; EGYPTIAN_HIEROGLYPHS
+ 0x16800, // 16800..16A38; BAMUM
+ 0x16F00, // 16F00..16F9F; MIAO
+ 0x1B000, // 1B000..1B000; KATAKANA
+ 0x1B001, // 1B001..1CFFF; HIRAGANA
+ 0x1D000, // 1D000..1D166; COMMON
+ 0x1D167, // 1D167..1D169; INHERITED
+ 0x1D16A, // 1D16A..1D17A; COMMON
+ 0x1D17B, // 1D17B..1D182; INHERITED
+ 0x1D183, // 1D183..1D184; COMMON
+ 0x1D185, // 1D185..1D18B; INHERITED
+ 0x1D18C, // 1D18C..1D1A9; COMMON
+ 0x1D1AA, // 1D1AA..1D1AD; INHERITED
+ 0x1D1AE, // 1D1AE..1D1FF; COMMON
+ 0x1D200, // 1D200..1D2FF; GREEK
+ 0x1D300, // 1D300..1EDFF; COMMON
+ 0x1EE00, // 1EE00..1EFFF; ARABIC
+ 0x1F000, // 1F000..1F1FF; COMMON
+ 0x1F200, // 1F200..1F200; HIRAGANA
+ 0x1F201, // 1F210..1FFFF; COMMON
+ 0x20000, // 20000..E0000; HAN
+ 0xE0001, // E0001..E00FF; COMMON
+ 0xE0100, // E0100..E01EF; INHERITED
+ 0xE01F0 // E01F0..10FFFF; UNKNOWN
+
+ };
+
+ private static final UnicodeScript[] scripts = {
+ COMMON,
+ LATIN,
+ COMMON,
+ LATIN,
+ COMMON,
+ LATIN,
+ COMMON,
+ LATIN,
+ COMMON,
+ LATIN,
+ COMMON,
+ LATIN,
+ COMMON,
+ LATIN,
+ COMMON,
+ LATIN,
+ COMMON,
+ BOPOMOFO,
+ COMMON,
+ INHERITED,
+ GREEK,
+ COMMON,
+ GREEK,
+ COMMON,
+ GREEK,
+ COMMON,
+ GREEK,
+ COMMON,
+ GREEK,
+ COPTIC,
+ GREEK,
+ CYRILLIC,
+ INHERITED,
+ CYRILLIC,
+ ARMENIAN,
+ COMMON,
+ ARMENIAN,
+ HEBREW,
+ ARABIC,
+ COMMON,
+ ARABIC,
+ COMMON,
+ ARABIC,
+ COMMON,
+ ARABIC,
+ COMMON,
+ ARABIC,
+ INHERITED,
+ ARABIC,
+ COMMON,
+ ARABIC,
+ INHERITED,
+ ARABIC,
+ COMMON,
+ ARABIC,
+ SYRIAC,
+ ARABIC,
+ THAANA,
+ NKO,
+ SAMARITAN,
+ MANDAIC,
+ ARABIC,
+ DEVANAGARI,
+ INHERITED,
+ DEVANAGARI,
+ COMMON,
+ DEVANAGARI,
+ BENGALI,
+ GURMUKHI,
+ GUJARATI,
+ ORIYA,
+ TAMIL,
+ TELUGU,
+ KANNADA,
+ MALAYALAM,
+ SINHALA,
+ THAI,
+ COMMON,
+ THAI,
+ LAO,
+ TIBETAN,
+ COMMON,
+ TIBETAN,
+ MYANMAR,
+ GEORGIAN,
+ COMMON,
+ GEORGIAN,
+ HANGUL,
+ ETHIOPIC,
+ CHEROKEE,
+ CANADIAN_ABORIGINAL,
+ OGHAM,
+ RUNIC,
+ COMMON,
+ RUNIC,
+ TAGALOG,
+ HANUNOO,
+ COMMON,
+ BUHID,
+ TAGBANWA,
+ KHMER,
+ MONGOLIAN,
+ COMMON,
+ MONGOLIAN,
+ COMMON,
+ MONGOLIAN,
+ CANADIAN_ABORIGINAL,
+ LIMBU,
+ TAI_LE,
+ NEW_TAI_LUE,
+ KHMER,
+ BUGINESE,
+ TAI_THAM,
+ BALINESE,
+ SUNDANESE,
+ BATAK,
+ LEPCHA,
+ OL_CHIKI,
+ SUNDANESE,
+ INHERITED,
+ COMMON,
+ INHERITED,
+ COMMON,
+ INHERITED,
+ COMMON,
+ INHERITED,
+ COMMON,
+ INHERITED,
+ COMMON,
+ LATIN,
+ GREEK,
+ CYRILLIC,
+ LATIN,
+ GREEK,
+ LATIN,
+ GREEK,
+ LATIN,
+ CYRILLIC,
+ LATIN,
+ GREEK,
+ INHERITED,
+ LATIN,
+ GREEK,
+ COMMON,
+ INHERITED,
+ COMMON,
+ LATIN,
+ COMMON,
+ LATIN,
+ COMMON,
+ LATIN,
+ COMMON,
+ INHERITED,
+ COMMON,
+ GREEK,
+ COMMON,
+ LATIN,
+ COMMON,
+ LATIN,
+ COMMON,
+ LATIN,
+ COMMON,
+ LATIN,
+ COMMON,
+ BRAILLE,
+ COMMON,
+ GLAGOLITIC,
+ LATIN,
+ COPTIC,
+ GEORGIAN,
+ TIFINAGH,
+ ETHIOPIC,
+ CYRILLIC,
+ COMMON,
+ HAN,
+ COMMON,
+ HAN,
+ COMMON,
+ HAN,
+ COMMON,
+ HAN,
+ INHERITED,
+ HANGUL,
+ COMMON,
+ HAN,
+ COMMON,
+ HIRAGANA,
+ INHERITED,
+ COMMON,
+ HIRAGANA,
+ COMMON,
+ KATAKANA,
+ COMMON,
+ KATAKANA,
+ BOPOMOFO,
+ HANGUL,
+ COMMON,
+ BOPOMOFO,
+ COMMON,
+ KATAKANA,
+ HANGUL,
+ COMMON,
+ HANGUL,
+ COMMON,
+ KATAKANA,
+ COMMON,
+ HAN,
+ COMMON,
+ HAN,
+ YI,
+ LISU,
+ VAI,
+ CYRILLIC,
+ BAMUM,
+ COMMON,
+ LATIN,
+ COMMON,
+ LATIN,
+ SYLOTI_NAGRI,
+ COMMON,
+ PHAGS_PA,
+ SAURASHTRA,
+ DEVANAGARI,
+ KAYAH_LI,
+ REJANG,
+ HANGUL,
+ JAVANESE,
+ CHAM,
+ MYANMAR,
+ TAI_VIET,
+ MEETEI_MAYEK,
+ ETHIOPIC,
+ MEETEI_MAYEK,
+ HANGUL,
+ UNKNOWN ,
+ HAN,
+ LATIN,
+ ARMENIAN,
+ HEBREW,
+ ARABIC,
+ COMMON,
+ ARABIC,
+ COMMON,
+ INHERITED,
+ COMMON,
+ INHERITED,
+ COMMON,
+ ARABIC,
+ COMMON,
+ LATIN,
+ COMMON,
+ LATIN,
+ COMMON,
+ KATAKANA,
+ COMMON,
+ KATAKANA,
+ COMMON,
+ HANGUL,
+ COMMON,
+ LINEAR_B,
+ COMMON,
+ GREEK,
+ COMMON,
+ INHERITED,
+ LYCIAN,
+ CARIAN,
+ OLD_ITALIC,
+ GOTHIC,
+ UGARITIC,
+ OLD_PERSIAN,
+ DESERET,
+ SHAVIAN,
+ OSMANYA,
+ CYPRIOT,
+ IMPERIAL_ARAMAIC,
+ PHOENICIAN,
+ LYDIAN,
+ MEROITIC_HIEROGLYPHS,
+ MEROITIC_CURSIVE,
+ KHAROSHTHI,
+ OLD_SOUTH_ARABIAN,
+ AVESTAN,
+ INSCRIPTIONAL_PARTHIAN,
+ INSCRIPTIONAL_PAHLAVI,
+ OLD_TURKIC,
+ ARABIC,
+ BRAHMI,
+ KAITHI,
+ SORA_SOMPENG,
+ CHAKMA,
+ SHARADA,
+ TAKRI,
+ CUNEIFORM,
+ EGYPTIAN_HIEROGLYPHS,
+ BAMUM,
+ MIAO,
+ KATAKANA,
+ HIRAGANA,
+ COMMON,
+ INHERITED,
+ COMMON,
+ INHERITED,
+ COMMON,
+ INHERITED,
+ COMMON,
+ INHERITED,
+ COMMON,
+ GREEK,
+ COMMON,
+ ARABIC,
+ COMMON,
+ HIRAGANA,
+ COMMON,
+ HAN,
+ COMMON,
+ INHERITED,
+ UNKNOWN
+ };
+
+ private static HashMap<String, Character.UnicodeScript> aliases;
+ static {
+ aliases = new HashMap<>(128);
+ aliases.put("ARAB", ARABIC);
+ aliases.put("ARMI", IMPERIAL_ARAMAIC);
+ aliases.put("ARMN", ARMENIAN);
+ aliases.put("AVST", AVESTAN);
+ aliases.put("BALI", BALINESE);
+ aliases.put("BAMU", BAMUM);
+ aliases.put("BATK", BATAK);
+ aliases.put("BENG", BENGALI);
+ aliases.put("BOPO", BOPOMOFO);
+ aliases.put("BRAI", BRAILLE);
+ aliases.put("BRAH", BRAHMI);
+ aliases.put("BUGI", BUGINESE);
+ aliases.put("BUHD", BUHID);
+ aliases.put("CAKM", CHAKMA);
+ aliases.put("CANS", CANADIAN_ABORIGINAL);
+ aliases.put("CARI", CARIAN);
+ aliases.put("CHAM", CHAM);
+ aliases.put("CHER", CHEROKEE);
+ aliases.put("COPT", COPTIC);
+ aliases.put("CPRT", CYPRIOT);
+ aliases.put("CYRL", CYRILLIC);
+ aliases.put("DEVA", DEVANAGARI);
+ aliases.put("DSRT", DESERET);
+ aliases.put("EGYP", EGYPTIAN_HIEROGLYPHS);
+ aliases.put("ETHI", ETHIOPIC);
+ aliases.put("GEOR", GEORGIAN);
+ aliases.put("GLAG", GLAGOLITIC);
+ aliases.put("GOTH", GOTHIC);
+ aliases.put("GREK", GREEK);
+ aliases.put("GUJR", GUJARATI);
+ aliases.put("GURU", GURMUKHI);
+ aliases.put("HANG", HANGUL);
+ aliases.put("HANI", HAN);
+ aliases.put("HANO", HANUNOO);
+ aliases.put("HEBR", HEBREW);
+ aliases.put("HIRA", HIRAGANA);
+ // it appears we don't have the KATAKANA_OR_HIRAGANA
+ //aliases.put("HRKT", KATAKANA_OR_HIRAGANA);
+ aliases.put("ITAL", OLD_ITALIC);
+ aliases.put("JAVA", JAVANESE);
+ aliases.put("KALI", KAYAH_LI);
+ aliases.put("KANA", KATAKANA);
+ aliases.put("KHAR", KHAROSHTHI);
+ aliases.put("KHMR", KHMER);
+ aliases.put("KNDA", KANNADA);
+ aliases.put("KTHI", KAITHI);
+ aliases.put("LANA", TAI_THAM);
+ aliases.put("LAOO", LAO);
+ aliases.put("LATN", LATIN);
+ aliases.put("LEPC", LEPCHA);
+ aliases.put("LIMB", LIMBU);
+ aliases.put("LINB", LINEAR_B);
+ aliases.put("LISU", LISU);
+ aliases.put("LYCI", LYCIAN);
+ aliases.put("LYDI", LYDIAN);
+ aliases.put("MAND", MANDAIC);
+ aliases.put("MERC", MEROITIC_CURSIVE);
+ aliases.put("MERO", MEROITIC_HIEROGLYPHS);
+ aliases.put("MLYM", MALAYALAM);
+ aliases.put("MONG", MONGOLIAN);
+ aliases.put("MTEI", MEETEI_MAYEK);
+ aliases.put("MYMR", MYANMAR);
+ aliases.put("NKOO", NKO);
+ aliases.put("OGAM", OGHAM);
+ aliases.put("OLCK", OL_CHIKI);
+ aliases.put("ORKH", OLD_TURKIC);
+ aliases.put("ORYA", ORIYA);
+ aliases.put("OSMA", OSMANYA);
+ aliases.put("PHAG", PHAGS_PA);
+ aliases.put("PLRD", MIAO);
+ aliases.put("PHLI", INSCRIPTIONAL_PAHLAVI);
+ aliases.put("PHNX", PHOENICIAN);
+ aliases.put("PRTI", INSCRIPTIONAL_PARTHIAN);
+ aliases.put("RJNG", REJANG);
+ aliases.put("RUNR", RUNIC);
+ aliases.put("SAMR", SAMARITAN);
+ aliases.put("SARB", OLD_SOUTH_ARABIAN);
+ aliases.put("SAUR", SAURASHTRA);
+ aliases.put("SHAW", SHAVIAN);
+ aliases.put("SHRD", SHARADA);
+ aliases.put("SINH", SINHALA);
+ aliases.put("SORA", SORA_SOMPENG);
+ aliases.put("SUND", SUNDANESE);
+ aliases.put("SYLO", SYLOTI_NAGRI);
+ aliases.put("SYRC", SYRIAC);
+ aliases.put("TAGB", TAGBANWA);
+ aliases.put("TALE", TAI_LE);
+ aliases.put("TAKR", TAKRI);
+ aliases.put("TALU", NEW_TAI_LUE);
+ aliases.put("TAML", TAMIL);
+ aliases.put("TAVT", TAI_VIET);
+ aliases.put("TELU", TELUGU);
+ aliases.put("TFNG", TIFINAGH);
+ aliases.put("TGLG", TAGALOG);
+ aliases.put("THAA", THAANA);
+ aliases.put("THAI", THAI);
+ aliases.put("TIBT", TIBETAN);
+ aliases.put("UGAR", UGARITIC);
+ aliases.put("VAII", VAI);
+ aliases.put("XPEO", OLD_PERSIAN);
+ aliases.put("XSUX", CUNEIFORM);
+ aliases.put("YIII", YI);
+ aliases.put("ZINH", INHERITED);
+ aliases.put("ZYYY", COMMON);
+ aliases.put("ZZZZ", UNKNOWN);
+ }
+
+ /**
+ * Returns the enum constant representing the Unicode script of which
+ * the given character (Unicode code point) is assigned to.
+ *
+ * @param codePoint the character (Unicode code point) in question.
+ * @return The {@code UnicodeScript} constant representing the
+ * Unicode script of which this character is assigned to.
+ *
+ * @exception IllegalArgumentException if the specified
+ * {@code codePoint} is an invalid Unicode code point.
+ * @see Character#isValidCodePoint(int)
+ *
+ */
+ public static UnicodeScript of(int codePoint) {
+ if (!isValidCodePoint(codePoint))
+ throw new IllegalArgumentException();
+ int type = getType(codePoint);
+ // leave SURROGATE and PRIVATE_USE for table lookup
+ if (type == UNASSIGNED)
+ return UNKNOWN;
+ int index = Arrays.binarySearch(scriptStarts, codePoint);
+ if (index < 0)
+ index = -index - 2;
+ return scripts[index];
+ }
+
+ /**
+ * Returns the UnicodeScript constant with the given Unicode script
+ * name or the script name alias. Script names and their aliases are
+ * determined by The Unicode Standard. The files Scripts<version>.txt
+ * and PropertyValueAliases<version>.txt define script names
+ * and the script name aliases for a particular version of the
+ * standard. The {@link Character} class specifies the version of
+ * the standard that it supports.
+ * <p>
+ * Character case is ignored for all of the valid script names.
+ * The en_US locale's case mapping rules are used to provide
+ * case-insensitive string comparisons for script name validation.
+ * <p>
+ *
+ * @param scriptName A {@code UnicodeScript} name.
+ * @return The {@code UnicodeScript} constant identified
+ * by {@code scriptName}
+ * @throws IllegalArgumentException if {@code scriptName} is an
+ * invalid name
+ * @throws NullPointerException if {@code scriptName} is null
+ */
+ public static final UnicodeScript forName(String scriptName) {
+ scriptName = scriptName.toUpperCase(Locale.ENGLISH);
+ //.replace(' ', '_'));
+ UnicodeScript sc = aliases.get(scriptName);
+ if (sc != null)
+ return sc;
+ return valueOf(scriptName);
+ }
+ }
+
+ /**
+ * The value of the {@code Character}.
+ *
+ * @serial
+ */
+ private final char value;
+
+ /** use serialVersionUID from JDK 1.0.2 for interoperability */
+ private static final long serialVersionUID = 3786198910865385080L;
+
+ /**
+ * Constructs a newly allocated {@code Character} object that
+ * represents the specified {@code char} value.
+ *
+ * @param value the value to be represented by the
+ * {@code Character} object.
+ */
+ public Character(char value) {
+ this.value = value;
+ }
+
+ private static class CharacterCache {
+ private CharacterCache(){}
+
+ static final Character cache[] = new Character[127 + 1];
+
+ static {
+ for (int i = 0; i < cache.length; i++)
+ cache[i] = new Character((char)i);
+ }
+ }
+
+ /**
+ * Returns a <tt>Character</tt> instance representing the specified
+ * <tt>char</tt> value.
+ * If a new <tt>Character</tt> instance is not required, this method
+ * should generally be used in preference to the constructor
+ * {@link #Character(char)}, as this method is likely to yield
+ * significantly better space and time performance by caching
+ * frequently requested values.
+ *
+ * This method will always cache values in the range {@code
+ * '\u005Cu0000'} to {@code '\u005Cu007F'}, inclusive, and may
+ * cache other values outside of this range.
+ *
+ * @param c a char value.
+ * @return a <tt>Character</tt> instance representing <tt>c</tt>.
+ * @since 1.5
+ */
+ public static Character valueOf(char c) {
+ if (c <= 127) { // must cache
+ return CharacterCache.cache[(int)c];
+ }
+ return new Character(c);
+ }
+
+ /**
+ * Returns the value of this {@code Character} object.
+ * @return the primitive {@code char} value represented by
+ * this object.
+ */
+ public char charValue() {
+ return value;
+ }
+
+ /**
+ * Returns a hash code for this {@code Character}; equal to the result
+ * of invoking {@code charValue()}.
+ *
+ * @return a hash code value for this {@code Character}
+ */
+ @Override
+ public int hashCode() {
+ return Character.hashCode(value);
+ }
+
+ /**
+ * Returns a hash code for a {@code char} value; compatible with
+ * {@code Character.hashCode()}.
+ *
+ * @since 1.8
+ *
+ * @param value The {@code char} for which to return a hash code.
+ * @return a hash code value for a {@code char} value.
+ */
+ public static int hashCode(char value) {
+ return (int)value;
+ }
+
+ /**
+ * Compares this object against the specified object.
+ * The result is {@code true} if and only if the argument is not
+ * {@code null} and is a {@code Character} object that
+ * represents the same {@code char} value as this object.
+ *
+ * @param obj the object to compare with.
+ * @return {@code true} if the objects are the same;
+ * {@code false} otherwise.
+ */
+ public boolean equals(Object obj) {
+ if (obj instanceof Character) {
+ return value == ((Character)obj).charValue();
+ }
+ return false;
+ }
+
+ /**
+ * Returns a {@code String} object representing this
+ * {@code Character}'s value. The result is a string of
+ * length 1 whose sole component is the primitive
+ * {@code char} value represented by this
+ * {@code Character} object.
+ *
+ * @return a string representation of this object.
+ */
+ public String toString() {
+ char buf[] = {value};
+ return String.valueOf(buf);
+ }
+
+ /**
+ * Returns a {@code String} object representing the
+ * specified {@code char}. The result is a string of length
+ * 1 consisting solely of the specified {@code char}.
+ *
+ * @param c the {@code char} to be converted
+ * @return the string representation of the specified {@code char}
+ * @since 1.4
+ */
+ public static String toString(char c) {
+ return String.valueOf(c);
+ }
+
+ /**
+ * Determines whether the specified code point is a valid
+ * <a href="http://www.unicode.org/glossary/#code_point">
+ * Unicode code point value</a>.
+ *
+ * @param codePoint the Unicode code point to be tested
+ * @return {@code true} if the specified code point value is between
+ * {@link #MIN_CODE_POINT} and
+ * {@link #MAX_CODE_POINT} inclusive;
+ * {@code false} otherwise.
+ * @since 1.5
+ */
+ public static boolean isValidCodePoint(int codePoint) {
+ // Optimized form of:
+ // codePoint >= MIN_CODE_POINT && codePoint <= MAX_CODE_POINT
+ int plane = codePoint >>> 16;
+ return plane < ((MAX_CODE_POINT + 1) >>> 16);
+ }
+
+ /**
+ * Determines whether the specified character (Unicode code point)
+ * is in the <a href="#BMP">Basic Multilingual Plane (BMP)</a>.
+ * Such code points can be represented using a single {@code char}.
+ *
+ * @param codePoint the character (Unicode code point) to be tested
+ * @return {@code true} if the specified code point is between
+ * {@link #MIN_VALUE} and {@link #MAX_VALUE} inclusive;
+ * {@code false} otherwise.
+ * @since 1.7
+ */
+ public static boolean isBmpCodePoint(int codePoint) {
+ return codePoint >>> 16 == 0;
+ // Optimized form of:
+ // codePoint >= MIN_VALUE && codePoint <= MAX_VALUE
+ // We consistently use logical shift (>>>) to facilitate
+ // additional runtime optimizations.
+ }
+
+ /**
+ * Determines whether the specified character (Unicode code point)
+ * is in the <a href="#supplementary">supplementary character</a> range.
+ *
+ * @param codePoint the character (Unicode code point) to be tested
+ * @return {@code true} if the specified code point is between
+ * {@link #MIN_SUPPLEMENTARY_CODE_POINT} and
+ * {@link #MAX_CODE_POINT} inclusive;
+ * {@code false} otherwise.
+ * @since 1.5
+ */
+ public static boolean isSupplementaryCodePoint(int codePoint) {
+ return codePoint >= MIN_SUPPLEMENTARY_CODE_POINT
+ && codePoint < MAX_CODE_POINT + 1;
+ }
+
+ /**
+ * Determines if the given {@code char} value is a
+ * <a href="http://www.unicode.org/glossary/#high_surrogate_code_unit">
+ * Unicode high-surrogate code unit</a>
+ * (also known as <i>leading-surrogate code unit</i>).
+ *
+ * <p>Such values do not represent characters by themselves,
+ * but are used in the representation of
+ * <a href="#supplementary">supplementary characters</a>
+ * in the UTF-16 encoding.
+ *
+ * @param ch the {@code char} value to be tested.
+ * @return {@code true} if the {@code char} value is between
+ * {@link #MIN_HIGH_SURROGATE} and
+ * {@link #MAX_HIGH_SURROGATE} inclusive;
+ * {@code false} otherwise.
+ * @see Character#isLowSurrogate(char)
+ * @see Character.UnicodeBlock#of(int)
+ * @since 1.5
+ */
+ public static boolean isHighSurrogate(char ch) {
+ // Help VM constant-fold; MAX_HIGH_SURROGATE + 1 == MIN_LOW_SURROGATE
+ return ch >= MIN_HIGH_SURROGATE && ch < (MAX_HIGH_SURROGATE + 1);
+ }
+
+ /**
+ * Determines if the given {@code char} value is a
+ * <a href="http://www.unicode.org/glossary/#low_surrogate_code_unit">
+ * Unicode low-surrogate code unit</a>
+ * (also known as <i>trailing-surrogate code unit</i>).
+ *
+ * <p>Such values do not represent characters by themselves,
+ * but are used in the representation of
+ * <a href="#supplementary">supplementary characters</a>
+ * in the UTF-16 encoding.
+ *
+ * @param ch the {@code char} value to be tested.
+ * @return {@code true} if the {@code char} value is between
+ * {@link #MIN_LOW_SURROGATE} and
+ * {@link #MAX_LOW_SURROGATE} inclusive;
+ * {@code false} otherwise.
+ * @see Character#isHighSurrogate(char)
+ * @since 1.5
+ */
+ public static boolean isLowSurrogate(char ch) {
+ return ch >= MIN_LOW_SURROGATE && ch < (MAX_LOW_SURROGATE + 1);
+ }
+
+ /**
+ * Determines if the given {@code char} value is a Unicode
+ * <i>surrogate code unit</i>.
+ *
+ * <p>Such values do not represent characters by themselves,
+ * but are used in the representation of
+ * <a href="#supplementary">supplementary characters</a>
+ * in the UTF-16 encoding.
+ *
+ * <p>A char value is a surrogate code unit if and only if it is either
+ * a {@linkplain #isLowSurrogate(char) low-surrogate code unit} or
+ * a {@linkplain #isHighSurrogate(char) high-surrogate code unit}.
+ *
+ * @param ch the {@code char} value to be tested.
+ * @return {@code true} if the {@code char} value is between
+ * {@link #MIN_SURROGATE} and
+ * {@link #MAX_SURROGATE} inclusive;
+ * {@code false} otherwise.
+ * @since 1.7
+ */
+ public static boolean isSurrogate(char ch) {
+ return ch >= MIN_SURROGATE && ch < (MAX_SURROGATE + 1);
+ }
+
+ /**
+ * Determines whether the specified pair of {@code char}
+ * values is a valid
+ * <a href="http://www.unicode.org/glossary/#surrogate_pair">
+ * Unicode surrogate pair</a>.
+
+ * <p>This method is equivalent to the expression:
+ * <blockquote><pre>{@code
+ * isHighSurrogate(high) && isLowSurrogate(low)
+ * }</pre></blockquote>
+ *
+ * @param high the high-surrogate code value to be tested
+ * @param low the low-surrogate code value to be tested
+ * @return {@code true} if the specified high and
+ * low-surrogate code values represent a valid surrogate pair;
+ * {@code false} otherwise.
+ * @since 1.5
+ */
+ public static boolean isSurrogatePair(char high, char low) {
+ return isHighSurrogate(high) && isLowSurrogate(low);
+ }
+
+ /**
+ * Determines the number of {@code char} values needed to
+ * represent the specified character (Unicode code point). If the
+ * specified character is equal to or greater than 0x10000, then
+ * the method returns 2. Otherwise, the method returns 1.
+ *
+ * <p>This method doesn't validate the specified character to be a
+ * valid Unicode code point. The caller must validate the
+ * character value using {@link #isValidCodePoint(int) isValidCodePoint}
+ * if necessary.
+ *
+ * @param codePoint the character (Unicode code point) to be tested.
+ * @return 2 if the character is a valid supplementary character; 1 otherwise.
+ * @see Character#isSupplementaryCodePoint(int)
+ * @since 1.5
+ */
+ public static int charCount(int codePoint) {
+ return codePoint >= MIN_SUPPLEMENTARY_CODE_POINT ? 2 : 1;
+ }
+
+ /**
+ * Converts the specified surrogate pair to its supplementary code
+ * point value. This method does not validate the specified
+ * surrogate pair. The caller must validate it using {@link
+ * #isSurrogatePair(char, char) isSurrogatePair} if necessary.
+ *
+ * @param high the high-surrogate code unit
+ * @param low the low-surrogate code unit
+ * @return the supplementary code point composed from the
+ * specified surrogate pair.
+ * @since 1.5
+ */
+ public static int toCodePoint(char high, char low) {
+ // Optimized form of:
+ // return ((high - MIN_HIGH_SURROGATE) << 10)
+ // + (low - MIN_LOW_SURROGATE)
+ // + MIN_SUPPLEMENTARY_CODE_POINT;
+ return ((high << 10) + low) + (MIN_SUPPLEMENTARY_CODE_POINT
+ - (MIN_HIGH_SURROGATE << 10)
+ - MIN_LOW_SURROGATE);
+ }
+
+ /**
+ * Returns the code point at the given index of the
+ * {@code CharSequence}. If the {@code char} value at
+ * the given index in the {@code CharSequence} is in the
+ * high-surrogate range, the following index is less than the
+ * length of the {@code CharSequence}, and the
+ * {@code char} value at the following index is in the
+ * low-surrogate range, then the supplementary code point
+ * corresponding to this surrogate pair is returned. Otherwise,
+ * the {@code char} value at the given index is returned.
+ *
+ * @param seq a sequence of {@code char} values (Unicode code
+ * units)
+ * @param index the index to the {@code char} values (Unicode
+ * code units) in {@code seq} to be converted
+ * @return the Unicode code point at the given index
+ * @exception NullPointerException if {@code seq} is null.
+ * @exception IndexOutOfBoundsException if the value
+ * {@code index} is negative or not less than
+ * {@link CharSequence#length() seq.length()}.
+ * @since 1.5
+ */
+ public static int codePointAt(CharSequence seq, int index) {
+ char c1 = seq.charAt(index);
+ if (isHighSurrogate(c1) && ++index < seq.length()) {
+ char c2 = seq.charAt(index);
+ if (isLowSurrogate(c2)) {
+ return toCodePoint(c1, c2);
+ }
+ }
+ return c1;
+ }
+
+ /**
+ * Returns the code point at the given index of the
+ * {@code char} array. If the {@code char} value at
+ * the given index in the {@code char} array is in the
+ * high-surrogate range, the following index is less than the
+ * length of the {@code char} array, and the
+ * {@code char} value at the following index is in the
+ * low-surrogate range, then the supplementary code point
+ * corresponding to this surrogate pair is returned. Otherwise,
+ * the {@code char} value at the given index is returned.
+ *
+ * @param a the {@code char} array
+ * @param index the index to the {@code char} values (Unicode
+ * code units) in the {@code char} array to be converted
+ * @return the Unicode code point at the given index
+ * @exception NullPointerException if {@code a} is null.
+ * @exception IndexOutOfBoundsException if the value
+ * {@code index} is negative or not less than
+ * the length of the {@code char} array.
+ * @since 1.5
+ */
+ public static int codePointAt(char[] a, int index) {
+ return codePointAtImpl(a, index, a.length);
+ }
+
+ /**
+ * Returns the code point at the given index of the
+ * {@code char} array, where only array elements with
+ * {@code index} less than {@code limit} can be used. If
+ * the {@code char} value at the given index in the
+ * {@code char} array is in the high-surrogate range, the
+ * following index is less than the {@code limit}, and the
+ * {@code char} value at the following index is in the
+ * low-surrogate range, then the supplementary code point
+ * corresponding to this surrogate pair is returned. Otherwise,
+ * the {@code char} value at the given index is returned.
+ *
+ * @param a the {@code char} array
+ * @param index the index to the {@code char} values (Unicode
+ * code units) in the {@code char} array to be converted
+ * @param limit the index after the last array element that
+ * can be used in the {@code char} array
+ * @return the Unicode code point at the given index
+ * @exception NullPointerException if {@code a} is null.
+ * @exception IndexOutOfBoundsException if the {@code index}
+ * argument is negative or not less than the {@code limit}
+ * argument, or if the {@code limit} argument is negative or
+ * greater than the length of the {@code char} array.
+ * @since 1.5
+ */
+ public static int codePointAt(char[] a, int index, int limit) {
+ if (index >= limit || limit < 0 || limit > a.length) {
+ throw new IndexOutOfBoundsException();
+ }
+ return codePointAtImpl(a, index, limit);
+ }
+
+ // throws ArrayIndexOutOfBoundsException if index out of bounds
+ static int codePointAtImpl(char[] a, int index, int limit) {
+ char c1 = a[index];
+ if (isHighSurrogate(c1) && ++index < limit) {
+ char c2 = a[index];
+ if (isLowSurrogate(c2)) {
+ return toCodePoint(c1, c2);
+ }
+ }
+ return c1;
+ }
+
+ /**
+ * Returns the code point preceding the given index of the
+ * {@code CharSequence}. If the {@code char} value at
+ * {@code (index - 1)} in the {@code CharSequence} is in
+ * the low-surrogate range, {@code (index - 2)} is not
+ * negative, and the {@code char} value at {@code (index - 2)}
+ * in the {@code CharSequence} is in the
+ * high-surrogate range, then the supplementary code point
+ * corresponding to this surrogate pair is returned. Otherwise,
+ * the {@code char} value at {@code (index - 1)} is
+ * returned.
+ *
+ * @param seq the {@code CharSequence} instance
+ * @param index the index following the code point that should be returned
+ * @return the Unicode code point value before the given index.
+ * @exception NullPointerException if {@code seq} is null.
+ * @exception IndexOutOfBoundsException if the {@code index}
+ * argument is less than 1 or greater than {@link
+ * CharSequence#length() seq.length()}.
+ * @since 1.5
+ */
+ public static int codePointBefore(CharSequence seq, int index) {
+ char c2 = seq.charAt(--index);
+ if (isLowSurrogate(c2) && index > 0) {
+ char c1 = seq.charAt(--index);
+ if (isHighSurrogate(c1)) {
+ return toCodePoint(c1, c2);
+ }
+ }
+ return c2;
+ }
+
+ /**
+ * Returns the code point preceding the given index of the
+ * {@code char} array. If the {@code char} value at
+ * {@code (index - 1)} in the {@code char} array is in
+ * the low-surrogate range, {@code (index - 2)} is not
+ * negative, and the {@code char} value at {@code (index - 2)}
+ * in the {@code char} array is in the
+ * high-surrogate range, then the supplementary code point
+ * corresponding to this surrogate pair is returned. Otherwise,
+ * the {@code char} value at {@code (index - 1)} is
+ * returned.
+ *
+ * @param a the {@code char} array
+ * @param index the index following the code point that should be returned
+ * @return the Unicode code point value before the given index.
+ * @exception NullPointerException if {@code a} is null.
+ * @exception IndexOutOfBoundsException if the {@code index}
+ * argument is less than 1 or greater than the length of the
+ * {@code char} array
+ * @since 1.5
+ */
+ public static int codePointBefore(char[] a, int index) {
+ return codePointBeforeImpl(a, index, 0);
+ }
+
+ /**
+ * Returns the code point preceding the given index of the
+ * {@code char} array, where only array elements with
+ * {@code index} greater than or equal to {@code start}
+ * can be used. If the {@code char} value at {@code (index - 1)}
+ * in the {@code char} array is in the
+ * low-surrogate range, {@code (index - 2)} is not less than
+ * {@code start}, and the {@code char} value at
+ * {@code (index - 2)} in the {@code char} array is in
+ * the high-surrogate range, then the supplementary code point
+ * corresponding to this surrogate pair is returned. Otherwise,
+ * the {@code char} value at {@code (index - 1)} is
+ * returned.
+ *
+ * @param a the {@code char} array
+ * @param index the index following the code point that should be returned
+ * @param start the index of the first array element in the
+ * {@code char} array
+ * @return the Unicode code point value before the given index.
+ * @exception NullPointerException if {@code a} is null.
+ * @exception IndexOutOfBoundsException if the {@code index}
+ * argument is not greater than the {@code start} argument or
+ * is greater than the length of the {@code char} array, or
+ * if the {@code start} argument is negative or not less than
+ * the length of the {@code char} array.
+ * @since 1.5
+ */
+ public static int codePointBefore(char[] a, int index, int start) {
+ if (index <= start || start < 0 || start >= a.length) {
+ throw new IndexOutOfBoundsException();
+ }
+ return codePointBeforeImpl(a, index, start);
+ }
+
+ // throws ArrayIndexOutOfBoundsException if index-1 out of bounds
+ static int codePointBeforeImpl(char[] a, int index, int start) {
+ char c2 = a[--index];
+ if (isLowSurrogate(c2) && index > start) {
+ char c1 = a[--index];
+ if (isHighSurrogate(c1)) {
+ return toCodePoint(c1, c2);
+ }
+ }
+ return c2;
+ }
+
+ /**
+ * Returns the leading surrogate (a
+ * <a href="http://www.unicode.org/glossary/#high_surrogate_code_unit">
+ * high surrogate code unit</a>) of the
+ * <a href="http://www.unicode.org/glossary/#surrogate_pair">
+ * surrogate pair</a>
+ * representing the specified supplementary character (Unicode
+ * code point) in the UTF-16 encoding. If the specified character
+ * is not a
+ * <a href="Character.html#supplementary">supplementary character</a>,
+ * an unspecified {@code char} is returned.
+ *
+ * <p>If
+ * {@link #isSupplementaryCodePoint isSupplementaryCodePoint(x)}
+ * is {@code true}, then
+ * {@link #isHighSurrogate isHighSurrogate}{@code (highSurrogate(x))} and
+ * {@link #toCodePoint toCodePoint}{@code (highSurrogate(x), }{@link #lowSurrogate lowSurrogate}{@code (x)) == x}
+ * are also always {@code true}.
+ *
+ * @param codePoint a supplementary character (Unicode code point)
+ * @return the leading surrogate code unit used to represent the
+ * character in the UTF-16 encoding
+ * @since 1.7
+ */
+ public static char highSurrogate(int codePoint) {
+ return (char) ((codePoint >>> 10)
+ + (MIN_HIGH_SURROGATE - (MIN_SUPPLEMENTARY_CODE_POINT >>> 10)));
+ }
+
+ /**
+ * Returns the trailing surrogate (a
+ * <a href="http://www.unicode.org/glossary/#low_surrogate_code_unit">
+ * low surrogate code unit</a>) of the
+ * <a href="http://www.unicode.org/glossary/#surrogate_pair">
+ * surrogate pair</a>
+ * representing the specified supplementary character (Unicode
+ * code point) in the UTF-16 encoding. If the specified character
+ * is not a
+ * <a href="Character.html#supplementary">supplementary character</a>,
+ * an unspecified {@code char} is returned.
+ *
+ * <p>If
+ * {@link #isSupplementaryCodePoint isSupplementaryCodePoint(x)}
+ * is {@code true}, then
+ * {@link #isLowSurrogate isLowSurrogate}{@code (lowSurrogate(x))} and
+ * {@link #toCodePoint toCodePoint}{@code (}{@link #highSurrogate highSurrogate}{@code (x), lowSurrogate(x)) == x}
+ * are also always {@code true}.
+ *
+ * @param codePoint a supplementary character (Unicode code point)
+ * @return the trailing surrogate code unit used to represent the
+ * character in the UTF-16 encoding
+ * @since 1.7
+ */
+ public static char lowSurrogate(int codePoint) {
+ return (char) ((codePoint & 0x3ff) + MIN_LOW_SURROGATE);
+ }
+
+ /**
+ * Converts the specified character (Unicode code point) to its
+ * UTF-16 representation. If the specified code point is a BMP
+ * (Basic Multilingual Plane or Plane 0) value, the same value is
+ * stored in {@code dst[dstIndex]}, and 1 is returned. If the
+ * specified code point is a supplementary character, its
+ * surrogate values are stored in {@code dst[dstIndex]}
+ * (high-surrogate) and {@code dst[dstIndex+1]}
+ * (low-surrogate), and 2 is returned.
+ *
+ * @param codePoint the character (Unicode code point) to be converted.
+ * @param dst an array of {@code char} in which the
+ * {@code codePoint}'s UTF-16 value is stored.
+ * @param dstIndex the start index into the {@code dst}
+ * array where the converted value is stored.
+ * @return 1 if the code point is a BMP code point, 2 if the
+ * code point is a supplementary code point.
+ * @exception IllegalArgumentException if the specified
+ * {@code codePoint} is not a valid Unicode code point.
+ * @exception NullPointerException if the specified {@code dst} is null.
+ * @exception IndexOutOfBoundsException if {@code dstIndex}
+ * is negative or not less than {@code dst.length}, or if
+ * {@code dst} at {@code dstIndex} doesn't have enough
+ * array element(s) to store the resulting {@code char}
+ * value(s). (If {@code dstIndex} is equal to
+ * {@code dst.length-1} and the specified
+ * {@code codePoint} is a supplementary character, the
+ * high-surrogate value is not stored in
+ * {@code dst[dstIndex]}.)
+ * @since 1.5
+ */
+ public static int toChars(int codePoint, char[] dst, int dstIndex) {
+ if (isBmpCodePoint(codePoint)) {
+ dst[dstIndex] = (char) codePoint;
+ return 1;
+ } else if (isValidCodePoint(codePoint)) {
+ toSurrogates(codePoint, dst, dstIndex);
+ return 2;
+ } else {
+ throw new IllegalArgumentException();
+ }
+ }
+
+ /**
+ * Converts the specified character (Unicode code point) to its
+ * UTF-16 representation stored in a {@code char} array. If
+ * the specified code point is a BMP (Basic Multilingual Plane or
+ * Plane 0) value, the resulting {@code char} array has
+ * the same value as {@code codePoint}. If the specified code
+ * point is a supplementary code point, the resulting
+ * {@code char} array has the corresponding surrogate pair.
+ *
+ * @param codePoint a Unicode code point
+ * @return a {@code char} array having
+ * {@code codePoint}'s UTF-16 representation.
+ * @exception IllegalArgumentException if the specified
+ * {@code codePoint} is not a valid Unicode code point.
+ * @since 1.5
+ */
+ public static char[] toChars(int codePoint) {
+ if (isBmpCodePoint(codePoint)) {
+ return new char[] { (char) codePoint };
+ } else if (isValidCodePoint(codePoint)) {
+ char[] result = new char[2];
+ toSurrogates(codePoint, result, 0);
+ return result;
+ } else {
+ throw new IllegalArgumentException();
+ }
+ }
+
+ static void toSurrogates(int codePoint, char[] dst, int index) {
+ // We write elements "backwards" to guarantee all-or-nothing
+ dst[index+1] = lowSurrogate(codePoint);
+ dst[index] = highSurrogate(codePoint);
+ }
+
+ /**
+ * Returns the number of Unicode code points in the text range of
+ * the specified char sequence. The text range begins at the
+ * specified {@code beginIndex} and extends to the
+ * {@code char} at index {@code endIndex - 1}. Thus the
+ * length (in {@code char}s) of the text range is
+ * {@code endIndex-beginIndex}. Unpaired surrogates within
+ * the text range count as one code point each.
+ *
+ * @param seq the char sequence
+ * @param beginIndex the index to the first {@code char} of
+ * the text range.
+ * @param endIndex the index after the last {@code char} of
+ * the text range.
+ * @return the number of Unicode code points in the specified text
+ * range
+ * @exception NullPointerException if {@code seq} is null.
+ * @exception IndexOutOfBoundsException if the
+ * {@code beginIndex} is negative, or {@code endIndex}
+ * is larger than the length of the given sequence, or
+ * {@code beginIndex} is larger than {@code endIndex}.
+ * @since 1.5
+ */
+ public static int codePointCount(CharSequence seq, int beginIndex, int endIndex) {
+ int length = seq.length();
+ if (beginIndex < 0 || endIndex > length || beginIndex > endIndex) {
+ throw new IndexOutOfBoundsException();
+ }
+ int n = endIndex - beginIndex;
+ for (int i = beginIndex; i < endIndex; ) {
+ if (isHighSurrogate(seq.charAt(i++)) && i < endIndex &&
+ isLowSurrogate(seq.charAt(i))) {
+ n--;
+ i++;
+ }
+ }
+ return n;
+ }
+
+ /**
+ * Returns the number of Unicode code points in a subarray of the
+ * {@code char} array argument. The {@code offset}
+ * argument is the index of the first {@code char} of the
+ * subarray and the {@code count} argument specifies the
+ * length of the subarray in {@code char}s. Unpaired
+ * surrogates within the subarray count as one code point each.
+ *
+ * @param a the {@code char} array
+ * @param offset the index of the first {@code char} in the
+ * given {@code char} array
+ * @param count the length of the subarray in {@code char}s
+ * @return the number of Unicode code points in the specified subarray
+ * @exception NullPointerException if {@code a} is null.
+ * @exception IndexOutOfBoundsException if {@code offset} or
+ * {@code count} is negative, or if {@code offset +
+ * count} is larger than the length of the given array.
+ * @since 1.5
+ */
+ public static int codePointCount(char[] a, int offset, int count) {
+ if (count > a.length - offset || offset < 0 || count < 0) {
+ throw new IndexOutOfBoundsException();
+ }
+ return codePointCountImpl(a, offset, count);
+ }
+
+ static int codePointCountImpl(char[] a, int offset, int count) {
+ int endIndex = offset + count;
+ int n = count;
+ for (int i = offset; i < endIndex; ) {
+ if (isHighSurrogate(a[i++]) && i < endIndex &&
+ isLowSurrogate(a[i])) {
+ n--;
+ i++;
+ }
+ }
+ return n;
+ }
+
+ /**
+ * Returns the index within the given char sequence that is offset
+ * from the given {@code index} by {@code codePointOffset}
+ * code points. Unpaired surrogates within the text range given by
+ * {@code index} and {@code codePointOffset} count as
+ * one code point each.
+ *
+ * @param seq the char sequence
+ * @param index the index to be offset
+ * @param codePointOffset the offset in code points
+ * @return the index within the char sequence
+ * @exception NullPointerException if {@code seq} is null.
+ * @exception IndexOutOfBoundsException if {@code index}
+ * is negative or larger then the length of the char sequence,
+ * or if {@code codePointOffset} is positive and the
+ * subsequence starting with {@code index} has fewer than
+ * {@code codePointOffset} code points, or if
+ * {@code codePointOffset} is negative and the subsequence
+ * before {@code index} has fewer than the absolute value
+ * of {@code codePointOffset} code points.
+ * @since 1.5
+ */
+ public static int offsetByCodePoints(CharSequence seq, int index,
+ int codePointOffset) {
+ int length = seq.length();
+ if (index < 0 || index > length) {
+ throw new IndexOutOfBoundsException();
+ }
+
+ int x = index;
+ if (codePointOffset >= 0) {
+ int i;
+ for (i = 0; x < length && i < codePointOffset; i++) {
+ if (isHighSurrogate(seq.charAt(x++)) && x < length &&
+ isLowSurrogate(seq.charAt(x))) {
+ x++;
+ }
+ }
+ if (i < codePointOffset) {
+ throw new IndexOutOfBoundsException();
+ }
+ } else {
+ int i;
+ for (i = codePointOffset; x > 0 && i < 0; i++) {
+ if (isLowSurrogate(seq.charAt(--x)) && x > 0 &&
+ isHighSurrogate(seq.charAt(x-1))) {
+ x--;
+ }
+ }
+ if (i < 0) {
+ throw new IndexOutOfBoundsException();
+ }
+ }
+ return x;
+ }
+
+ /**
+ * Returns the index within the given {@code char} subarray
+ * that is offset from the given {@code index} by
+ * {@code codePointOffset} code points. The
+ * {@code start} and {@code count} arguments specify a
+ * subarray of the {@code char} array. Unpaired surrogates
+ * within the text range given by {@code index} and
+ * {@code codePointOffset} count as one code point each.
+ *
+ * @param a the {@code char} array
+ * @param start the index of the first {@code char} of the
+ * subarray
+ * @param count the length of the subarray in {@code char}s
+ * @param index the index to be offset
+ * @param codePointOffset the offset in code points
+ * @return the index within the subarray
+ * @exception NullPointerException if {@code a} is null.
+ * @exception IndexOutOfBoundsException
+ * if {@code start} or {@code count} is negative,
+ * or if {@code start + count} is larger than the length of
+ * the given array,
+ * or if {@code index} is less than {@code start} or
+ * larger then {@code start + count},
+ * or if {@code codePointOffset} is positive and the text range
+ * starting with {@code index} and ending with {@code start + count - 1}
+ * has fewer than {@code codePointOffset} code
+ * points,
+ * or if {@code codePointOffset} is negative and the text range
+ * starting with {@code start} and ending with {@code index - 1}
+ * has fewer than the absolute value of
+ * {@code codePointOffset} code points.
+ * @since 1.5
+ */
+ public static int offsetByCodePoints(char[] a, int start, int count,
+ int index, int codePointOffset) {
+ if (count > a.length-start || start < 0 || count < 0
+ || index < start || index > start+count) {
+ throw new IndexOutOfBoundsException();
+ }
+ return offsetByCodePointsImpl(a, start, count, index, codePointOffset);
+ }
+
+ static int offsetByCodePointsImpl(char[]a, int start, int count,
+ int index, int codePointOffset) {
+ int x = index;
+ if (codePointOffset >= 0) {
+ int limit = start + count;
+ int i;
+ for (i = 0; x < limit && i < codePointOffset; i++) {
+ if (isHighSurrogate(a[x++]) && x < limit &&
+ isLowSurrogate(a[x])) {
+ x++;
+ }
+ }
+ if (i < codePointOffset) {
+ throw new IndexOutOfBoundsException();
+ }
+ } else {
+ int i;
+ for (i = codePointOffset; x > start && i < 0; i++) {
+ if (isLowSurrogate(a[--x]) && x > start &&
+ isHighSurrogate(a[x-1])) {
+ x--;
+ }
+ }
+ if (i < 0) {
+ throw new IndexOutOfBoundsException();
+ }
+ }
+ return x;
+ }
+
+ /**
+ * Determines if the specified character is a lowercase character.
+ * <p>
+ * A character is lowercase if its general category type, provided
+ * by {@code Character.getType(ch)}, is
+ * {@code LOWERCASE_LETTER}, or it has contributory property
+ * Other_Lowercase as defined by the Unicode Standard.
+ * <p>
+ * The following are examples of lowercase characters:
+ * <blockquote><pre>
+ * a b c d e f g h i j k l m n o p q r s t u v w x y z
+ * '\u00DF' '\u00E0' '\u00E1' '\u00E2' '\u00E3' '\u00E4' '\u00E5' '\u00E6'
+ * '\u00E7' '\u00E8' '\u00E9' '\u00EA' '\u00EB' '\u00EC' '\u00ED' '\u00EE'
+ * '\u00EF' '\u00F0' '\u00F1' '\u00F2' '\u00F3' '\u00F4' '\u00F5' '\u00F6'
+ * '\u00F8' '\u00F9' '\u00FA' '\u00FB' '\u00FC' '\u00FD' '\u00FE' '\u00FF'
+ * </pre></blockquote>
+ * <p> Many other Unicode characters are lowercase too.
+ *
+ * <p><b>Note:</b> This method cannot handle <a
+ * href="#supplementary"> supplementary characters</a>. To support
+ * all Unicode characters, including supplementary characters, use
+ * the {@link #isLowerCase(int)} method.
+ *
+ * @param ch the character to be tested.
+ * @return {@code true} if the character is lowercase;
+ * {@code false} otherwise.
+ * @see Character#isLowerCase(char)
+ * @see Character#isTitleCase(char)
+ * @see Character#toLowerCase(char)
+ * @see Character#getType(char)
+ */
+ public static boolean isLowerCase(char ch) {
+ return isLowerCase((int)ch);
+ }
+
+ /**
+ * Determines if the specified character (Unicode code point) is a
+ * lowercase character.
+ * <p>
+ * A character is lowercase if its general category type, provided
+ * by {@link Character#getType getType(codePoint)}, is
+ * {@code LOWERCASE_LETTER}, or it has contributory property
+ * Other_Lowercase as defined by the Unicode Standard.
+ * <p>
+ * The following are examples of lowercase characters:
+ * <blockquote><pre>
+ * a b c d e f g h i j k l m n o p q r s t u v w x y z
+ * '\u00DF' '\u00E0' '\u00E1' '\u00E2' '\u00E3' '\u00E4' '\u00E5' '\u00E6'
+ * '\u00E7' '\u00E8' '\u00E9' '\u00EA' '\u00EB' '\u00EC' '\u00ED' '\u00EE'
+ * '\u00EF' '\u00F0' '\u00F1' '\u00F2' '\u00F3' '\u00F4' '\u00F5' '\u00F6'
+ * '\u00F8' '\u00F9' '\u00FA' '\u00FB' '\u00FC' '\u00FD' '\u00FE' '\u00FF'
+ * </pre></blockquote>
+ * <p> Many other Unicode characters are lowercase too.
+ *
+ * @param codePoint the character (Unicode code point) to be tested.
+ * @return {@code true} if the character is lowercase;
+ * {@code false} otherwise.
+ * @see Character#isLowerCase(int)
+ * @see Character#isTitleCase(int)
+ * @see Character#toLowerCase(int)
+ * @see Character#getType(int)
+ * @since 1.5
+ */
+ // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+ /*
+ public static boolean isLowerCase(int codePoint) {
+ return getType(codePoint) == Character.LOWERCASE_LETTER ||
+ CharacterData.of(codePoint).isOtherLowercase(codePoint);
+ }
+ */
+ public static boolean isLowerCase(int codePoint) {
+ return isLowerCaseImpl(codePoint);
+ }
+
+ @FastNative
+ static native boolean isLowerCaseImpl(int codePoint);
+ // END Android-changed: Reimplement methods natively on top of ICU4C.
+
+ /**
+ * Determines if the specified character is an uppercase character.
+ * <p>
+ * A character is uppercase if its general category type, provided by
+ * {@code Character.getType(ch)}, is {@code UPPERCASE_LETTER}.
+ * or it has contributory property Other_Uppercase as defined by the Unicode Standard.
+ * <p>
+ * The following are examples of uppercase characters:
+ * <blockquote><pre>
+ * A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
+ * '\u00C0' '\u00C1' '\u00C2' '\u00C3' '\u00C4' '\u00C5' '\u00C6' '\u00C7'
+ * '\u00C8' '\u00C9' '\u00CA' '\u00CB' '\u00CC' '\u00CD' '\u00CE' '\u00CF'
+ * '\u00D0' '\u00D1' '\u00D2' '\u00D3' '\u00D4' '\u00D5' '\u00D6' '\u00D8'
+ * '\u00D9' '\u00DA' '\u00DB' '\u00DC' '\u00DD' '\u00DE'
+ * </pre></blockquote>
+ * <p> Many other Unicode characters are uppercase too.
+ *
+ * <p><b>Note:</b> This method cannot handle <a
+ * href="#supplementary"> supplementary characters</a>. To support
+ * all Unicode characters, including supplementary characters, use
+ * the {@link #isUpperCase(int)} method.
+ *
+ * @param ch the character to be tested.
+ * @return {@code true} if the character is uppercase;
+ * {@code false} otherwise.
+ * @see Character#isLowerCase(char)
+ * @see Character#isTitleCase(char)
+ * @see Character#toUpperCase(char)
+ * @see Character#getType(char)
+ * @since 1.0
+ */
+ public static boolean isUpperCase(char ch) {
+ return isUpperCase((int)ch);
+ }
+
+ /**
+ * Determines if the specified character (Unicode code point) is an uppercase character.
+ * <p>
+ * A character is uppercase if its general category type, provided by
+ * {@link Character#getType(int) getType(codePoint)}, is {@code UPPERCASE_LETTER},
+ * or it has contributory property Other_Uppercase as defined by the Unicode Standard.
+ * <p>
+ * The following are examples of uppercase characters:
+ * <blockquote><pre>
+ * A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
+ * '\u00C0' '\u00C1' '\u00C2' '\u00C3' '\u00C4' '\u00C5' '\u00C6' '\u00C7'
+ * '\u00C8' '\u00C9' '\u00CA' '\u00CB' '\u00CC' '\u00CD' '\u00CE' '\u00CF'
+ * '\u00D0' '\u00D1' '\u00D2' '\u00D3' '\u00D4' '\u00D5' '\u00D6' '\u00D8'
+ * '\u00D9' '\u00DA' '\u00DB' '\u00DC' '\u00DD' '\u00DE'
+ * </pre></blockquote>
+ * <p> Many other Unicode characters are uppercase too.<p>
+ *
+ * @param codePoint the character (Unicode code point) to be tested.
+ * @return {@code true} if the character is uppercase;
+ * {@code false} otherwise.
+ * @see Character#isLowerCase(int)
+ * @see Character#isTitleCase(int)
+ * @see Character#toUpperCase(int)
+ * @see Character#getType(int)
+ * @since 1.5
+ */
+ // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+ /*
+ public static boolean isUpperCase(int codePoint) {
+ return getType(codePoint) == Character.UPPERCASE_LETTER ||
+ CharacterData.of(codePoint).isOtherUppercase(codePoint);
+ }
+ */
+ public static boolean isUpperCase(int codePoint) {
+ return isUpperCaseImpl(codePoint);
+ }
+
+ @FastNative
+ static native boolean isUpperCaseImpl(int codePoint);
+ // END Android-changed: Reimplement methods natively on top of ICU4C.
+
+ /**
+ * Determines if the specified character is a titlecase character.
+ * <p>
+ * A character is a titlecase character if its general
+ * category type, provided by {@code Character.getType(ch)},
+ * is {@code TITLECASE_LETTER}.
+ * <p>
+ * Some characters look like pairs of Latin letters. For example, there
+ * is an uppercase letter that looks like "LJ" and has a corresponding
+ * lowercase letter that looks like "lj". A third form, which looks like "Lj",
+ * is the appropriate form to use when rendering a word in lowercase
+ * with initial capitals, as for a book title.
+ * <p>
+ * These are some of the Unicode characters for which this method returns
+ * {@code true}:
+ * <ul>
+ * <li>{@code LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON}
+ * <li>{@code LATIN CAPITAL LETTER L WITH SMALL LETTER J}
+ * <li>{@code LATIN CAPITAL LETTER N WITH SMALL LETTER J}
+ * <li>{@code LATIN CAPITAL LETTER D WITH SMALL LETTER Z}
+ * </ul>
+ * <p> Many other Unicode characters are titlecase too.
+ *
+ * <p><b>Note:</b> This method cannot handle <a
+ * href="#supplementary"> supplementary characters</a>. To support
+ * all Unicode characters, including supplementary characters, use
+ * the {@link #isTitleCase(int)} method.
+ *
+ * @param ch the character to be tested.
+ * @return {@code true} if the character is titlecase;
+ * {@code false} otherwise.
+ * @see Character#isLowerCase(char)
+ * @see Character#isUpperCase(char)
+ * @see Character#toTitleCase(char)
+ * @see Character#getType(char)
+ * @since 1.0.2
+ */
+ public static boolean isTitleCase(char ch) {
+ return isTitleCase((int)ch);
+ }
+
+ /**
+ * Determines if the specified character (Unicode code point) is a titlecase character.
+ * <p>
+ * A character is a titlecase character if its general
+ * category type, provided by {@link Character#getType(int) getType(codePoint)},
+ * is {@code TITLECASE_LETTER}.
+ * <p>
+ * Some characters look like pairs of Latin letters. For example, there
+ * is an uppercase letter that looks like "LJ" and has a corresponding
+ * lowercase letter that looks like "lj". A third form, which looks like "Lj",
+ * is the appropriate form to use when rendering a word in lowercase
+ * with initial capitals, as for a book title.
+ * <p>
+ * These are some of the Unicode characters for which this method returns
+ * {@code true}:
+ * <ul>
+ * <li>{@code LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON}
+ * <li>{@code LATIN CAPITAL LETTER L WITH SMALL LETTER J}
+ * <li>{@code LATIN CAPITAL LETTER N WITH SMALL LETTER J}
+ * <li>{@code LATIN CAPITAL LETTER D WITH SMALL LETTER Z}
+ * </ul>
+ * <p> Many other Unicode characters are titlecase too.<p>
+ *
+ * @param codePoint the character (Unicode code point) to be tested.
+ * @return {@code true} if the character is titlecase;
+ * {@code false} otherwise.
+ * @see Character#isLowerCase(int)
+ * @see Character#isUpperCase(int)
+ * @see Character#toTitleCase(int)
+ * @see Character#getType(int)
+ * @since 1.5
+ */
+ // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+ /*
+ public static boolean isTitleCase(int codePoint) {
+ return getType(codePoint) == Character.TITLECASE_LETTER;
+ }
+ */
+ public static boolean isTitleCase(int codePoint) {
+ return isTitleCaseImpl(codePoint);
+ }
+
+ @FastNative
+ static native boolean isTitleCaseImpl(int codePoint);
+ // END Android-changed: Reimplement methods natively on top of ICU4C.
+
+ /**
+ * Determines if the specified character is a digit.
+ * <p>
+ * A character is a digit if its general category type, provided
+ * by {@code Character.getType(ch)}, is
+ * {@code DECIMAL_DIGIT_NUMBER}.
+ * <p>
+ * Some Unicode character ranges that contain digits:
+ * <ul>
+ * <li>{@code '\u005Cu0030'} through {@code '\u005Cu0039'},
+ * ISO-LATIN-1 digits ({@code '0'} through {@code '9'})
+ * <li>{@code '\u005Cu0660'} through {@code '\u005Cu0669'},
+ * Arabic-Indic digits
+ * <li>{@code '\u005Cu06F0'} through {@code '\u005Cu06F9'},
+ * Extended Arabic-Indic digits
+ * <li>{@code '\u005Cu0966'} through {@code '\u005Cu096F'},
+ * Devanagari digits
+ * <li>{@code '\u005CuFF10'} through {@code '\u005CuFF19'},
+ * Fullwidth digits
+ * </ul>
+ *
+ * Many other character ranges contain digits as well.
+ *
+ * <p><b>Note:</b> This method cannot handle <a
+ * href="#supplementary"> supplementary characters</a>. To support
+ * all Unicode characters, including supplementary characters, use
+ * the {@link #isDigit(int)} method.
+ *
+ * @param ch the character to be tested.
+ * @return {@code true} if the character is a digit;
+ * {@code false} otherwise.
+ * @see Character#digit(char, int)
+ * @see Character#forDigit(int, int)
+ * @see Character#getType(char)
+ */
+ public static boolean isDigit(char ch) {
+ return isDigit((int)ch);
+ }
+
+ /**
+ * Determines if the specified character (Unicode code point) is a digit.
+ * <p>
+ * A character is a digit if its general category type, provided
+ * by {@link Character#getType(int) getType(codePoint)}, is
+ * {@code DECIMAL_DIGIT_NUMBER}.
+ * <p>
+ * Some Unicode character ranges that contain digits:
+ * <ul>
+ * <li>{@code '\u005Cu0030'} through {@code '\u005Cu0039'},
+ * ISO-LATIN-1 digits ({@code '0'} through {@code '9'})
+ * <li>{@code '\u005Cu0660'} through {@code '\u005Cu0669'},
+ * Arabic-Indic digits
+ * <li>{@code '\u005Cu06F0'} through {@code '\u005Cu06F9'},
+ * Extended Arabic-Indic digits
+ * <li>{@code '\u005Cu0966'} through {@code '\u005Cu096F'},
+ * Devanagari digits
+ * <li>{@code '\u005CuFF10'} through {@code '\u005CuFF19'},
+ * Fullwidth digits
+ * </ul>
+ *
+ * Many other character ranges contain digits as well.
+ *
+ * @param codePoint the character (Unicode code point) to be tested.
+ * @return {@code true} if the character is a digit;
+ * {@code false} otherwise.
+ * @see Character#forDigit(int, int)
+ * @see Character#getType(int)
+ * @since 1.5
+ */
+ // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+ /*
+ public static boolean isDigit(int codePoint) {
+ return getType(codePoint) == Character.DECIMAL_DIGIT_NUMBER;
+ }
+ */
+ public static boolean isDigit(int codePoint) {
+ return isDigitImpl(codePoint);
+ }
+
+ @FastNative
+ static native boolean isDigitImpl(int codePoint);
+ // END Android-changed: Reimplement methods natively on top of ICU4C.
+
+ /**
+ * Determines if a character is defined in Unicode.
+ * <p>
+ * A character is defined if at least one of the following is true:
+ * <ul>
+ * <li>It has an entry in the UnicodeData file.
+ * <li>It has a value in a range defined by the UnicodeData file.
+ * </ul>
+ *
+ * <p><b>Note:</b> This method cannot handle <a
+ * href="#supplementary"> supplementary characters</a>. To support
+ * all Unicode characters, including supplementary characters, use
+ * the {@link #isDefined(int)} method.
+ *
+ * @param ch the character to be tested
+ * @return {@code true} if the character has a defined meaning
+ * in Unicode; {@code false} otherwise.
+ * @see Character#isDigit(char)
+ * @see Character#isLetter(char)
+ * @see Character#isLetterOrDigit(char)
+ * @see Character#isLowerCase(char)
+ * @see Character#isTitleCase(char)
+ * @see Character#isUpperCase(char)
+ * @since 1.0.2
+ */
+ public static boolean isDefined(char ch) {
+ return isDefined((int)ch);
+ }
+
+ /**
+ * Determines if a character (Unicode code point) is defined in Unicode.
+ * <p>
+ * A character is defined if at least one of the following is true:
+ * <ul>
+ * <li>It has an entry in the UnicodeData file.
+ * <li>It has a value in a range defined by the UnicodeData file.
+ * </ul>
+ *
+ * @param codePoint the character (Unicode code point) to be tested.
+ * @return {@code true} if the character has a defined meaning
+ * in Unicode; {@code false} otherwise.
+ * @see Character#isDigit(int)
+ * @see Character#isLetter(int)
+ * @see Character#isLetterOrDigit(int)
+ * @see Character#isLowerCase(int)
+ * @see Character#isTitleCase(int)
+ * @see Character#isUpperCase(int)
+ * @since 1.5
+ */
+ // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+ /*
+ public static boolean isDefined(int codePoint) {
+ return getType(codePoint) != Character.UNASSIGNED;
+ }
+ */
+ public static boolean isDefined(int codePoint) {
+ return isDefinedImpl(codePoint);
+ }
+
+ @FastNative
+ static native boolean isDefinedImpl(int codePoint);
+ // END Android-changed: Reimplement methods natively on top of ICU4C.
+
+ /**
+ * Determines if the specified character is a letter.
+ * <p>
+ * A character is considered to be a letter if its general
+ * category type, provided by {@code Character.getType(ch)},
+ * is any of the following:
+ * <ul>
+ * <li> {@code UPPERCASE_LETTER}
+ * <li> {@code LOWERCASE_LETTER}
+ * <li> {@code TITLECASE_LETTER}
+ * <li> {@code MODIFIER_LETTER}
+ * <li> {@code OTHER_LETTER}
+ * </ul>
+ *
+ * Not all letters have case. Many characters are
+ * letters but are neither uppercase nor lowercase nor titlecase.
+ *
+ * <p><b>Note:</b> This method cannot handle <a
+ * href="#supplementary"> supplementary characters</a>. To support
+ * all Unicode characters, including supplementary characters, use
+ * the {@link #isLetter(int)} method.
+ *
+ * @param ch the character to be tested.
+ * @return {@code true} if the character is a letter;
+ * {@code false} otherwise.
+ * @see Character#isDigit(char)
+ * @see Character#isJavaIdentifierStart(char)
+ * @see Character#isJavaLetter(char)
+ * @see Character#isJavaLetterOrDigit(char)
+ * @see Character#isLetterOrDigit(char)
+ * @see Character#isLowerCase(char)
+ * @see Character#isTitleCase(char)
+ * @see Character#isUnicodeIdentifierStart(char)
+ * @see Character#isUpperCase(char)
+ */
+ public static boolean isLetter(char ch) {
+ return isLetter((int)ch);
+ }
+
+ /**
+ * Determines if the specified character (Unicode code point) is a letter.
+ * <p>
+ * A character is considered to be a letter if its general
+ * category type, provided by {@link Character#getType(int) getType(codePoint)},
+ * is any of the following:
+ * <ul>
+ * <li> {@code UPPERCASE_LETTER}
+ * <li> {@code LOWERCASE_LETTER}
+ * <li> {@code TITLECASE_LETTER}
+ * <li> {@code MODIFIER_LETTER}
+ * <li> {@code OTHER_LETTER}
+ * </ul>
+ *
+ * Not all letters have case. Many characters are
+ * letters but are neither uppercase nor lowercase nor titlecase.
+ *
+ * @param codePoint the character (Unicode code point) to be tested.
+ * @return {@code true} if the character is a letter;
+ * {@code false} otherwise.
+ * @see Character#isDigit(int)
+ * @see Character#isJavaIdentifierStart(int)
+ * @see Character#isLetterOrDigit(int)
+ * @see Character#isLowerCase(int)
+ * @see Character#isTitleCase(int)
+ * @see Character#isUnicodeIdentifierStart(int)
+ * @see Character#isUpperCase(int)
+ * @since 1.5
+ */
+ // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+ /*
+ public static boolean isLetter(int codePoint) {
+ return ((((1 << Character.UPPERCASE_LETTER) |
+ (1 << Character.LOWERCASE_LETTER) |
+ (1 << Character.TITLECASE_LETTER) |
+ (1 << Character.MODIFIER_LETTER) |
+ (1 << Character.OTHER_LETTER)) >> getType(codePoint)) & 1)
+ != 0;
+ }
+ */
+ public static boolean isLetter(int codePoint) {
+ return isLetterImpl(codePoint);
+ }
+
+ @FastNative
+ static native boolean isLetterImpl(int codePoint);
+ // END Android-changed: Reimplement methods natively on top of ICU4C.
+
+ /**
+ * Determines if the specified character is a letter or digit.
+ * <p>
+ * A character is considered to be a letter or digit if either
+ * {@code Character.isLetter(char ch)} or
+ * {@code Character.isDigit(char ch)} returns
+ * {@code true} for the character.
+ *
+ * <p><b>Note:</b> This method cannot handle <a
+ * href="#supplementary"> supplementary characters</a>. To support
+ * all Unicode characters, including supplementary characters, use
+ * the {@link #isLetterOrDigit(int)} method.
+ *
+ * @param ch the character to be tested.
+ * @return {@code true} if the character is a letter or digit;
+ * {@code false} otherwise.
+ * @see Character#isDigit(char)
+ * @see Character#isJavaIdentifierPart(char)
+ * @see Character#isJavaLetter(char)
+ * @see Character#isJavaLetterOrDigit(char)
+ * @see Character#isLetter(char)
+ * @see Character#isUnicodeIdentifierPart(char)
+ * @since 1.0.2
+ */
+ public static boolean isLetterOrDigit(char ch) {
+ return isLetterOrDigit((int)ch);
+ }
+
+ /**
+ * Determines if the specified character (Unicode code point) is a letter or digit.
+ * <p>
+ * A character is considered to be a letter or digit if either
+ * {@link #isLetter(int) isLetter(codePoint)} or
+ * {@link #isDigit(int) isDigit(codePoint)} returns
+ * {@code true} for the character.
+ *
+ * @param codePoint the character (Unicode code point) to be tested.
+ * @return {@code true} if the character is a letter or digit;
+ * {@code false} otherwise.
+ * @see Character#isDigit(int)
+ * @see Character#isJavaIdentifierPart(int)
+ * @see Character#isLetter(int)
+ * @see Character#isUnicodeIdentifierPart(int)
+ * @since 1.5
+ */
+ // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+ /*
+ public static boolean isLetterOrDigit(int codePoint) {
+ return ((((1 << Character.UPPERCASE_LETTER) |
+ (1 << Character.LOWERCASE_LETTER) |
+ (1 << Character.TITLECASE_LETTER) |
+ (1 << Character.MODIFIER_LETTER) |
+ (1 << Character.OTHER_LETTER) |
+ (1 << Character.DECIMAL_DIGIT_NUMBER)) >> getType(codePoint)) & 1)
+ != 0;
+ }
+ */
+ public static boolean isLetterOrDigit(int codePoint) {
+ return isLetterOrDigitImpl(codePoint);
+ }
+
+ @FastNative
+ static native boolean isLetterOrDigitImpl(int codePoint);
+ // END Android-changed: Reimplement methods natively on top of ICU4C.
+
+ /**
+ * Determines if the specified character is permissible as the first
+ * character in a Java identifier.
+ * <p>
+ * A character may start a Java identifier if and only if
+ * one of the following is true:
+ * <ul>
+ * <li> {@link #isLetter(char) isLetter(ch)} returns {@code true}
+ * <li> {@link #getType(char) getType(ch)} returns {@code LETTER_NUMBER}
+ * <li> {@code ch} is a currency symbol (such as {@code '$'})
+ * <li> {@code ch} is a connecting punctuation character (such as {@code '_'}).
+ * </ul>
+ *
+ * @param ch the character to be tested.
+ * @return {@code true} if the character may start a Java
+ * identifier; {@code false} otherwise.
+ * @see Character#isJavaLetterOrDigit(char)
+ * @see Character#isJavaIdentifierStart(char)
+ * @see Character#isJavaIdentifierPart(char)
+ * @see Character#isLetter(char)
+ * @see Character#isLetterOrDigit(char)
+ * @see Character#isUnicodeIdentifierStart(char)
+ * @since 1.02
+ * @deprecated Replaced by isJavaIdentifierStart(char).
+ */
+ @Deprecated
+ public static boolean isJavaLetter(char ch) {
+ return isJavaIdentifierStart(ch);
+ }
+
+ /**
+ * Determines if the specified character may be part of a Java
+ * identifier as other than the first character.
+ * <p>
+ * A character may be part of a Java identifier if and only if any
+ * of the following are true:
+ * <ul>
+ * <li> it is a letter
+ * <li> it is a currency symbol (such as {@code '$'})
+ * <li> it is a connecting punctuation character (such as {@code '_'})
+ * <li> it is a digit
+ * <li> it is a numeric letter (such as a Roman numeral character)
+ * <li> it is a combining mark
+ * <li> it is a non-spacing mark
+ * <li> {@code isIdentifierIgnorable} returns
+ * {@code true} for the character.
+ * </ul>
+ *
+ * @param ch the character to be tested.
+ * @return {@code true} if the character may be part of a
+ * Java identifier; {@code false} otherwise.
+ * @see Character#isJavaLetter(char)
+ * @see Character#isJavaIdentifierStart(char)
+ * @see Character#isJavaIdentifierPart(char)
+ * @see Character#isLetter(char)
+ * @see Character#isLetterOrDigit(char)
+ * @see Character#isUnicodeIdentifierPart(char)
+ * @see Character#isIdentifierIgnorable(char)
+ * @since 1.02
+ * @deprecated Replaced by isJavaIdentifierPart(char).
+ */
+ @Deprecated
+ public static boolean isJavaLetterOrDigit(char ch) {
+ return isJavaIdentifierPart(ch);
+ }
+
+ /**
+ * Determines if the specified character (Unicode code point) is an alphabet.
+ * <p>
+ * A character is considered to be alphabetic if its general category type,
+ * provided by {@link Character#getType(int) getType(codePoint)}, is any of
+ * the following:
+ * <ul>
+ * <li> <code>UPPERCASE_LETTER</code>
+ * <li> <code>LOWERCASE_LETTER</code>
+ * <li> <code>TITLECASE_LETTER</code>
+ * <li> <code>MODIFIER_LETTER</code>
+ * <li> <code>OTHER_LETTER</code>
+ * <li> <code>LETTER_NUMBER</code>
+ * </ul>
+ * or it has contributory property Other_Alphabetic as defined by the
+ * Unicode Standard.
+ *
+ * @param codePoint the character (Unicode code point) to be tested.
+ * @return <code>true</code> if the character is a Unicode alphabet
+ * character, <code>false</code> otherwise.
+ * @since 1.7
+ */
+ // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+ /*
+ public static boolean isAlphabetic(int codePoint) {
+ return (((((1 << Character.UPPERCASE_LETTER) |
+ (1 << Character.LOWERCASE_LETTER) |
+ (1 << Character.TITLECASE_LETTER) |
+ (1 << Character.MODIFIER_LETTER) |
+ (1 << Character.OTHER_LETTER) |
+ (1 << Character.LETTER_NUMBER)) >> getType(codePoint)) & 1) != 0) ||
+ CharacterData.of(codePoint).isOtherAlphabetic(codePoint);
+ }
+ */
+ public static boolean isAlphabetic(int codePoint) {
+ return isAlphabeticImpl(codePoint);
+ }
+
+ @FastNative
+ static native boolean isAlphabeticImpl(int codePoint);
+ // END Android-changed: Reimplement methods natively on top of ICU4C.
+
+ /**
+ * Determines if the specified character (Unicode code point) is a CJKV
+ * (Chinese, Japanese, Korean and Vietnamese) ideograph, as defined by
+ * the Unicode Standard.
+ *
+ * @param codePoint the character (Unicode code point) to be tested.
+ * @return <code>true</code> if the character is a Unicode ideograph
+ * character, <code>false</code> otherwise.
+ * @since 1.7
+ */
+ // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+ /*
+ public static boolean isIdeographic(int codePoint) {
+ return CharacterData.of(codePoint).isIdeographic(codePoint);
+ }
+ */
+ public static boolean isIdeographic(int codePoint) {
+ return isIdeographicImpl(codePoint);
+ }
+ @FastNative
+ static native boolean isIdeographicImpl(int codePoint);
+ // END Android-changed: Reimplement methods natively on top of ICU4C.
+
+ // Android-changed: Removed @see tag (target does not exist on Android):
+ // @see javax.lang.model.SourceVersion#isIdentifier(CharSequence)
+ /**
+ * Determines if the specified character is
+ * permissible as the first character in a Java identifier.
+ * <p>
+ * A character may start a Java identifier if and only if
+ * one of the following conditions is true:
+ * <ul>
+ * <li> {@link #isLetter(char) isLetter(ch)} returns {@code true}
+ * <li> {@link #getType(char) getType(ch)} returns {@code LETTER_NUMBER}
+ * <li> {@code ch} is a currency symbol (such as {@code '$'})
+ * <li> {@code ch} is a connecting punctuation character (such as {@code '_'}).
+ * </ul>
+ *
+ * <p><b>Note:</b> This method cannot handle <a
+ * href="#supplementary"> supplementary characters</a>. To support
+ * all Unicode characters, including supplementary characters, use
+ * the {@link #isJavaIdentifierStart(int)} method.
+ *
+ * @param ch the character to be tested.
+ * @return {@code true} if the character may start a Java identifier;
+ * {@code false} otherwise.
+ * @see Character#isJavaIdentifierPart(char)
+ * @see Character#isLetter(char)
+ * @see Character#isUnicodeIdentifierStart(char)
+ * @since 1.1
+ */
+ public static boolean isJavaIdentifierStart(char ch) {
+ return isJavaIdentifierStart((int)ch);
+ }
+
+ // Android-changed: Removed @see tag (target does not exist on Android):
+ // @see javax.lang.model.SourceVersion#isIdentifier(CharSequence)
+ /**
+ * Determines if the character (Unicode code point) is
+ * permissible as the first character in a Java identifier.
+ * <p>
+ * A character may start a Java identifier if and only if
+ * one of the following conditions is true:
+ * <ul>
+ * <li> {@link #isLetter(int) isLetter(codePoint)}
+ * returns {@code true}
+ * <li> {@link #getType(int) getType(codePoint)}
+ * returns {@code LETTER_NUMBER}
+ * <li> the referenced character is a currency symbol (such as {@code '$'})
+ * <li> the referenced character is a connecting punctuation character
+ * (such as {@code '_'}).
+ * </ul>
+ *
+ * @param codePoint the character (Unicode code point) to be tested.
+ * @return {@code true} if the character may start a Java identifier;
+ * {@code false} otherwise.
+ * @see Character#isJavaIdentifierPart(int)
+ * @see Character#isLetter(int)
+ * @see Character#isUnicodeIdentifierStart(int)
+ * @since 1.5
+ */
+ // BEGIN Android-changed: Use ICU.
+ /*
+ public static boolean isJavaIdentifierStart(int codePoint) {
+ return CharacterData.of(codePoint).isJavaIdentifierStart(codePoint);
+ }
+ */
+ public static boolean isJavaIdentifierStart(int codePoint) {
+ // Use precomputed bitmasks to optimize the ASCII range.
+ if (codePoint < 64) {
+ return (codePoint == '$'); // There's only one character in this range.
+ } else if (codePoint < 128) {
+ return (0x7fffffe87fffffeL & (1L << (codePoint - 64))) != 0;
+ }
+ return ((1 << getType(codePoint))
+ & ((1 << UPPERCASE_LETTER)
+ | (1 << LOWERCASE_LETTER)
+ | (1 << TITLECASE_LETTER)
+ | (1 << MODIFIER_LETTER)
+ | (1 << OTHER_LETTER)
+ | (1 << CURRENCY_SYMBOL)
+ | (1 << CONNECTOR_PUNCTUATION)
+ | (1 << LETTER_NUMBER))) != 0;
+ }
+ // END Android-changed: Use ICU.
+
+ // Android-changed: Removed @see tag (target does not exist on Android):
+ // @see javax.lang.model.SourceVersion#isIdentifier(CharSequence)
+ /**
+ * Determines if the specified character may be part of a Java
+ * identifier as other than the first character.
+ * <p>
+ * A character may be part of a Java identifier if any of the following
+ * are true:
+ * <ul>
+ * <li> it is a letter
+ * <li> it is a currency symbol (such as {@code '$'})
+ * <li> it is a connecting punctuation character (such as {@code '_'})
+ * <li> it is a digit
+ * <li> it is a numeric letter (such as a Roman numeral character)
+ * <li> it is a combining mark
+ * <li> it is a non-spacing mark
+ * <li> {@code isIdentifierIgnorable} returns
+ * {@code true} for the character
+ * </ul>
+ *
+ * <p><b>Note:</b> This method cannot handle <a
+ * href="#supplementary"> supplementary characters</a>. To support
+ * all Unicode characters, including supplementary characters, use
+ * the {@link #isJavaIdentifierPart(int)} method.
+ *
+ * @param ch the character to be tested.
+ * @return {@code true} if the character may be part of a
+ * Java identifier; {@code false} otherwise.
+ * @see Character#isIdentifierIgnorable(char)
+ * @see Character#isJavaIdentifierStart(char)
+ * @see Character#isLetterOrDigit(char)
+ * @see Character#isUnicodeIdentifierPart(char)
+ * @since 1.1
+ */
+ public static boolean isJavaIdentifierPart(char ch) {
+ return isJavaIdentifierPart((int)ch);
+ }
+
+ // Android-changed: Removed @see tag (target does not exist on Android):
+ // @see javax.lang.model.SourceVersion#isIdentifier(CharSequence)
+ /**
+ * Determines if the character (Unicode code point) may be part of a Java
+ * identifier as other than the first character.
+ * <p>
+ * A character may be part of a Java identifier if any of the following
+ * are true:
+ * <ul>
+ * <li> it is a letter
+ * <li> it is a currency symbol (such as {@code '$'})
+ * <li> it is a connecting punctuation character (such as {@code '_'})
+ * <li> it is a digit
+ * <li> it is a numeric letter (such as a Roman numeral character)
+ * <li> it is a combining mark
+ * <li> it is a non-spacing mark
+ * <li> {@link #isIdentifierIgnorable(int)
+ * isIdentifierIgnorable(codePoint)} returns {@code true} for
+ * the character
+ * </ul>
+ *
+ * @param codePoint the character (Unicode code point) to be tested.
+ * @return {@code true} if the character may be part of a
+ * Java identifier; {@code false} otherwise.
+ * @see Character#isIdentifierIgnorable(int)
+ * @see Character#isJavaIdentifierStart(int)
+ * @see Character#isLetterOrDigit(int)
+ * @see Character#isUnicodeIdentifierPart(int)
+ * @since 1.5
+ */
+ // BEGIN Android-changed: Use ICU.
+ /*
+ public static boolean isJavaIdentifierPart(int codePoint) {
+ return CharacterData.of(codePoint).isJavaIdentifierPart(codePoint);
+ }
+ */
+ public static boolean isJavaIdentifierPart(int codePoint) {
+ // Use precomputed bitmasks to optimize the ASCII range.
+ if (codePoint < 64) {
+ return (0x3ff00100fffc1ffL & (1L << codePoint)) != 0;
+ } else if (codePoint < 128) {
+ return (0x87fffffe87fffffeL & (1L << (codePoint - 64))) != 0;
+ }
+ return ((1 << getType(codePoint))
+ & ((1 << UPPERCASE_LETTER)
+ | (1 << LOWERCASE_LETTER)
+ | (1 << TITLECASE_LETTER)
+ | (1 << MODIFIER_LETTER)
+ | (1 << OTHER_LETTER)
+ | (1 << CURRENCY_SYMBOL)
+ | (1 << CONNECTOR_PUNCTUATION)
+ | (1 << DECIMAL_DIGIT_NUMBER)
+ | (1 << LETTER_NUMBER)
+ | (1 << FORMAT)
+ | (1 << COMBINING_SPACING_MARK)
+ | (1 << NON_SPACING_MARK))) != 0
+ || (codePoint >= 0 && codePoint <= 8) || (codePoint >= 0xe && codePoint <= 0x1b)
+ || (codePoint >= 0x7f && codePoint <= 0x9f);
+ }
+ // END Android-changed: Use ICU.
+
+ /**
+ * Determines if the specified character is permissible as the
+ * first character in a Unicode identifier.
+ * <p>
+ * A character may start a Unicode identifier if and only if
+ * one of the following conditions is true:
+ * <ul>
+ * <li> {@link #isLetter(char) isLetter(ch)} returns {@code true}
+ * <li> {@link #getType(char) getType(ch)} returns
+ * {@code LETTER_NUMBER}.
+ * </ul>
+ *
+ * <p><b>Note:</b> This method cannot handle <a
+ * href="#supplementary"> supplementary characters</a>. To support
+ * all Unicode characters, including supplementary characters, use
+ * the {@link #isUnicodeIdentifierStart(int)} method.
+ *
+ * @param ch the character to be tested.
+ * @return {@code true} if the character may start a Unicode
+ * identifier; {@code false} otherwise.
+ * @see Character#isJavaIdentifierStart(char)
+ * @see Character#isLetter(char)
+ * @see Character#isUnicodeIdentifierPart(char)
+ * @since 1.1
+ */
+ public static boolean isUnicodeIdentifierStart(char ch) {
+ return isUnicodeIdentifierStart((int)ch);
+ }
+
+ /**
+ * Determines if the specified character (Unicode code point) is permissible as the
+ * first character in a Unicode identifier.
+ * <p>
+ * A character may start a Unicode identifier if and only if
+ * one of the following conditions is true:
+ * <ul>
+ * <li> {@link #isLetter(int) isLetter(codePoint)}
+ * returns {@code true}
+ * <li> {@link #getType(int) getType(codePoint)}
+ * returns {@code LETTER_NUMBER}.
+ * </ul>
+ * @param codePoint the character (Unicode code point) to be tested.
+ * @return {@code true} if the character may start a Unicode
+ * identifier; {@code false} otherwise.
+ * @see Character#isJavaIdentifierStart(int)
+ * @see Character#isLetter(int)
+ * @see Character#isUnicodeIdentifierPart(int)
+ * @since 1.5
+ */
+ // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+ /*
+ public static boolean isUnicodeIdentifierStart(int codePoint) {
+ return CharacterData.of(codePoint).isUnicodeIdentifierStart(codePoint);
+ }
+ */
+ public static boolean isUnicodeIdentifierStart(int codePoint) {
+ return isUnicodeIdentifierStartImpl(codePoint);
+ }
+
+ @FastNative
+ static native boolean isUnicodeIdentifierStartImpl(int codePoint);
+ // END Android-changed: Reimplement methods natively on top of ICU4C.
+
+ /**
+ * Determines if the specified character may be part of a Unicode
+ * identifier as other than the first character.
+ * <p>
+ * A character may be part of a Unicode identifier if and only if
+ * one of the following statements is true:
+ * <ul>
+ * <li> it is a letter
+ * <li> it is a connecting punctuation character (such as {@code '_'})
+ * <li> it is a digit
+ * <li> it is a numeric letter (such as a Roman numeral character)
+ * <li> it is a combining mark
+ * <li> it is a non-spacing mark
+ * <li> {@code isIdentifierIgnorable} returns
+ * {@code true} for this character.
+ * </ul>
+ *
+ * <p><b>Note:</b> This method cannot handle <a
+ * href="#supplementary"> supplementary characters</a>. To support
+ * all Unicode characters, including supplementary characters, use
+ * the {@link #isUnicodeIdentifierPart(int)} method.
+ *
+ * @param ch the character to be tested.
+ * @return {@code true} if the character may be part of a
+ * Unicode identifier; {@code false} otherwise.
+ * @see Character#isIdentifierIgnorable(char)
+ * @see Character#isJavaIdentifierPart(char)
+ * @see Character#isLetterOrDigit(char)
+ * @see Character#isUnicodeIdentifierStart(char)
+ * @since 1.1
+ */
+ public static boolean isUnicodeIdentifierPart(char ch) {
+ return isUnicodeIdentifierPart((int)ch);
+ }
+
+ /**
+ * Determines if the specified character (Unicode code point) may be part of a Unicode
+ * identifier as other than the first character.
+ * <p>
+ * A character may be part of a Unicode identifier if and only if
+ * one of the following statements is true:
+ * <ul>
+ * <li> it is a letter
+ * <li> it is a connecting punctuation character (such as {@code '_'})
+ * <li> it is a digit
+ * <li> it is a numeric letter (such as a Roman numeral character)
+ * <li> it is a combining mark
+ * <li> it is a non-spacing mark
+ * <li> {@code isIdentifierIgnorable} returns
+ * {@code true} for this character.
+ * </ul>
+ * @param codePoint the character (Unicode code point) to be tested.
+ * @return {@code true} if the character may be part of a
+ * Unicode identifier; {@code false} otherwise.
+ * @see Character#isIdentifierIgnorable(int)
+ * @see Character#isJavaIdentifierPart(int)
+ * @see Character#isLetterOrDigit(int)
+ * @see Character#isUnicodeIdentifierStart(int)
+ * @since 1.5
+ */
+ // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+ /*
+ public static boolean isUnicodeIdentifierPart(int codePoint) {
+ return CharacterData.of(codePoint).isUnicodeIdentifierPart(codePoint);
+ }
+ */
+ public static boolean isUnicodeIdentifierPart(int codePoint) {
+ return isUnicodeIdentifierPartImpl(codePoint);
+ }
+
+ @FastNative
+ static native boolean isUnicodeIdentifierPartImpl(int codePoint);
+ // END Android-changed: Reimplement methods natively on top of ICU4C.
+
+ /**
+ * Determines if the specified character should be regarded as
+ * an ignorable character in a Java identifier or a Unicode identifier.
+ * <p>
+ * The following Unicode characters are ignorable in a Java identifier
+ * or a Unicode identifier:
+ * <ul>
+ * <li>ISO control characters that are not whitespace
+ * <ul>
+ * <li>{@code '\u005Cu0000'} through {@code '\u005Cu0008'}
+ * <li>{@code '\u005Cu000E'} through {@code '\u005Cu001B'}
+ * <li>{@code '\u005Cu007F'} through {@code '\u005Cu009F'}
+ * </ul>
+ *
+ * <li>all characters that have the {@code FORMAT} general
+ * category value
+ * </ul>
+ *
+ * <p><b>Note:</b> This method cannot handle <a
+ * href="#supplementary"> supplementary characters</a>. To support
+ * all Unicode characters, including supplementary characters, use
+ * the {@link #isIdentifierIgnorable(int)} method.
+ *
+ * @param ch the character to be tested.
+ * @return {@code true} if the character is an ignorable control
+ * character that may be part of a Java or Unicode identifier;
+ * {@code false} otherwise.
+ * @see Character#isJavaIdentifierPart(char)
+ * @see Character#isUnicodeIdentifierPart(char)
+ * @since 1.1
+ */
+ public static boolean isIdentifierIgnorable(char ch) {
+ return isIdentifierIgnorable((int)ch);
+ }
+
+ /**
+ * Determines if the specified character (Unicode code point) should be regarded as
+ * an ignorable character in a Java identifier or a Unicode identifier.
+ * <p>
+ * The following Unicode characters are ignorable in a Java identifier
+ * or a Unicode identifier:
+ * <ul>
+ * <li>ISO control characters that are not whitespace
+ * <ul>
+ * <li>{@code '\u005Cu0000'} through {@code '\u005Cu0008'}
+ * <li>{@code '\u005Cu000E'} through {@code '\u005Cu001B'}
+ * <li>{@code '\u005Cu007F'} through {@code '\u005Cu009F'}
+ * </ul>
+ *
+ * <li>all characters that have the {@code FORMAT} general
+ * category value
+ * </ul>
+ *
+ * @param codePoint the character (Unicode code point) to be tested.
+ * @return {@code true} if the character is an ignorable control
+ * character that may be part of a Java or Unicode identifier;
+ * {@code false} otherwise.
+ * @see Character#isJavaIdentifierPart(int)
+ * @see Character#isUnicodeIdentifierPart(int)
+ * @since 1.5
+ */
+ // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+ /*
+ public static boolean isIdentifierIgnorable(int codePoint) {
+ return CharacterData.of(codePoint).isIdentifierIgnorable(codePoint);
+ }
+ */
+ public static boolean isIdentifierIgnorable(int codePoint) {
+ return isIdentifierIgnorableImpl(codePoint);
+ }
+
+ @FastNative
+ static native boolean isIdentifierIgnorableImpl(int codePoint);
+ // END Android-changed: Reimplement methods natively on top of ICU4C.
+
+ /**
+ * Converts the character argument to lowercase using case
+ * mapping information from the UnicodeData file.
+ * <p>
+ * Note that
+ * {@code Character.isLowerCase(Character.toLowerCase(ch))}
+ * does not always return {@code true} for some ranges of
+ * characters, particularly those that are symbols or ideographs.
+ *
+ * <p>In general, {@link String#toLowerCase()} should be used to map
+ * characters to lowercase. {@code String} case mapping methods
+ * have several benefits over {@code Character} case mapping methods.
+ * {@code String} case mapping methods can perform locale-sensitive
+ * mappings, context-sensitive mappings, and 1:M character mappings, whereas
+ * the {@code Character} case mapping methods cannot.
+ *
+ * <p><b>Note:</b> This method cannot handle <a
+ * href="#supplementary"> supplementary characters</a>. To support
+ * all Unicode characters, including supplementary characters, use
+ * the {@link #toLowerCase(int)} method.
+ *
+ * @param ch the character to be converted.
+ * @return the lowercase equivalent of the character, if any;
+ * otherwise, the character itself.
+ * @see Character#isLowerCase(char)
+ * @see String#toLowerCase()
+ */
+ public static char toLowerCase(char ch) {
+ return (char)toLowerCase((int)ch);
+ }
+
+ /**
+ * Converts the character (Unicode code point) argument to
+ * lowercase using case mapping information from the UnicodeData
+ * file.
+ *
+ * <p> Note that
+ * {@code Character.isLowerCase(Character.toLowerCase(codePoint))}
+ * does not always return {@code true} for some ranges of
+ * characters, particularly those that are symbols or ideographs.
+ *
+ * <p>In general, {@link String#toLowerCase()} should be used to map
+ * characters to lowercase. {@code String} case mapping methods
+ * have several benefits over {@code Character} case mapping methods.
+ * {@code String} case mapping methods can perform locale-sensitive
+ * mappings, context-sensitive mappings, and 1:M character mappings, whereas
+ * the {@code Character} case mapping methods cannot.
+ *
+ * @param codePoint the character (Unicode code point) to be converted.
+ * @return the lowercase equivalent of the character (Unicode code
+ * point), if any; otherwise, the character itself.
+ * @see Character#isLowerCase(int)
+ * @see String#toLowerCase()
+ *
+ * @since 1.5
+ */
+ // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+ /*
+ public static int toLowerCase(int codePoint) {
+ return CharacterData.of(codePoint).toLowerCase(codePoint);
+ }
+ */
+ public static int toLowerCase(int codePoint) {
+ if (codePoint >= 'A' && codePoint <= 'Z') {
+ return codePoint + ('a' - 'A');
+ }
+
+ // All ASCII codepoints except the ones above remain unchanged.
+ if (codePoint < 0x80) {
+ return codePoint;
+ }
+
+ return toLowerCaseImpl(codePoint);
+ }
+
+ @FastNative
+ static native int toLowerCaseImpl(int codePoint);
+ // END Android-changed: Reimplement methods natively on top of ICU4C.
+
+ /**
+ * Converts the character argument to uppercase using case mapping
+ * information from the UnicodeData file.
+ * <p>
+ * Note that
+ * {@code Character.isUpperCase(Character.toUpperCase(ch))}
+ * does not always return {@code true} for some ranges of
+ * characters, particularly those that are symbols or ideographs.
+ *
+ * <p>In general, {@link String#toUpperCase()} should be used to map
+ * characters to uppercase. {@code String} case mapping methods
+ * have several benefits over {@code Character} case mapping methods.
+ * {@code String} case mapping methods can perform locale-sensitive
+ * mappings, context-sensitive mappings, and 1:M character mappings, whereas
+ * the {@code Character} case mapping methods cannot.
+ *
+ * <p><b>Note:</b> This method cannot handle <a
+ * href="#supplementary"> supplementary characters</a>. To support
+ * all Unicode characters, including supplementary characters, use
+ * the {@link #toUpperCase(int)} method.
+ *
+ * @param ch the character to be converted.
+ * @return the uppercase equivalent of the character, if any;
+ * otherwise, the character itself.
+ * @see Character#isUpperCase(char)
+ * @see String#toUpperCase()
+ */
+ public static char toUpperCase(char ch) {
+ return (char)toUpperCase((int)ch);
+ }
+
+ /**
+ * Converts the character (Unicode code point) argument to
+ * uppercase using case mapping information from the UnicodeData
+ * file.
+ *
+ * <p>Note that
+ * {@code Character.isUpperCase(Character.toUpperCase(codePoint))}
+ * does not always return {@code true} for some ranges of
+ * characters, particularly those that are symbols or ideographs.
+ *
+ * <p>In general, {@link String#toUpperCase()} should be used to map
+ * characters to uppercase. {@code String} case mapping methods
+ * have several benefits over {@code Character} case mapping methods.
+ * {@code String} case mapping methods can perform locale-sensitive
+ * mappings, context-sensitive mappings, and 1:M character mappings, whereas
+ * the {@code Character} case mapping methods cannot.
+ *
+ * @param codePoint the character (Unicode code point) to be converted.
+ * @return the uppercase equivalent of the character, if any;
+ * otherwise, the character itself.
+ * @see Character#isUpperCase(int)
+ * @see String#toUpperCase()
+ *
+ * @since 1.5
+ */
+ // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+ /*
+ public static int toUpperCase(int codePoint) {
+ return CharacterData.of(codePoint).toUpperCase(codePoint);
+ }
+ */
+ public static int toUpperCase(int codePoint) {
+ if (codePoint >= 'a' && codePoint <= 'z') {
+ return codePoint - ('a' - 'A');
+ }
+
+ // All ASCII codepoints except the ones above remain unchanged.
+ if (codePoint < 0x80) {
+ return codePoint;
+ }
+
+ return toUpperCaseImpl(codePoint);
+ }
+
+ @FastNative
+ static native int toUpperCaseImpl(int codePoint);
+ // END Android-changed: Reimplement methods natively on top of ICU4C.
+
+ /**
+ * Converts the character argument to titlecase using case mapping
+ * information from the UnicodeData file. If a character has no
+ * explicit titlecase mapping and is not itself a titlecase char
+ * according to UnicodeData, then the uppercase mapping is
+ * returned as an equivalent titlecase mapping. If the
+ * {@code char} argument is already a titlecase
+ * {@code char}, the same {@code char} value will be
+ * returned.
+ * <p>
+ * Note that
+ * {@code Character.isTitleCase(Character.toTitleCase(ch))}
+ * does not always return {@code true} for some ranges of
+ * characters.
+ *
+ * <p><b>Note:</b> This method cannot handle <a
+ * href="#supplementary"> supplementary characters</a>. To support
+ * all Unicode characters, including supplementary characters, use
+ * the {@link #toTitleCase(int)} method.
+ *
+ * @param ch the character to be converted.
+ * @return the titlecase equivalent of the character, if any;
+ * otherwise, the character itself.
+ * @see Character#isTitleCase(char)
+ * @see Character#toLowerCase(char)
+ * @see Character#toUpperCase(char)
+ * @since 1.0.2
+ */
+ public static char toTitleCase(char ch) {
+ return (char)toTitleCase((int)ch);
+ }
+
+ /**
+ * Converts the character (Unicode code point) argument to titlecase using case mapping
+ * information from the UnicodeData file. If a character has no
+ * explicit titlecase mapping and is not itself a titlecase char
+ * according to UnicodeData, then the uppercase mapping is
+ * returned as an equivalent titlecase mapping. If the
+ * character argument is already a titlecase
+ * character, the same character value will be
+ * returned.
+ *
+ * <p>Note that
+ * {@code Character.isTitleCase(Character.toTitleCase(codePoint))}
+ * does not always return {@code true} for some ranges of
+ * characters.
+ *
+ * @param codePoint the character (Unicode code point) to be converted.
+ * @return the titlecase equivalent of the character, if any;
+ * otherwise, the character itself.
+ * @see Character#isTitleCase(int)
+ * @see Character#toLowerCase(int)
+ * @see Character#toUpperCase(int)
+ * @since 1.5
+ */
+ // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+ /*
+ public static int toTitleCase(int codePoint) {
+ return CharacterData.of(codePoint).toTitleCase(codePoint);
+ }
+ */
+ public static int toTitleCase(int codePoint) {
+ return toTitleCaseImpl(codePoint);
+ }
+
+ @FastNative
+ static native int toTitleCaseImpl(int codePoint);
+ // END Android-changed: Reimplement methods natively on top of ICU4C.
+
+ /**
+ * Returns the numeric value of the character {@code ch} in the
+ * specified radix.
+ * <p>
+ * If the radix is not in the range {@code MIN_RADIX} ≤
+ * {@code radix} ≤ {@code MAX_RADIX} or if the
+ * value of {@code ch} is not a valid digit in the specified
+ * radix, {@code -1} is returned. A character is a valid digit
+ * if at least one of the following is true:
+ * <ul>
+ * <li>The method {@code isDigit} is {@code true} of the character
+ * and the Unicode decimal digit value of the character (or its
+ * single-character decomposition) is less than the specified radix.
+ * In this case the decimal digit value is returned.
+ * <li>The character is one of the uppercase Latin letters
+ * {@code 'A'} through {@code 'Z'} and its code is less than
+ * {@code radix + 'A' - 10}.
+ * In this case, {@code ch - 'A' + 10}
+ * is returned.
+ * <li>The character is one of the lowercase Latin letters
+ * {@code 'a'} through {@code 'z'} and its code is less than
+ * {@code radix + 'a' - 10}.
+ * In this case, {@code ch - 'a' + 10}
+ * is returned.
+ * <li>The character is one of the fullwidth uppercase Latin letters A
+ * ({@code '\u005CuFF21'}) through Z ({@code '\u005CuFF3A'})
+ * and its code is less than
+ * {@code radix + '\u005CuFF21' - 10}.
+ * In this case, {@code ch - '\u005CuFF21' + 10}
+ * is returned.
+ * <li>The character is one of the fullwidth lowercase Latin letters a
+ * ({@code '\u005CuFF41'}) through z ({@code '\u005CuFF5A'})
+ * and its code is less than
+ * {@code radix + '\u005CuFF41' - 10}.
+ * In this case, {@code ch - '\u005CuFF41' + 10}
+ * is returned.
+ * </ul>
+ *
+ * <p><b>Note:</b> This method cannot handle <a
+ * href="#supplementary"> supplementary characters</a>. To support
+ * all Unicode characters, including supplementary characters, use
+ * the {@link #digit(int, int)} method.
+ *
+ * @param ch the character to be converted.
+ * @param radix the radix.
+ * @return the numeric value represented by the character in the
+ * specified radix.
+ * @see Character#forDigit(int, int)
+ * @see Character#isDigit(char)
+ */
+ public static int digit(char ch, int radix) {
+ return digit((int)ch, radix);
+ }
+
+ /**
+ * Returns the numeric value of the specified character (Unicode
+ * code point) in the specified radix.
+ *
+ * <p>If the radix is not in the range {@code MIN_RADIX} ≤
+ * {@code radix} ≤ {@code MAX_RADIX} or if the
+ * character is not a valid digit in the specified
+ * radix, {@code -1} is returned. A character is a valid digit
+ * if at least one of the following is true:
+ * <ul>
+ * <li>The method {@link #isDigit(int) isDigit(codePoint)} is {@code true} of the character
+ * and the Unicode decimal digit value of the character (or its
+ * single-character decomposition) is less than the specified radix.
+ * In this case the decimal digit value is returned.
+ * <li>The character is one of the uppercase Latin letters
+ * {@code 'A'} through {@code 'Z'} and its code is less than
+ * {@code radix + 'A' - 10}.
+ * In this case, {@code codePoint - 'A' + 10}
+ * is returned.
+ * <li>The character is one of the lowercase Latin letters
+ * {@code 'a'} through {@code 'z'} and its code is less than
+ * {@code radix + 'a' - 10}.
+ * In this case, {@code codePoint - 'a' + 10}
+ * is returned.
+ * <li>The character is one of the fullwidth uppercase Latin letters A
+ * ({@code '\u005CuFF21'}) through Z ({@code '\u005CuFF3A'})
+ * and its code is less than
+ * {@code radix + '\u005CuFF21' - 10}.
+ * In this case,
+ * {@code codePoint - '\u005CuFF21' + 10}
+ * is returned.
+ * <li>The character is one of the fullwidth lowercase Latin letters a
+ * ({@code '\u005CuFF41'}) through z ({@code '\u005CuFF5A'})
+ * and its code is less than
+ * {@code radix + '\u005CuFF41'- 10}.
+ * In this case,
+ * {@code codePoint - '\u005CuFF41' + 10}
+ * is returned.
+ * </ul>
+ *
+ * @param codePoint the character (Unicode code point) to be converted.
+ * @param radix the radix.
+ * @return the numeric value represented by the character in the
+ * specified radix.
+ * @see Character#forDigit(int, int)
+ * @see Character#isDigit(int)
+ * @since 1.5
+ */
+ // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+ /*
+ public static int digit(int codePoint, int radix) {
+ return CharacterData.of(codePoint).digit(codePoint, radix);
+ }
+ */
+ public static int digit(int codePoint, int radix) {
+ if (radix < MIN_RADIX || radix > MAX_RADIX) {
+ return -1;
+ }
+ if (codePoint < 128) {
+ // Optimized for ASCII
+ int result = -1;
+ if ('0' <= codePoint && codePoint <= '9') {
+ result = codePoint - '0';
+ } else if ('a' <= codePoint && codePoint <= 'z') {
+ result = 10 + (codePoint - 'a');
+ } else if ('A' <= codePoint && codePoint <= 'Z') {
+ result = 10 + (codePoint - 'A');
+ }
+ return result < radix ? result : -1;
+ }
+ return digitImpl(codePoint, radix);
+ }
+
+ @FastNative
+ native static int digitImpl(int codePoint, int radix);
+ // END Android-changed: Reimplement methods natively on top of ICU4C.
+
+ /**
+ * Returns the {@code int} value that the specified Unicode
+ * character represents. For example, the character
+ * {@code '\u005Cu216C'} (the roman numeral fifty) will return
+ * an int with a value of 50.
+ * <p>
+ * The letters A-Z in their uppercase ({@code '\u005Cu0041'} through
+ * {@code '\u005Cu005A'}), lowercase
+ * ({@code '\u005Cu0061'} through {@code '\u005Cu007A'}), and
+ * full width variant ({@code '\u005CuFF21'} through
+ * {@code '\u005CuFF3A'} and {@code '\u005CuFF41'} through
+ * {@code '\u005CuFF5A'}) forms have numeric values from 10
+ * through 35. This is independent of the Unicode specification,
+ * which does not assign numeric values to these {@code char}
+ * values.
+ * <p>
+ * If the character does not have a numeric value, then -1 is returned.
+ * If the character has a numeric value that cannot be represented as a
+ * nonnegative integer (for example, a fractional value), then -2
+ * is returned.
+ *
+ * <p><b>Note:</b> This method cannot handle <a
+ * href="#supplementary"> supplementary characters</a>. To support
+ * all Unicode characters, including supplementary characters, use
+ * the {@link #getNumericValue(int)} method.
+ *
+ * @param ch the character to be converted.
+ * @return the numeric value of the character, as a nonnegative {@code int}
+ * value; -2 if the character has a numeric value that is not a
+ * nonnegative integer; -1 if the character has no numeric value.
+ * @see Character#forDigit(int, int)
+ * @see Character#isDigit(char)
+ * @since 1.1
+ */
+ public static int getNumericValue(char ch) {
+ return getNumericValue((int)ch);
+ }
+
+ /**
+ * Returns the {@code int} value that the specified
+ * character (Unicode code point) represents. For example, the character
+ * {@code '\u005Cu216C'} (the Roman numeral fifty) will return
+ * an {@code int} with a value of 50.
+ * <p>
+ * The letters A-Z in their uppercase ({@code '\u005Cu0041'} through
+ * {@code '\u005Cu005A'}), lowercase
+ * ({@code '\u005Cu0061'} through {@code '\u005Cu007A'}), and
+ * full width variant ({@code '\u005CuFF21'} through
+ * {@code '\u005CuFF3A'} and {@code '\u005CuFF41'} through
+ * {@code '\u005CuFF5A'}) forms have numeric values from 10
+ * through 35. This is independent of the Unicode specification,
+ * which does not assign numeric values to these {@code char}
+ * values.
+ * <p>
+ * If the character does not have a numeric value, then -1 is returned.
+ * If the character has a numeric value that cannot be represented as a
+ * nonnegative integer (for example, a fractional value), then -2
+ * is returned.
+ *
+ * @param codePoint the character (Unicode code point) to be converted.
+ * @return the numeric value of the character, as a nonnegative {@code int}
+ * value; -2 if the character has a numeric value that is not a
+ * nonnegative integer; -1 if the character has no numeric value.
+ * @see Character#forDigit(int, int)
+ * @see Character#isDigit(int)
+ * @since 1.5
+ */
+ // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+ /*
+ public static int getNumericValue(int codePoint) {
+ return CharacterData.of(codePoint).getNumericValue(codePoint);
+ }
+ */
+ public static int getNumericValue(int codePoint) {
+ // This is both an optimization and papers over differences between Java and ICU.
+ if (codePoint < 128) {
+ if (codePoint >= '0' && codePoint <= '9') {
+ return codePoint - '0';
+ }
+ if (codePoint >= 'a' && codePoint <= 'z') {
+ return codePoint - ('a' - 10);
+ }
+ if (codePoint >= 'A' && codePoint <= 'Z') {
+ return codePoint - ('A' - 10);
+ }
+ return -1;
+ }
+ // Full-width uppercase A-Z.
+ if (codePoint >= 0xff21 && codePoint <= 0xff3a) {
+ return codePoint - 0xff17;
+ }
+ // Full-width lowercase a-z.
+ if (codePoint >= 0xff41 && codePoint <= 0xff5a) {
+ return codePoint - 0xff37;
+ }
+ return getNumericValueImpl(codePoint);
+ }
+
+ @FastNative
+ native static int getNumericValueImpl(int codePoint);
+ // END Android-changed: Reimplement methods natively on top of ICU4C.
+
+ /**
+ * Determines if the specified character is ISO-LATIN-1 white space.
+ * This method returns {@code true} for the following five
+ * characters only:
+ * <table summary="truechars">
+ * <tr><td>{@code '\t'}</td> <td>{@code U+0009}</td>
+ * <td>{@code HORIZONTAL TABULATION}</td></tr>
+ * <tr><td>{@code '\n'}</td> <td>{@code U+000A}</td>
+ * <td>{@code NEW LINE}</td></tr>
+ * <tr><td>{@code '\f'}</td> <td>{@code U+000C}</td>
+ * <td>{@code FORM FEED}</td></tr>
+ * <tr><td>{@code '\r'}</td> <td>{@code U+000D}</td>
+ * <td>{@code CARRIAGE RETURN}</td></tr>
+ * <tr><td>{@code ' '}</td> <td>{@code U+0020}</td>
+ * <td>{@code SPACE}</td></tr>
+ * </table>
+ *
+ * @param ch the character to be tested.
+ * @return {@code true} if the character is ISO-LATIN-1 white
+ * space; {@code false} otherwise.
+ * @see Character#isSpaceChar(char)
+ * @see Character#isWhitespace(char)
+ * @deprecated Replaced by isWhitespace(char).
+ */
+ @Deprecated
+ public static boolean isSpace(char ch) {
+ return (ch <= 0x0020) &&
+ (((((1L << 0x0009) |
+ (1L << 0x000A) |
+ (1L << 0x000C) |
+ (1L << 0x000D) |
+ (1L << 0x0020)) >> ch) & 1L) != 0);
+ }
+
+
+ /**
+ * Determines if the specified character is a Unicode space character.
+ * A character is considered to be a space character if and only if
+ * it is specified to be a space character by the Unicode Standard. This
+ * method returns true if the character's general category type is any of
+ * the following:
+ * <ul>
+ * <li> {@code SPACE_SEPARATOR}
+ * <li> {@code LINE_SEPARATOR}
+ * <li> {@code PARAGRAPH_SEPARATOR}
+ * </ul>
+ *
+ * <p><b>Note:</b> This method cannot handle <a
+ * href="#supplementary"> supplementary characters</a>. To support
+ * all Unicode characters, including supplementary characters, use
+ * the {@link #isSpaceChar(int)} method.
+ *
+ * @param ch the character to be tested.
+ * @return {@code true} if the character is a space character;
+ * {@code false} otherwise.
+ * @see Character#isWhitespace(char)
+ * @since 1.1
+ */
+ public static boolean isSpaceChar(char ch) {
+ return isSpaceChar((int)ch);
+ }
+
+ /**
+ * Determines if the specified character (Unicode code point) is a
+ * Unicode space character. A character is considered to be a
+ * space character if and only if it is specified to be a space
+ * character by the Unicode Standard. This method returns true if
+ * the character's general category type is any of the following:
+ *
+ * <ul>
+ * <li> {@link #SPACE_SEPARATOR}
+ * <li> {@link #LINE_SEPARATOR}
+ * <li> {@link #PARAGRAPH_SEPARATOR}
+ * </ul>
+ *
+ * @param codePoint the character (Unicode code point) to be tested.
+ * @return {@code true} if the character is a space character;
+ * {@code false} otherwise.
+ * @see Character#isWhitespace(int)
+ * @since 1.5
+ */
+ // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+ /*
+ public static boolean isSpaceChar(int codePoint) {
+ return ((((1 << Character.SPACE_SEPARATOR) |
+ (1 << Character.LINE_SEPARATOR) |
+ (1 << Character.PARAGRAPH_SEPARATOR)) >> getType(codePoint)) & 1)
+ != 0;
+ }
+ */
+ public static boolean isSpaceChar(int codePoint) {
+ // We don't just call into icu4c because of the JNI overhead. Ideally we'd fix that.
+ // SPACE or NO-BREAK SPACE?
+ if (codePoint == 0x20 || codePoint == 0xa0) {
+ return true;
+ }
+ if (codePoint < 0x1000) {
+ return false;
+ }
+ // OGHAM SPACE MARK or MONGOLIAN VOWEL SEPARATOR?
+ if (codePoint == 0x1680 || codePoint == 0x180e) {
+ return true;
+ }
+ if (codePoint < 0x2000) {
+ return false;
+ }
+ if (codePoint <= 0xffff) {
+ // Other whitespace from General Punctuation...
+ return codePoint <= 0x200a || codePoint == 0x2028 || codePoint == 0x2029 || codePoint == 0x202f || codePoint == 0x205f ||
+ codePoint == 0x3000; // ...or CJK Symbols and Punctuation?
+ }
+ // Let icu4c worry about non-BMP code points.
+ return isSpaceCharImpl(codePoint);
+ }
+
+ @FastNative
+ static native boolean isSpaceCharImpl(int codePoint);
+ // END Android-changed: Reimplement methods natively on top of ICU4C.
+
+ /**
+ * Determines if the specified character is white space according to Java.
+ * A character is a Java whitespace character if and only if it satisfies
+ * one of the following criteria:
+ * <ul>
+ * <li> It is a Unicode space character ({@code SPACE_SEPARATOR},
+ * {@code LINE_SEPARATOR}, or {@code PARAGRAPH_SEPARATOR})
+ * but is not also a non-breaking space ({@code '\u005Cu00A0'},
+ * {@code '\u005Cu2007'}, {@code '\u005Cu202F'}).
+ * <li> It is {@code '\u005Ct'}, U+0009 HORIZONTAL TABULATION.
+ * <li> It is {@code '\u005Cn'}, U+000A LINE FEED.
+ * <li> It is {@code '\u005Cu000B'}, U+000B VERTICAL TABULATION.
+ * <li> It is {@code '\u005Cf'}, U+000C FORM FEED.
+ * <li> It is {@code '\u005Cr'}, U+000D CARRIAGE RETURN.
+ * <li> It is {@code '\u005Cu001C'}, U+001C FILE SEPARATOR.
+ * <li> It is {@code '\u005Cu001D'}, U+001D GROUP SEPARATOR.
+ * <li> It is {@code '\u005Cu001E'}, U+001E RECORD SEPARATOR.
+ * <li> It is {@code '\u005Cu001F'}, U+001F UNIT SEPARATOR.
+ * </ul>
+ *
+ * <p><b>Note:</b> This method cannot handle <a
+ * href="#supplementary"> supplementary characters</a>. To support
+ * all Unicode characters, including supplementary characters, use
+ * the {@link #isWhitespace(int)} method.
+ *
+ * @param ch the character to be tested.
+ * @return {@code true} if the character is a Java whitespace
+ * character; {@code false} otherwise.
+ * @see Character#isSpaceChar(char)
+ * @since 1.1
+ */
+ public static boolean isWhitespace(char ch) {
+ return isWhitespace((int)ch);
+ }
+
+ /**
+ * Determines if the specified character (Unicode code point) is
+ * white space according to Java. A character is a Java
+ * whitespace character if and only if it satisfies one of the
+ * following criteria:
+ * <ul>
+ * <li> It is a Unicode space character ({@link #SPACE_SEPARATOR},
+ * {@link #LINE_SEPARATOR}, or {@link #PARAGRAPH_SEPARATOR})
+ * but is not also a non-breaking space ({@code '\u005Cu00A0'},
+ * {@code '\u005Cu2007'}, {@code '\u005Cu202F'}).
+ * <li> It is {@code '\u005Ct'}, U+0009 HORIZONTAL TABULATION.
+ * <li> It is {@code '\u005Cn'}, U+000A LINE FEED.
+ * <li> It is {@code '\u005Cu000B'}, U+000B VERTICAL TABULATION.
+ * <li> It is {@code '\u005Cf'}, U+000C FORM FEED.
+ * <li> It is {@code '\u005Cr'}, U+000D CARRIAGE RETURN.
+ * <li> It is {@code '\u005Cu001C'}, U+001C FILE SEPARATOR.
+ * <li> It is {@code '\u005Cu001D'}, U+001D GROUP SEPARATOR.
+ * <li> It is {@code '\u005Cu001E'}, U+001E RECORD SEPARATOR.
+ * <li> It is {@code '\u005Cu001F'}, U+001F UNIT SEPARATOR.
+ * </ul>
+ * <p>
+ *
+ * @param codePoint the character (Unicode code point) to be tested.
+ * @return {@code true} if the character is a Java whitespace
+ * character; {@code false} otherwise.
+ * @see Character#isSpaceChar(int)
+ * @since 1.5
+ */
+ // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+ /*
+ public static boolean isWhitespace(int codePoint) {
+ return CharacterData.of(codePoint).isWhitespace(codePoint);
+ }
+ */
+ public static boolean isWhitespace(int codePoint) {
+ // We don't just call into icu4c because of the JNI overhead. Ideally we'd fix that.
+ // Any ASCII whitespace character?
+ if ((codePoint >= 0x1c && codePoint <= 0x20) || (codePoint >= 0x09 && codePoint <= 0x0d)) {
+ return true;
+ }
+ if (codePoint < 0x1000) {
+ return false;
+ }
+ // OGHAM SPACE MARK or MONGOLIAN VOWEL SEPARATOR?
+ if (codePoint == 0x1680 || codePoint == 0x180e) {
+ return true;
+ }
+ if (codePoint < 0x2000) {
+ return false;
+ }
+ // Exclude General Punctuation's non-breaking spaces (which includes FIGURE SPACE).
+ if (codePoint == 0x2007 || codePoint == 0x202f) {
+ return false;
+ }
+ if (codePoint <= 0xffff) {
+ // Other whitespace from General Punctuation...
+ return codePoint <= 0x200a || codePoint == 0x2028 || codePoint == 0x2029 || codePoint == 0x205f ||
+ codePoint == 0x3000; // ...or CJK Symbols and Punctuation?
+ }
+ // Let icu4c worry about non-BMP code points.
+ return isWhitespaceImpl(codePoint);
+ }
+
+ @FastNative
+ native static boolean isWhitespaceImpl(int codePoint);
+ // END Android-changed: Reimplement methods natively on top of ICU4C.
+
+ /**
+ * Determines if the specified character is an ISO control
+ * character. A character is considered to be an ISO control
+ * character if its code is in the range {@code '\u005Cu0000'}
+ * through {@code '\u005Cu001F'} or in the range
+ * {@code '\u005Cu007F'} through {@code '\u005Cu009F'}.
+ *
+ * <p><b>Note:</b> This method cannot handle <a
+ * href="#supplementary"> supplementary characters</a>. To support
+ * all Unicode characters, including supplementary characters, use
+ * the {@link #isISOControl(int)} method.
+ *
+ * @param ch the character to be tested.
+ * @return {@code true} if the character is an ISO control character;
+ * {@code false} otherwise.
+ *
+ * @see Character#isSpaceChar(char)
+ * @see Character#isWhitespace(char)
+ * @since 1.1
+ */
+ public static boolean isISOControl(char ch) {
+ return isISOControl((int)ch);
+ }
+
+ /**
+ * Determines if the referenced character (Unicode code point) is an ISO control
+ * character. A character is considered to be an ISO control
+ * character if its code is in the range {@code '\u005Cu0000'}
+ * through {@code '\u005Cu001F'} or in the range
+ * {@code '\u005Cu007F'} through {@code '\u005Cu009F'}.
+ *
+ * @param codePoint the character (Unicode code point) to be tested.
+ * @return {@code true} if the character is an ISO control character;
+ * {@code false} otherwise.
+ * @see Character#isSpaceChar(int)
+ * @see Character#isWhitespace(int)
+ * @since 1.5
+ */
+ public static boolean isISOControl(int codePoint) {
+ // Optimized form of:
+ // (codePoint >= 0x00 && codePoint <= 0x1F) ||
+ // (codePoint >= 0x7F && codePoint <= 0x9F);
+ return codePoint <= 0x9F &&
+ (codePoint >= 0x7F || (codePoint >>> 5 == 0));
+ }
+
+ /**
+ * Returns a value indicating a character's general category.
+ *
+ * <p><b>Note:</b> This method cannot handle <a
+ * href="#supplementary"> supplementary characters</a>. To support
+ * all Unicode characters, including supplementary characters, use
+ * the {@link #getType(int)} method.
+ *
+ * @param ch the character to be tested.
+ * @return a value of type {@code int} representing the
+ * character's general category.
+ * @see Character#COMBINING_SPACING_MARK
+ * @see Character#CONNECTOR_PUNCTUATION
+ * @see Character#CONTROL
+ * @see Character#CURRENCY_SYMBOL
+ * @see Character#DASH_PUNCTUATION
+ * @see Character#DECIMAL_DIGIT_NUMBER
+ * @see Character#ENCLOSING_MARK
+ * @see Character#END_PUNCTUATION
+ * @see Character#FINAL_QUOTE_PUNCTUATION
+ * @see Character#FORMAT
+ * @see Character#INITIAL_QUOTE_PUNCTUATION
+ * @see Character#LETTER_NUMBER
+ * @see Character#LINE_SEPARATOR
+ * @see Character#LOWERCASE_LETTER
+ * @see Character#MATH_SYMBOL
+ * @see Character#MODIFIER_LETTER
+ * @see Character#MODIFIER_SYMBOL
+ * @see Character#NON_SPACING_MARK
+ * @see Character#OTHER_LETTER
+ * @see Character#OTHER_NUMBER
+ * @see Character#OTHER_PUNCTUATION
+ * @see Character#OTHER_SYMBOL
+ * @see Character#PARAGRAPH_SEPARATOR
+ * @see Character#PRIVATE_USE
+ * @see Character#SPACE_SEPARATOR
+ * @see Character#START_PUNCTUATION
+ * @see Character#SURROGATE
+ * @see Character#TITLECASE_LETTER
+ * @see Character#UNASSIGNED
+ * @see Character#UPPERCASE_LETTER
+ * @since 1.1
+ */
+ public static int getType(char ch) {
+ return getType((int)ch);
+ }
+
+ /**
+ * Returns a value indicating a character's general category.
+ *
+ * @param codePoint the character (Unicode code point) to be tested.
+ * @return a value of type {@code int} representing the
+ * character's general category.
+ * @see Character#COMBINING_SPACING_MARK COMBINING_SPACING_MARK
+ * @see Character#CONNECTOR_PUNCTUATION CONNECTOR_PUNCTUATION
+ * @see Character#CONTROL CONTROL
+ * @see Character#CURRENCY_SYMBOL CURRENCY_SYMBOL
+ * @see Character#DASH_PUNCTUATION DASH_PUNCTUATION
+ * @see Character#DECIMAL_DIGIT_NUMBER DECIMAL_DIGIT_NUMBER
+ * @see Character#ENCLOSING_MARK ENCLOSING_MARK
+ * @see Character#END_PUNCTUATION END_PUNCTUATION
+ * @see Character#FINAL_QUOTE_PUNCTUATION FINAL_QUOTE_PUNCTUATION
+ * @see Character#FORMAT FORMAT
+ * @see Character#INITIAL_QUOTE_PUNCTUATION INITIAL_QUOTE_PUNCTUATION
+ * @see Character#LETTER_NUMBER LETTER_NUMBER
+ * @see Character#LINE_SEPARATOR LINE_SEPARATOR
+ * @see Character#LOWERCASE_LETTER LOWERCASE_LETTER
+ * @see Character#MATH_SYMBOL MATH_SYMBOL
+ * @see Character#MODIFIER_LETTER MODIFIER_LETTER
+ * @see Character#MODIFIER_SYMBOL MODIFIER_SYMBOL
+ * @see Character#NON_SPACING_MARK NON_SPACING_MARK
+ * @see Character#OTHER_LETTER OTHER_LETTER
+ * @see Character#OTHER_NUMBER OTHER_NUMBER
+ * @see Character#OTHER_PUNCTUATION OTHER_PUNCTUATION
+ * @see Character#OTHER_SYMBOL OTHER_SYMBOL
+ * @see Character#PARAGRAPH_SEPARATOR PARAGRAPH_SEPARATOR
+ * @see Character#PRIVATE_USE PRIVATE_USE
+ * @see Character#SPACE_SEPARATOR SPACE_SEPARATOR
+ * @see Character#START_PUNCTUATION START_PUNCTUATION
+ * @see Character#SURROGATE SURROGATE
+ * @see Character#TITLECASE_LETTER TITLECASE_LETTER
+ * @see Character#UNASSIGNED UNASSIGNED
+ * @see Character#UPPERCASE_LETTER UPPERCASE_LETTER
+ * @since 1.5
+ */
+ // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+ /*
+ public static int getType(int codePoint) {
+ return CharacterData.of(codePoint).getType(codePoint);
+ }
+ */
+ public static int getType(int codePoint) {
+ int type = getTypeImpl(codePoint);
+ // The type values returned by ICU are not RI-compatible. The RI skips the value 17.
+ if (type <= Character.FORMAT) {
+ return type;
+ }
+ return (type + 1);
+ }
+
+ @FastNative
+ static native int getTypeImpl(int codePoint);
+ // END Android-changed: Reimplement methods natively on top of ICU4C.
+
+ /**
+ * Determines the character representation for a specific digit in
+ * the specified radix. If the value of {@code radix} is not a
+ * valid radix, or the value of {@code digit} is not a valid
+ * digit in the specified radix, the null character
+ * ({@code '\u005Cu0000'}) is returned.
+ * <p>
+ * The {@code radix} argument is valid if it is greater than or
+ * equal to {@code MIN_RADIX} and less than or equal to
+ * {@code MAX_RADIX}. The {@code digit} argument is valid if
+ * {@code 0 <= digit < radix}.
+ * <p>
+ * If the digit is less than 10, then
+ * {@code '0' + digit} is returned. Otherwise, the value
+ * {@code 'a' + digit - 10} is returned.
+ *
+ * @param digit the number to convert to a character.
+ * @param radix the radix.
+ * @return the {@code char} representation of the specified digit
+ * in the specified radix.
+ * @see Character#MIN_RADIX
+ * @see Character#MAX_RADIX
+ * @see Character#digit(char, int)
+ */
+ public static char forDigit(int digit, int radix) {
+ if ((digit >= radix) || (digit < 0)) {
+ return '\0';
+ }
+ if ((radix < Character.MIN_RADIX) || (radix > Character.MAX_RADIX)) {
+ return '\0';
+ }
+ if (digit < 10) {
+ return (char)('0' + digit);
+ }
+ return (char)('a' - 10 + digit);
+ }
+
+ /**
+ * Returns the Unicode directionality property for the given
+ * character. Character directionality is used to calculate the
+ * visual ordering of text. The directionality value of undefined
+ * {@code char} values is {@code DIRECTIONALITY_UNDEFINED}.
+ *
+ * <p><b>Note:</b> This method cannot handle <a
+ * href="#supplementary"> supplementary characters</a>. To support
+ * all Unicode characters, including supplementary characters, use
+ * the {@link #getDirectionality(int)} method.
+ *
+ * @param ch {@code char} for which the directionality property
+ * is requested.
+ * @return the directionality property of the {@code char} value.
+ *
+ * @see Character#DIRECTIONALITY_UNDEFINED
+ * @see Character#DIRECTIONALITY_LEFT_TO_RIGHT
+ * @see Character#DIRECTIONALITY_RIGHT_TO_LEFT
+ * @see Character#DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC
+ * @see Character#DIRECTIONALITY_EUROPEAN_NUMBER
+ * @see Character#DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR
+ * @see Character#DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR
+ * @see Character#DIRECTIONALITY_ARABIC_NUMBER
+ * @see Character#DIRECTIONALITY_COMMON_NUMBER_SEPARATOR
+ * @see Character#DIRECTIONALITY_NONSPACING_MARK
+ * @see Character#DIRECTIONALITY_BOUNDARY_NEUTRAL
+ * @see Character#DIRECTIONALITY_PARAGRAPH_SEPARATOR
+ * @see Character#DIRECTIONALITY_SEGMENT_SEPARATOR
+ * @see Character#DIRECTIONALITY_WHITESPACE
+ * @see Character#DIRECTIONALITY_OTHER_NEUTRALS
+ * @see Character#DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING
+ * @see Character#DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE
+ * @see Character#DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING
+ * @see Character#DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE
+ * @see Character#DIRECTIONALITY_POP_DIRECTIONAL_FORMAT
+ * @since 1.4
+ */
+ public static byte getDirectionality(char ch) {
+ return getDirectionality((int)ch);
+ }
+
+ /**
+ * Returns the Unicode directionality property for the given
+ * character (Unicode code point). Character directionality is
+ * used to calculate the visual ordering of text. The
+ * directionality value of undefined character is {@link
+ * #DIRECTIONALITY_UNDEFINED}.
+ *
+ * @param codePoint the character (Unicode code point) for which
+ * the directionality property is requested.
+ * @return the directionality property of the character.
+ *
+ * @see Character#DIRECTIONALITY_UNDEFINED DIRECTIONALITY_UNDEFINED
+ * @see Character#DIRECTIONALITY_LEFT_TO_RIGHT DIRECTIONALITY_LEFT_TO_RIGHT
+ * @see Character#DIRECTIONALITY_RIGHT_TO_LEFT DIRECTIONALITY_RIGHT_TO_LEFT
+ * @see Character#DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC
+ * @see Character#DIRECTIONALITY_EUROPEAN_NUMBER DIRECTIONALITY_EUROPEAN_NUMBER
+ * @see Character#DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR
+ * @see Character#DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR
+ * @see Character#DIRECTIONALITY_ARABIC_NUMBER DIRECTIONALITY_ARABIC_NUMBER
+ * @see Character#DIRECTIONALITY_COMMON_NUMBER_SEPARATOR DIRECTIONALITY_COMMON_NUMBER_SEPARATOR
+ * @see Character#DIRECTIONALITY_NONSPACING_MARK DIRECTIONALITY_NONSPACING_MARK
+ * @see Character#DIRECTIONALITY_BOUNDARY_NEUTRAL DIRECTIONALITY_BOUNDARY_NEUTRAL
+ * @see Character#DIRECTIONALITY_PARAGRAPH_SEPARATOR DIRECTIONALITY_PARAGRAPH_SEPARATOR
+ * @see Character#DIRECTIONALITY_SEGMENT_SEPARATOR DIRECTIONALITY_SEGMENT_SEPARATOR
+ * @see Character#DIRECTIONALITY_WHITESPACE DIRECTIONALITY_WHITESPACE
+ * @see Character#DIRECTIONALITY_OTHER_NEUTRALS DIRECTIONALITY_OTHER_NEUTRALS
+ * @see Character#DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING
+ * @see Character#DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE
+ * @see Character#DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING
+ * @see Character#DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE
+ * @see Character#DIRECTIONALITY_POP_DIRECTIONAL_FORMAT DIRECTIONALITY_POP_DIRECTIONAL_FORMAT
+ * @since 1.5
+ */
+ // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+ /*
+ public static byte getDirectionality(int codePoint) {
+ return CharacterData.of(codePoint).getDirectionality(codePoint);
+ }
+ */
+ public static byte getDirectionality(int codePoint) {
+ if (getType(codePoint) == Character.UNASSIGNED) {
+ return Character.DIRECTIONALITY_UNDEFINED;
+ }
+
+ byte directionality = getDirectionalityImpl(codePoint);
+ if (directionality >= 0 && directionality < DIRECTIONALITY.length) {
+ return DIRECTIONALITY[directionality];
+ }
+ return Character.DIRECTIONALITY_UNDEFINED;
+ }
+
+ @FastNative
+ native static byte getDirectionalityImpl(int codePoint);
+ // END Android-changed: Reimplement methods natively on top of ICU4C.
+
+ /**
+ * Determines whether the character is mirrored according to the
+ * Unicode specification. Mirrored characters should have their
+ * glyphs horizontally mirrored when displayed in text that is
+ * right-to-left. For example, {@code '\u005Cu0028'} LEFT
+ * PARENTHESIS is semantically defined to be an <i>opening
+ * parenthesis</i>. This will appear as a "(" in text that is
+ * left-to-right but as a ")" in text that is right-to-left.
+ *
+ * <p><b>Note:</b> This method cannot handle <a
+ * href="#supplementary"> supplementary characters</a>. To support
+ * all Unicode characters, including supplementary characters, use
+ * the {@link #isMirrored(int)} method.
+ *
+ * @param ch {@code char} for which the mirrored property is requested
+ * @return {@code true} if the char is mirrored, {@code false}
+ * if the {@code char} is not mirrored or is not defined.
+ * @since 1.4
+ */
+ public static boolean isMirrored(char ch) {
+ return isMirrored((int)ch);
+ }
+
+ /**
+ * Determines whether the specified character (Unicode code point)
+ * is mirrored according to the Unicode specification. Mirrored
+ * characters should have their glyphs horizontally mirrored when
+ * displayed in text that is right-to-left. For example,
+ * {@code '\u005Cu0028'} LEFT PARENTHESIS is semantically
+ * defined to be an <i>opening parenthesis</i>. This will appear
+ * as a "(" in text that is left-to-right but as a ")" in text
+ * that is right-to-left.
+ *
+ * @param codePoint the character (Unicode code point) to be tested.
+ * @return {@code true} if the character is mirrored, {@code false}
+ * if the character is not mirrored or is not defined.
+ * @since 1.5
+ */
+ // BEGIN Android-changed: Reimplement methods natively on top of ICU4C.
+ /*
+ public static boolean isMirrored(int codePoint) {
+ return CharacterData.of(codePoint).isMirrored(codePoint);
+ }
+ */
+ public static boolean isMirrored(int codePoint) {
+ return isMirroredImpl(codePoint);
+ }
+
+ @FastNative
+ native static boolean isMirroredImpl(int codePoint);
+ // END Android-changed: Reimplement methods natively on top of ICU4C.
+
+ /**
+ * Compares two {@code Character} objects numerically.
+ *
+ * @param anotherCharacter the {@code Character} to be compared.
+
+ * @return the value {@code 0} if the argument {@code Character}
+ * is equal to this {@code Character}; a value less than
+ * {@code 0} if this {@code Character} is numerically less
+ * than the {@code Character} argument; and a value greater than
+ * {@code 0} if this {@code Character} is numerically greater
+ * than the {@code Character} argument (unsigned comparison).
+ * Note that this is strictly a numerical comparison; it is not
+ * locale-dependent.
+ * @since 1.2
+ */
+ public int compareTo(Character anotherCharacter) {
+ return compare(this.value, anotherCharacter.value);
+ }
+
+ /**
+ * Compares two {@code char} values numerically.
+ * The value returned is identical to what would be returned by:
+ * <pre>
+ * Character.valueOf(x).compareTo(Character.valueOf(y))
+ * </pre>
+ *
+ * @param x the first {@code char} to compare
+ * @param y the second {@code char} to compare
+ * @return the value {@code 0} if {@code x == y};
+ * a value less than {@code 0} if {@code x < y}; and
+ * a value greater than {@code 0} if {@code x > y}
+ * @since 1.7
+ */
+ public static int compare(char x, char y) {
+ return x - y;
+ }
+
+ // BEGIN Android-removed: Use ICU.
+ /**
+ * Converts the character (Unicode code point) argument to uppercase using
+ * information from the UnicodeData file.
+ * <p>
+ *
+ * @param codePoint the character (Unicode code point) to be converted.
+ * @return either the uppercase equivalent of the character, if
+ * any, or an error flag ({@code Character.ERROR})
+ * that indicates that a 1:M {@code char} mapping exists.
+ * @see Character#isLowerCase(char)
+ * @see Character#isUpperCase(char)
+ * @see Character#toLowerCase(char)
+ * @see Character#toTitleCase(char)
+ * @since 1.4
+ *
+ static int toUpperCaseEx(int codePoint) {
+ assert isValidCodePoint(codePoint);
+ return CharacterData.of(codePoint).toUpperCaseEx(codePoint);
+ }
+
+ /**
+ * Converts the character (Unicode code point) argument to uppercase using case
+ * mapping information from the SpecialCasing file in the Unicode
+ * specification. If a character has no explicit uppercase
+ * mapping, then the {@code char} itself is returned in the
+ * {@code char[]}.
+ *
+ * @param codePoint the character (Unicode code point) to be converted.
+ * @return a {@code char[]} with the uppercased character.
+ * @since 1.4
+ *
+ static char[] toUpperCaseCharArray(int codePoint) {
+ // As of Unicode 6.0, 1:M uppercasings only happen in the BMP.
+ assert isBmpCodePoint(codePoint);
+ return CharacterData.of(codePoint).toUpperCaseCharArray(codePoint);
+ }
+ */
+ // END Android-removed: Use ICU.
+
+ /**
+ * The number of bits used to represent a <tt>char</tt> value in unsigned
+ * binary form, constant {@code 16}.
+ *
+ * @since 1.5
+ */
+ public static final int SIZE = 16;
+
+ /**
+ * The number of bytes used to represent a {@code char} value in unsigned
+ * binary form.
+ *
+ * @since 1.8
+ */
+ public static final int BYTES = SIZE / Byte.SIZE;
+
+ /**
+ * Returns the value obtained by reversing the order of the bytes in the
+ * specified <tt>char</tt> value.
+ *
+ * @param ch The {@code char} of which to reverse the byte order.
+ * @return the value obtained by reversing (or, equivalently, swapping)
+ * the bytes in the specified <tt>char</tt> value.
+ * @since 1.5
+ */
+ public static char reverseBytes(char ch) {
+ return (char) (((ch & 0xFF00) >> 8) | (ch << 8));
+ }
+
+ /**
+ * Returns the Unicode name of the specified character
+ * {@code codePoint}, or null if the code point is
+ * {@link #UNASSIGNED unassigned}.
+ * <p>
+ * Note: if the specified character is not assigned a name by
+ * the <i>UnicodeData</i> file (part of the Unicode Character
+ * Database maintained by the Unicode Consortium), the returned
+ * name is the same as the result of expression.
+ *
+ * <blockquote>{@code
+ * Character.UnicodeBlock.of(codePoint).toString().replace('_', ' ')
+ * + " "
+ * + Integer.toHexString(codePoint).toUpperCase(Locale.ENGLISH);
+ *
+ * }</blockquote>
+ *
+ * @param codePoint the character (Unicode code point)
+ *
+ * @return the Unicode name of the specified character, or null if
+ * the code point is unassigned.
+ *
+ * @exception IllegalArgumentException if the specified
+ * {@code codePoint} is not a valid Unicode
+ * code point.
+ *
+ * @since 1.7
+ */
+ public static String getName(int codePoint) {
+ if (!isValidCodePoint(codePoint)) {
+ throw new IllegalArgumentException();
+ }
+ // Android-changed: Use ICU.
+ // String name = CharacterName.get(codePoint);
+ String name = getNameImpl(codePoint);
+ if (name != null)
+ return name;
+ if (getType(codePoint) == UNASSIGNED)
+ return null;
+ UnicodeBlock block = UnicodeBlock.of(codePoint);
+ if (block != null)
+ return block.toString().replace('_', ' ') + " "
+ + Integer.toHexString(codePoint).toUpperCase(Locale.ENGLISH);
+ // should never come here
+ return Integer.toHexString(codePoint).toUpperCase(Locale.ENGLISH);
+ }
+
+ // Android-added: Use ICU.
+ // Implement getNameImpl() natively.
+ private static native String getNameImpl(int codePoint);
+}
diff --git a/java/lang/Class.annotated.java b/java/lang/Class.annotated.java
new file mode 100644
index 0000000..fd80abb
--- /dev/null
+++ b/java/lang/Class.annotated.java
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 2014, 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;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Type;
+import java.lang.reflect.GenericDeclaration;
+import java.lang.reflect.TypeVariable;
+import java.io.Serializable;
+import java.lang.reflect.Array;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Method;
+import java.lang.reflect.Field;
+import java.lang.reflect.Member;
+import java.io.InputStream;
+import java.util.HashMap;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Class<T> implements java.io.Serializable, java.lang.reflect.GenericDeclaration, java.lang.reflect.Type, java.lang.reflect.AnnotatedElement {
+
+Class() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String toGenericString() { throw new RuntimeException("Stub!"); }
+
+public static java.lang.Class<?> forName(java.lang.String className) throws java.lang.ClassNotFoundException { throw new RuntimeException("Stub!"); }
+
+public static java.lang.Class<?> forName(java.lang.String name, boolean initialize, java.lang.ClassLoader loader) throws java.lang.ClassNotFoundException { throw new RuntimeException("Stub!"); }
+
+public native T newInstance() throws java.lang.IllegalAccessException, java.lang.InstantiationException;
+
+public boolean isInstance(java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public boolean isAssignableFrom(java.lang.Class<?> cls) { throw new RuntimeException("Stub!"); }
+
+public boolean isInterface() { throw new RuntimeException("Stub!"); }
+
+public boolean isArray() { throw new RuntimeException("Stub!"); }
+
+public boolean isPrimitive() { throw new RuntimeException("Stub!"); }
+
+public boolean isFinalizable() { throw new RuntimeException("Stub!"); }
+
+public boolean isAnnotation() { throw new RuntimeException("Stub!"); }
+
+public boolean isSynthetic() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String getName() { throw new RuntimeException("Stub!"); }
+
+public java.lang.ClassLoader getClassLoader() { throw new RuntimeException("Stub!"); }
+
+public synchronized java.lang.reflect.TypeVariable<java.lang.Class<T>>[] getTypeParameters() { throw new RuntimeException("Stub!"); }
+
+public java.lang.Class<? super T> getSuperclass() { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.Type getGenericSuperclass() { throw new RuntimeException("Stub!"); }
+
+public java.lang.Package getPackage() { throw new RuntimeException("Stub!"); }
+
[email protected]
+public java.lang.String getPackageName$() { throw new RuntimeException("Stub!"); }
+
+public java.lang.Class<?>[] getInterfaces() { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.Type[] getGenericInterfaces() { throw new RuntimeException("Stub!"); }
+
+public java.lang.Class<?> getComponentType() { throw new RuntimeException("Stub!"); }
+
+public int getModifiers() { throw new RuntimeException("Stub!"); }
+
+public java.lang.Object[] getSigners() { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.Method getEnclosingMethod() { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.Constructor<?> getEnclosingConstructor() { throw new RuntimeException("Stub!"); }
+
+public native java.lang.Class<?> getDeclaringClass();
+
+public native java.lang.Class<?> getEnclosingClass();
+
+public java.lang.String getSimpleName() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String getTypeName() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String getCanonicalName() { throw new RuntimeException("Stub!"); }
+
+public native boolean isAnonymousClass();
+
+public boolean isLocalClass() { throw new RuntimeException("Stub!"); }
+
+public boolean isMemberClass() { throw new RuntimeException("Stub!"); }
+
+public java.lang.Class<?>[] getClasses() { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.Field[] getFields() throws java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.Method[] getMethods() throws java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.Constructor<?>[] getConstructors() throws java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.Field getField(java.lang.String name) throws java.lang.NoSuchFieldException { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.Method getMethod(java.lang.String name, java.lang.Class<?>... parameterTypes) throws java.lang.NoSuchMethodException, java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.Constructor<T> getConstructor(java.lang.Class<?>... parameterTypes) throws java.lang.NoSuchMethodException, java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+public native java.lang.Class<?>[] getDeclaredClasses();
+
+public native java.lang.reflect.Field[] getDeclaredFields();
+
[email protected]
+public native java.lang.reflect.Field[] getDeclaredFieldsUnchecked(boolean publicOnly);
+
+public java.lang.reflect.Method[] getDeclaredMethods() throws java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
[email protected]
+public native java.lang.reflect.Method[] getDeclaredMethodsUnchecked(boolean publicOnly);
+
+public java.lang.reflect.Constructor<?>[] getDeclaredConstructors() throws java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+public native java.lang.reflect.Field getDeclaredField(java.lang.String name) throws java.lang.NoSuchFieldException;
+
+public java.lang.reflect.Method getDeclaredMethod(java.lang.String name, java.lang.Class<?>... parameterTypes) throws java.lang.NoSuchMethodException, java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.Method getInstanceMethod(java.lang.String name, java.lang.Class<?>[] parameterTypes) throws java.lang.IllegalAccessException, java.lang.NoSuchMethodException { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.Constructor<T> getDeclaredConstructor(java.lang.Class<?>... parameterTypes) throws java.lang.NoSuchMethodException, java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+public java.io.InputStream getResourceAsStream(java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+public java.net.URL getResource(java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+public java.security.ProtectionDomain getProtectionDomain() { throw new RuntimeException("Stub!"); }
+
+public boolean desiredAssertionStatus() { throw new RuntimeException("Stub!"); }
+
+public boolean isEnum() { throw new RuntimeException("Stub!"); }
+
+public T[] getEnumConstants() { throw new RuntimeException("Stub!"); }
+
+public T[] getEnumConstantsShared() { throw new RuntimeException("Stub!"); }
+
+public T cast(java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public <U> java.lang.Class<? extends U> asSubclass(java.lang.Class<U> clazz) { throw new RuntimeException("Stub!"); }
+
+public <A extends java.lang.annotation.Annotation> A getAnnotation(java.lang.Class<A> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public boolean isAnnotationPresent(java.lang.Class<? extends java.lang.annotation.Annotation> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public <A extends java.lang.annotation.Annotation> A[] getAnnotationsByType(java.lang.Class<A> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public java.lang.annotation.Annotation[] getAnnotations() { throw new RuntimeException("Stub!"); }
+
+public native <A extends java.lang.annotation.Annotation> A getDeclaredAnnotation(java.lang.Class<A> annotationClass);
+
+public native java.lang.annotation.Annotation[] getDeclaredAnnotations();
+
+public boolean isProxy() { throw new RuntimeException("Stub!"); }
+
+public int getAccessFlags() { throw new RuntimeException("Stub!"); }
+}
+
diff --git a/java/lang/Class.java b/java/lang/Class.java
new file mode 100644
index 0000000..f792248
--- /dev/null
+++ b/java/lang/Class.java
@@ -0,0 +1,2675 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 2014, 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;
+
+import dalvik.annotation.optimization.FastNative;
+
+import java.io.InputStream;
+import java.io.Serializable;
+import java.lang.annotation.Annotation;
+import java.lang.annotation.Inherited;
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.GenericDeclaration;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Objects;
+import libcore.reflect.GenericSignatureParser;
+import libcore.reflect.InternalNames;
+import libcore.reflect.Types;
+import libcore.util.BasicLruCache;
+import libcore.util.CollectionUtils;
+import libcore.util.EmptyArray;
+
+import dalvik.system.ClassExt;
+import sun.reflect.CallerSensitive;
+import sun.reflect.Reflection;
+
+/**
+ * Instances of the class {@code Class} represent classes and
+ * interfaces in a running Java application. An enum is a kind of
+ * class and an annotation is a kind of interface. Every array also
+ * belongs to a class that is reflected as a {@code Class} object
+ * that is shared by all arrays with the same element type and number
+ * of dimensions. The primitive Java types ({@code boolean},
+ * {@code byte}, {@code char}, {@code short},
+ * {@code int}, {@code long}, {@code float}, and
+ * {@code double}), and the keyword {@code void} are also
+ * represented as {@code Class} objects.
+ *
+ * <p> {@code Class} has no public constructor. Instead {@code Class}
+ * objects are constructed automatically by the Java Virtual Machine as classes
+ * are loaded and by calls to the {@code defineClass} method in the class
+ * loader.
+ *
+ * <p> The following example uses a {@code Class} object to print the
+ * class name of an object:
+ *
+ * <blockquote><pre>
+ * void printClassName(Object obj) {
+ * System.out.println("The class of " + obj +
+ * " is " + obj.getClass().getName());
+ * }
+ * </pre></blockquote>
+ *
+ * <p> It is also possible to get the {@code Class} object for a named
+ * type (or for void) using a class literal. See Section 15.8.2 of
+ * <cite>The Java™ Language Specification</cite>.
+ * For example:
+ *
+ * <blockquote>
+ * {@code System.out.println("The name of class Foo is: "+Foo.class.getName());}
+ * </blockquote>
+ *
+ * @param <T> the type of the class modeled by this {@code Class}
+ * object. For example, the type of {@code String.class} is {@code
+ * Class<String>}. Use {@code Class<?>} if the class being modeled is
+ * unknown.
+ *
+ * @author unascribed
+ * @see java.lang.ClassLoader#defineClass(byte[], int, int)
+ * @since JDK1.0
+ */
+public final class Class<T> implements java.io.Serializable,
+ GenericDeclaration,
+ Type,
+ AnnotatedElement {
+ private static final int ANNOTATION= 0x00002000;
+ private static final int ENUM = 0x00004000;
+ private static final int SYNTHETIC = 0x00001000;
+ private static final int FINALIZABLE = 0x80000000;
+
+ /** defining class loader, or null for the "bootstrap" system loader. */
+ private transient ClassLoader classLoader;
+
+ /**
+ * For array classes, the component class object for instanceof/checkcast (for String[][][],
+ * this will be String[][]). null for non-array classes.
+ */
+ private transient Class<?> componentType;
+
+ /**
+ * DexCache of resolved constant pool entries. Will be null for certain runtime-generated classes
+ * e.g. arrays and primitive classes.
+ */
+ private transient Object dexCache;
+
+ /**
+ * Extra data that only some classes possess. This is allocated lazily as needed.
+ */
+ private transient ClassExt extData;
+
+ /**
+ * The interface table (iftable_) contains pairs of a interface class and an array of the
+ * interface methods. There is one pair per interface supported by this class. That
+ * means one pair for each interface we support directly, indirectly via superclass, or
+ * indirectly via a superinterface. This will be null if neither we nor our superclass
+ * implement any interfaces.
+ *
+ * Why we need this: given "class Foo implements Face", declare "Face faceObj = new Foo()".
+ * Invoke faceObj.blah(), where "blah" is part of the Face interface. We can't easily use a
+ * single vtable.
+ *
+ * For every interface a concrete class implements, we create an array of the concrete vtable_
+ * methods for the methods in the interface.
+ */
+ private transient Object[] ifTable;
+
+ /** Lazily computed name of this class; always prefer calling getName(). */
+ private transient String name;
+
+ /** The superclass, or null if this is java.lang.Object, an interface or primitive type. */
+ private transient Class<? super T> superClass;
+
+ /**
+ * Virtual method table (vtable), for use by "invoke-virtual". The vtable from the superclass
+ * is copied in, and virtual methods from our class either replace those from the super or are
+ * appended. For abstract classes, methods may be created in the vtable that aren't in
+ * virtual_ methods_ for miranda methods.
+ */
+ private transient Object vtable;
+
+ /**
+ * Instance fields. These describe the layout of the contents of an Object. Note that only the
+ * fields directly declared by this class are listed in iFields; fields declared by a
+ * superclass are listed in the superclass's Class.iFields.
+ *
+ * All instance fields that refer to objects are guaranteed to be at the beginning of the field
+ * list. {@link Class#numReferenceInstanceFields} specifies the number of reference fields.
+ */
+ private transient long iFields;
+
+ /** All methods with this class as the base for virtual dispatch. */
+ private transient long methods;
+
+ /** Static fields */
+ private transient long sFields;
+
+ /** access flags; low 16 bits are defined by VM spec */
+ private transient int accessFlags;
+
+ /** Class flags to help the GC with object scanning. */
+ private transient int classFlags;
+
+ /**
+ * Total size of the Class instance; used when allocating storage on GC heap.
+ * See also {@link Class#objectSize}.
+ */
+ private transient int classSize;
+
+ /**
+ * tid used to check for recursive static initializer invocation.
+ */
+ private transient int clinitThreadId;
+
+ /**
+ * Class def index from dex file. An index of 65535 indicates that there is no class definition,
+ * for example for an array type.
+ * TODO: really 16bits as type indices are 16bit.
+ */
+ private transient int dexClassDefIndex;
+
+ /**
+ * Class type index from dex file, lazily computed. An index of 65535 indicates that the type
+ * index isn't known. Volatile to avoid double-checked locking bugs.
+ * TODO: really 16bits as type indices are 16bit.
+ */
+ private transient volatile int dexTypeIndex;
+
+ /** Number of instance fields that are object references. */
+ private transient int numReferenceInstanceFields;
+
+ /** Number of static fields that are object references. */
+ private transient int numReferenceStaticFields;
+
+ /**
+ * Total object size; used when allocating storage on GC heap. For interfaces and abstract
+ * classes this will be zero. See also {@link Class#classSize}.
+ */
+ private transient int objectSize;
+
+ /**
+ * Aligned object size for allocation fast path. The value is max int if the object is
+ * uninitialized or finalizable, otherwise the aligned object size.
+ */
+ private transient int objectSizeAllocFastPath;
+
+ /**
+ * The lower 16 bits is the primitive type value, or 0 if not a primitive type; set for
+ * generated primitive classes.
+ */
+ private transient int primitiveType;
+
+ /** Bitmap of offsets of iFields. */
+ private transient int referenceInstanceOffsets;
+
+ /** State of class initialization */
+ private transient int status;
+
+ /** Offset of the first virtual method copied from an interface in the methods array. */
+ private transient short copiedMethodsOffset;
+
+ /** Offset of the first virtual method defined in this class in the methods array. */
+ private transient short virtualMethodsOffset;
+
+ /*
+ * Private constructor. Only the Java Virtual Machine creates Class objects.
+ * This constructor is not used and prevents the default constructor being
+ * generated.
+ */
+ private Class() {}
+
+
+ /**
+ * Converts the object to a string. The string representation is the
+ * string "class" or "interface", followed by a space, and then by the
+ * fully qualified name of the class in the format returned by
+ * {@code getName}. If this {@code Class} object represents a
+ * primitive type, this method returns the name of the primitive type. If
+ * this {@code Class} object represents void this method returns
+ * "void".
+ *
+ * @return a string representation of this class object.
+ */
+ public String toString() {
+ return (isInterface() ? "interface " : (isPrimitive() ? "" : "class "))
+ + getName();
+ }
+
+ /**
+ * Returns a string describing this {@code Class}, including
+ * information about modifiers and type parameters.
+ *
+ * The string is formatted as a list of type modifiers, if any,
+ * followed by the kind of type (empty string for primitive types
+ * and {@code class}, {@code enum}, {@code interface}, or
+ * <code>@</code>{@code interface}, as appropriate), followed
+ * by the type's name, followed by an angle-bracketed
+ * comma-separated list of the type's type parameters, if any.
+ *
+ * A space is used to separate modifiers from one another and to
+ * separate any modifiers from the kind of type. The modifiers
+ * occur in canonical order. If there are no type parameters, the
+ * type parameter list is elided.
+ *
+ * <p>Note that since information about the runtime representation
+ * of a type is being generated, modifiers not present on the
+ * originating source code or illegal on the originating source
+ * code may be present.
+ *
+ * @return a string describing this {@code Class}, including
+ * information about modifiers and type parameters
+ *
+ * @since 1.8
+ */
+ public String toGenericString() {
+ if (isPrimitive()) {
+ return toString();
+ } else {
+ StringBuilder sb = new StringBuilder();
+
+ // Class modifiers are a superset of interface modifiers
+ int modifiers = getModifiers() & Modifier.classModifiers();
+ if (modifiers != 0) {
+ sb.append(Modifier.toString(modifiers));
+ sb.append(' ');
+ }
+
+ if (isAnnotation()) {
+ sb.append('@');
+ }
+ if (isInterface()) { // Note: all annotation types are interfaces
+ sb.append("interface");
+ } else {
+ if (isEnum())
+ sb.append("enum");
+ else
+ sb.append("class");
+ }
+ sb.append(' ');
+ sb.append(getName());
+
+ TypeVariable<?>[] typeparms = getTypeParameters();
+ if (typeparms.length > 0) {
+ boolean first = true;
+ sb.append('<');
+ for(TypeVariable<?> typeparm: typeparms) {
+ if (!first)
+ sb.append(',');
+ sb.append(typeparm.getTypeName());
+ first = false;
+ }
+ sb.append('>');
+ }
+
+ return sb.toString();
+ }
+ }
+
+ /**
+ * Returns the {@code Class} object associated with the class or
+ * interface with the given string name. Invoking this method is
+ * equivalent to:
+ *
+ * <blockquote>
+ * {@code Class.forName(className, true, currentLoader)}
+ * </blockquote>
+ *
+ * where {@code currentLoader} denotes the defining class loader of
+ * the current class.
+ *
+ * <p> For example, the following code fragment returns the
+ * runtime {@code Class} descriptor for the class named
+ * {@code java.lang.Thread}:
+ *
+ * <blockquote>
+ * {@code Class t = Class.forName("java.lang.Thread")}
+ * </blockquote>
+ * <p>
+ * A call to {@code forName("X")} causes the class named
+ * {@code X} to be initialized.
+ *
+ * @param className the fully qualified name of the desired class.
+ * @return the {@code Class} object for the class with the
+ * specified name.
+ * @exception LinkageError if the linkage fails
+ * @exception ExceptionInInitializerError if the initialization provoked
+ * by this method fails
+ * @exception ClassNotFoundException if the class cannot be located
+ */
+ @CallerSensitive
+ public static Class<?> forName(String className)
+ throws ClassNotFoundException {
+ Class<?> caller = Reflection.getCallerClass();
+ return forName(className, true, ClassLoader.getClassLoader(caller));
+ }
+
+
+ /**
+ * Returns the {@code Class} object associated with the class or
+ * interface with the given string name, using the given class loader.
+ * Given the fully qualified name for a class or interface (in the same
+ * format returned by {@code getName}) this method attempts to
+ * locate, load, and link the class or interface. The specified class
+ * loader is used to load the class or interface. If the parameter
+ * {@code loader} is null, the class is loaded through the bootstrap
+ * class loader. The class is initialized only if the
+ * {@code initialize} parameter is {@code true} and if it has
+ * not been initialized earlier.
+ *
+ * <p> If {@code name} denotes a primitive type or void, an attempt
+ * will be made to locate a user-defined class in the unnamed package whose
+ * name is {@code name}. Therefore, this method cannot be used to
+ * obtain any of the {@code Class} objects representing primitive
+ * types or void.
+ *
+ * <p> If {@code name} denotes an array class, the component type of
+ * the array class is loaded but not initialized.
+ *
+ * <p> For example, in an instance method the expression:
+ *
+ * <blockquote>
+ * {@code Class.forName("Foo")}
+ * </blockquote>
+ *
+ * is equivalent to:
+ *
+ * <blockquote>
+ * {@code Class.forName("Foo", true, this.getClass().getClassLoader())}
+ * </blockquote>
+ *
+ * Note that this method throws errors related to loading, linking or
+ * initializing as specified in Sections 12.2, 12.3 and 12.4 of <em>The
+ * Java Language Specification</em>.
+ * Note that this method does not check whether the requested class
+ * is accessible to its caller.
+ *
+ * <p> If the {@code loader} is {@code null}, and a security
+ * manager is present, and the caller's class loader is not null, then this
+ * method calls the security manager's {@code checkPermission} method
+ * with a {@code RuntimePermission("getClassLoader")} permission to
+ * ensure it's ok to access the bootstrap class loader.
+ *
+ * @param name fully qualified name of the desired class
+ * @param initialize if {@code true} the class will be initialized.
+ * See Section 12.4 of <em>The Java Language Specification</em>.
+ * @param loader class loader from which the class must be loaded
+ * @return class object representing the desired class
+ *
+ * @exception LinkageError if the linkage fails
+ * @exception ExceptionInInitializerError if the initialization provoked
+ * by this method fails
+ * @exception ClassNotFoundException if the class cannot be located by
+ * the specified class loader
+ *
+ * @see java.lang.Class#forName(String)
+ * @see java.lang.ClassLoader
+ * @since 1.2
+ */
+ @CallerSensitive
+ public static Class<?> forName(String name, boolean initialize,
+ ClassLoader loader)
+ throws ClassNotFoundException
+ {
+ if (loader == null) {
+ loader = BootClassLoader.getInstance();
+ }
+ Class<?> result;
+ try {
+ result = classForName(name, initialize, loader);
+ } catch (ClassNotFoundException e) {
+ Throwable cause = e.getCause();
+ if (cause instanceof LinkageError) {
+ throw (LinkageError) cause;
+ }
+ throw e;
+ }
+ return result;
+ }
+
+ /** Called after security checks have been made. */
+ @FastNative
+ static native Class<?> classForName(String className, boolean shouldInitialize,
+ ClassLoader classLoader) throws ClassNotFoundException;
+
+ /**
+ * Creates a new instance of the class represented by this {@code Class}
+ * object. The class is instantiated as if by a {@code new}
+ * expression with an empty argument list. The class is initialized if it
+ * has not already been initialized.
+ *
+ * <p>Note that this method propagates any exception thrown by the
+ * nullary constructor, including a checked exception. Use of
+ * this method effectively bypasses the compile-time exception
+ * checking that would otherwise be performed by the compiler.
+ * The {@link
+ * java.lang.reflect.Constructor#newInstance(java.lang.Object...)
+ * Constructor.newInstance} method avoids this problem by wrapping
+ * any exception thrown by the constructor in a (checked) {@link
+ * java.lang.reflect.InvocationTargetException}.
+ *
+ * @return a newly allocated instance of the class represented by this
+ * object.
+ * @throws IllegalAccessException if the class or its nullary
+ * constructor is not accessible.
+ * @throws InstantiationException
+ * if this {@code Class} represents an abstract class,
+ * an interface, an array class, a primitive type, or void;
+ * or if the class has no nullary constructor;
+ * or if the instantiation fails for some other reason.
+ * @throws ExceptionInInitializerError if the initialization
+ * provoked by this method fails.
+ * @throws SecurityException
+ * If a security manager, <i>s</i>, is present and
+ * the caller's class loader is not the same as or an
+ * ancestor of the class loader for the current class and
+ * invocation of {@link SecurityManager#checkPackageAccess
+ * s.checkPackageAccess()} denies access to the package
+ * of this class.
+ */
+ @FastNative
+ public native T newInstance() throws InstantiationException, IllegalAccessException;
+
+ /**
+ * Determines if the specified {@code Object} is assignment-compatible
+ * with the object represented by this {@code Class}. This method is
+ * the dynamic equivalent of the Java language {@code instanceof}
+ * operator. The method returns {@code true} if the specified
+ * {@code Object} argument is non-null and can be cast to the
+ * reference type represented by this {@code Class} object without
+ * raising a {@code ClassCastException.} It returns {@code false}
+ * otherwise.
+ *
+ * <p> Specifically, if this {@code Class} object represents a
+ * declared class, this method returns {@code true} if the specified
+ * {@code Object} argument is an instance of the represented class (or
+ * of any of its subclasses); it returns {@code false} otherwise. If
+ * this {@code Class} object represents an array class, this method
+ * returns {@code true} if the specified {@code Object} argument
+ * can be converted to an object of the array class by an identity
+ * conversion or by a widening reference conversion; it returns
+ * {@code false} otherwise. If this {@code Class} object
+ * represents an interface, this method returns {@code true} if the
+ * class or any superclass of the specified {@code Object} argument
+ * implements this interface; it returns {@code false} otherwise. If
+ * this {@code Class} object represents a primitive type, this method
+ * returns {@code false}.
+ *
+ * @param obj the object to check
+ * @return true if {@code obj} is an instance of this class
+ *
+ * @since JDK1.1
+ */
+ public boolean isInstance(Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ return isAssignableFrom(obj.getClass());
+ }
+
+
+ /**
+ * Determines if the class or interface represented by this
+ * {@code Class} object is either the same as, or is a superclass or
+ * superinterface of, the class or interface represented by the specified
+ * {@code Class} parameter. It returns {@code true} if so;
+ * otherwise it returns {@code false}. If this {@code Class}
+ * object represents a primitive type, this method returns
+ * {@code true} if the specified {@code Class} parameter is
+ * exactly this {@code Class} object; otherwise it returns
+ * {@code false}.
+ *
+ * <p> Specifically, this method tests whether the type represented by the
+ * specified {@code Class} parameter can be converted to the type
+ * represented by this {@code Class} object via an identity conversion
+ * or via a widening reference conversion. See <em>The Java Language
+ * Specification</em>, sections 5.1.1 and 5.1.4 , for details.
+ *
+ * @param cls the {@code Class} object to be checked
+ * @return the {@code boolean} value indicating whether objects of the
+ * type {@code cls} can be assigned to objects of this class
+ * @exception NullPointerException if the specified Class parameter is
+ * null.
+ * @since JDK1.1
+ */
+ public boolean isAssignableFrom(Class<?> cls) {
+ if (this == cls) {
+ return true; // Can always assign to things of the same type.
+ } else if (this == Object.class) {
+ return !cls.isPrimitive(); // Can assign any reference to java.lang.Object.
+ } else if (isArray()) {
+ return cls.isArray() && componentType.isAssignableFrom(cls.componentType);
+ } else if (isInterface()) {
+ // Search iftable which has a flattened and uniqued list of interfaces.
+ Object[] iftable = cls.ifTable;
+ if (iftable != null) {
+ for (int i = 0; i < iftable.length; i += 2) {
+ if (iftable[i] == this) {
+ return true;
+ }
+ }
+ }
+ return false;
+ } else {
+ if (!cls.isInterface()) {
+ for (cls = cls.superClass; cls != null; cls = cls.superClass) {
+ if (cls == this) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ }
+
+ /**
+ * Determines if the specified {@code Class} object represents an
+ * interface type.
+ *
+ * @return {@code true} if this object represents an interface;
+ * {@code false} otherwise.
+ */
+ public boolean isInterface() {
+ return (accessFlags & Modifier.INTERFACE) != 0;
+ }
+
+ /**
+ * Determines if this {@code Class} object represents an array class.
+ *
+ * @return {@code true} if this object represents an array class;
+ * {@code false} otherwise.
+ * @since JDK1.1
+ */
+ public boolean isArray() {
+ return getComponentType() != null;
+ }
+
+ /**
+ * Determines if the specified {@code Class} object represents a
+ * primitive type.
+ *
+ * <p> There are nine predefined {@code Class} objects to represent
+ * the eight primitive types and void. These are created by the Java
+ * Virtual Machine, and have the same names as the primitive types that
+ * they represent, namely {@code boolean}, {@code byte},
+ * {@code char}, {@code short}, {@code int},
+ * {@code long}, {@code float}, and {@code double}.
+ *
+ * <p> These objects may only be accessed via the following public static
+ * final variables, and are the only {@code Class} objects for which
+ * this method returns {@code true}.
+ *
+ * @return true if and only if this class represents a primitive type
+ *
+ * @see java.lang.Boolean#TYPE
+ * @see java.lang.Character#TYPE
+ * @see java.lang.Byte#TYPE
+ * @see java.lang.Short#TYPE
+ * @see java.lang.Integer#TYPE
+ * @see java.lang.Long#TYPE
+ * @see java.lang.Float#TYPE
+ * @see java.lang.Double#TYPE
+ * @see java.lang.Void#TYPE
+ * @since JDK1.1
+ */
+ public boolean isPrimitive() {
+ return (primitiveType & 0xFFFF) != 0;
+ }
+
+ /**
+ * Indicates whether this {@code Class} or its parents override finalize.
+ *
+ * @return {@code true} if and if this class or its parents override
+ * finalize;
+ *
+ * @hide
+ */
+ public boolean isFinalizable() {
+ return (getModifiers() & FINALIZABLE) != 0;
+ }
+
+ /**
+ * Returns true if this {@code Class} object represents an annotation
+ * type. Note that if this method returns true, {@link #isInterface()}
+ * would also return true, as all annotation types are also interfaces.
+ *
+ * @return {@code true} if this class object represents an annotation
+ * type; {@code false} otherwise
+ * @since 1.5
+ */
+ public boolean isAnnotation() {
+ return (getModifiers() & ANNOTATION) != 0;
+ }
+
+ /**
+ * Returns {@code true} if this class is a synthetic class;
+ * returns {@code false} otherwise.
+ * @return {@code true} if and only if this class is a synthetic class as
+ * defined by the Java Language Specification.
+ * @jls 13.1 The Form of a Binary
+ * @since 1.5
+ */
+ public boolean isSynthetic() {
+ return (getModifiers() & SYNTHETIC) != 0;
+ }
+
+ /**
+ * Returns the name of the entity (class, interface, array class,
+ * primitive type, or void) represented by this {@code Class} object,
+ * as a {@code String}.
+ *
+ * <p> If this class object represents a reference type that is not an
+ * array type then the binary name of the class is returned, as specified
+ * by
+ * <cite>The Java™ Language Specification</cite>.
+ *
+ * <p> If this class object represents a primitive type or void, then the
+ * name returned is a {@code String} equal to the Java language
+ * keyword corresponding to the primitive type or void.
+ *
+ * <p> If this class object represents a class of arrays, then the internal
+ * form of the name consists of the name of the element type preceded by
+ * one or more '{@code [}' characters representing the depth of the array
+ * nesting. The encoding of element type names is as follows:
+ *
+ * <blockquote><table summary="Element types and encodings">
+ * <tr><th> Element Type <th> <th> Encoding
+ * <tr><td> boolean <td> <td align=center> Z
+ * <tr><td> byte <td> <td align=center> B
+ * <tr><td> char <td> <td align=center> C
+ * <tr><td> class or interface
+ * <td> <td align=center> L<i>classname</i>;
+ * <tr><td> double <td> <td align=center> D
+ * <tr><td> float <td> <td align=center> F
+ * <tr><td> int <td> <td align=center> I
+ * <tr><td> long <td> <td align=center> J
+ * <tr><td> short <td> <td align=center> S
+ * </table></blockquote>
+ *
+ * <p> The class or interface name <i>classname</i> is the binary name of
+ * the class specified above.
+ *
+ * <p> Examples:
+ * <blockquote><pre>
+ * String.class.getName()
+ * returns "java.lang.String"
+ * byte.class.getName()
+ * returns "byte"
+ * (new Object[3]).getClass().getName()
+ * returns "[Ljava.lang.Object;"
+ * (new int[3][4][5][6][7][8][9]).getClass().getName()
+ * returns "[[[[[[[I"
+ * </pre></blockquote>
+ *
+ * @return the name of the class or interface
+ * represented by this object.
+ */
+ public String getName() {
+ String name = this.name;
+ if (name == null)
+ this.name = name = getNameNative();
+ return name;
+ }
+
+ @FastNative
+ private native String getNameNative();
+
+ /**
+ * Returns the class loader for the class. Some implementations may use
+ * null to represent the bootstrap class loader. This method will return
+ * null in such implementations if this class was loaded by the bootstrap
+ * class loader.
+ *
+ * <p> If a security manager is present, and the caller's class loader is
+ * not null and the caller's class loader is not the same as or an ancestor of
+ * the class loader for the class whose class loader is requested, then
+ * this method calls the security manager's {@code checkPermission}
+ * method with a {@code RuntimePermission("getClassLoader")}
+ * permission to ensure it's ok to access the class loader for the class.
+ *
+ * <p>If this object
+ * represents a primitive type or void, null is returned.
+ *
+ * @return the class loader that loaded the class or interface
+ * represented by this object.
+ * @throws SecurityException
+ * if a security manager exists and its
+ * {@code checkPermission} method denies
+ * access to the class loader for the class.
+ * @see java.lang.ClassLoader
+ * @see SecurityManager#checkPermission
+ * @see java.lang.RuntimePermission
+ */
+ public ClassLoader getClassLoader() {
+ if (isPrimitive()) {
+ return null;
+ }
+ // Android-note: The RI returns null in the case where Android returns BootClassLoader.
+ // Noted in http://b/111850480#comment3
+ return (classLoader == null) ? BootClassLoader.getInstance() : classLoader;
+ }
+
+ /**
+ * Returns an array of {@code TypeVariable} objects that represent the
+ * type variables declared by the generic declaration represented by this
+ * {@code GenericDeclaration} object, in declaration order. Returns an
+ * array of length 0 if the underlying generic declaration declares no type
+ * variables.
+ *
+ * @return an array of {@code TypeVariable} objects that represent
+ * the type variables declared by this generic declaration
+ * @throws java.lang.reflect.GenericSignatureFormatError if the generic
+ * signature of this generic declaration does not conform to
+ * the format specified in
+ * <cite>The Java™ Virtual Machine Specification</cite>
+ * @since 1.5
+ */
+ @Override
+ public synchronized TypeVariable<Class<T>>[] getTypeParameters() {
+ String annotationSignature = getSignatureAttribute();
+ if (annotationSignature == null) {
+ return EmptyArray.TYPE_VARIABLE;
+ }
+ GenericSignatureParser parser = new GenericSignatureParser(getClassLoader());
+ parser.parseForClass(this, annotationSignature);
+ return parser.formalTypeParameters;
+ }
+
+
+ /**
+ * Returns the {@code Class} representing the superclass of the entity
+ * (class, interface, primitive type or void) represented by this
+ * {@code Class}. If this {@code Class} represents either the
+ * {@code Object} class, an interface, a primitive type, or void, then
+ * null is returned. If this object represents an array class then the
+ * {@code Class} object representing the {@code Object} class is
+ * returned.
+ *
+ * @return the superclass of the class represented by this object.
+ */
+ public Class<? super T> getSuperclass() {
+ // For interfaces superClass is Object (which agrees with the JNI spec)
+ // but not with the expected behavior here.
+ if (isInterface()) {
+ return null;
+ } else {
+ return superClass;
+ }
+ }
+
+ /**
+ * Returns the {@code Type} representing the direct superclass of
+ * the entity (class, interface, primitive type or void) represented by
+ * this {@code Class}.
+ *
+ * <p>If the superclass is a parameterized type, the {@code Type}
+ * object returned must accurately reflect the actual type
+ * parameters used in the source code. The parameterized type
+ * representing the superclass is created if it had not been
+ * created before. See the declaration of {@link
+ * java.lang.reflect.ParameterizedType ParameterizedType} for the
+ * semantics of the creation process for parameterized types. If
+ * this {@code Class} represents either the {@code Object}
+ * class, an interface, a primitive type, or void, then null is
+ * returned. If this object represents an array class then the
+ * {@code Class} object representing the {@code Object} class is
+ * returned.
+ *
+ * @throws java.lang.reflect.GenericSignatureFormatError if the generic
+ * class signature does not conform to the format specified in
+ * <cite>The Java™ Virtual Machine Specification</cite>
+ * @throws TypeNotPresentException if the generic superclass
+ * refers to a non-existent type declaration
+ * @throws java.lang.reflect.MalformedParameterizedTypeException if the
+ * generic superclass refers to a parameterized type that cannot be
+ * instantiated for any reason
+ * @return the superclass of the class represented by this object
+ * @since 1.5
+ */
+ public Type getGenericSuperclass() {
+ Type genericSuperclass = getSuperclass();
+ // This method is specified to return null for all cases where getSuperclass
+ // returns null, i.e, for primitives, interfaces, void and java.lang.Object.
+ if (genericSuperclass == null) {
+ return null;
+ }
+
+ String annotationSignature = getSignatureAttribute();
+ if (annotationSignature != null) {
+ GenericSignatureParser parser = new GenericSignatureParser(getClassLoader());
+ parser.parseForClass(this, annotationSignature);
+ genericSuperclass = parser.superclassType;
+ }
+ return Types.getType(genericSuperclass);
+ }
+
+ /**
+ * Gets the package for this class. The class loader of this class is used
+ * to find the package. If the class was loaded by the bootstrap class
+ * loader the set of packages loaded from CLASSPATH is searched to find the
+ * package of the class. Null is returned if no package object was created
+ * by the class loader of this class.
+ *
+ * <p> Packages have attributes for versions and specifications only if the
+ * information was defined in the manifests that accompany the classes, and
+ * if the class loader created the package instance with the attributes
+ * from the manifest.
+ *
+ * @return the package of the class, or null if no package
+ * information is available from the archive or codebase.
+ */
+ public Package getPackage() {
+ ClassLoader loader = getClassLoader();
+ if (loader != null) {
+ String packageName = getPackageName$();
+ return packageName != null ? loader.getPackage(packageName) : null;
+ }
+ return null;
+ }
+
+ /**
+ * Returns the package name of this class. This returns null for classes in
+ * the default package.
+ *
+ * @hide
+ */
+ public String getPackageName$() {
+ String name = getName();
+ int last = name.lastIndexOf('.');
+ return last == -1 ? null : name.substring(0, last);
+ }
+
+
+ /**
+ * Determines the interfaces implemented by the class or interface
+ * represented by this object.
+ *
+ * <p> If this object represents a class, the return value is an array
+ * containing objects representing all interfaces implemented by the
+ * class. The order of the interface objects in the array corresponds to
+ * the order of the interface names in the {@code implements} clause
+ * of the declaration of the class represented by this object. For
+ * example, given the declaration:
+ * <blockquote>
+ * {@code class Shimmer implements FloorWax, DessertTopping { ... }}
+ * </blockquote>
+ * suppose the value of {@code s} is an instance of
+ * {@code Shimmer}; the value of the expression:
+ * <blockquote>
+ * {@code s.getClass().getInterfaces()[0]}
+ * </blockquote>
+ * is the {@code Class} object that represents interface
+ * {@code FloorWax}; and the value of:
+ * <blockquote>
+ * {@code s.getClass().getInterfaces()[1]}
+ * </blockquote>
+ * is the {@code Class} object that represents interface
+ * {@code DessertTopping}.
+ *
+ * <p> If this object represents an interface, the array contains objects
+ * representing all interfaces extended by the interface. The order of the
+ * interface objects in the array corresponds to the order of the interface
+ * names in the {@code extends} clause of the declaration of the
+ * interface represented by this object.
+ *
+ * <p> If this object represents a class or interface that implements no
+ * interfaces, the method returns an array of length 0.
+ *
+ * <p> If this object represents a primitive type or void, the method
+ * returns an array of length 0.
+ *
+ * <p> If this {@code Class} object represents an array type, the
+ * interfaces {@code Cloneable} and {@code java.io.Serializable} are
+ * returned in that order.
+ *
+ * @return an array of interfaces implemented by this class.
+ */
+ public Class<?>[] getInterfaces() {
+ if (isArray()) {
+ return new Class<?>[] { Cloneable.class, Serializable.class };
+ }
+
+ final Class<?>[] ifaces = getInterfacesInternal();
+ if (ifaces == null) {
+ return EmptyArray.CLASS;
+ }
+
+ return ifaces;
+ }
+
+ @FastNative
+ private native Class<?>[] getInterfacesInternal();
+
+
+ /**
+ * Returns the {@code Type}s representing the interfaces
+ * directly implemented by the class or interface represented by
+ * this object.
+ *
+ * <p>If a superinterface is a parameterized type, the
+ * {@code Type} object returned for it must accurately reflect
+ * the actual type parameters used in the source code. The
+ * parameterized type representing each superinterface is created
+ * if it had not been created before. See the declaration of
+ * {@link java.lang.reflect.ParameterizedType ParameterizedType}
+ * for the semantics of the creation process for parameterized
+ * types.
+ *
+ * <p> If this object represents a class, the return value is an
+ * array containing objects representing all interfaces
+ * implemented by the class. The order of the interface objects in
+ * the array corresponds to the order of the interface names in
+ * the {@code implements} clause of the declaration of the class
+ * represented by this object. In the case of an array class, the
+ * interfaces {@code Cloneable} and {@code Serializable} are
+ * returned in that order.
+ *
+ * <p>If this object represents an interface, the array contains
+ * objects representing all interfaces directly extended by the
+ * interface. The order of the interface objects in the array
+ * corresponds to the order of the interface names in the
+ * {@code extends} clause of the declaration of the interface
+ * represented by this object.
+ *
+ * <p>If this object represents a class or interface that
+ * implements no interfaces, the method returns an array of length
+ * 0.
+ *
+ * <p>If this object represents a primitive type or void, the
+ * method returns an array of length 0.
+ *
+ * @throws java.lang.reflect.GenericSignatureFormatError
+ * if the generic class signature does not conform to the format
+ * specified in
+ * <cite>The Java™ Virtual Machine Specification</cite>
+ * @throws TypeNotPresentException if any of the generic
+ * superinterfaces refers to a non-existent type declaration
+ * @throws java.lang.reflect.MalformedParameterizedTypeException
+ * if any of the generic superinterfaces refer to a parameterized
+ * type that cannot be instantiated for any reason
+ * @return an array of interfaces implemented by this class
+ * @since 1.5
+ */
+ public Type[] getGenericInterfaces() {
+ Type[] result;
+ synchronized (Caches.genericInterfaces) {
+ result = Caches.genericInterfaces.get(this);
+ if (result == null) {
+ String annotationSignature = getSignatureAttribute();
+ if (annotationSignature == null) {
+ result = getInterfaces();
+ } else {
+ GenericSignatureParser parser = new GenericSignatureParser(getClassLoader());
+ parser.parseForClass(this, annotationSignature);
+ result = Types.getTypeArray(parser.interfaceTypes, false);
+ }
+ Caches.genericInterfaces.put(this, result);
+ }
+ }
+ return (result.length == 0) ? result : result.clone();
+ }
+
+
+ /**
+ * Returns the {@code Class} representing the component type of an
+ * array. If this class does not represent an array class this method
+ * returns null.
+ *
+ * @return the {@code Class} representing the component type of this
+ * class if this class is an array
+ * @see java.lang.reflect.Array
+ * @since JDK1.1
+ */
+ public Class<?> getComponentType() {
+ return componentType;
+ }
+
+ /**
+ * Returns the Java language modifiers for this class or interface, encoded
+ * in an integer. The modifiers consist of the Java Virtual Machine's
+ * constants for {@code public}, {@code protected},
+ * {@code private}, {@code final}, {@code static},
+ * {@code abstract} and {@code interface}; they should be decoded
+ * using the methods of class {@code Modifier}.
+ *
+ * <p> If the underlying class is an array class, then its
+ * {@code public}, {@code private} and {@code protected}
+ * modifiers are the same as those of its component type. If this
+ * {@code Class} represents a primitive type or void, its
+ * {@code public} modifier is always {@code true}, and its
+ * {@code protected} and {@code private} modifiers are always
+ * {@code false}. If this object represents an array class, a
+ * primitive type or void, then its {@code final} modifier is always
+ * {@code true} and its interface modifier is always
+ * {@code false}. The values of its other modifiers are not determined
+ * by this specification.
+ *
+ * <p> The modifier encodings are defined in <em>The Java Virtual Machine
+ * Specification</em>, table 4.1.
+ *
+ * @return the {@code int} representing the modifiers for this class
+ * @see java.lang.reflect.Modifier
+ * @since JDK1.1
+ */
+ public int getModifiers() {
+ // Array classes inherit modifiers from their component types, but in the case of arrays
+ // of an inner class, the class file may contain "fake" access flags because it's not valid
+ // for a top-level class to private, say. The real access flags are stored in the InnerClass
+ // attribute, so we need to make sure we drill down to the inner class: the accessFlags
+ // field is not the value we want to return, and the synthesized array class does not itself
+ // have an InnerClass attribute. https://code.google.com/p/android/issues/detail?id=56267
+ if (isArray()) {
+ int componentModifiers = getComponentType().getModifiers();
+ if ((componentModifiers & Modifier.INTERFACE) != 0) {
+ componentModifiers &= ~(Modifier.INTERFACE | Modifier.STATIC);
+ }
+ return Modifier.ABSTRACT | Modifier.FINAL | componentModifiers;
+ }
+ int JAVA_FLAGS_MASK = 0xffff;
+ int modifiers = this.getInnerClassFlags(accessFlags & JAVA_FLAGS_MASK);
+ return modifiers & JAVA_FLAGS_MASK;
+ }
+
+ /**
+ * Gets the signers of this class.
+ *
+ * @return the signers of this class, or null if there are no signers. In
+ * particular, this method returns null if this object represents
+ * a primitive type or void.
+ * @since JDK1.1
+ */
+ public Object[] getSigners() {
+ return null;
+ }
+
+ @FastNative
+ private native Method getEnclosingMethodNative();
+
+ /**
+ * If this {@code Class} object represents a local or anonymous
+ * class within a method, returns a {@link
+ * java.lang.reflect.Method Method} object representing the
+ * immediately enclosing method of the underlying class. Returns
+ * {@code null} otherwise.
+ *
+ * In particular, this method returns {@code null} if the underlying
+ * class is a local or anonymous class immediately enclosed by a type
+ * declaration, instance initializer or static initializer.
+ *
+ * @return the immediately enclosing method of the underlying class, if
+ * that class is a local or anonymous class; otherwise {@code null}.
+ * @since 1.5
+ */
+ // Android-changed: Removed SecurityException
+ public Method getEnclosingMethod() {
+ if (classNameImpliesTopLevel()) {
+ return null;
+ }
+ return getEnclosingMethodNative();
+ }
+
+ /**
+ * If this {@code Class} object represents a local or anonymous
+ * class within a constructor, returns a {@link
+ * java.lang.reflect.Constructor Constructor} object representing
+ * the immediately enclosing constructor of the underlying
+ * class. Returns {@code null} otherwise. In particular, this
+ * method returns {@code null} if the underlying class is a local
+ * or anonymous class immediately enclosed by a type declaration,
+ * instance initializer or static initializer.
+ *
+ * @return the immediately enclosing constructor of the underlying class, if
+ * that class is a local or anonymous class; otherwise {@code null}.
+ * @since 1.5
+ */
+ // Android-changed: Removed SecurityException
+ public Constructor<?> getEnclosingConstructor() {
+ if (classNameImpliesTopLevel()) {
+ return null;
+ }
+ return getEnclosingConstructorNative();
+ }
+
+ @FastNative
+ private native Constructor<?> getEnclosingConstructorNative();
+
+ private boolean classNameImpliesTopLevel() {
+ return !getName().contains("$");
+ }
+
+
+ /**
+ * If the class or interface represented by this {@code Class} object
+ * is a member of another class, returns the {@code Class} object
+ * representing the class in which it was declared. This method returns
+ * null if this class or interface is not a member of any other class. If
+ * this {@code Class} object represents an array class, a primitive
+ * type, or void,then this method returns null.
+ *
+ * @return the declaring class for this class
+ * @since JDK1.1
+ */
+ // Android-changed: Removed SecurityException
+ @FastNative
+ public native Class<?> getDeclaringClass();
+
+ /**
+ * Returns the immediately enclosing class of the underlying
+ * class. If the underlying class is a top level class this
+ * method returns {@code null}.
+ * @return the immediately enclosing class of the underlying class
+ * @since 1.5
+ */
+ // Android-changed: Removed SecurityException
+ @FastNative
+ public native Class<?> getEnclosingClass();
+
+ /**
+ * Returns the simple name of the underlying class as given in the
+ * source code. Returns an empty string if the underlying class is
+ * anonymous.
+ *
+ * <p>The simple name of an array is the simple name of the
+ * component type with "[]" appended. In particular the simple
+ * name of an array whose component type is anonymous is "[]".
+ *
+ * @return the simple name of the underlying class
+ * @since 1.5
+ */
+ public String getSimpleName() {
+ if (isArray())
+ return getComponentType().getSimpleName()+"[]";
+
+ if (isAnonymousClass()) {
+ return "";
+ }
+
+ if (isMemberClass() || isLocalClass()) {
+ // Note that we obtain this information from getInnerClassName(), which uses
+ // dex system annotations to obtain the name. It is possible for this information
+ // to disagree with the actual enclosing class name. For example, if dex
+ // manipulation tools have renamed the enclosing class without adjusting
+ // the system annotation to match. See http://b/28800927.
+ return getInnerClassName();
+ }
+
+ String simpleName = getName();
+ final int dot = simpleName.lastIndexOf(".");
+ if (dot > 0) {
+ return simpleName.substring(simpleName.lastIndexOf(".")+1); // strip the package name
+ }
+
+ return simpleName;
+ }
+
+ /**
+ * Return an informative string for the name of this type.
+ *
+ * @return an informative string for the name of this type
+ * @since 1.8
+ */
+ public String getTypeName() {
+ if (isArray()) {
+ try {
+ Class<?> cl = this;
+ int dimensions = 0;
+ while (cl.isArray()) {
+ dimensions++;
+ cl = cl.getComponentType();
+ }
+ StringBuilder sb = new StringBuilder();
+ sb.append(cl.getName());
+ for (int i = 0; i < dimensions; i++) {
+ sb.append("[]");
+ }
+ return sb.toString();
+ } catch (Throwable e) { /*FALLTHRU*/ }
+ }
+ return getName();
+ }
+
+ /**
+ * Returns the canonical name of the underlying class as
+ * defined by the Java Language Specification. Returns null if
+ * the underlying class does not have a canonical name (i.e., if
+ * it is a local or anonymous class or an array whose component
+ * type does not have a canonical name).
+ * @return the canonical name of the underlying class if it exists, and
+ * {@code null} otherwise.
+ * @since 1.5
+ */
+ public String getCanonicalName() {
+ if (isArray()) {
+ String canonicalName = getComponentType().getCanonicalName();
+ if (canonicalName != null)
+ return canonicalName + "[]";
+ else
+ return null;
+ }
+ if (isLocalOrAnonymousClass())
+ return null;
+ Class<?> enclosingClass = getEnclosingClass();
+ if (enclosingClass == null) { // top level class
+ return getName();
+ } else {
+ String enclosingName = enclosingClass.getCanonicalName();
+ if (enclosingName == null)
+ return null;
+ return enclosingName + "." + getSimpleName();
+ }
+ }
+
+ /**
+ * Returns {@code true} if and only if the underlying class
+ * is an anonymous class.
+ *
+ * @return {@code true} if and only if this class is an anonymous class.
+ * @since 1.5
+ */
+ @FastNative
+ public native boolean isAnonymousClass();
+
+ /**
+ * Returns {@code true} if and only if the underlying class
+ * is a local class.
+ *
+ * @return {@code true} if and only if this class is a local class.
+ * @since 1.5
+ */
+ public boolean isLocalClass() {
+ return (getEnclosingMethod() != null || getEnclosingConstructor() != null)
+ && !isAnonymousClass();
+ }
+
+ /**
+ * Returns {@code true} if and only if the underlying class
+ * is a member class.
+ *
+ * @return {@code true} if and only if this class is a member class.
+ * @since 1.5
+ */
+ public boolean isMemberClass() {
+ return getDeclaringClass() != null;
+ }
+
+ /**
+ * Returns {@code true} if this is a local class or an anonymous
+ * class. Returns {@code false} otherwise.
+ */
+ private boolean isLocalOrAnonymousClass() {
+ // JVM Spec 4.8.6: A class must have an EnclosingMethod
+ // attribute if and only if it is a local class or an
+ // anonymous class.
+ return isLocalClass() || isAnonymousClass();
+ }
+
+ /**
+ * Returns an array containing {@code Class} objects representing all
+ * the public classes and interfaces that are members of the class
+ * represented by this {@code Class} object. This includes public
+ * class and interface members inherited from superclasses and public class
+ * and interface members declared by the class. This method returns an
+ * array of length 0 if this {@code Class} object has no public member
+ * classes or interfaces. This method also returns an array of length 0 if
+ * this {@code Class} object represents a primitive type, an array
+ * class, or void.
+ *
+ * @return the array of {@code Class} objects representing the public
+ * members of this class
+ *
+ * @since JDK1.1
+ */
+ @CallerSensitive
+ public Class<?>[] getClasses() {
+ List<Class<?>> result = new ArrayList<Class<?>>();
+ for (Class<?> c = this; c != null; c = c.superClass) {
+ for (Class<?> member : c.getDeclaredClasses()) {
+ if (Modifier.isPublic(member.getModifiers())) {
+ result.add(member);
+ }
+ }
+ }
+ return result.toArray(new Class[result.size()]);
+ }
+
+
+ /**
+ * Returns an array containing {@code Field} objects reflecting all
+ * the accessible public fields of the class or interface represented by
+ * this {@code Class} object.
+ *
+ * <p> If this {@code Class} object represents a class or interface with no
+ * no accessible public fields, then this method returns an array of length
+ * 0.
+ *
+ * <p> If this {@code Class} object represents a class, then this method
+ * returns the public fields of the class and of all its superclasses.
+ *
+ * <p> If this {@code Class} object represents an interface, then this
+ * method returns the fields of the interface and of all its
+ * superinterfaces.
+ *
+ * <p> If this {@code Class} object represents an array type, a primitive
+ * type, or void, then this method returns an array of length 0.
+ *
+ * <p> The elements in the returned array are not sorted and are not in any
+ * particular order.
+ *
+ * @return the array of {@code Field} objects representing the
+ * public fields
+ * @throws SecurityException
+ * If a security manager, <i>s</i>, is present and
+ * the caller's class loader is not the same as or an
+ * ancestor of the class loader for the current class and
+ * invocation of {@link SecurityManager#checkPackageAccess
+ * s.checkPackageAccess()} denies access to the package
+ * of this class.
+ *
+ * @since JDK1.1
+ * @jls 8.2 Class Members
+ * @jls 8.3 Field Declarations
+ */
+ @CallerSensitive
+ public Field[] getFields() throws SecurityException {
+ List<Field> fields = new ArrayList<Field>();
+ getPublicFieldsRecursive(fields);
+ return fields.toArray(new Field[fields.size()]);
+ }
+
+ /**
+ * Populates {@code result} with public fields defined by this class, its
+ * superclasses, and all implemented interfaces.
+ */
+ private void getPublicFieldsRecursive(List<Field> result) {
+ // search superclasses
+ for (Class<?> c = this; c != null; c = c.superClass) {
+ Collections.addAll(result, c.getPublicDeclaredFields());
+ }
+
+ // search iftable which has a flattened and uniqued list of interfaces
+ Object[] iftable = ifTable;
+ if (iftable != null) {
+ for (int i = 0; i < iftable.length; i += 2) {
+ Collections.addAll(result, ((Class<?>) iftable[i]).getPublicDeclaredFields());
+ }
+ }
+ }
+
+ /**
+ * Returns an array containing {@code Method} objects reflecting all the
+ * public methods of the class or interface represented by this {@code
+ * Class} object, including those declared by the class or interface and
+ * those inherited from superclasses and superinterfaces.
+ *
+ * <p> If this {@code Class} object represents a type that has multiple
+ * public methods with the same name and parameter types, but different
+ * return types, then the returned array has a {@code Method} object for
+ * each such method.
+ *
+ * <p> If this {@code Class} object represents a type with a class
+ * initialization method {@code <clinit>}, then the returned array does
+ * <em>not</em> have a corresponding {@code Method} object.
+ *
+ * <p> If this {@code Class} object represents an array type, then the
+ * returned array has a {@code Method} object for each of the public
+ * methods inherited by the array type from {@code Object}. It does not
+ * contain a {@code Method} object for {@code clone()}.
+ *
+ * <p> If this {@code Class} object represents an interface then the
+ * returned array does not contain any implicitly declared methods from
+ * {@code Object}. Therefore, if no methods are explicitly declared in
+ * this interface or any of its superinterfaces then the returned array
+ * has length 0. (Note that a {@code Class} object which represents a class
+ * always has public methods, inherited from {@code Object}.)
+ *
+ * <p> If this {@code Class} object represents a primitive type or void,
+ * then the returned array has length 0.
+ *
+ * <p> Static methods declared in superinterfaces of the class or interface
+ * represented by this {@code Class} object are not considered members of
+ * the class or interface.
+ *
+ * <p> The elements in the returned array are not sorted and are not in any
+ * particular order.
+ *
+ * @return the array of {@code Method} objects representing the
+ * public methods of this class
+ * @throws SecurityException
+ * If a security manager, <i>s</i>, is present and
+ * the caller's class loader is not the same as or an
+ * ancestor of the class loader for the current class and
+ * invocation of {@link SecurityManager#checkPackageAccess
+ * s.checkPackageAccess()} denies access to the package
+ * of this class.
+ *
+ * @jls 8.2 Class Members
+ * @jls 8.4 Method Declarations
+ * @since JDK1.1
+ */
+ @CallerSensitive
+ public Method[] getMethods() throws SecurityException {
+ List<Method> methods = new ArrayList<Method>();
+ getPublicMethodsInternal(methods);
+ /*
+ * Remove duplicate methods defined by superclasses and
+ * interfaces, preferring to keep methods declared by derived
+ * types.
+ */
+ CollectionUtils.removeDuplicates(methods, Method.ORDER_BY_SIGNATURE);
+ return methods.toArray(new Method[methods.size()]);
+ }
+
+ /**
+ * Populates {@code result} with public methods defined by this class, its
+ * superclasses, and all implemented interfaces, including overridden methods.
+ */
+ private void getPublicMethodsInternal(List<Method> result) {
+ Collections.addAll(result, getDeclaredMethodsUnchecked(true));
+ if (!isInterface()) {
+ // Search superclasses, for interfaces don't search java.lang.Object.
+ for (Class<?> c = superClass; c != null; c = c.superClass) {
+ Collections.addAll(result, c.getDeclaredMethodsUnchecked(true));
+ }
+ }
+ // Search iftable which has a flattened and uniqued list of interfaces.
+ Object[] iftable = ifTable;
+ if (iftable != null) {
+ for (int i = 0; i < iftable.length; i += 2) {
+ Class<?> ifc = (Class<?>) iftable[i];
+ Collections.addAll(result, ifc.getDeclaredMethodsUnchecked(true));
+ }
+ }
+ }
+
+ /**
+ * Returns an array containing {@code Constructor} objects reflecting
+ * all the public constructors of the class represented by this
+ * {@code Class} object. An array of length 0 is returned if the
+ * class has no public constructors, or if the class is an array class, or
+ * if the class reflects a primitive type or void.
+ *
+ * Note that while this method returns an array of {@code
+ * Constructor<T>} objects (that is an array of constructors from
+ * this class), the return type of this method is {@code
+ * Constructor<?>[]} and <em>not</em> {@code Constructor<T>[]} as
+ * might be expected. This less informative return type is
+ * necessary since after being returned from this method, the
+ * array could be modified to hold {@code Constructor} objects for
+ * different classes, which would violate the type guarantees of
+ * {@code Constructor<T>[]}.
+ *
+ * @return the array of {@code Constructor} objects representing the
+ * public constructors of this class
+ * @throws SecurityException
+ * If a security manager, <i>s</i>, is present and
+ * the caller's class loader is not the same as or an
+ * ancestor of the class loader for the current class and
+ * invocation of {@link SecurityManager#checkPackageAccess
+ * s.checkPackageAccess()} denies access to the package
+ * of this class.
+ *
+ * @since JDK1.1
+ */
+ @CallerSensitive
+ public Constructor<?>[] getConstructors() throws SecurityException {
+ return getDeclaredConstructorsInternal(true);
+ }
+
+
+ /**
+ * Returns a {@code Field} object that reflects the specified public member
+ * field of the class or interface represented by this {@code Class}
+ * object. The {@code name} parameter is a {@code String} specifying the
+ * simple name of the desired field.
+ *
+ * <p> The field to be reflected is determined by the algorithm that
+ * follows. Let C be the class or interface represented by this object:
+ *
+ * <OL>
+ * <LI> If C declares a public field with the name specified, that is the
+ * field to be reflected.</LI>
+ * <LI> If no field was found in step 1 above, this algorithm is applied
+ * recursively to each direct superinterface of C. The direct
+ * superinterfaces are searched in the order they were declared.</LI>
+ * <LI> If no field was found in steps 1 and 2 above, and C has a
+ * superclass S, then this algorithm is invoked recursively upon S.
+ * If C has no superclass, then a {@code NoSuchFieldException}
+ * is thrown.</LI>
+ * </OL>
+ *
+ * <p> If this {@code Class} object represents an array type, then this
+ * method does not find the {@code length} field of the array type.
+ *
+ * @param name the field name
+ * @return the {@code Field} object of this class specified by
+ * {@code name}
+ * @throws NoSuchFieldException if a field with the specified name is
+ * not found.
+ * @throws NullPointerException if {@code name} is {@code null}
+ * @throws SecurityException
+ * If a security manager, <i>s</i>, is present and
+ * the caller's class loader is not the same as or an
+ * ancestor of the class loader for the current class and
+ * invocation of {@link SecurityManager#checkPackageAccess
+ * s.checkPackageAccess()} denies access to the package
+ * of this class.
+ *
+ * @since JDK1.1
+ * @jls 8.2 Class Members
+ * @jls 8.3 Field Declarations
+ */
+ // Android-changed: Removed SecurityException
+ public Field getField(String name)
+ throws NoSuchFieldException {
+ if (name == null) {
+ throw new NullPointerException("name == null");
+ }
+ Field result = getPublicFieldRecursive(name);
+ if (result == null) {
+ throw new NoSuchFieldException(name);
+ }
+ return result;
+ }
+
+ /**
+ * The native implementation of the {@code getField} method.
+ *
+ * @throws NullPointerException
+ * if name is null.
+ * @see #getField(String)
+ */
+ @FastNative
+ private native Field getPublicFieldRecursive(String name);
+
+ /**
+ * Returns a {@code Method} object that reflects the specified public
+ * member method of the class or interface represented by this
+ * {@code Class} object. The {@code name} parameter is a
+ * {@code String} specifying the simple name of the desired method. The
+ * {@code parameterTypes} parameter is an array of {@code Class}
+ * objects that identify the method's formal parameter types, in declared
+ * order. If {@code parameterTypes} is {@code null}, it is
+ * treated as if it were an empty array.
+ *
+ * <p> If the {@code name} is "{@code <init>}" or "{@code <clinit>}" a
+ * {@code NoSuchMethodException} is raised. Otherwise, the method to
+ * be reflected is determined by the algorithm that follows. Let C be the
+ * class or interface represented by this object:
+ * <OL>
+ * <LI> C is searched for a <I>matching method</I>, as defined below. If a
+ * matching method is found, it is reflected.</LI>
+ * <LI> If no matching method is found by step 1 then:
+ * <OL TYPE="a">
+ * <LI> If C is a class other than {@code Object}, then this algorithm is
+ * invoked recursively on the superclass of C.</LI>
+ * <LI> If C is the class {@code Object}, or if C is an interface, then
+ * the superinterfaces of C (if any) are searched for a matching
+ * method. If any such method is found, it is reflected.</LI>
+ * </OL></LI>
+ * </OL>
+ *
+ * <p> To find a matching method in a class or interface C: If C
+ * declares exactly one public method with the specified name and exactly
+ * the same formal parameter types, that is the method reflected. If more
+ * than one such method is found in C, and one of these methods has a
+ * return type that is more specific than any of the others, that method is
+ * reflected; otherwise one of the methods is chosen arbitrarily.
+ *
+ * <p>Note that there may be more than one matching method in a
+ * class because while the Java language forbids a class to
+ * declare multiple methods with the same signature but different
+ * return types, the Java virtual machine does not. This
+ * increased flexibility in the virtual machine can be used to
+ * implement various language features. For example, covariant
+ * returns can be implemented with {@linkplain
+ * java.lang.reflect.Method#isBridge bridge methods}; the bridge
+ * method and the method being overridden would have the same
+ * signature but different return types.
+ *
+ * <p> If this {@code Class} object represents an array type, then this
+ * method does not find the {@code clone()} method.
+ *
+ * <p> Static methods declared in superinterfaces of the class or interface
+ * represented by this {@code Class} object are not considered members of
+ * the class or interface.
+ *
+ * @param name the name of the method
+ * @param parameterTypes the list of parameters
+ * @return the {@code Method} object that matches the specified
+ * {@code name} and {@code parameterTypes}
+ * @throws NoSuchMethodException if a matching method is not found
+ * or if the name is "<init>"or "<clinit>".
+ * @throws NullPointerException if {@code name} is {@code null}
+ * @throws SecurityException
+ * If a security manager, <i>s</i>, is present and
+ * the caller's class loader is not the same as or an
+ * ancestor of the class loader for the current class and
+ * invocation of {@link SecurityManager#checkPackageAccess
+ * s.checkPackageAccess()} denies access to the package
+ * of this class.
+ *
+ * @jls 8.2 Class Members
+ * @jls 8.4 Method Declarations
+ * @since JDK1.1
+ */
+ @CallerSensitive
+ public Method getMethod(String name, Class<?>... parameterTypes)
+ throws NoSuchMethodException, SecurityException {
+ return getMethod(name, parameterTypes, true);
+ }
+
+
+ /**
+ * Returns a {@code Constructor} object that reflects the specified
+ * public constructor of the class represented by this {@code Class}
+ * object. The {@code parameterTypes} parameter is an array of
+ * {@code Class} objects that identify the constructor's formal
+ * parameter types, in declared order.
+ *
+ * If this {@code Class} object represents an inner class
+ * declared in a non-static context, the formal parameter types
+ * include the explicit enclosing instance as the first parameter.
+ *
+ * <p> The constructor to reflect is the public constructor of the class
+ * represented by this {@code Class} object whose formal parameter
+ * types match those specified by {@code parameterTypes}.
+ *
+ * @param parameterTypes the parameter array
+ * @return the {@code Constructor} object of the public constructor that
+ * matches the specified {@code parameterTypes}
+ * @throws NoSuchMethodException if a matching method is not found.
+ * @throws SecurityException
+ * If a security manager, <i>s</i>, is present and
+ * the caller's class loader is not the same as or an
+ * ancestor of the class loader for the current class and
+ * invocation of {@link SecurityManager#checkPackageAccess
+ * s.checkPackageAccess()} denies access to the package
+ * of this class.
+ *
+ * @since JDK1.1
+ */
+ public Constructor<T> getConstructor(Class<?>... parameterTypes)
+ throws NoSuchMethodException, SecurityException {
+ return getConstructor0(parameterTypes, Member.PUBLIC);
+ }
+
+
+ /**
+ * Returns an array of {@code Class} objects reflecting all the
+ * classes and interfaces declared as members of the class represented by
+ * this {@code Class} object. This includes public, protected, default
+ * (package) access, and private classes and interfaces declared by the
+ * class, but excludes inherited classes and interfaces. This method
+ * returns an array of length 0 if the class declares no classes or
+ * interfaces as members, or if this {@code Class} object represents a
+ * primitive type, an array class, or void.
+ *
+ * @return the array of {@code Class} objects representing all the
+ * declared members of this class
+ * @throws SecurityException
+ * If a security manager, <i>s</i>, is present and any of the
+ * following conditions is met:
+ *
+ * <ul>
+ *
+ * <li> the caller's class loader is not the same as the
+ * class loader of this class and invocation of
+ * {@link SecurityManager#checkPermission
+ * s.checkPermission} method with
+ * {@code RuntimePermission("accessDeclaredMembers")}
+ * denies access to the declared classes within this class
+ *
+ * <li> the caller's class loader is not the same as or an
+ * ancestor of the class loader for the current class and
+ * invocation of {@link SecurityManager#checkPackageAccess
+ * s.checkPackageAccess()} denies access to the package
+ * of this class
+ *
+ * </ul>
+ *
+ * @since JDK1.1
+ */
+ // Android-changed: Removed SecurityException
+ @FastNative
+ public native Class<?>[] getDeclaredClasses();
+
+ /**
+ * Returns an array of {@code Field} objects reflecting all the fields
+ * declared by the class or interface represented by this
+ * {@code Class} object. This includes public, protected, default
+ * (package) access, and private fields, but excludes inherited fields.
+ *
+ * <p> If this {@code Class} object represents a class or interface with no
+ * declared fields, then this method returns an array of length 0.
+ *
+ * <p> If this {@code Class} object represents an array type, a primitive
+ * type, or void, then this method returns an array of length 0.
+ *
+ * <p> The elements in the returned array are not sorted and are not in any
+ * particular order.
+ *
+ * @return the array of {@code Field} objects representing all the
+ * declared fields of this class
+ * @throws SecurityException
+ * If a security manager, <i>s</i>, is present and any of the
+ * following conditions is met:
+ *
+ * <ul>
+ *
+ * <li> the caller's class loader is not the same as the
+ * class loader of this class and invocation of
+ * {@link SecurityManager#checkPermission
+ * s.checkPermission} method with
+ * {@code RuntimePermission("accessDeclaredMembers")}
+ * denies access to the declared fields within this class
+ *
+ * <li> the caller's class loader is not the same as or an
+ * ancestor of the class loader for the current class and
+ * invocation of {@link SecurityManager#checkPackageAccess
+ * s.checkPackageAccess()} denies access to the package
+ * of this class
+ *
+ * </ul>
+ *
+ * @since JDK1.1
+ * @jls 8.2 Class Members
+ * @jls 8.3 Field Declarations
+ */
+ // Android-changed: Removed SecurityException
+ @FastNative
+ public native Field[] getDeclaredFields();
+
+ /**
+ * Populates a list of fields without performing any security or type
+ * resolution checks first. If no fields exist, the list is not modified.
+ *
+ * @param publicOnly Whether to return only public fields.
+ * @hide
+ */
+ @FastNative
+ public native Field[] getDeclaredFieldsUnchecked(boolean publicOnly);
+
+ /**
+ *
+ * Returns an array containing {@code Method} objects reflecting all the
+ * declared methods of the class or interface represented by this {@code
+ * Class} object, including public, protected, default (package)
+ * access, and private methods, but excluding inherited methods.
+ *
+ * <p> If this {@code Class} object represents a type that has multiple
+ * declared methods with the same name and parameter types, but different
+ * return types, then the returned array has a {@code Method} object for
+ * each such method.
+ *
+ * <p> If this {@code Class} object represents a type that has a class
+ * initialization method {@code <clinit>}, then the returned array does
+ * <em>not</em> have a corresponding {@code Method} object.
+ *
+ * <p> If this {@code Class} object represents a class or interface with no
+ * declared methods, then the returned array has length 0.
+ *
+ * <p> If this {@code Class} object represents an array type, a primitive
+ * type, or void, then the returned array has length 0.
+ *
+ * <p> The elements in the returned array are not sorted and are not in any
+ * particular order.
+ *
+ * @return the array of {@code Method} objects representing all the
+ * declared methods of this class
+ * @throws SecurityException
+ * If a security manager, <i>s</i>, is present and any of the
+ * following conditions is met:
+ *
+ * <ul>
+ *
+ * <li> the caller's class loader is not the same as the
+ * class loader of this class and invocation of
+ * {@link SecurityManager#checkPermission
+ * s.checkPermission} method with
+ * {@code RuntimePermission("accessDeclaredMembers")}
+ * denies access to the declared methods within this class
+ *
+ * <li> the caller's class loader is not the same as or an
+ * ancestor of the class loader for the current class and
+ * invocation of {@link SecurityManager#checkPackageAccess
+ * s.checkPackageAccess()} denies access to the package
+ * of this class
+ *
+ * </ul>
+ *
+ * @jls 8.2 Class Members
+ * @jls 8.4 Method Declarations
+ * @since JDK1.1
+ */
+ public Method[] getDeclaredMethods() throws SecurityException {
+ Method[] result = getDeclaredMethodsUnchecked(false);
+ for (Method m : result) {
+ // Throw NoClassDefFoundError if types cannot be resolved.
+ m.getReturnType();
+ m.getParameterTypes();
+ }
+ return result;
+ }
+
+ /**
+ * Populates a list of methods without performing any security or type
+ * resolution checks first. If no methods exist, the list is not modified.
+ *
+ * @param publicOnly Whether to return only public methods.
+ * @hide
+ */
+ @FastNative
+ public native Method[] getDeclaredMethodsUnchecked(boolean publicOnly);
+
+ /**
+ * Returns an array of {@code Constructor} objects reflecting all the
+ * constructors declared by the class represented by this
+ * {@code Class} object. These are public, protected, default
+ * (package) access, and private constructors. The elements in the array
+ * returned are not sorted and are not in any particular order. If the
+ * class has a default constructor, it is included in the returned array.
+ * This method returns an array of length 0 if this {@code Class}
+ * object represents an interface, a primitive type, an array class, or
+ * void.
+ *
+ * <p> See <em>The Java Language Specification</em>, section 8.2.
+ *
+ * @return the array of {@code Constructor} objects representing all the
+ * declared constructors of this class
+ * @throws SecurityException
+ * If a security manager, <i>s</i>, is present and any of the
+ * following conditions is met:
+ *
+ * <ul>
+ *
+ * <li> the caller's class loader is not the same as the
+ * class loader of this class and invocation of
+ * {@link SecurityManager#checkPermission
+ * s.checkPermission} method with
+ * {@code RuntimePermission("accessDeclaredMembers")}
+ * denies access to the declared constructors within this class
+ *
+ * <li> the caller's class loader is not the same as or an
+ * ancestor of the class loader for the current class and
+ * invocation of {@link SecurityManager#checkPackageAccess
+ * s.checkPackageAccess()} denies access to the package
+ * of this class
+ *
+ * </ul>
+ *
+ * @since JDK1.1
+ */
+ public Constructor<?>[] getDeclaredConstructors() throws SecurityException {
+ return getDeclaredConstructorsInternal(false);
+ }
+
+
+ /**
+ * Returns the constructor with the given parameters if it is defined by this class;
+ * {@code null} otherwise. This may return a non-public member.
+ */
+ @FastNative
+ private native Constructor<?>[] getDeclaredConstructorsInternal(boolean publicOnly);
+
+ /**
+ * Returns a {@code Field} object that reflects the specified declared
+ * field of the class or interface represented by this {@code Class}
+ * object. The {@code name} parameter is a {@code String} that specifies
+ * the simple name of the desired field.
+ *
+ * <p> If this {@code Class} object represents an array type, then this
+ * method does not find the {@code length} field of the array type.
+ *
+ * @param name the name of the field
+ * @return the {@code Field} object for the specified field in this
+ * class
+ * @throws NoSuchFieldException if a field with the specified name is
+ * not found.
+ * @throws NullPointerException if {@code name} is {@code null}
+ * @throws SecurityException
+ * If a security manager, <i>s</i>, is present and any of the
+ * following conditions is met:
+ *
+ * <ul>
+ *
+ * <li> the caller's class loader is not the same as the
+ * class loader of this class and invocation of
+ * {@link SecurityManager#checkPermission
+ * s.checkPermission} method with
+ * {@code RuntimePermission("accessDeclaredMembers")}
+ * denies access to the declared field
+ *
+ * <li> the caller's class loader is not the same as or an
+ * ancestor of the class loader for the current class and
+ * invocation of {@link SecurityManager#checkPackageAccess
+ * s.checkPackageAccess()} denies access to the package
+ * of this class
+ *
+ * </ul>
+ *
+ * @since JDK1.1
+ * @jls 8.2 Class Members
+ * @jls 8.3 Field Declarations
+ */
+ // Android-changed: Removed SecurityException
+ @FastNative
+ public native Field getDeclaredField(String name) throws NoSuchFieldException;
+
+ /**
+ * Returns the subset of getDeclaredFields which are public.
+ */
+ @FastNative
+ private native Field[] getPublicDeclaredFields();
+
+ /**
+ * Returns a {@code Method} object that reflects the specified
+ * declared method of the class or interface represented by this
+ * {@code Class} object. The {@code name} parameter is a
+ * {@code String} that specifies the simple name of the desired
+ * method, and the {@code parameterTypes} parameter is an array of
+ * {@code Class} objects that identify the method's formal parameter
+ * types, in declared order. If more than one method with the same
+ * parameter types is declared in a class, and one of these methods has a
+ * return type that is more specific than any of the others, that method is
+ * returned; otherwise one of the methods is chosen arbitrarily. If the
+ * name is "<init>"or "<clinit>" a {@code NoSuchMethodException}
+ * is raised.
+ *
+ * <p> If this {@code Class} object represents an array type, then this
+ * method does not find the {@code clone()} method.
+ *
+ * @param name the name of the method
+ * @param parameterTypes the parameter array
+ * @return the {@code Method} object for the method of this class
+ * matching the specified name and parameters
+ * @throws NoSuchMethodException if a matching method is not found.
+ * @throws NullPointerException if {@code name} is {@code null}
+ * @throws SecurityException
+ * If a security manager, <i>s</i>, is present and any of the
+ * following conditions is met:
+ *
+ * <ul>
+ *
+ * <li> the caller's class loader is not the same as the
+ * class loader of this class and invocation of
+ * {@link SecurityManager#checkPermission
+ * s.checkPermission} method with
+ * {@code RuntimePermission("accessDeclaredMembers")}
+ * denies access to the declared method
+ *
+ * <li> the caller's class loader is not the same as or an
+ * ancestor of the class loader for the current class and
+ * invocation of {@link SecurityManager#checkPackageAccess
+ * s.checkPackageAccess()} denies access to the package
+ * of this class
+ *
+ * </ul>
+ *
+ * @jls 8.2 Class Members
+ * @jls 8.4 Method Declarations
+ * @since JDK1.1
+ */
+ @CallerSensitive
+ public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
+ throws NoSuchMethodException, SecurityException {
+ return getMethod(name, parameterTypes, false);
+ }
+
+ private Method getMethod(String name, Class<?>[] parameterTypes, boolean recursivePublicMethods)
+ throws NoSuchMethodException {
+ if (name == null) {
+ throw new NullPointerException("name == null");
+ }
+ if (parameterTypes == null) {
+ parameterTypes = EmptyArray.CLASS;
+ }
+ for (Class<?> c : parameterTypes) {
+ if (c == null) {
+ throw new NoSuchMethodException("parameter type is null");
+ }
+ }
+ Method result = recursivePublicMethods ? getPublicMethodRecursive(name, parameterTypes)
+ : getDeclaredMethodInternal(name, parameterTypes);
+ // Fail if we didn't find the method or it was expected to be public.
+ if (result == null ||
+ (recursivePublicMethods && !Modifier.isPublic(result.getAccessFlags()))) {
+ throw new NoSuchMethodException(getName() + "." + name + " "
+ + Arrays.toString(parameterTypes));
+ }
+ return result;
+ }
+ private Method getPublicMethodRecursive(String name, Class<?>[] parameterTypes) {
+ // search superclasses
+ for (Class<?> c = this; c != null; c = c.getSuperclass()) {
+ Method result = c.getDeclaredMethodInternal(name, parameterTypes);
+ if (result != null && Modifier.isPublic(result.getAccessFlags())) {
+ return result;
+ }
+ }
+
+ return findInterfaceMethod(name, parameterTypes);
+ }
+
+ /**
+ * Returns an instance method that's defined on this class or any super classes, regardless
+ * of its access flags. Constructors are excluded.
+ *
+ * This function does not perform access checks and its semantics don't match any dex byte code
+ * instruction or public reflection API. This is used by {@code MethodHandles.findVirtual}
+ * which will perform access checks on the returned method.
+ *
+ * @hide
+ */
+ public Method getInstanceMethod(String name, Class<?>[] parameterTypes)
+ throws NoSuchMethodException, IllegalAccessException {
+ for (Class<?> c = this; c != null; c = c.getSuperclass()) {
+ Method result = c.getDeclaredMethodInternal(name, parameterTypes);
+ if (result != null && !Modifier.isStatic(result.getModifiers())) {
+ return result;
+ }
+ }
+
+ return findInterfaceMethod(name, parameterTypes);
+ }
+
+ private Method findInterfaceMethod(String name, Class<?>[] parameterTypes) {
+ Object[] iftable = ifTable;
+ if (iftable != null) {
+ // Search backwards so more specific interfaces are searched first. This ensures that
+ // the method we return is not overridden by one of it's subtypes that this class also
+ // implements.
+ for (int i = iftable.length - 2; i >= 0; i -= 2) {
+ Class<?> ifc = (Class<?>) iftable[i];
+ Method result = ifc.getPublicMethodRecursive(name, parameterTypes);
+ if (result != null && Modifier.isPublic(result.getAccessFlags())) {
+ return result;
+ }
+ }
+ }
+
+ return null;
+ }
+
+
+ /**
+ * Returns a {@code Constructor} object that reflects the specified
+ * constructor of the class or interface represented by this
+ * {@code Class} object. The {@code parameterTypes} parameter is
+ * an array of {@code Class} objects that identify the constructor's
+ * formal parameter types, in declared order.
+ *
+ * If this {@code Class} object represents an inner class
+ * declared in a non-static context, the formal parameter types
+ * include the explicit enclosing instance as the first parameter.
+ *
+ * @param parameterTypes the parameter array
+ * @return The {@code Constructor} object for the constructor with the
+ * specified parameter list
+ * @throws NoSuchMethodException if a matching method is not found.
+ * @throws SecurityException
+ * If a security manager, <i>s</i>, is present and any of the
+ * following conditions is met:
+ *
+ * <ul>
+ *
+ * <li> the caller's class loader is not the same as the
+ * class loader of this class and invocation of
+ * {@link SecurityManager#checkPermission
+ * s.checkPermission} method with
+ * {@code RuntimePermission("accessDeclaredMembers")}
+ * denies access to the declared constructor
+ *
+ * <li> the caller's class loader is not the same as or an
+ * ancestor of the class loader for the current class and
+ * invocation of {@link SecurityManager#checkPackageAccess
+ * s.checkPackageAccess()} denies access to the package
+ * of this class
+ *
+ * </ul>
+ *
+ * @since JDK1.1
+ */
+ @CallerSensitive
+ public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
+ throws NoSuchMethodException, SecurityException {
+ return getConstructor0(parameterTypes, Member.DECLARED);
+ }
+
+ /**
+ * Finds a resource with a given name. The rules for searching resources
+ * associated with a given class are implemented by the defining
+ * {@linkplain ClassLoader class loader} of the class. This method
+ * delegates to this object's class loader. If this object was loaded by
+ * the bootstrap class loader, the method delegates to {@link
+ * ClassLoader#getSystemResourceAsStream}.
+ *
+ * <p> Before delegation, an absolute resource name is constructed from the
+ * given resource name using this algorithm:
+ *
+ * <ul>
+ *
+ * <li> If the {@code name} begins with a {@code '/'}
+ * (<tt>'\u002f'</tt>), then the absolute name of the resource is the
+ * portion of the {@code name} following the {@code '/'}.
+ *
+ * <li> Otherwise, the absolute name is of the following form:
+ *
+ * <blockquote>
+ * {@code modified_package_name/name}
+ * </blockquote>
+ *
+ * <p> Where the {@code modified_package_name} is the package name of this
+ * object with {@code '/'} substituted for {@code '.'}
+ * (<tt>'\u002e'</tt>).
+ *
+ * </ul>
+ *
+ * @param name name of the desired resource
+ * @return A {@link java.io.InputStream} object or {@code null} if
+ * no resource with this name is found
+ * @throws NullPointerException If {@code name} is {@code null}
+ * @since JDK1.1
+ */
+ public InputStream getResourceAsStream(String name) {
+ name = resolveName(name);
+ ClassLoader cl = getClassLoader();
+ if (cl==null) {
+ // A system class.
+ return ClassLoader.getSystemResourceAsStream(name);
+ }
+ return cl.getResourceAsStream(name);
+ }
+
+ /**
+ * Finds a resource with a given name. The rules for searching resources
+ * associated with a given class are implemented by the defining
+ * {@linkplain ClassLoader class loader} of the class. This method
+ * delegates to this object's class loader. If this object was loaded by
+ * the bootstrap class loader, the method delegates to {@link
+ * ClassLoader#getSystemResource}.
+ *
+ * <p> Before delegation, an absolute resource name is constructed from the
+ * given resource name using this algorithm:
+ *
+ * <ul>
+ *
+ * <li> If the {@code name} begins with a {@code '/'}
+ * (<tt>'\u002f'</tt>), then the absolute name of the resource is the
+ * portion of the {@code name} following the {@code '/'}.
+ *
+ * <li> Otherwise, the absolute name is of the following form:
+ *
+ * <blockquote>
+ * {@code modified_package_name/name}
+ * </blockquote>
+ *
+ * <p> Where the {@code modified_package_name} is the package name of this
+ * object with {@code '/'} substituted for {@code '.'}
+ * (<tt>'\u002e'</tt>).
+ *
+ * </ul>
+ *
+ * @param name name of the desired resource
+ * @return A {@link java.net.URL} object or {@code null} if no
+ * resource with this name is found
+ * @since JDK1.1
+ */
+ public java.net.URL getResource(String name) {
+ name = resolveName(name);
+ ClassLoader cl = getClassLoader();
+ if (cl==null) {
+ // A system class.
+ return ClassLoader.getSystemResource(name);
+ }
+ return cl.getResource(name);
+ }
+
+ /**
+ * Returns the {@code ProtectionDomain} of this class. If there is a
+ * security manager installed, this method first calls the security
+ * manager's {@code checkPermission} method with a
+ * {@code RuntimePermission("getProtectionDomain")} permission to
+ * ensure it's ok to get the
+ * {@code ProtectionDomain}.
+ *
+ * @return the ProtectionDomain of this class
+ *
+ * @throws SecurityException
+ * if a security manager exists and its
+ * {@code checkPermission} method doesn't allow
+ * getting the ProtectionDomain.
+ *
+ * @see java.security.ProtectionDomain
+ * @see SecurityManager#checkPermission
+ * @see java.lang.RuntimePermission
+ * @since 1.2
+ */
+ public java.security.ProtectionDomain getProtectionDomain() {
+ return null;
+ }
+
+ /*
+ * Return the runtime's Class object for the named
+ * primitive type.
+ */
+ @FastNative
+ static native Class<?> getPrimitiveClass(String name);
+
+ /**
+ * Add a package name prefix if the name is not absolute Remove leading "/"
+ * if name is absolute
+ */
+ private String resolveName(String name) {
+ if (name == null) {
+ return name;
+ }
+ if (!name.startsWith("/")) {
+ Class<?> c = this;
+ while (c.isArray()) {
+ c = c.getComponentType();
+ }
+ String baseName = c.getName();
+ int index = baseName.lastIndexOf('.');
+ if (index != -1) {
+ name = baseName.substring(0, index).replace('.', '/')
+ +"/"+name;
+ }
+ } else {
+ name = name.substring(1);
+ }
+ return name;
+ }
+
+ private Constructor<T> getConstructor0(Class<?>[] parameterTypes,
+ int which) throws NoSuchMethodException
+ {
+ if (parameterTypes == null) {
+ parameterTypes = EmptyArray.CLASS;
+ }
+ for (Class<?> c : parameterTypes) {
+ if (c == null) {
+ throw new NoSuchMethodException("parameter type is null");
+ }
+ }
+ Constructor<T> result = getDeclaredConstructorInternal(parameterTypes);
+ if (result == null || which == Member.PUBLIC && !Modifier.isPublic(result.getAccessFlags())) {
+ throw new NoSuchMethodException(getName() + ".<init> "
+ + Arrays.toString(parameterTypes));
+ }
+ return result;
+ }
+
+ /** use serialVersionUID from JDK 1.1 for interoperability */
+ private static final long serialVersionUID = 3206093459760846163L;
+
+
+ /**
+ * Returns the constructor with the given parameters if it is defined by this class;
+ * {@code null} otherwise. This may return a non-public member.
+ *
+ * @param args the types of the parameters to the constructor.
+ */
+ @FastNative
+ private native Constructor<T> getDeclaredConstructorInternal(Class<?>[] args);
+
+ /**
+ * Returns the assertion status that would be assigned to this
+ * class if it were to be initialized at the time this method is invoked.
+ * If this class has had its assertion status set, the most recent
+ * setting will be returned; otherwise, if any package default assertion
+ * status pertains to this class, the most recent setting for the most
+ * specific pertinent package default assertion status is returned;
+ * otherwise, if this class is not a system class (i.e., it has a
+ * class loader) its class loader's default assertion status is returned;
+ * otherwise, the system class default assertion status is returned.
+ * <p>
+ * Few programmers will have any need for this method; it is provided
+ * for the benefit of the JRE itself. (It allows a class to determine at
+ * the time that it is initialized whether assertions should be enabled.)
+ * Note that this method is not guaranteed to return the actual
+ * assertion status that was (or will be) associated with the specified
+ * class when it was (or will be) initialized.
+ *
+ * @return the desired assertion status of the specified class.
+ * @see java.lang.ClassLoader#setClassAssertionStatus
+ * @see java.lang.ClassLoader#setPackageAssertionStatus
+ * @see java.lang.ClassLoader#setDefaultAssertionStatus
+ * @since 1.4
+ */
+ public boolean desiredAssertionStatus() {
+ return false;
+ }
+
+ /**
+ * Returns the simple name of a member or local class, or {@code null} otherwise.
+ */
+ @FastNative
+ private native String getInnerClassName();
+
+ @FastNative
+ private native int getInnerClassFlags(int defaultValue);
+
+ /**
+ * Returns true if and only if this class was declared as an enum in the
+ * source code.
+ *
+ * @return true if and only if this class was declared as an enum in the
+ * source code
+ * @since 1.5
+ */
+ public boolean isEnum() {
+ // An enum must both directly extend java.lang.Enum and have
+ // the ENUM bit set; classes for specialized enum constants
+ // don't do the former.
+ return (this.getModifiers() & ENUM) != 0 &&
+ this.getSuperclass() == java.lang.Enum.class;
+ }
+
+ /**
+ * Returns the elements of this enum class or null if this
+ * Class object does not represent an enum type.
+ *
+ * @return an array containing the values comprising the enum class
+ * represented by this Class object in the order they're
+ * declared, or null if this Class object does not
+ * represent an enum type
+ * @since 1.5
+ */
+ public T[] getEnumConstants() {
+ T[] values = getEnumConstantsShared();
+ return (values != null) ? values.clone() : null;
+ }
+
+ // Android-changed: Made public/hidden instead of using sun.misc.SharedSecrets.
+ /**
+ * Returns the elements of this enum class or null if this
+ * Class object does not represent an enum type;
+ * identical to getEnumConstants except that the result is
+ * uncloned, cached, and shared by all callers.
+ * @hide
+ */
+ public T[] getEnumConstantsShared() {
+ if (!isEnum()) return null;
+ return (T[]) Enum.getSharedConstants((Class) this);
+ }
+
+ /**
+ * Casts an object to the class or interface represented
+ * by this {@code Class} object.
+ *
+ * @param obj the object to be cast
+ * @return the object after casting, or null if obj is null
+ *
+ * @throws ClassCastException if the object is not
+ * null and is not assignable to the type T.
+ *
+ * @since 1.5
+ */
+ @SuppressWarnings("unchecked")
+ public T cast(Object obj) {
+ if (obj != null && !isInstance(obj))
+ throw new ClassCastException(cannotCastMsg(obj));
+ return (T) obj;
+ }
+
+ private String cannotCastMsg(Object obj) {
+ return "Cannot cast " + obj.getClass().getName() + " to " + getName();
+ }
+
+ /**
+ * Casts this {@code Class} object to represent a subclass of the class
+ * represented by the specified class object. Checks that the cast
+ * is valid, and throws a {@code ClassCastException} if it is not. If
+ * this method succeeds, it always returns a reference to this class object.
+ *
+ * <p>This method is useful when a client needs to "narrow" the type of
+ * a {@code Class} object to pass it to an API that restricts the
+ * {@code Class} objects that it is willing to accept. A cast would
+ * generate a compile-time warning, as the correctness of the cast
+ * could not be checked at runtime (because generic types are implemented
+ * by erasure).
+ *
+ * @param <U> the type to cast this class object to
+ * @param clazz the class of the type to cast this class object to
+ * @return this {@code Class} object, cast to represent a subclass of
+ * the specified class object.
+ * @throws ClassCastException if this {@code Class} object does not
+ * represent a subclass of the specified class (here "subclass" includes
+ * the class itself).
+ * @since 1.5
+ */
+ @SuppressWarnings("unchecked")
+ public <U> Class<? extends U> asSubclass(Class<U> clazz) {
+ if (clazz.isAssignableFrom(this))
+ return (Class<? extends U>) this;
+ else
+ throw new ClassCastException(this.toString() +
+ " cannot be cast to " + clazz.getName());
+ }
+
+ /**
+ * @throws NullPointerException {@inheritDoc}
+ * @since 1.5
+ */
+ @SuppressWarnings("unchecked")
+ public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {
+ Objects.requireNonNull(annotationClass);
+
+ A annotation = getDeclaredAnnotation(annotationClass);
+ if (annotation != null) {
+ return annotation;
+ }
+
+ if (annotationClass.isDeclaredAnnotationPresent(Inherited.class)) {
+ for (Class<?> sup = getSuperclass(); sup != null; sup = sup.getSuperclass()) {
+ annotation = sup.getDeclaredAnnotation(annotationClass);
+ if (annotation != null) {
+ return annotation;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @throws NullPointerException {@inheritDoc}
+ * @since 1.5
+ */
+ @Override
+ public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
+ if (annotationClass == null) {
+ throw new NullPointerException("annotationClass == null");
+ }
+
+ if (isDeclaredAnnotationPresent(annotationClass)) {
+ return true;
+ }
+
+ if (annotationClass.isDeclaredAnnotationPresent(Inherited.class)) {
+ for (Class<?> sup = getSuperclass(); sup != null; sup = sup.getSuperclass()) {
+ if (sup.isDeclaredAnnotationPresent(annotationClass)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * @throws NullPointerException {@inheritDoc}
+ * @since 1.8
+ */
+ @Override
+ public <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationClass) {
+ // Find any associated annotations [directly or repeatably (indirectly) present on this].
+ A[] annotations = GenericDeclaration.super.getAnnotationsByType(annotationClass);
+
+ if (annotations.length != 0) {
+ return annotations;
+ }
+
+ // Nothing was found, attempt looking for associated annotations recursively up to the root
+ // class if and only if:
+ // * The annotation class was marked with @Inherited.
+ //
+ // Inherited annotations are not coalesced into a single set: the first declaration found is
+ // returned.
+
+ if (annotationClass.isDeclaredAnnotationPresent(Inherited.class)) {
+ Class<?> superClass = getSuperclass(); // Returns null if klass's base is Object.
+
+ if (superClass != null) {
+ return superClass.getAnnotationsByType(annotationClass);
+ }
+ }
+
+ // Annotated was not marked with @Inherited, or no superclass.
+ return (A[]) Array.newInstance(annotationClass, 0); // Safe by construction.
+ }
+
+ /**
+ * @since 1.5
+ */
+ @Override
+ public Annotation[] getAnnotations() {
+ /*
+ * We need to get the annotations declared on this class, plus the
+ * annotations from superclasses that have the "@Inherited" annotation
+ * set. We create a temporary map to use while we accumulate the
+ * annotations and convert it to an array at the end.
+ *
+ * It's possible to have duplicates when annotations are inherited.
+ * We use a Map to filter those out.
+ *
+ * HashMap might be overkill here.
+ */
+ HashMap<Class<?>, Annotation> map = new HashMap<Class<?>, Annotation>();
+ for (Annotation declaredAnnotation : getDeclaredAnnotations()) {
+ map.put(declaredAnnotation.annotationType(), declaredAnnotation);
+ }
+ for (Class<?> sup = getSuperclass(); sup != null; sup = sup.getSuperclass()) {
+ for (Annotation declaredAnnotation : sup.getDeclaredAnnotations()) {
+ Class<? extends Annotation> clazz = declaredAnnotation.annotationType();
+ if (!map.containsKey(clazz) && clazz.isDeclaredAnnotationPresent(Inherited.class)) {
+ map.put(clazz, declaredAnnotation);
+ }
+ }
+ }
+
+ /* Convert annotation values from HashMap to array. */
+ Collection<Annotation> coll = map.values();
+ return coll.toArray(new Annotation[coll.size()]);
+ }
+
+ /**
+ * @throws NullPointerException {@inheritDoc}
+ * @since 1.8
+ */
+ @Override
+ @FastNative
+ public native <A extends Annotation> A getDeclaredAnnotation(Class<A> annotationClass);
+
+ /**
+ * @since 1.5
+ */
+ @Override
+ @FastNative
+ public native Annotation[] getDeclaredAnnotations();
+
+ /**
+ * Returns true if the annotation exists.
+ */
+ @FastNative
+ private native boolean isDeclaredAnnotationPresent(Class<? extends Annotation> annotationClass);
+
+ private String getSignatureAttribute() {
+ String[] annotation = getSignatureAnnotation();
+ if (annotation == null) {
+ return null;
+ }
+ StringBuilder result = new StringBuilder();
+ for (String s : annotation) {
+ result.append(s);
+ }
+ return result.toString();
+ }
+
+ @FastNative
+ private native String[] getSignatureAnnotation();
+
+ /**
+ * Is this a runtime created proxy class?
+ *
+ * @hide
+ */
+ public boolean isProxy() {
+ return (accessFlags & 0x00040000) != 0;
+ }
+
+ /**
+ * @hide
+ */
+ public int getAccessFlags() {
+ return accessFlags;
+ }
+
+
+ /**
+ * Returns the method if it is defined by this class; {@code null} otherwise. This may return a
+ * non-public member.
+ *
+ * @param name the method name
+ * @param args the method's parameter types
+ */
+ @FastNative
+ private native Method getDeclaredMethodInternal(String name, Class<?>[] args);
+
+ private static class Caches {
+ /**
+ * Cache to avoid frequent recalculation of generic interfaces, which is generally uncommon.
+ * Sized sufficient to allow ConcurrentHashMapTest to run without recalculating its generic
+ * interfaces (required to avoid time outs). Validated by running reflection heavy code
+ * such as applications using Guice-like frameworks.
+ */
+ private static final BasicLruCache<Class, Type[]> genericInterfaces
+ = new BasicLruCache<Class, Type[]>(8);
+ }
+}
diff --git a/java/lang/ClassCastException.java b/java/lang/ClassCastException.java
new file mode 100644
index 0000000..e4ca76c
--- /dev/null
+++ b/java/lang/ClassCastException.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 1994, 2013, 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;
+
+/**
+ * Thrown to indicate that the code has attempted to cast an object
+ * to a subclass of which it is not an instance. For example, the
+ * following code generates a <code>ClassCastException</code>:
+ * <blockquote><pre>
+ * Object x = new Integer(0);
+ * System.out.println((String)x);
+ * </pre></blockquote>
+ *
+ * @author unascribed
+ * @since JDK1.0
+ */
+public
+class ClassCastException extends RuntimeException {
+ private static final long serialVersionUID = -9223365651070458532L;
+
+ /**
+ * Constructs a <code>ClassCastException</code> with no detail message.
+ */
+ public ClassCastException() {
+ super();
+ }
+
+ /**
+ * Constructs a <code>ClassCastException</code> with the specified
+ * detail message.
+ *
+ * @param s the detail message.
+ */
+ public ClassCastException(String s) {
+ super(s);
+ }
+}
diff --git a/java/lang/ClassCircularityError.java b/java/lang/ClassCircularityError.java
new file mode 100644
index 0000000..64e5361
--- /dev/null
+++ b/java/lang/ClassCircularityError.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 1995, 2008, 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;
+
+/**
+ * Thrown when the Java Virtual Machine detects a circularity in the
+ * superclass hierarchy of a class being loaded.
+ *
+ * @author unascribed
+ * @since JDK1.0
+ */
+public class ClassCircularityError extends LinkageError {
+ private static final long serialVersionUID = 1054362542914539689L;
+
+ /**
+ * Constructs a {@code ClassCircularityError} with no detail message.
+ */
+ public ClassCircularityError() {
+ super();
+ }
+
+ /**
+ * Constructs a {@code ClassCircularityError} with the specified detail
+ * message.
+ *
+ * @param s
+ * The detail message
+ */
+ public ClassCircularityError(String s) {
+ super(s);
+ }
+}
diff --git a/java/lang/ClassFormatError.java b/java/lang/ClassFormatError.java
new file mode 100644
index 0000000..2dc81db
--- /dev/null
+++ b/java/lang/ClassFormatError.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 1994, 2008, 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;
+
+/**
+ * Thrown when the Java Virtual Machine attempts to read a class
+ * file and determines that the file is malformed or otherwise cannot
+ * be interpreted as a class file.
+ *
+ * @author unascribed
+ * @since JDK1.0
+ */
+public
+class ClassFormatError extends LinkageError {
+ private static final long serialVersionUID = -8420114879011949195L;
+
+ /**
+ * Constructs a <code>ClassFormatError</code> with no detail message.
+ */
+ public ClassFormatError() {
+ super();
+ }
+
+ /**
+ * Constructs a <code>ClassFormatError</code> with the specified
+ * detail message.
+ *
+ * @param s the detail message.
+ */
+ public ClassFormatError(String s) {
+ super(s);
+ }
+}
diff --git a/java/lang/ClassLoader.java b/java/lang/ClassLoader.java
new file mode 100644
index 0000000..0a8b08a
--- /dev/null
+++ b/java/lang/ClassLoader.java
@@ -0,0 +1,1428 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2013, 2015, 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;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.File;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.security.AccessController;
+import java.security.AccessControlContext;
+import java.security.CodeSource;
+import java.security.Policy;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.security.ProtectionDomain;
+import java.security.cert.Certificate;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.Stack;
+import java.util.Map;
+import java.util.Vector;
+import java.util.Hashtable;
+import java.util.WeakHashMap;
+import java.util.concurrent.ConcurrentHashMap;
+import dalvik.system.PathClassLoader;
+import java.util.List;
+import sun.misc.CompoundEnumeration;
+import sun.misc.Resource;
+import sun.misc.URLClassPath;
+import sun.misc.VM;
+import sun.reflect.CallerSensitive;
+import sun.reflect.Reflection;
+import sun.security.util.SecurityConstants;
+
+/**
+ * A class loader is an object that is responsible for loading classes. The
+ * class <tt>ClassLoader</tt> is an abstract class. Given the <a
+ * href="#name">binary name</a> of a class, a class loader should attempt to
+ * locate or generate data that constitutes a definition for the class. A
+ * typical strategy is to transform the name into a file name and then read a
+ * "class file" of that name from a file system.
+ *
+ * <p> Every {@link Class <tt>Class</tt>} object contains a {@link
+ * Class#getClassLoader() reference} to the <tt>ClassLoader</tt> that defined
+ * it.
+ *
+ * <p> <tt>Class</tt> objects for array classes are not created by class
+ * loaders, but are created automatically as required by the Java runtime.
+ * The class loader for an array class, as returned by {@link
+ * Class#getClassLoader()} is the same as the class loader for its element
+ * type; if the element type is a primitive type, then the array class has no
+ * class loader.
+ *
+ * <p> Applications implement subclasses of <tt>ClassLoader</tt> in order to
+ * extend the manner in which the Java virtual machine dynamically loads
+ * classes.
+ *
+ * <p> Class loaders may typically be used by security managers to indicate
+ * security domains.
+ *
+ * <p> The <tt>ClassLoader</tt> class uses a delegation model to search for
+ * classes and resources. Each instance of <tt>ClassLoader</tt> has an
+ * associated parent class loader. When requested to find a class or
+ * resource, a <tt>ClassLoader</tt> instance will delegate the search for the
+ * class or resource to its parent class loader before attempting to find the
+ * class or resource itself. The virtual machine's built-in class loader,
+ * called the "bootstrap class loader", does not itself have a parent but may
+ * serve as the parent of a <tt>ClassLoader</tt> instance.
+ *
+ * <p> Class loaders that support concurrent loading of classes are known as
+ * <em>parallel capable</em> class loaders and are required to register
+ * themselves at their class initialization time by invoking the
+ * {@link
+ * #registerAsParallelCapable <tt>ClassLoader.registerAsParallelCapable</tt>}
+ * method. Note that the <tt>ClassLoader</tt> class is registered as parallel
+ * capable by default. However, its subclasses still need to register themselves
+ * if they are parallel capable. <br>
+ * In environments in which the delegation model is not strictly
+ * hierarchical, class loaders need to be parallel capable, otherwise class
+ * loading can lead to deadlocks because the loader lock is held for the
+ * duration of the class loading process (see {@link #loadClass
+ * <tt>loadClass</tt>} methods).
+ *
+ * <p> Normally, the Java virtual machine loads classes from the local file
+ * system in a platform-dependent manner. For example, on UNIX systems, the
+ * virtual machine loads classes from the directory defined by the
+ * <tt>CLASSPATH</tt> environment variable.
+ *
+ * <p> However, some classes may not originate from a file; they may originate
+ * from other sources, such as the network, or they could be constructed by an
+ * application. The method {@link #defineClass(String, byte[], int, int)
+ * <tt>defineClass</tt>} converts an array of bytes into an instance of class
+ * <tt>Class</tt>. Instances of this newly defined class can be created using
+ * {@link Class#newInstance <tt>Class.newInstance</tt>}.
+ *
+ * <p> The methods and constructors of objects created by a class loader may
+ * reference other classes. To determine the class(es) referred to, the Java
+ * virtual machine invokes the {@link #loadClass <tt>loadClass</tt>} method of
+ * the class loader that originally created the class.
+ *
+ * <p> For example, an application could create a network class loader to
+ * download class files from a server. Sample code might look like:
+ *
+ * <blockquote><pre>
+ * ClassLoader loader = new NetworkClassLoader(host, port);
+ * Object main = loader.loadClass("Main", true).newInstance();
+ * . . .
+ * </pre></blockquote>
+ *
+ * <p> The network class loader subclass must define the methods {@link
+ * #findClass <tt>findClass</tt>} and <tt>loadClassData</tt> to load a class
+ * from the network. Once it has downloaded the bytes that make up the class,
+ * it should use the method {@link #defineClass <tt>defineClass</tt>} to
+ * create a class instance. A sample implementation is:
+ *
+ * <blockquote><pre>
+ * class NetworkClassLoader extends ClassLoader {
+ * String host;
+ * int port;
+ *
+ * public Class findClass(String name) {
+ * byte[] b = loadClassData(name);
+ * return defineClass(name, b, 0, b.length);
+ * }
+ *
+ * private byte[] loadClassData(String name) {
+ * // load the class data from the connection
+ * . . .
+ * }
+ * }
+ * </pre></blockquote>
+ *
+ * <h3> <a name="name">Binary names</a> </h3>
+ *
+ * <p> Any class name provided as a {@link String} parameter to methods in
+ * <tt>ClassLoader</tt> must be a binary name as defined by
+ * <cite>The Java™ Language Specification</cite>.
+ *
+ * <p> Examples of valid class names include:
+ * <blockquote><pre>
+ * "java.lang.String"
+ * "javax.swing.JSpinner$DefaultEditor"
+ * "java.security.KeyStore$Builder$FileBuilder$1"
+ * "java.net.URLClassLoader$3$1"
+ * </pre></blockquote>
+ *
+ * @see #resolveClass(Class)
+ * @since 1.0
+ */
+public abstract class ClassLoader {
+
+ static private class SystemClassLoader {
+ public static ClassLoader loader = ClassLoader.createSystemClassLoader();
+ }
+
+ /**
+ * To avoid unloading individual classes, {@link java.lang.reflect.Proxy}
+ * only generates one class for each set of interfaces. This maps sets of
+ * interfaces to the proxy class that implements all of them. It is declared
+ * here so that these generated classes can be unloaded with their class
+ * loader.
+ *
+ * @hide
+ */
+ public final Map<List<Class<?>>, Class<?>> proxyCache =
+ new HashMap<List<Class<?>>, Class<?>>();
+
+ // The parent class loader for delegation
+ // Note: VM hardcoded the offset of this field, thus all new fields
+ // must be added *after* it.
+ private final ClassLoader parent;
+
+ /**
+ * Encapsulates the set of parallel capable loader types.
+ */
+ private static ClassLoader createSystemClassLoader() {
+ String classPath = System.getProperty("java.class.path", ".");
+ String librarySearchPath = System.getProperty("java.library.path", "");
+
+ // String[] paths = classPath.split(":");
+ // URL[] urls = new URL[paths.length];
+ // for (int i = 0; i < paths.length; i++) {
+ // try {
+ // urls[i] = new URL("file://" + paths[i]);
+ // }
+ // catch (Exception ex) {
+ // ex.printStackTrace();
+ // }
+ // }
+ //
+ // return new java.net.URLClassLoader(urls, null);
+
+ // TODO Make this a java.net.URLClassLoader once we have those?
+ return new PathClassLoader(classPath, librarySearchPath, BootClassLoader.getInstance());
+ }
+
+ // The packages defined in this class loader. Each package name is mapped
+ // to its corresponding Package object.
+ // @GuardedBy("itself")
+ private final HashMap<String, Package> packages = new HashMap<>();
+
+ /**
+ * Pointer to the allocator used by the runtime to allocate metadata such
+ * as ArtFields and ArtMethods.
+ */
+ private transient long allocator;
+
+ /**
+ * Pointer to the class table, only used from within the runtime.
+ */
+ private transient long classTable;
+
+ private static Void checkCreateClassLoader() {
+ return null;
+ }
+
+ private ClassLoader(Void unused, ClassLoader parent) {
+ this.parent = parent;
+ }
+
+ /**
+ * Creates a new class loader using the specified parent class loader for
+ * delegation.
+ *
+ * <p> If there is a security manager, its {@link
+ * SecurityManager#checkCreateClassLoader()
+ * <tt>checkCreateClassLoader</tt>} method is invoked. This may result in
+ * a security exception. </p>
+ *
+ * @param parent
+ * The parent class loader
+ *
+ * @throws SecurityException
+ * If a security manager exists and its
+ * <tt>checkCreateClassLoader</tt> method doesn't allow creation
+ * of a new class loader.
+ *
+ * @since 1.2
+ */
+ protected ClassLoader(ClassLoader parent) {
+ this(checkCreateClassLoader(), parent);
+ }
+
+ /**
+ * Creates a new class loader using the <tt>ClassLoader</tt> returned by
+ * the method {@link #getSystemClassLoader()
+ * <tt>getSystemClassLoader()</tt>} as the parent class loader.
+ *
+ * <p> If there is a security manager, its {@link
+ * SecurityManager#checkCreateClassLoader()
+ * <tt>checkCreateClassLoader</tt>} method is invoked. This may result in
+ * a security exception. </p>
+ *
+ * @throws SecurityException
+ * If a security manager exists and its
+ * <tt>checkCreateClassLoader</tt> method doesn't allow creation
+ * of a new class loader.
+ */
+ protected ClassLoader() {
+ this(checkCreateClassLoader(), getSystemClassLoader());
+ }
+
+ // -- Class --
+
+ /**
+ * Loads the class with the specified <a href="#name">binary name</a>.
+ * This method searches for classes in the same manner as the {@link
+ * #loadClass(String, boolean)} method. It is invoked by the Java virtual
+ * machine to resolve class references. Invoking this method is equivalent
+ * to invoking {@link #loadClass(String, boolean) <tt>loadClass(name,
+ * false)</tt>}.
+ *
+ * @param name
+ * The <a href="#name">binary name</a> of the class
+ *
+ * @return The resulting <tt>Class</tt> object
+ *
+ * @throws ClassNotFoundException
+ * If the class was not found
+ */
+ public Class<?> loadClass(String name) throws ClassNotFoundException {
+ return loadClass(name, false);
+ }
+
+ /**
+ * Loads the class with the specified <a href="#name">binary name</a>. The
+ * default implementation of this method searches for classes in the
+ * following order:
+ *
+ * <ol>
+ *
+ * <li><p> Invoke {@link #findLoadedClass(String)} to check if the class
+ * has already been loaded. </p></li>
+ *
+ * <li><p> Invoke the {@link #loadClass(String) <tt>loadClass</tt>} method
+ * on the parent class loader. If the parent is <tt>null</tt> the class
+ * loader built-in to the virtual machine is used, instead. </p></li>
+ *
+ * <li><p> Invoke the {@link #findClass(String)} method to find the
+ * class. </p></li>
+ *
+ * </ol>
+ *
+ * <p> If the class was found using the above steps, and the
+ * <tt>resolve</tt> flag is true, this method will then invoke the {@link
+ * #resolveClass(Class)} method on the resulting <tt>Class</tt> object.
+ *
+ * <p> Subclasses of <tt>ClassLoader</tt> are encouraged to override {@link
+ * #findClass(String)}, rather than this method. </p>
+ *
+ *
+ * @param name
+ * The <a href="#name">binary name</a> of the class
+ *
+ * @param resolve
+ * If <tt>true</tt> then resolve the class
+ *
+ * @return The resulting <tt>Class</tt> object
+ *
+ * @throws ClassNotFoundException
+ * If the class could not be found
+ */
+ // Android-removed: Remove references to getClassLoadingLock
+ // Remove perf counters.
+ //
+ // <p> Unless overridden, this method synchronizes on the result of
+ // {@link #getClassLoadingLock <tt>getClassLoadingLock</tt>} method
+ // during the entire class loading process.
+ protected Class<?> loadClass(String name, boolean resolve)
+ throws ClassNotFoundException
+ {
+ // First, check if the class has already been loaded
+ Class<?> c = findLoadedClass(name);
+ if (c == null) {
+ try {
+ if (parent != null) {
+ c = parent.loadClass(name, false);
+ } else {
+ c = findBootstrapClassOrNull(name);
+ }
+ } catch (ClassNotFoundException e) {
+ // ClassNotFoundException thrown if class not found
+ // from the non-null parent class loader
+ }
+
+ if (c == null) {
+ // If still not found, then invoke findClass in order
+ // to find the class.
+ c = findClass(name);
+ }
+ }
+ return c;
+ }
+
+
+ /**
+ * Finds the class with the specified <a href="#name">binary name</a>.
+ * This method should be overridden by class loader implementations that
+ * follow the delegation model for loading classes, and will be invoked by
+ * the {@link #loadClass <tt>loadClass</tt>} method after checking the
+ * parent class loader for the requested class. The default implementation
+ * throws a <tt>ClassNotFoundException</tt>.
+ *
+ * @param name
+ * The <a href="#name">binary name</a> of the class
+ *
+ * @return The resulting <tt>Class</tt> object
+ *
+ * @throws ClassNotFoundException
+ * If the class could not be found
+ *
+ * @since 1.2
+ */
+ protected Class<?> findClass(String name) throws ClassNotFoundException {
+ throw new ClassNotFoundException(name);
+ }
+
+ /**
+ * Converts an array of bytes into an instance of class <tt>Class</tt>.
+ * Before the <tt>Class</tt> can be used it must be resolved. This method
+ * is deprecated in favor of the version that takes a <a
+ * href="#name">binary name</a> as its first argument, and is more secure.
+ *
+ * @param b
+ * The bytes that make up the class data. The bytes in positions
+ * <tt>off</tt> through <tt>off+len-1</tt> should have the format
+ * of a valid class file as defined by
+ * <cite>The Java™ Virtual Machine Specification</cite>.
+ *
+ * @param off
+ * The start offset in <tt>b</tt> of the class data
+ *
+ * @param len
+ * The length of the class data
+ *
+ * @return The <tt>Class</tt> object that was created from the specified
+ * class data
+ *
+ * @throws ClassFormatError
+ * If the data did not contain a valid class
+ *
+ * @throws IndexOutOfBoundsException
+ * If either <tt>off</tt> or <tt>len</tt> is negative, or if
+ * <tt>off+len</tt> is greater than <tt>b.length</tt>.
+ *
+ * @throws SecurityException
+ * If an attempt is made to add this class to a package that
+ * contains classes that were signed by a different set of
+ * certificates than this class, or if an attempt is made
+ * to define a class in a package with a fully-qualified name
+ * that starts with "{@code java.}".
+ *
+ * @see #loadClass(String, boolean)
+ * @see #resolveClass(Class)
+ *
+ * @deprecated Replaced by {@link #defineClass(String, byte[], int, int)
+ * defineClass(String, byte[], int, int)}
+ */
+ @Deprecated
+ protected final Class<?> defineClass(byte[] b, int off, int len)
+ throws ClassFormatError
+ {
+ throw new UnsupportedOperationException("can't load this type of class file");
+ }
+
+ /**
+ * Converts an array of bytes into an instance of class <tt>Class</tt>.
+ * Before the <tt>Class</tt> can be used it must be resolved.
+ *
+ * <p> This method assigns a default {@link java.security.ProtectionDomain
+ * <tt>ProtectionDomain</tt>} to the newly defined class. The
+ * <tt>ProtectionDomain</tt> is effectively granted the same set of
+ * permissions returned when {@link
+ * java.security.Policy#getPermissions(java.security.CodeSource)
+ * <tt>Policy.getPolicy().getPermissions(new CodeSource(null, null))</tt>}
+ * is invoked. The default domain is created on the first invocation of
+ * {@link #defineClass(String, byte[], int, int) <tt>defineClass</tt>},
+ * and re-used on subsequent invocations.
+ *
+ * <p> To assign a specific <tt>ProtectionDomain</tt> to the class, use
+ * the {@link #defineClass(String, byte[], int, int,
+ * java.security.ProtectionDomain) <tt>defineClass</tt>} method that takes a
+ * <tt>ProtectionDomain</tt> as one of its arguments. </p>
+ *
+ * @param name
+ * The expected <a href="#name">binary name</a> of the class, or
+ * <tt>null</tt> if not known
+ *
+ * @param b
+ * The bytes that make up the class data. The bytes in positions
+ * <tt>off</tt> through <tt>off+len-1</tt> should have the format
+ * of a valid class file as defined by
+ * <cite>The Java™ Virtual Machine Specification</cite>.
+ *
+ * @param off
+ * The start offset in <tt>b</tt> of the class data
+ *
+ * @param len
+ * The length of the class data
+ *
+ * @return The <tt>Class</tt> object that was created from the specified
+ * class data.
+ *
+ * @throws ClassFormatError
+ * If the data did not contain a valid class
+ *
+ * @throws IndexOutOfBoundsException
+ * If either <tt>off</tt> or <tt>len</tt> is negative, or if
+ * <tt>off+len</tt> is greater than <tt>b.length</tt>.
+ *
+ * @throws SecurityException
+ * If an attempt is made to add this class to a package that
+ * contains classes that were signed by a different set of
+ * certificates than this class (which is unsigned), or if
+ * <tt>name</tt> begins with "<tt>java.</tt>".
+ *
+ * @see #loadClass(String, boolean)
+ * @see #resolveClass(Class)
+ * @see java.security.CodeSource
+ * @see java.security.SecureClassLoader
+ *
+ * @since 1.1
+ */
+ protected final Class<?> defineClass(String name, byte[] b, int off, int len)
+ throws ClassFormatError
+ {
+ throw new UnsupportedOperationException("can't load this type of class file");
+ }
+
+
+ /**
+ * Converts an array of bytes into an instance of class <tt>Class</tt>,
+ * with an optional <tt>ProtectionDomain</tt>. If the domain is
+ * <tt>null</tt>, then a default domain will be assigned to the class as
+ * specified in the documentation for {@link #defineClass(String, byte[],
+ * int, int)}. Before the class can be used it must be resolved.
+ *
+ * <p> The first class defined in a package determines the exact set of
+ * certificates that all subsequent classes defined in that package must
+ * contain. The set of certificates for a class is obtained from the
+ * {@link java.security.CodeSource <tt>CodeSource</tt>} within the
+ * <tt>ProtectionDomain</tt> of the class. Any classes added to that
+ * package must contain the same set of certificates or a
+ * <tt>SecurityException</tt> will be thrown. Note that if
+ * <tt>name</tt> is <tt>null</tt>, this check is not performed.
+ * You should always pass in the <a href="#name">binary name</a> of the
+ * class you are defining as well as the bytes. This ensures that the
+ * class you are defining is indeed the class you think it is.
+ *
+ * <p> The specified <tt>name</tt> cannot begin with "<tt>java.</tt>", since
+ * all classes in the "<tt>java.*</tt> packages can only be defined by the
+ * bootstrap class loader. If <tt>name</tt> is not <tt>null</tt>, it
+ * must be equal to the <a href="#name">binary name</a> of the class
+ * specified by the byte array "<tt>b</tt>", otherwise a {@link
+ * NoClassDefFoundError <tt>NoClassDefFoundError</tt>} will be thrown. </p>
+ *
+ * @param name
+ * The expected <a href="#name">binary name</a> of the class, or
+ * <tt>null</tt> if not known
+ *
+ * @param b
+ * The bytes that make up the class data. The bytes in positions
+ * <tt>off</tt> through <tt>off+len-1</tt> should have the format
+ * of a valid class file as defined by
+ * <cite>The Java™ Virtual Machine Specification</cite>.
+ *
+ * @param off
+ * The start offset in <tt>b</tt> of the class data
+ *
+ * @param len
+ * The length of the class data
+ *
+ * @param protectionDomain
+ * The ProtectionDomain of the class
+ *
+ * @return The <tt>Class</tt> object created from the data,
+ * and optional <tt>ProtectionDomain</tt>.
+ *
+ * @throws ClassFormatError
+ * If the data did not contain a valid class
+ *
+ * @throws NoClassDefFoundError
+ * If <tt>name</tt> is not equal to the <a href="#name">binary
+ * name</a> of the class specified by <tt>b</tt>
+ *
+ * @throws IndexOutOfBoundsException
+ * If either <tt>off</tt> or <tt>len</tt> is negative, or if
+ * <tt>off+len</tt> is greater than <tt>b.length</tt>.
+ *
+ * @throws SecurityException
+ * If an attempt is made to add this class to a package that
+ * contains classes that were signed by a different set of
+ * certificates than this class, or if <tt>name</tt> begins with
+ * "<tt>java.</tt>".
+ */
+ // Android-changed: Remove <tt> from link for NoClassDefFoundError
+ protected final Class<?> defineClass(String name, byte[] b, int off, int len,
+ ProtectionDomain protectionDomain)
+ throws ClassFormatError
+ {
+ throw new UnsupportedOperationException("can't load this type of class file");
+ }
+
+ /**
+ * Converts a {@link java.nio.ByteBuffer <tt>ByteBuffer</tt>}
+ * into an instance of class <tt>Class</tt>,
+ * with an optional <tt>ProtectionDomain</tt>. If the domain is
+ * <tt>null</tt>, then a default domain will be assigned to the class as
+ * specified in the documentation for {@link #defineClass(String, byte[],
+ * int, int)}. Before the class can be used it must be resolved.
+ *
+ * <p>The rules about the first class defined in a package determining the
+ * set of certificates for the package, and the restrictions on class names
+ * are identical to those specified in the documentation for {@link
+ * #defineClass(String, byte[], int, int, ProtectionDomain)}.
+ *
+ * <p> An invocation of this method of the form
+ * <i>cl</i><tt>.defineClass(</tt><i>name</i><tt>,</tt>
+ * <i>bBuffer</i><tt>,</tt> <i>pd</i><tt>)</tt> yields exactly the same
+ * result as the statements
+ *
+ *<p> <tt>
+ * ...<br>
+ * byte[] temp = new byte[bBuffer.{@link
+ * java.nio.ByteBuffer#remaining remaining}()];<br>
+ * bBuffer.{@link java.nio.ByteBuffer#get(byte[])
+ * get}(temp);<br>
+ * return {@link #defineClass(String, byte[], int, int, ProtectionDomain)
+ * cl.defineClass}(name, temp, 0,
+ * temp.length, pd);<br>
+ * </tt></p>
+ *
+ * @param name
+ * The expected <a href="#name">binary name</a>. of the class, or
+ * <tt>null</tt> if not known
+ *
+ * @param b
+ * The bytes that make up the class data. The bytes from positions
+ * <tt>b.position()</tt> through <tt>b.position() + b.limit() -1
+ * </tt> should have the format of a valid class file as defined by
+ * <cite>The Java™ Virtual Machine Specification</cite>.
+ *
+ * @param protectionDomain
+ * The ProtectionDomain of the class, or <tt>null</tt>.
+ *
+ * @return The <tt>Class</tt> object created from the data,
+ * and optional <tt>ProtectionDomain</tt>.
+ *
+ * @throws ClassFormatError
+ * If the data did not contain a valid class.
+ *
+ * @throws NoClassDefFoundError
+ * If <tt>name</tt> is not equal to the <a href="#name">binary
+ * name</a> of the class specified by <tt>b</tt>
+ *
+ * @throws SecurityException
+ * If an attempt is made to add this class to a package that
+ * contains classes that were signed by a different set of
+ * certificates than this class, or if <tt>name</tt> begins with
+ * "<tt>java.</tt>".
+ *
+ * @see #defineClass(String, byte[], int, int, ProtectionDomain)
+ *
+ * @since 1.5
+ */
+ protected final Class<?> defineClass(String name, java.nio.ByteBuffer b,
+ ProtectionDomain protectionDomain)
+ throws ClassFormatError
+ {
+ throw new UnsupportedOperationException("can't load this type of class file");
+ }
+
+ /**
+ * Links the specified class. This (misleadingly named) method may be
+ * used by a class loader to link a class. If the class <tt>c</tt> has
+ * already been linked, then this method simply returns. Otherwise, the
+ * class is linked as described in the "Execution" chapter of
+ * <cite>The Java™ Language Specification</cite>.
+ *
+ * @param c
+ * The class to link
+ *
+ * @throws NullPointerException
+ * If <tt>c</tt> is <tt>null</tt>.
+ *
+ * @see #defineClass(String, byte[], int, int)
+ */
+ protected final void resolveClass(Class<?> c) {
+ }
+
+ /**
+ * Finds a class with the specified <a href="#name">binary name</a>,
+ * loading it if necessary.
+ *
+ * <p> This method loads the class through the system class loader (see
+ * {@link #getSystemClassLoader()}). The <tt>Class</tt> object returned
+ * might have more than one <tt>ClassLoader</tt> associated with it.
+ * Subclasses of <tt>ClassLoader</tt> need not usually invoke this method,
+ * because most class loaders need to override just {@link
+ * #findClass(String)}. </p>
+ *
+ * @param name
+ * The <a href="#name">binary name</a> of the class
+ *
+ * @return The <tt>Class</tt> object for the specified <tt>name</tt>
+ *
+ * @throws ClassNotFoundException
+ * If the class could not be found
+ *
+ * @see #ClassLoader(ClassLoader)
+ * @see #getParent()
+ */
+ protected final Class<?> findSystemClass(String name)
+ throws ClassNotFoundException
+ {
+ return Class.forName(name, false, getSystemClassLoader());
+ }
+
+ /**
+ * Returns a class loaded by the bootstrap class loader;
+ * or return null if not found.
+ */
+ private Class<?> findBootstrapClassOrNull(String name)
+ {
+ return null;
+ }
+
+ /**
+ * Returns the class with the given <a href="#name">binary name</a> if this
+ * loader has been recorded by the Java virtual machine as an initiating
+ * loader of a class with that <a href="#name">binary name</a>. Otherwise
+ * <tt>null</tt> is returned.
+ *
+ * @param name
+ * The <a href="#name">binary name</a> of the class
+ *
+ * @return The <tt>Class</tt> object, or <tt>null</tt> if the class has
+ * not been loaded
+ *
+ * @since 1.1
+ */
+ protected final Class<?> findLoadedClass(String name) {
+ ClassLoader loader;
+ if (this == BootClassLoader.getInstance())
+ loader = null;
+ else
+ loader = this;
+ return VMClassLoader.findLoadedClass(loader, name);
+ }
+
+ /**
+ * Sets the signers of a class. This should be invoked after defining a
+ * class.
+ *
+ * @param c
+ * The <tt>Class</tt> object
+ *
+ * @param signers
+ * The signers for the class
+ *
+ * @since 1.1
+ */
+ protected final void setSigners(Class<?> c, Object[] signers) {
+ }
+
+
+ // -- Resource --
+
+ /**
+ * Finds the resource with the given name. A resource is some data
+ * (images, audio, text, etc) that can be accessed by class code in a way
+ * that is independent of the location of the code.
+ *
+ * <p> The name of a resource is a '<tt>/</tt>'-separated path name that
+ * identifies the resource.
+ *
+ * <p> This method will first search the parent class loader for the
+ * resource; if the parent is <tt>null</tt> the path of the class loader
+ * built-in to the virtual machine is searched. That failing, this method
+ * will invoke {@link #findResource(String)} to find the resource. </p>
+ *
+ * @apiNote When overriding this method it is recommended that an
+ * implementation ensures that any delegation is consistent with the {@link
+ * #getResources(java.lang.String) getResources(String)} method.
+ *
+ * @param name
+ * The resource name
+ *
+ * @return A <tt>URL</tt> object for reading the resource, or
+ * <tt>null</tt> if the resource could not be found or the invoker
+ * doesn't have adequate privileges to get the resource.
+ *
+ * @since 1.1
+ */
+ public URL getResource(String name) {
+ URL url;
+ if (parent != null) {
+ url = parent.getResource(name);
+ } else {
+ url = getBootstrapResource(name);
+ }
+ if (url == null) {
+ url = findResource(name);
+ }
+ return url;
+ }
+
+ /**
+ * Finds all the resources with the given name. A resource is some data
+ * (images, audio, text, etc) that can be accessed by class code in a way
+ * that is independent of the location of the code.
+ *
+ * <p>The name of a resource is a <tt>/</tt>-separated path name that
+ * identifies the resource.
+ *
+ * <p> The search order is described in the documentation for {@link
+ * #getResource(String)}. </p>
+ *
+ * @apiNote When overriding this method it is recommended that an
+ * implementation ensures that any delegation is consistent with the {@link
+ * #getResource(java.lang.String) getResource(String)} method. This should
+ * ensure that the first element returned by the Enumeration's
+ * {@code nextElement} method is the same resource that the
+ * {@code getResource(String)} method would return.
+ *
+ * @param name
+ * The resource name
+ *
+ * @return An enumeration of {@link java.net.URL <tt>URL</tt>} objects for
+ * the resource. If no resources could be found, the enumeration
+ * will be empty. Resources that the class loader doesn't have
+ * access to will not be in the enumeration.
+ *
+ * @throws IOException
+ * If I/O errors occur
+ *
+ * @see #findResources(String)
+ *
+ * @since 1.2
+ */
+ public Enumeration<URL> getResources(String name) throws IOException {
+ @SuppressWarnings("unchecked")
+ Enumeration<URL>[] tmp = (Enumeration<URL>[]) new Enumeration<?>[2];
+ if (parent != null) {
+ tmp[0] = parent.getResources(name);
+ } else {
+ tmp[0] = getBootstrapResources(name);
+ }
+ tmp[1] = findResources(name);
+
+ return new CompoundEnumeration<>(tmp);
+ }
+
+ /**
+ * Finds the resource with the given name. Class loader implementations
+ * should override this method to specify where to find resources.
+ *
+ * @param name
+ * The resource name
+ *
+ * @return A <tt>URL</tt> object for reading the resource, or
+ * <tt>null</tt> if the resource could not be found
+ *
+ * @since 1.2
+ */
+ protected URL findResource(String name) {
+ return null;
+ }
+
+ /**
+ * Returns an enumeration of {@link java.net.URL <tt>URL</tt>} objects
+ * representing all the resources with the given name. Class loader
+ * implementations should override this method to specify where to load
+ * resources from.
+ *
+ * @param name
+ * The resource name
+ *
+ * @return An enumeration of {@link java.net.URL <tt>URL</tt>} objects for
+ * the resources
+ *
+ * @throws IOException
+ * If I/O errors occur
+ *
+ * @since 1.2
+ */
+ protected Enumeration<URL> findResources(String name) throws IOException {
+ return java.util.Collections.emptyEnumeration();
+ }
+
+ /**
+ * Registers the caller as parallel capable.
+ * The registration succeeds if and only if all of the following
+ * conditions are met:
+ * <ol>
+ * <li> no instance of the caller has been created</li>
+ * <li> all of the super classes (except class Object) of the caller are
+ * registered as parallel capable</li>
+ * </ol>
+ * <p>Note that once a class loader is registered as parallel capable, there
+ * is no way to change it back.</p>
+ *
+ * @return true if the caller is successfully registered as
+ * parallel capable and false if otherwise.
+ *
+ * @since 1.7
+ */
+ @CallerSensitive
+ protected static boolean registerAsParallelCapable() {
+ return true;
+ }
+
+ /**
+ * Find a resource of the specified name from the search path used to load
+ * classes. This method locates the resource through the system class
+ * loader (see {@link #getSystemClassLoader()}).
+ *
+ * @param name
+ * The resource name
+ *
+ * @return A {@link java.net.URL <tt>URL</tt>} object for reading the
+ * resource, or <tt>null</tt> if the resource could not be found
+ *
+ * @since 1.1
+ */
+ public static URL getSystemResource(String name) {
+ ClassLoader system = getSystemClassLoader();
+ if (system == null) {
+ return getBootstrapResource(name);
+ }
+ return system.getResource(name);
+ }
+
+ /**
+ * Finds all resources of the specified name from the search path used to
+ * load classes. The resources thus found are returned as an
+ * {@link java.util.Enumeration <tt>Enumeration</tt>} of {@link
+ * java.net.URL <tt>URL</tt>} objects.
+ *
+ * <p> The search order is described in the documentation for {@link
+ * #getSystemResource(String)}. </p>
+ *
+ * @param name
+ * The resource name
+ *
+ * @return An enumeration of resource {@link java.net.URL <tt>URL</tt>}
+ * objects
+ *
+ * @throws IOException
+ * If I/O errors occur
+
+ * @since 1.2
+ */
+ public static Enumeration<URL> getSystemResources(String name)
+ throws IOException
+ {
+ ClassLoader system = getSystemClassLoader();
+ if (system == null) {
+ return getBootstrapResources(name);
+ }
+ return system.getResources(name);
+ }
+
+ /**
+ * Find resources from the VM's built-in classloader.
+ */
+ private static URL getBootstrapResource(String name) {
+ return null;
+ }
+
+ /**
+ * Find resources from the VM's built-in classloader.
+ */
+ private static Enumeration<URL> getBootstrapResources(String name)
+ throws IOException
+ {
+ return null;
+ }
+
+
+
+ /**
+ * Returns an input stream for reading the specified resource.
+ *
+ * <p> The search order is described in the documentation for {@link
+ * #getResource(String)}. </p>
+ *
+ * @param name
+ * The resource name
+ *
+ * @return An input stream for reading the resource, or <tt>null</tt>
+ * if the resource could not be found
+ *
+ * @since 1.1
+ */
+ public InputStream getResourceAsStream(String name) {
+ URL url = getResource(name);
+ try {
+ return url != null ? url.openStream() : null;
+ } catch (IOException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Open for reading, a resource of the specified name from the search path
+ * used to load classes. This method locates the resource through the
+ * system class loader (see {@link #getSystemClassLoader()}).
+ *
+ * @param name
+ * The resource name
+ *
+ * @return An input stream for reading the resource, or <tt>null</tt>
+ * if the resource could not be found
+ *
+ * @since 1.1
+ */
+ public static InputStream getSystemResourceAsStream(String name) {
+ URL url = getSystemResource(name);
+ try {
+ return url != null ? url.openStream() : null;
+ } catch (IOException e) {
+ return null;
+ }
+ }
+
+
+ // -- Hierarchy --
+
+ /**
+ * Returns the parent class loader for delegation. Some implementations may
+ * use <tt>null</tt> to represent the bootstrap class loader. This method
+ * will return <tt>null</tt> in such implementations if this class loader's
+ * parent is the bootstrap class loader.
+ *
+ * <p> If a security manager is present, and the invoker's class loader is
+ * not <tt>null</tt> and is not an ancestor of this class loader, then this
+ * method invokes the security manager's {@link
+ * SecurityManager#checkPermission(java.security.Permission)
+ * <tt>checkPermission</tt>} method with a {@link
+ * RuntimePermission#RuntimePermission(String)
+ * <tt>RuntimePermission("getClassLoader")</tt>} permission to verify
+ * access to the parent class loader is permitted. If not, a
+ * <tt>SecurityException</tt> will be thrown. </p>
+ *
+ * @return The parent <tt>ClassLoader</tt>
+ *
+ * @throws SecurityException
+ * If a security manager exists and its <tt>checkPermission</tt>
+ * method doesn't allow access to this class loader's parent class
+ * loader.
+ *
+ * @since 1.2
+ */
+ @CallerSensitive
+ public final ClassLoader getParent() {
+ return parent;
+ }
+
+ // Android-changed: Removed "java.system.class.loader" paragraph.
+ /**
+ * Returns the system class loader for delegation. This is the default
+ * delegation parent for new <tt>ClassLoader</tt> instances, and is
+ * typically the class loader used to start the application.
+ *
+ * <p> This method is first invoked early in the runtime's startup
+ * sequence, at which point it creates the system class loader and sets it
+ * as the context class loader of the invoking <tt>Thread</tt>.
+ *
+ * <p> The default system class loader is an implementation-dependent
+ * instance of this class.
+ *
+ * <p> If a security manager is present, and the invoker's class loader is
+ * not <tt>null</tt> and the invoker's class loader is not the same as or
+ * an ancestor of the system class loader, then this method invokes the
+ * security manager's {@link
+ * SecurityManager#checkPermission(java.security.Permission)
+ * <tt>checkPermission</tt>} method with a {@link
+ * RuntimePermission#RuntimePermission(String)
+ * <tt>RuntimePermission("getClassLoader")</tt>} permission to verify
+ * access to the system class loader. If not, a
+ * <tt>SecurityException</tt> will be thrown. </p>
+ *
+ * @return The system <tt>ClassLoader</tt> for delegation, or
+ * <tt>null</tt> if none
+ *
+ * @throws SecurityException
+ * If a security manager exists and its <tt>checkPermission</tt>
+ * method doesn't allow access to the system class loader.
+ *
+ * @throws IllegalStateException
+ * If invoked recursively during the construction of the class
+ * loader specified by the "<tt>java.system.class.loader</tt>"
+ * property.
+ *
+ * @throws Error
+ * If the system property "<tt>java.system.class.loader</tt>"
+ * is defined but the named class could not be loaded, the
+ * provider class does not define the required constructor, or an
+ * exception is thrown by that constructor when it is invoked. The
+ * underlying cause of the error can be retrieved via the
+ * {@link Throwable#getCause()} method.
+ *
+ * @revised 1.4
+ */
+ @CallerSensitive
+ public static ClassLoader getSystemClassLoader() {
+ return SystemClassLoader.loader;
+ }
+
+ // Returns the class's class loader, or null if none.
+ static ClassLoader getClassLoader(Class<?> caller) {
+ // This can be null if the VM is requesting it
+ if (caller == null) {
+ return null;
+ }
+ // Android-changed: Use Class.getClassLoader(); there is no Class.getClassLoader0().
+ // // Circumvent security check since this is package-private
+ // return caller.getClassLoader0();
+ return caller.getClassLoader();
+ }
+
+ // -- Package --
+
+ /**
+ * Defines a package by name in this <tt>ClassLoader</tt>. This allows
+ * class loaders to define the packages for their classes. Packages must
+ * be created before the class is defined, and package names must be
+ * unique within a class loader and cannot be redefined or changed once
+ * created.
+ *
+ * @param name
+ * The package name
+ *
+ * @param specTitle
+ * The specification title
+ *
+ * @param specVersion
+ * The specification version
+ *
+ * @param specVendor
+ * The specification vendor
+ *
+ * @param implTitle
+ * The implementation title
+ *
+ * @param implVersion
+ * The implementation version
+ *
+ * @param implVendor
+ * The implementation vendor
+ *
+ * @param sealBase
+ * If not <tt>null</tt>, then this package is sealed with
+ * respect to the given code source {@link java.net.URL
+ * <tt>URL</tt>} object. Otherwise, the package is not sealed.
+ *
+ * @return The newly defined <tt>Package</tt> object
+ *
+ * @throws IllegalArgumentException
+ * If package name duplicates an existing package either in this
+ * class loader or one of its ancestors
+ *
+ * @since 1.2
+ */
+ protected Package definePackage(String name, String specTitle,
+ String specVersion, String specVendor,
+ String implTitle, String implVersion,
+ String implVendor, URL sealBase)
+ throws IllegalArgumentException
+ {
+ synchronized (packages) {
+ Package pkg = packages.get(name);
+ if (pkg != null) {
+ throw new IllegalArgumentException(name);
+ }
+ pkg = new Package(name, specTitle, specVersion, specVendor,
+ implTitle, implVersion, implVendor,
+ sealBase, this);
+ packages.put(name, pkg);
+ return pkg;
+ }
+ }
+
+ /**
+ * Returns a <tt>Package</tt> that has been defined by this class loader
+ * or any of its ancestors.
+ *
+ * @param name
+ * The package name
+ *
+ * @return The <tt>Package</tt> corresponding to the given name, or
+ * <tt>null</tt> if not found
+ *
+ * @since 1.2
+ */
+ protected Package getPackage(String name) {
+ Package pkg;
+ synchronized (packages) {
+ pkg = packages.get(name);
+ }
+ return pkg;
+ }
+
+ /**
+ * Returns all of the <tt>Packages</tt> defined by this class loader and
+ * its ancestors.
+ *
+ * @return The array of <tt>Package</tt> objects defined by this
+ * <tt>ClassLoader</tt>
+ *
+ * @since 1.2
+ */
+ protected Package[] getPackages() {
+ Map<String, Package> map;
+ synchronized (packages) {
+ map = new HashMap<>(packages);
+ }
+ Package[] pkgs;
+ return map.values().toArray(new Package[map.size()]);
+ }
+
+
+ // -- Native library access --
+
+ /**
+ * Returns the absolute path name of a native library. The VM invokes this
+ * method to locate the native libraries that belong to classes loaded with
+ * this class loader. If this method returns <tt>null</tt>, the VM
+ * searches the library along the path specified as the
+ * "<tt>java.library.path</tt>" property.
+ *
+ * @param libname
+ * The library name
+ *
+ * @return The absolute path of the native library
+ *
+ * @see System#loadLibrary(String)
+ * @see System#mapLibraryName(String)
+ *
+ * @since 1.2
+ */
+ protected String findLibrary(String libname) {
+ return null;
+ }
+
+ /**
+ * Sets the default assertion status for this class loader. This setting
+ * determines whether classes loaded by this class loader and initialized
+ * in the future will have assertions enabled or disabled by default.
+ * This setting may be overridden on a per-package or per-class basis by
+ * invoking {@link #setPackageAssertionStatus(String, boolean)} or {@link
+ * #setClassAssertionStatus(String, boolean)}.
+ *
+ * @param enabled
+ * <tt>true</tt> if classes loaded by this class loader will
+ * henceforth have assertions enabled by default, <tt>false</tt>
+ * if they will have assertions disabled by default.
+ *
+ * @since 1.4
+ */
+ public void setDefaultAssertionStatus(boolean enabled) {
+ }
+
+ /**
+ * Sets the package default assertion status for the named package. The
+ * package default assertion status determines the assertion status for
+ * classes initialized in the future that belong to the named package or
+ * any of its "subpackages".
+ *
+ * <p> A subpackage of a package named p is any package whose name begins
+ * with "<tt>p.</tt>". For example, <tt>javax.swing.text</tt> is a
+ * subpackage of <tt>javax.swing</tt>, and both <tt>java.util</tt> and
+ * <tt>java.lang.reflect</tt> are subpackages of <tt>java</tt>.
+ *
+ * <p> In the event that multiple package defaults apply to a given class,
+ * the package default pertaining to the most specific package takes
+ * precedence over the others. For example, if <tt>javax.lang</tt> and
+ * <tt>javax.lang.reflect</tt> both have package defaults associated with
+ * them, the latter package default applies to classes in
+ * <tt>javax.lang.reflect</tt>.
+ *
+ * <p> Package defaults take precedence over the class loader's default
+ * assertion status, and may be overridden on a per-class basis by invoking
+ * {@link #setClassAssertionStatus(String, boolean)}. </p>
+ *
+ * @param packageName
+ * The name of the package whose package default assertion status
+ * is to be set. A <tt>null</tt> value indicates the unnamed
+ * package that is "current"
+ * (see section 7.4.2 of
+ * <cite>The Java™ Language Specification</cite>.)
+ *
+ * @param enabled
+ * <tt>true</tt> if classes loaded by this classloader and
+ * belonging to the named package or any of its subpackages will
+ * have assertions enabled by default, <tt>false</tt> if they will
+ * have assertions disabled by default.
+ *
+ * @since 1.4
+ */
+ public void setPackageAssertionStatus(String packageName,
+ boolean enabled) {
+ }
+
+ /**
+ * Sets the desired assertion status for the named top-level class in this
+ * class loader and any nested classes contained therein. This setting
+ * takes precedence over the class loader's default assertion status, and
+ * over any applicable per-package default. This method has no effect if
+ * the named class has already been initialized. (Once a class is
+ * initialized, its assertion status cannot change.)
+ *
+ * <p> If the named class is not a top-level class, this invocation will
+ * have no effect on the actual assertion status of any class. </p>
+ *
+ * @param className
+ * The fully qualified class name of the top-level class whose
+ * assertion status is to be set.
+ *
+ * @param enabled
+ * <tt>true</tt> if the named class is to have assertions
+ * enabled when (and if) it is initialized, <tt>false</tt> if the
+ * class is to have assertions disabled.
+ *
+ * @since 1.4
+ */
+ public void setClassAssertionStatus(String className, boolean enabled) {
+ }
+
+ /**
+ * Sets the default assertion status for this class loader to
+ * <tt>false</tt> and discards any package defaults or class assertion
+ * status settings associated with the class loader. This method is
+ * provided so that class loaders can be made to ignore any command line or
+ * persistent assertion status settings and "start with a clean slate."
+ *
+ * @since 1.4
+ */
+ public void clearAssertionStatus() {
+ /*
+ * Whether or not "Java assertion maps" are initialized, set
+ * them to empty maps, effectively ignoring any present settings.
+ */
+ }
+}
+
+
+class BootClassLoader extends ClassLoader {
+
+ private static BootClassLoader instance;
+
+ @FindBugsSuppressWarnings("DP_CREATE_CLASSLOADER_INSIDE_DO_PRIVILEGED")
+ public static synchronized BootClassLoader getInstance() {
+ if (instance == null) {
+ instance = new BootClassLoader();
+ }
+
+ return instance;
+ }
+
+ public BootClassLoader() {
+ super(null);
+ }
+
+ @Override
+ protected Class<?> findClass(String name) throws ClassNotFoundException {
+ return Class.classForName(name, false, null);
+ }
+
+ @Override
+ protected URL findResource(String name) {
+ return VMClassLoader.getResource(name);
+ }
+
+ @SuppressWarnings("unused")
+ @Override
+ protected Enumeration<URL> findResources(String resName) throws IOException {
+ return Collections.enumeration(VMClassLoader.getResources(resName));
+ }
+
+ /**
+ * Returns package information for the given package. Unfortunately, the
+ * Android BootClassLoader doesn't really have this information, and as a
+ * non-secure ClassLoader, it isn't even required to, according to the spec.
+ * Yet, we want to provide it, in order to make all those hopeful callers of
+ * {@code myClass.getPackage().getName()} happy. Thus we construct a Package
+ * object the first time it is being requested and fill most of the fields
+ * with dummy values. The Package object is then put into the ClassLoader's
+ * Package cache, so we see the same one next time. We don't create Package
+ * objects for null arguments or for the default package.
+ * <p>
+ * There a limited chance that we end up with multiple Package objects
+ * representing the same package: It can happen when when a package is
+ * scattered across different JAR files being loaded by different
+ * ClassLoaders. Rather unlikely, and given that this whole thing is more or
+ * less a workaround, probably not worth the effort.
+ */
+ @Override
+ protected Package getPackage(String name) {
+ if (name != null && !name.isEmpty()) {
+ synchronized (this) {
+ Package pack = super.getPackage(name);
+
+ if (pack == null) {
+ pack = definePackage(name, "Unknown", "0.0", "Unknown", "Unknown", "0.0",
+ "Unknown", null);
+ }
+
+ return pack;
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public URL getResource(String resName) {
+ return findResource(resName);
+ }
+
+ @Override
+ protected Class<?> loadClass(String className, boolean resolve)
+ throws ClassNotFoundException {
+ Class<?> clazz = findLoadedClass(className);
+
+ if (clazz == null) {
+ clazz = findClass(className);
+ }
+
+ return clazz;
+ }
+
+ @Override
+ public Enumeration<URL> getResources(String resName) throws IOException {
+ return findResources(resName);
+ }
+}
diff --git a/java/lang/ClassNotFoundException.java b/java/lang/ClassNotFoundException.java
new file mode 100644
index 0000000..1211e9f
--- /dev/null
+++ b/java/lang/ClassNotFoundException.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 1995, 2004, 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;
+
+/**
+ * Thrown when an application tries to load in a class through its
+ * string name using:
+ * <ul>
+ * <li>The <code>forName</code> method in class <code>Class</code>.
+ * <li>The <code>findSystemClass</code> method in class
+ * <code>ClassLoader</code> .
+ * <li>The <code>loadClass</code> method in class <code>ClassLoader</code>.
+ * </ul>
+ * <p>
+ * but no definition for the class with the specified name could be found.
+ *
+ * <p>As of release 1.4, this exception has been retrofitted to conform to
+ * the general purpose exception-chaining mechanism. The "optional exception
+ * that was raised while loading the class" that may be provided at
+ * construction time and accessed via the {@link #getException()} method is
+ * now known as the <i>cause</i>, and may be accessed via the {@link
+ * Throwable#getCause()} method, as well as the aforementioned "legacy method."
+ *
+ * @author unascribed
+ * @see java.lang.Class#forName(java.lang.String)
+ * @see java.lang.ClassLoader#findSystemClass(java.lang.String)
+ * @see java.lang.ClassLoader#loadClass(java.lang.String, boolean)
+ * @since JDK1.0
+ */
+public class ClassNotFoundException extends ReflectiveOperationException {
+ /**
+ * use serialVersionUID from JDK 1.1.X for interoperability
+ */
+ private static final long serialVersionUID = 9176873029745254542L;
+
+ /**
+ * This field holds the exception ex if the
+ * ClassNotFoundException(String s, Throwable ex) constructor was
+ * used to instantiate the object
+ * @serial
+ * @since 1.2
+ */
+ private Throwable ex;
+
+ /**
+ * Constructs a <code>ClassNotFoundException</code> with no detail message.
+ */
+ public ClassNotFoundException() {
+ super((Throwable)null); // Disallow initCause
+ }
+
+ /**
+ * Constructs a <code>ClassNotFoundException</code> with the
+ * specified detail message.
+ *
+ * @param s the detail message.
+ */
+ public ClassNotFoundException(String s) {
+ super(s, null); // Disallow initCause
+ }
+
+ /**
+ * Constructs a <code>ClassNotFoundException</code> with the
+ * specified detail message and optional exception that was
+ * raised while loading the class.
+ *
+ * @param s the detail message
+ * @param ex the exception that was raised while loading the class
+ * @since 1.2
+ */
+ public ClassNotFoundException(String s, Throwable ex) {
+ super(s, null); // Disallow initCause
+ this.ex = ex;
+ }
+
+ /**
+ * Returns the exception that was raised if an error occurred while
+ * attempting to load the class. Otherwise, returns <tt>null</tt>.
+ *
+ * <p>This method predates the general-purpose exception chaining facility.
+ * The {@link Throwable#getCause()} method is now the preferred means of
+ * obtaining this information.
+ *
+ * @return the <code>Exception</code> that was raised while loading a class
+ * @since 1.2
+ */
+ public Throwable getException() {
+ return ex;
+ }
+
+ /**
+ * Returns the cause of this exception (the exception that was raised
+ * if an error occurred while attempting to load the class; otherwise
+ * <tt>null</tt>).
+ *
+ * @return the cause of this exception.
+ * @since 1.4
+ */
+ public Throwable getCause() {
+ return ex;
+ }
+}
diff --git a/java/lang/CloneNotSupportedException.java b/java/lang/CloneNotSupportedException.java
new file mode 100644
index 0000000..e43901c
--- /dev/null
+++ b/java/lang/CloneNotSupportedException.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 1995, 2008, 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;
+
+/**
+ * Thrown to indicate that the <code>clone</code> method in class
+ * <code>Object</code> has been called to clone an object, but that
+ * the object's class does not implement the <code>Cloneable</code>
+ * interface.
+ * <p>
+ * Applications that override the <code>clone</code> method can also
+ * throw this exception to indicate that an object could not or
+ * should not be cloned.
+ *
+ * @author unascribed
+ * @see java.lang.Cloneable
+ * @see java.lang.Object#clone()
+ * @since JDK1.0
+ */
+
+public
+class CloneNotSupportedException extends Exception {
+ private static final long serialVersionUID = 5195511250079656443L;
+
+ /**
+ * Constructs a <code>CloneNotSupportedException</code> with no
+ * detail message.
+ */
+ public CloneNotSupportedException() {
+ super();
+ }
+
+ /**
+ * Constructs a <code>CloneNotSupportedException</code> with the
+ * specified detail message.
+ *
+ * @param s the detail message.
+ */
+ public CloneNotSupportedException(String s) {
+ super(s);
+ }
+}
diff --git a/java/lang/Cloneable.java b/java/lang/Cloneable.java
new file mode 100644
index 0000000..14cf2a9
--- /dev/null
+++ b/java/lang/Cloneable.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 1995, 2004, 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;
+
+/**
+ * A class implements the <code>Cloneable</code> interface to
+ * indicate to the {@link java.lang.Object#clone()} method that it
+ * is legal for that method to make a
+ * field-for-field copy of instances of that class.
+ * <p>
+ * Invoking Object's clone method on an instance that does not implement the
+ * <code>Cloneable</code> interface results in the exception
+ * <code>CloneNotSupportedException</code> being thrown.
+ * <p>
+ * By convention, classes that implement this interface should override
+ * <tt>Object.clone</tt> (which is protected) with a public method.
+ * See {@link java.lang.Object#clone()} for details on overriding this
+ * method.
+ * <p>
+ * Note that this interface does <i>not</i> contain the <tt>clone</tt> method.
+ * Therefore, it is not possible to clone an object merely by virtue of the
+ * fact that it implements this interface. Even if the clone method is invoked
+ * reflectively, there is no guarantee that it will succeed.
+ *
+ * @author unascribed
+ * @see java.lang.CloneNotSupportedException
+ * @see java.lang.Object#clone()
+ * @since JDK1.0
+ */
+public interface Cloneable {
+}
diff --git a/java/lang/Comparable.java b/java/lang/Comparable.java
new file mode 100644
index 0000000..a88cf16
--- /dev/null
+++ b/java/lang/Comparable.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 1997, 2013, 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;
+import java.util.*;
+
+/**
+ * This interface imposes a total ordering on the objects of each class that
+ * implements it. This ordering is referred to as the class's <i>natural
+ * ordering</i>, and the class's <tt>compareTo</tt> method is referred to as
+ * its <i>natural comparison method</i>.<p>
+ *
+ * Lists (and arrays) of objects that implement this interface can be sorted
+ * automatically by {@link Collections#sort(List) Collections.sort} (and
+ * {@link Arrays#sort(Object[]) Arrays.sort}). Objects that implement this
+ * interface can be used as keys in a {@linkplain SortedMap sorted map} or as
+ * elements in a {@linkplain SortedSet sorted set}, without the need to
+ * specify a {@linkplain Comparator comparator}.<p>
+ *
+ * The natural ordering for a class <tt>C</tt> is said to be <i>consistent
+ * with equals</i> if and only if <tt>e1.compareTo(e2) == 0</tt> has
+ * the same boolean value as <tt>e1.equals(e2)</tt> for every
+ * <tt>e1</tt> and <tt>e2</tt> of class <tt>C</tt>. Note that <tt>null</tt>
+ * is not an instance of any class, and <tt>e.compareTo(null)</tt> should
+ * throw a <tt>NullPointerException</tt> even though <tt>e.equals(null)</tt>
+ * returns <tt>false</tt>.<p>
+ *
+ * It is strongly recommended (though not required) that natural orderings be
+ * consistent with equals. This is so because sorted sets (and sorted maps)
+ * without explicit comparators behave "strangely" when they are used with
+ * elements (or keys) whose natural ordering is inconsistent with equals. In
+ * particular, such a sorted set (or sorted map) violates the general contract
+ * for set (or map), which is defined in terms of the <tt>equals</tt>
+ * method.<p>
+ *
+ * For example, if one adds two keys <tt>a</tt> and <tt>b</tt> such that
+ * {@code (!a.equals(b) && a.compareTo(b) == 0)} to a sorted
+ * set that does not use an explicit comparator, the second <tt>add</tt>
+ * operation returns false (and the size of the sorted set does not increase)
+ * because <tt>a</tt> and <tt>b</tt> are equivalent from the sorted set's
+ * perspective.<p>
+ *
+ * Virtually all Java core classes that implement <tt>Comparable</tt> have natural
+ * orderings that are consistent with equals. One exception is
+ * <tt>java.math.BigDecimal</tt>, whose natural ordering equates
+ * <tt>BigDecimal</tt> objects with equal values and different precisions
+ * (such as 4.0 and 4.00).<p>
+ *
+ * For the mathematically inclined, the <i>relation</i> that defines
+ * the natural ordering on a given class C is:<pre>
+ * {(x, y) such that x.compareTo(y) <= 0}.
+ * </pre> The <i>quotient</i> for this total order is: <pre>
+ * {(x, y) such that x.compareTo(y) == 0}.
+ * </pre>
+ *
+ * It follows immediately from the contract for <tt>compareTo</tt> that the
+ * quotient is an <i>equivalence relation</i> on <tt>C</tt>, and that the
+ * natural ordering is a <i>total order</i> on <tt>C</tt>. When we say that a
+ * class's natural ordering is <i>consistent with equals</i>, we mean that the
+ * quotient for the natural ordering is the equivalence relation defined by
+ * the class's {@link Object#equals(Object) equals(Object)} method:<pre>
+ * {(x, y) such that x.equals(y)}. </pre><p>
+ *
+ * This interface is a member of the
+ * <a href="{@docRoot}/../technotes/guides/collections/index.html">
+ * Java Collections Framework</a>.
+ *
+ * @param <T> the type of objects that this object may be compared to
+ *
+ * @author Josh Bloch
+ * @see java.util.Comparator
+ * @since 1.2
+ */
+public interface Comparable<T> {
+ /**
+ * Compares this object with the specified object for order. Returns a
+ * negative integer, zero, or a positive integer as this object is less
+ * than, equal to, or greater than the specified object.
+ *
+ * <p>The implementor must ensure <tt>sgn(x.compareTo(y)) ==
+ * -sgn(y.compareTo(x))</tt> for all <tt>x</tt> and <tt>y</tt>. (This
+ * implies that <tt>x.compareTo(y)</tt> must throw an exception iff
+ * <tt>y.compareTo(x)</tt> throws an exception.)
+ *
+ * <p>The implementor must also ensure that the relation is transitive:
+ * <tt>(x.compareTo(y)>0 && y.compareTo(z)>0)</tt> implies
+ * <tt>x.compareTo(z)>0</tt>.
+ *
+ * <p>Finally, the implementor must ensure that <tt>x.compareTo(y)==0</tt>
+ * implies that <tt>sgn(x.compareTo(z)) == sgn(y.compareTo(z))</tt>, for
+ * all <tt>z</tt>.
+ *
+ * <p>It is strongly recommended, but <i>not</i> strictly required that
+ * <tt>(x.compareTo(y)==0) == (x.equals(y))</tt>. Generally speaking, any
+ * class that implements the <tt>Comparable</tt> interface and violates
+ * this condition should clearly indicate this fact. The recommended
+ * language is "Note: this class has a natural ordering that is
+ * inconsistent with equals."
+ *
+ * <p>In the foregoing description, the notation
+ * <tt>sgn(</tt><i>expression</i><tt>)</tt> designates the mathematical
+ * <i>signum</i> function, which is defined to return one of <tt>-1</tt>,
+ * <tt>0</tt>, or <tt>1</tt> according to whether the value of
+ * <i>expression</i> is negative, zero or positive.
+ *
+ * @param o the object to be compared.
+ * @return a negative integer, zero, or a positive integer as this object
+ * is less than, equal to, or greater than the specified object.
+ *
+ * @throws NullPointerException if the specified object is null
+ * @throws ClassCastException if the specified object's type prevents it
+ * from being compared to this object.
+ */
+ public int compareTo(T o);
+}
diff --git a/java/lang/Compiler.java b/java/lang/Compiler.java
new file mode 100644
index 0000000..def9a83
--- /dev/null
+++ b/java/lang/Compiler.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1995, 2008, 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;
+
+/**
+ * Does nothing on Android.
+ */
+public final class Compiler {
+ /**
+ * Prevent this class from being instantiated.
+ */
+ private Compiler() {} // don't make instances
+
+ /**
+ * Compiles the specified class using the JIT compiler and indicates if
+ * compilation has been successful. Does nothing and returns false on
+ * Android.
+ *
+ * @param classToCompile
+ * java.lang.Class the class to JIT compile
+ * @return {@code true} if the compilation has been successful;
+ * {@code false} if it has failed or if there is no JIT compiler
+ * available.
+ */
+ public static boolean compileClass(Class<?> classToCompile) {
+ return false;
+ }
+
+ /**
+ * Compiles all classes whose name matches the specified name using the JIT
+ * compiler and indicates if compilation has been successful. Does nothing
+ * and returns false on Android.
+ *
+ * @param nameRoot
+ * the string to match class names with.
+ * @return {@code true} if the compilation has been successful;
+ * {@code false} if it has failed or if there is no JIT compiler
+ * available.
+ */
+ public static boolean compileClasses(String nameRoot) {
+ return false;
+ }
+
+ /**
+ * Executes an operation according to the specified command object. This
+ * method is the low-level interface to the JIT compiler. It may return any
+ * object or {@code null} if no JIT compiler is available. Returns null
+ * on Android, whether or not the system has a JIT.
+ *
+ * @param cmd
+ * the command object for the JIT compiler.
+ * @return the result of executing command or {@code null}.
+ */
+ public static Object command(Object cmd) {
+ return null;
+ }
+
+ /**
+ * Enables the JIT compiler. Does nothing on Android.
+ */
+ public static void enable() {
+
+ }
+
+ /**
+ * Disables the JIT compiler. Does nothing on Android.
+ */
+ public static void disable() {
+
+ }
+}
diff --git a/java/lang/Daemons.java b/java/lang/Daemons.java
new file mode 100644
index 0000000..568614f
--- /dev/null
+++ b/java/lang/Daemons.java
@@ -0,0 +1,528 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.lang;
+
+import android.compat.annotation.UnsupportedAppUsage;
+import android.system.Os;
+import android.system.OsConstants;
+
+import java.lang.ref.FinalizerReference;
+import java.lang.ref.Reference;
+import java.lang.ref.ReferenceQueue;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicInteger;
+import libcore.util.EmptyArray;
+
+import dalvik.system.VMRuntime;
+import dalvik.system.VMDebug;
+
+/**
+ * Calls Object.finalize() on objects in the finalizer reference queue. The VM
+ * will abort if any finalize() call takes more than the maximum finalize time
+ * to complete.
+ *
+ * @hide
+ */
+public final class Daemons {
+ private static final int NANOS_PER_MILLI = 1000 * 1000;
+
+ // This used to be final. IT IS NOW ONLY WRITTEN. We now update it when we look at the command
+ // line argument, for the benefit of mis-behaved apps that might read it. SLATED FOR REMOVAL.
+ // There is no reason to use this: Finalizers should not rely on the value. If a finalizer takes
+ // appreciable time, the work should be done elsewhere. Based on disassembly of Daemons.class,
+ // the value is effectively inlined, so changing the field never did have an effect.
+ // DO NOT USE. FOR ANYTHING. THIS WILL BE REMOVED SHORTLY.
+ @UnsupportedAppUsage
+ private static long MAX_FINALIZE_NANOS = 10L * 1000 * NANOS_PER_MILLI;
+
+ private static final Daemon[] DAEMONS = new Daemon[] {
+ HeapTaskDaemon.INSTANCE,
+ ReferenceQueueDaemon.INSTANCE,
+ FinalizerDaemon.INSTANCE,
+ FinalizerWatchdogDaemon.INSTANCE,
+ };
+ private static final CountDownLatch POST_ZYGOTE_START_LATCH = new CountDownLatch(DAEMONS.length);
+ private static final CountDownLatch PRE_ZYGOTE_START_LATCH = new CountDownLatch(DAEMONS.length);
+
+ private static boolean postZygoteFork = false;
+
+ @UnsupportedAppUsage
+ public static void start() {
+ for (Daemon daemon : DAEMONS) {
+ daemon.start();
+ }
+ }
+
+ public static void startPostZygoteFork() {
+ postZygoteFork = true;
+ for (Daemon daemon : DAEMONS) {
+ daemon.startPostZygoteFork();
+ }
+ }
+
+ @UnsupportedAppUsage
+ public static void stop() {
+ for (Daemon daemon : DAEMONS) {
+ daemon.stop();
+ }
+ }
+
+ private static void waitForDaemonStart() throws Exception {
+ if (postZygoteFork) {
+ POST_ZYGOTE_START_LATCH.await();
+ } else {
+ PRE_ZYGOTE_START_LATCH.await();
+ }
+ }
+
+ /**
+ * A background task that provides runtime support to the application.
+ * Daemons can be stopped and started, but only so that the zygote can be a
+ * single-threaded process when it forks.
+ */
+ private static abstract class Daemon implements Runnable {
+ @UnsupportedAppUsage
+ private Thread thread;
+ private String name;
+ private boolean postZygoteFork;
+
+ protected Daemon(String name) {
+ this.name = name;
+ }
+
+ @UnsupportedAppUsage
+ public synchronized void start() {
+ startInternal();
+ }
+
+ public synchronized void startPostZygoteFork() {
+ postZygoteFork = true;
+ startInternal();
+ }
+
+ public void startInternal() {
+ if (thread != null) {
+ throw new IllegalStateException("already running");
+ }
+ thread = new Thread(ThreadGroup.systemThreadGroup, this, name);
+ thread.setDaemon(true);
+ thread.setSystemDaemon(true);
+ thread.start();
+ }
+
+ public final void run() {
+ if (postZygoteFork) {
+ // We don't set the priority before the Thread.start() call above because
+ // Thread.start() will call SetNativePriority and overwrite the desired native
+ // priority. We (may) use a native priority that doesn't have a corresponding
+ // java.lang.Thread-level priority (native priorities are more coarse-grained.)
+ VMRuntime.getRuntime().setSystemDaemonThreadPriority();
+ POST_ZYGOTE_START_LATCH.countDown();
+ } else {
+ PRE_ZYGOTE_START_LATCH.countDown();
+ }
+ runInternal();
+ }
+
+ public abstract void runInternal();
+
+ /**
+ * Returns true while the current thread should continue to run; false
+ * when it should return.
+ */
+ @UnsupportedAppUsage
+ protected synchronized boolean isRunning() {
+ return thread != null;
+ }
+
+ public synchronized void interrupt() {
+ interrupt(thread);
+ }
+
+ public synchronized void interrupt(Thread thread) {
+ if (thread == null) {
+ throw new IllegalStateException("not running");
+ }
+ thread.interrupt();
+ }
+
+ /**
+ * Waits for the runtime thread to stop. This interrupts the thread
+ * currently running the runnable and then waits for it to exit.
+ */
+ @UnsupportedAppUsage
+ public void stop() {
+ Thread threadToStop;
+ synchronized (this) {
+ threadToStop = thread;
+ thread = null;
+ }
+ if (threadToStop == null) {
+ throw new IllegalStateException("not running");
+ }
+ interrupt(threadToStop);
+ while (true) {
+ try {
+ threadToStop.join();
+ return;
+ } catch (InterruptedException ignored) {
+ } catch (OutOfMemoryError ignored) {
+ // An OOME may be thrown if allocating the InterruptedException failed.
+ }
+ }
+ }
+
+ /**
+ * Returns the current stack trace of the thread, or an empty stack trace
+ * if the thread is not currently running.
+ */
+ public synchronized StackTraceElement[] getStackTrace() {
+ return thread != null ? thread.getStackTrace() : EmptyArray.STACK_TRACE_ELEMENT;
+ }
+ }
+
+ /**
+ * This heap management thread moves elements from the garbage collector's
+ * pending list to the managed reference queue.
+ */
+ private static class ReferenceQueueDaemon extends Daemon {
+ @UnsupportedAppUsage
+ private static final ReferenceQueueDaemon INSTANCE = new ReferenceQueueDaemon();
+
+ ReferenceQueueDaemon() {
+ super("ReferenceQueueDaemon");
+ }
+
+ @Override public void runInternal() {
+ while (isRunning()) {
+ Reference<?> list;
+ try {
+ synchronized (ReferenceQueue.class) {
+ while (ReferenceQueue.unenqueued == null) {
+ ReferenceQueue.class.wait();
+ }
+ list = ReferenceQueue.unenqueued;
+ ReferenceQueue.unenqueued = null;
+ }
+ } catch (InterruptedException e) {
+ continue;
+ } catch (OutOfMemoryError e) {
+ continue;
+ }
+ ReferenceQueue.enqueuePending(list);
+ }
+ }
+ }
+
+ private static class FinalizerDaemon extends Daemon {
+ @UnsupportedAppUsage
+ private static final FinalizerDaemon INSTANCE = new FinalizerDaemon();
+ private final ReferenceQueue<Object> queue = FinalizerReference.queue;
+ private final AtomicInteger progressCounter = new AtomicInteger(0);
+ // Object (not reference!) being finalized. Accesses may race!
+ @UnsupportedAppUsage
+ private Object finalizingObject = null;
+
+ FinalizerDaemon() {
+ super("FinalizerDaemon");
+ }
+
+ @Override public void runInternal() {
+ // This loop may be performance critical, since we need to keep up with mutator
+ // generation of finalizable objects.
+ // We minimize the amount of work we do per finalizable object. For example, we avoid
+ // reading the current time here, since that involves a kernel call per object. We
+ // limit fast path communication with FinalizerWatchDogDaemon to what's unavoidable: A
+ // non-volatile store to communicate the current finalizable object, e.g. for
+ // reporting, and a release store (lazySet) to a counter.
+ // We do stop the FinalizerWatchDogDaemon if we have nothing to do for a
+ // potentially extended period. This prevents the device from waking up regularly
+ // during idle times.
+
+ // Local copy of progressCounter; saves a fence per increment on ARM and MIPS.
+ int localProgressCounter = progressCounter.get();
+
+ while (isRunning()) {
+ try {
+ // Use non-blocking poll to avoid FinalizerWatchdogDaemon communication
+ // when busy.
+ FinalizerReference<?> finalizingReference = (FinalizerReference<?>)queue.poll();
+ if (finalizingReference != null) {
+ finalizingObject = finalizingReference.get();
+ progressCounter.lazySet(++localProgressCounter);
+ } else {
+ finalizingObject = null;
+ progressCounter.lazySet(++localProgressCounter);
+ // Slow path; block.
+ FinalizerWatchdogDaemon.INSTANCE.goToSleep();
+ finalizingReference = (FinalizerReference<?>)queue.remove();
+ finalizingObject = finalizingReference.get();
+ progressCounter.set(++localProgressCounter);
+ FinalizerWatchdogDaemon.INSTANCE.wakeUp();
+ }
+ doFinalize(finalizingReference);
+ } catch (InterruptedException ignored) {
+ } catch (OutOfMemoryError ignored) {
+ }
+ }
+ }
+
+ @FindBugsSuppressWarnings("FI_EXPLICIT_INVOCATION")
+ private void doFinalize(FinalizerReference<?> reference) {
+ FinalizerReference.remove(reference);
+ Object object = reference.get();
+ reference.clear();
+ try {
+ object.finalize();
+ } catch (Throwable ex) {
+ // The RI silently swallows these, but Android has always logged.
+ System.logE("Uncaught exception thrown by finalizer", ex);
+ } finally {
+ // Done finalizing, stop holding the object as live.
+ finalizingObject = null;
+ }
+ }
+ }
+
+ /**
+ * The watchdog exits the VM if the finalizer ever gets stuck. We consider
+ * the finalizer to be stuck if it spends more than MAX_FINALIZATION_MILLIS
+ * on one instance.
+ */
+ private static class FinalizerWatchdogDaemon extends Daemon {
+ @UnsupportedAppUsage
+ private static final FinalizerWatchdogDaemon INSTANCE = new FinalizerWatchdogDaemon();
+
+ private boolean needToWork = true; // Only accessed in synchronized methods.
+
+ private long finalizerTimeoutMs = 0; // Lazily initialized.
+
+ FinalizerWatchdogDaemon() {
+ super("FinalizerWatchdogDaemon");
+ }
+
+ @Override public void runInternal() {
+ while (isRunning()) {
+ if (!sleepUntilNeeded()) {
+ // We have been interrupted, need to see if this daemon has been stopped.
+ continue;
+ }
+ final Object finalizing = waitForFinalization();
+ if (finalizing != null && !VMDebug.isDebuggerConnected()) {
+ finalizerTimedOut(finalizing);
+ break;
+ }
+ }
+ }
+
+ /**
+ * Wait until something is ready to be finalized.
+ * Return false if we have been interrupted
+ * See also http://code.google.com/p/android/issues/detail?id=22778.
+ */
+ private synchronized boolean sleepUntilNeeded() {
+ while (!needToWork) {
+ try {
+ wait();
+ } catch (InterruptedException e) {
+ // Daemon.stop may have interrupted us.
+ return false;
+ } catch (OutOfMemoryError e) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Notify daemon that it's OK to sleep until notified that something is ready to be
+ * finalized.
+ */
+ private synchronized void goToSleep() {
+ needToWork = false;
+ }
+
+ /**
+ * Notify daemon that there is something ready to be finalized.
+ */
+ private synchronized void wakeUp() {
+ needToWork = true;
+ notify();
+ }
+
+ private synchronized boolean getNeedToWork() {
+ return needToWork;
+ }
+
+ /**
+ * Sleep for the given number of milliseconds.
+ * @return false if we were interrupted.
+ */
+ private boolean sleepForMillis(long durationMillis) {
+ long startMillis = System.currentTimeMillis();
+ while (true) {
+ long elapsedMillis = System.currentTimeMillis() - startMillis;
+ long sleepMillis = durationMillis - elapsedMillis;
+ if (sleepMillis <= 0) {
+ return true;
+ }
+ try {
+ Thread.sleep(sleepMillis);
+ } catch (InterruptedException e) {
+ if (!isRunning()) {
+ return false;
+ }
+ } catch (OutOfMemoryError ignored) {
+ if (!isRunning()) {
+ return false;
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Return an object that took too long to finalize or return null.
+ * Wait VMRuntime.getFinalizerTimeoutMs. If the FinalizerDaemon took essentially the
+ * whole time processing a single reference, return that reference. Otherwise return
+ * null. Only called from a single thread.
+ */
+ private Object waitForFinalization() {
+ if (finalizerTimeoutMs == 0) {
+ finalizerTimeoutMs = VMRuntime.getRuntime().getFinalizerTimeoutMs();
+ // Temporary app backward compatibility. Remove eventually.
+ MAX_FINALIZE_NANOS = NANOS_PER_MILLI * finalizerTimeoutMs;
+ }
+ long startCount = FinalizerDaemon.INSTANCE.progressCounter.get();
+ // Avoid remembering object being finalized, so as not to keep it alive.
+ if (!sleepForMillis(finalizerTimeoutMs)) {
+ // Don't report possibly spurious timeout if we are interrupted.
+ return null;
+ }
+ if (getNeedToWork() && FinalizerDaemon.INSTANCE.progressCounter.get() == startCount) {
+ // We assume that only remove() and doFinalize() may take time comparable to
+ // the finalizer timeout.
+ // We observed neither the effect of the gotoSleep() nor the increment preceding a
+ // later wakeUp. Any remove() call by the FinalizerDaemon during our sleep
+ // interval must have been followed by a wakeUp call before we checked needToWork.
+ // But then we would have seen the counter increment. Thus there cannot have
+ // been such a remove() call.
+ // The FinalizerDaemon must not have progressed (from either the beginning or the
+ // last progressCounter increment) to either the next increment or gotoSleep()
+ // call. Thus we must have taken essentially the whole finalizerTimeoutMs in a
+ // single doFinalize() call. Thus it's OK to time out. finalizingObject was set
+ // just before the counter increment, which preceded the doFinalize call. Thus we
+ // are guaranteed to get the correct finalizing value below, unless doFinalize()
+ // just finished as we were timing out, in which case we may get null or a later
+ // one. In this last case, we are very likely to discard it below.
+ Object finalizing = FinalizerDaemon.INSTANCE.finalizingObject;
+ sleepForMillis(500);
+ // Recheck to make it even less likely we report the wrong finalizing object in
+ // the case which a very slow finalization just finished as we were timing out.
+ if (getNeedToWork()
+ && FinalizerDaemon.INSTANCE.progressCounter.get() == startCount) {
+ return finalizing;
+ }
+ }
+ return null;
+ }
+
+ private static void finalizerTimedOut(Object object) {
+ // The current object has exceeded the finalization deadline; abort!
+ String message = object.getClass().getName() + ".finalize() timed out after "
+ + VMRuntime.getRuntime().getFinalizerTimeoutMs() / 1000 + " seconds";
+ Exception syntheticException = new TimeoutException(message);
+ // We use the stack from where finalize() was running to show where it was stuck.
+ syntheticException.setStackTrace(FinalizerDaemon.INSTANCE.getStackTrace());
+
+ // Send SIGQUIT to get native stack traces.
+ try {
+ Os.kill(Os.getpid(), OsConstants.SIGQUIT);
+ // Sleep a few seconds to let the stack traces print.
+ Thread.sleep(5000);
+ } catch (Exception e) {
+ System.logE("failed to send SIGQUIT", e);
+ } catch (OutOfMemoryError ignored) {
+ // May occur while trying to allocate the exception.
+ }
+
+ // Ideally, we'd want to do this if this Thread had no handler to dispatch to.
+ // Unfortunately, it's extremely to messy to query whether a given Thread has *some*
+ // handler to dispatch to, either via a handler set on itself, via its ThreadGroup
+ // object or via the defaultUncaughtExceptionHandler.
+ //
+ // As an approximation, we log by hand an exit if there's no pre-exception handler nor
+ // a default uncaught exception handler.
+ //
+ // Note that this condition will only ever be hit by ART host tests and standalone
+ // dalvikvm invocations. All zygote forked process *will* have a pre-handler set
+ // in RuntimeInit and they cannot subsequently override it.
+ if (Thread.getUncaughtExceptionPreHandler() == null &&
+ Thread.getDefaultUncaughtExceptionHandler() == null) {
+ // If we have no handler, log and exit.
+ System.logE(message, syntheticException);
+ System.exit(2);
+ }
+
+ // Otherwise call the handler to do crash reporting.
+ // We don't just throw because we're not the thread that
+ // timed out; we're the thread that detected it.
+ Thread.currentThread().dispatchUncaughtException(syntheticException);
+ }
+ }
+
+ // Adds a heap trim task to the heap event processor, not called from java. Left for
+ // compatibility purposes due to reflection.
+ @UnsupportedAppUsage
+ public static void requestHeapTrim() {
+ VMRuntime.getRuntime().requestHeapTrim();
+ }
+
+ // Adds a concurrent GC request task ot the heap event processor, not called from java. Left
+ // for compatibility purposes due to reflection.
+ public static void requestGC() {
+ VMRuntime.getRuntime().requestConcurrentGC();
+ }
+
+ private static class HeapTaskDaemon extends Daemon {
+ private static final HeapTaskDaemon INSTANCE = new HeapTaskDaemon();
+
+ HeapTaskDaemon() {
+ super("HeapTaskDaemon");
+ }
+
+ // Overrides the Daemon.interupt method which is called from Daemons.stop.
+ public synchronized void interrupt(Thread thread) {
+ VMRuntime.getRuntime().stopHeapTaskProcessor();
+ }
+
+ @Override public void runInternal() {
+ synchronized (this) {
+ if (isRunning()) {
+ // Needs to be synchronized or else we there is a race condition where we start
+ // the thread, call stopHeapTaskProcessor before we start the heap task
+ // processor, resulting in a deadlock since startHeapTaskProcessor restarts it
+ // while the other thread is waiting in Daemons.stop().
+ VMRuntime.getRuntime().startHeapTaskProcessor();
+ }
+ }
+ // This runs tasks until we are stopped and there is no more pending task.
+ VMRuntime.getRuntime().runHeapTasks();
+ }
+ }
+}
diff --git a/java/lang/Deprecated.java b/java/lang/Deprecated.java
new file mode 100644
index 0000000..58a0691
--- /dev/null
+++ b/java/lang/Deprecated.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2003, 2013, 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;
+
+import java.lang.annotation.*;
+import static java.lang.annotation.ElementType.*;
+
+/**
+ * A program element annotated @Deprecated is one that programmers
+ * are discouraged from using, typically because it is dangerous,
+ * or because a better alternative exists. Compilers warn when a
+ * deprecated program element is used or overridden in non-deprecated code.
+ *
+ * @author Neal Gafter
+ * @since 1.5
+ * @jls 9.6.3.6 @Deprecated
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
+public @interface Deprecated {
+}
diff --git a/java/lang/DexCache.java b/java/lang/DexCache.java
new file mode 100644
index 0000000..e35a69d
--- /dev/null
+++ b/java/lang/DexCache.java
@@ -0,0 +1,130 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.lang;
+
+import android.compat.annotation.UnsupportedAppUsage;
+import dalvik.annotation.optimization.FastNative;
+
+/**
+ * A dex cache holds resolved copies of strings, fields, methods, and classes from the dexfile.
+ */
+final class DexCache {
+ /** The classloader this dex cache is for. */
+ private ClassLoader classLoader;
+
+ /** The location of the associated dex file. */
+ private String location;
+
+ /** Holds C pointer to dexFile. */
+ @UnsupportedAppUsage
+ private long dexFile;
+
+ /**
+ * References to pre resolved strings.
+ */
+ private long preResolvedStrings;
+
+ /**
+ * References to CallSite (C array pointer) as they become resolved following
+ * interpreter semantics.
+ */
+ private long resolvedCallSites;
+
+ /**
+ * References to fields (C array pointer) as they become resolved following
+ * interpreter semantics. May refer to fields defined in other dex files.
+ */
+ private long resolvedFields;
+
+ /**
+ * References to MethodType (C array pointer) as they become resolved following
+ * interpreter semantics.
+ */
+ private long resolvedMethodTypes;
+
+ /**
+ * References to methods (C array pointer) as they become resolved following
+ * interpreter semantics. May refer to methods defined in other dex files.
+ */
+ private long resolvedMethods;
+
+ /**
+ * References to types (C array pointer) as they become resolved following
+ * interpreter semantics. May refer to types defined in other dex files.
+ */
+ private long resolvedTypes;
+
+ /**
+ * References to strings (C array pointer) as they become resolved following
+ * interpreter semantics. All strings are interned.
+ */
+ private long strings;
+
+ /**
+ * The number of elements in the native pre resolved strings array.
+ */
+ private int numPreResolvedStrings;
+
+ /**
+ * The number of elements in the native call sites array.
+ */
+ private int numResolvedCallSites;
+
+ /**
+ * The number of elements in the native resolvedFields array.
+ */
+ private int numResolvedFields;
+
+ /**
+ * The number of elements in the native method types array.
+ */
+ private int numResolvedMethodTypes;
+
+ /**
+ * The number of elements in the native resolvedMethods array.
+ */
+ private int numResolvedMethods;
+
+ /**
+ * The number of elements in the native resolvedTypes array.
+ */
+ private int numResolvedTypes;
+
+ /**
+ * The number of elements in the native strings array.
+ */
+ private int numStrings;
+
+ // Only created by the VM.
+ private DexCache() {}
+}
diff --git a/java/lang/Double.annotated.java b/java/lang/Double.annotated.java
new file mode 100644
index 0000000..8f565fc
--- /dev/null
+++ b/java/lang/Double.annotated.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 1994, 2013, 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;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Double extends java.lang.Number implements java.lang.Comparable<java.lang.Double> {
+
+public Double(double value) { throw new RuntimeException("Stub!"); }
+
+public Double(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String toString(double d) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String toHexString(double d) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Double valueOf(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Double valueOf(double d) { throw new RuntimeException("Stub!"); }
+
+public static double parseDouble(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public static boolean isNaN(double v) { throw new RuntimeException("Stub!"); }
+
+public static boolean isInfinite(double v) { throw new RuntimeException("Stub!"); }
+
+public static boolean isFinite(double d) { throw new RuntimeException("Stub!"); }
+
+public boolean isNaN() { throw new RuntimeException("Stub!"); }
+
+public boolean isInfinite() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public byte byteValue() { throw new RuntimeException("Stub!"); }
+
+public short shortValue() { throw new RuntimeException("Stub!"); }
+
+public int intValue() { throw new RuntimeException("Stub!"); }
+
+public long longValue() { throw new RuntimeException("Stub!"); }
+
+public float floatValue() { throw new RuntimeException("Stub!"); }
+
+public double doubleValue() { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public static int hashCode(double value) { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public static long doubleToLongBits(double value) { throw new RuntimeException("Stub!"); }
+
+public static native long doubleToRawLongBits(double value);
+
+public static native double longBitsToDouble(long bits);
+
+public int compareTo(@libcore.util.NonNull java.lang.Double anotherDouble) { throw new RuntimeException("Stub!"); }
+
+public static int compare(double d1, double d2) { throw new RuntimeException("Stub!"); }
+
+public static double sum(double a, double b) { throw new RuntimeException("Stub!"); }
+
+public static double max(double a, double b) { throw new RuntimeException("Stub!"); }
+
+public static double min(double a, double b) { throw new RuntimeException("Stub!"); }
+
+public static final int BYTES = 8; // 0x8
+
+public static final int MAX_EXPONENT = 1023; // 0x3ff
+
+public static final double MAX_VALUE = 1.7976931348623157E308;
+
+public static final int MIN_EXPONENT = -1022; // 0xfffffc02
+
+public static final double MIN_NORMAL = 2.2250738585072014E-308;
+
+public static final double MIN_VALUE = 4.9E-324;
+
+public static final double NEGATIVE_INFINITY = (-1.0/0.0);
+
+public static final double NaN = (0.0/0.0);
+
+public static final double POSITIVE_INFINITY = (1.0/0.0);
+
+public static final int SIZE = 64; // 0x40
+
+public static final java.lang.Class<java.lang.Double> TYPE;
+static { TYPE = null; }
+}
+
diff --git a/java/lang/Double.java b/java/lang/Double.java
new file mode 100644
index 0000000..690ca6a
--- /dev/null
+++ b/java/lang/Double.java
@@ -0,0 +1,1058 @@
+/*
+ * Copyright (c) 1994, 2013, 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;
+
+import sun.misc.FloatingDecimal;
+import sun.misc.FpUtils;
+import sun.misc.DoubleConsts;
+
+/**
+ * The {@code Double} class wraps a value of the primitive type
+ * {@code double} in an object. An object of type
+ * {@code Double} contains a single field whose type is
+ * {@code double}.
+ *
+ * <p>In addition, this class provides several methods for converting a
+ * {@code double} to a {@code String} and a
+ * {@code String} to a {@code double}, as well as other
+ * constants and methods useful when dealing with a
+ * {@code double}.
+ *
+ * @author Lee Boynton
+ * @author Arthur van Hoff
+ * @author Joseph D. Darcy
+ * @since JDK1.0
+ */
+public final class Double extends Number implements Comparable<Double> {
+ /**
+ * A constant holding the positive infinity of type
+ * {@code double}. It is equal to the value returned by
+ * {@code Double.longBitsToDouble(0x7ff0000000000000L)}.
+ */
+ public static final double POSITIVE_INFINITY = 1.0 / 0.0;
+
+ /**
+ * A constant holding the negative infinity of type
+ * {@code double}. It is equal to the value returned by
+ * {@code Double.longBitsToDouble(0xfff0000000000000L)}.
+ */
+ public static final double NEGATIVE_INFINITY = -1.0 / 0.0;
+
+ /**
+ * A constant holding a Not-a-Number (NaN) value of type
+ * {@code double}. It is equivalent to the value returned by
+ * {@code Double.longBitsToDouble(0x7ff8000000000000L)}.
+ */
+ public static final double NaN = 0.0d / 0.0;
+
+ /**
+ * A constant holding the largest positive finite value of type
+ * {@code double},
+ * (2-2<sup>-52</sup>)·2<sup>1023</sup>. It is equal to
+ * the hexadecimal floating-point literal
+ * {@code 0x1.fffffffffffffP+1023} and also equal to
+ * {@code Double.longBitsToDouble(0x7fefffffffffffffL)}.
+ */
+ public static final double MAX_VALUE = 0x1.fffffffffffffP+1023; // 1.7976931348623157e+308
+
+ /**
+ * A constant holding the smallest positive normal value of type
+ * {@code double}, 2<sup>-1022</sup>. It is equal to the
+ * hexadecimal floating-point literal {@code 0x1.0p-1022} and also
+ * equal to {@code Double.longBitsToDouble(0x0010000000000000L)}.
+ *
+ * @since 1.6
+ */
+ public static final double MIN_NORMAL = 0x1.0p-1022; // 2.2250738585072014E-308
+
+ /**
+ * A constant holding the smallest positive nonzero value of type
+ * {@code double}, 2<sup>-1074</sup>. It is equal to the
+ * hexadecimal floating-point literal
+ * {@code 0x0.0000000000001P-1022} and also equal to
+ * {@code Double.longBitsToDouble(0x1L)}.
+ */
+ public static final double MIN_VALUE = 0x0.0000000000001P-1022; // 4.9e-324
+
+ /**
+ * Maximum exponent a finite {@code double} variable may have.
+ * It is equal to the value returned by
+ * {@code Math.getExponent(Double.MAX_VALUE)}.
+ *
+ * @since 1.6
+ */
+ public static final int MAX_EXPONENT = 1023;
+
+ /**
+ * Minimum exponent a normalized {@code double} variable may
+ * have. It is equal to the value returned by
+ * {@code Math.getExponent(Double.MIN_NORMAL)}.
+ *
+ * @since 1.6
+ */
+ public static final int MIN_EXPONENT = -1022;
+
+ /**
+ * The number of bits used to represent a {@code double} value.
+ *
+ * @since 1.5
+ */
+ public static final int SIZE = 64;
+
+ /**
+ * The number of bytes used to represent a {@code double} value.
+ *
+ * @since 1.8
+ */
+ public static final int BYTES = SIZE / Byte.SIZE;
+
+ /**
+ * The {@code Class} instance representing the primitive type
+ * {@code double}.
+ *
+ * @since JDK1.1
+ */
+ @SuppressWarnings("unchecked")
+ public static final Class<Double> TYPE = (Class<Double>) Class.getPrimitiveClass("double");
+
+ /**
+ * Returns a string representation of the {@code double}
+ * argument. All characters mentioned below are ASCII characters.
+ * <ul>
+ * <li>If the argument is NaN, the result is the string
+ * "{@code NaN}".
+ * <li>Otherwise, the result is a string that represents the sign and
+ * magnitude (absolute value) of the argument. If the sign is negative,
+ * the first character of the result is '{@code -}'
+ * ({@code '\u005Cu002D'}); if the sign is positive, no sign character
+ * appears in the result. As for the magnitude <i>m</i>:
+ * <ul>
+ * <li>If <i>m</i> is infinity, it is represented by the characters
+ * {@code "Infinity"}; thus, positive infinity produces the result
+ * {@code "Infinity"} and negative infinity produces the result
+ * {@code "-Infinity"}.
+ *
+ * <li>If <i>m</i> is zero, it is represented by the characters
+ * {@code "0.0"}; thus, negative zero produces the result
+ * {@code "-0.0"} and positive zero produces the result
+ * {@code "0.0"}.
+ *
+ * <li>If <i>m</i> is greater than or equal to 10<sup>-3</sup> but less
+ * than 10<sup>7</sup>, then it is represented as the integer part of
+ * <i>m</i>, in decimal form with no leading zeroes, followed by
+ * '{@code .}' ({@code '\u005Cu002E'}), followed by one or
+ * more decimal digits representing the fractional part of <i>m</i>.
+ *
+ * <li>If <i>m</i> is less than 10<sup>-3</sup> or greater than or
+ * equal to 10<sup>7</sup>, then it is represented in so-called
+ * "computerized scientific notation." Let <i>n</i> be the unique
+ * integer such that 10<sup><i>n</i></sup> ≤ <i>m</i> {@literal <}
+ * 10<sup><i>n</i>+1</sup>; then let <i>a</i> be the
+ * mathematically exact quotient of <i>m</i> and
+ * 10<sup><i>n</i></sup> so that 1 ≤ <i>a</i> {@literal <} 10. The
+ * magnitude is then represented as the integer part of <i>a</i>,
+ * as a single decimal digit, followed by '{@code .}'
+ * ({@code '\u005Cu002E'}), followed by decimal digits
+ * representing the fractional part of <i>a</i>, followed by the
+ * letter '{@code E}' ({@code '\u005Cu0045'}), followed
+ * by a representation of <i>n</i> as a decimal integer, as
+ * produced by the method {@link Integer#toString(int)}.
+ * </ul>
+ * </ul>
+ * How many digits must be printed for the fractional part of
+ * <i>m</i> or <i>a</i>? There must be at least one digit to represent
+ * the fractional part, and beyond that as many, but only as many, more
+ * digits as are needed to uniquely distinguish the argument value from
+ * adjacent values of type {@code double}. That is, suppose that
+ * <i>x</i> is the exact mathematical value represented by the decimal
+ * representation produced by this method for a finite nonzero argument
+ * <i>d</i>. Then <i>d</i> must be the {@code double} value nearest
+ * to <i>x</i>; or if two {@code double} values are equally close
+ * to <i>x</i>, then <i>d</i> must be one of them and the least
+ * significant bit of the significand of <i>d</i> must be {@code 0}.
+ *
+ * <p>To create localized string representations of a floating-point
+ * value, use subclasses of {@link java.text.NumberFormat}.
+ *
+ * @param d the {@code double} to be converted.
+ * @return a string representation of the argument.
+ */
+ public static String toString(double d) {
+ return FloatingDecimal.toJavaFormatString(d);
+ }
+
+ /**
+ * Returns a hexadecimal string representation of the
+ * {@code double} argument. All characters mentioned below
+ * are ASCII characters.
+ *
+ * <ul>
+ * <li>If the argument is NaN, the result is the string
+ * "{@code NaN}".
+ * <li>Otherwise, the result is a string that represents the sign
+ * and magnitude of the argument. If the sign is negative, the
+ * first character of the result is '{@code -}'
+ * ({@code '\u005Cu002D'}); if the sign is positive, no sign
+ * character appears in the result. As for the magnitude <i>m</i>:
+ *
+ * <ul>
+ * <li>If <i>m</i> is infinity, it is represented by the string
+ * {@code "Infinity"}; thus, positive infinity produces the
+ * result {@code "Infinity"} and negative infinity produces
+ * the result {@code "-Infinity"}.
+ *
+ * <li>If <i>m</i> is zero, it is represented by the string
+ * {@code "0x0.0p0"}; thus, negative zero produces the result
+ * {@code "-0x0.0p0"} and positive zero produces the result
+ * {@code "0x0.0p0"}.
+ *
+ * <li>If <i>m</i> is a {@code double} value with a
+ * normalized representation, substrings are used to represent the
+ * significand and exponent fields. The significand is
+ * represented by the characters {@code "0x1."}
+ * followed by a lowercase hexadecimal representation of the rest
+ * of the significand as a fraction. Trailing zeros in the
+ * hexadecimal representation are removed unless all the digits
+ * are zero, in which case a single zero is used. Next, the
+ * exponent is represented by {@code "p"} followed
+ * by a decimal string of the unbiased exponent as if produced by
+ * a call to {@link Integer#toString(int) Integer.toString} on the
+ * exponent value.
+ *
+ * <li>If <i>m</i> is a {@code double} value with a subnormal
+ * representation, the significand is represented by the
+ * characters {@code "0x0."} followed by a
+ * hexadecimal representation of the rest of the significand as a
+ * fraction. Trailing zeros in the hexadecimal representation are
+ * removed. Next, the exponent is represented by
+ * {@code "p-1022"}. Note that there must be at
+ * least one nonzero digit in a subnormal significand.
+ *
+ * </ul>
+ *
+ * </ul>
+ *
+ * <table border>
+ * <caption>Examples</caption>
+ * <tr><th>Floating-point Value</th><th>Hexadecimal String</th>
+ * <tr><td>{@code 1.0}</td> <td>{@code 0x1.0p0}</td>
+ * <tr><td>{@code -1.0}</td> <td>{@code -0x1.0p0}</td>
+ * <tr><td>{@code 2.0}</td> <td>{@code 0x1.0p1}</td>
+ * <tr><td>{@code 3.0}</td> <td>{@code 0x1.8p1}</td>
+ * <tr><td>{@code 0.5}</td> <td>{@code 0x1.0p-1}</td>
+ * <tr><td>{@code 0.25}</td> <td>{@code 0x1.0p-2}</td>
+ * <tr><td>{@code Double.MAX_VALUE}</td>
+ * <td>{@code 0x1.fffffffffffffp1023}</td>
+ * <tr><td>{@code Minimum Normal Value}</td>
+ * <td>{@code 0x1.0p-1022}</td>
+ * <tr><td>{@code Maximum Subnormal Value}</td>
+ * <td>{@code 0x0.fffffffffffffp-1022}</td>
+ * <tr><td>{@code Double.MIN_VALUE}</td>
+ * <td>{@code 0x0.0000000000001p-1022}</td>
+ * </table>
+ * @param d the {@code double} to be converted.
+ * @return a hex string representation of the argument.
+ * @since 1.5
+ * @author Joseph D. Darcy
+ */
+ public static String toHexString(double d) {
+ /*
+ * Modeled after the "a" conversion specifier in C99, section
+ * 7.19.6.1; however, the output of this method is more
+ * tightly specified.
+ */
+ if (!isFinite(d) )
+ // For infinity and NaN, use the decimal output.
+ return Double.toString(d);
+ else {
+ // Initialized to maximum size of output.
+ StringBuilder answer = new StringBuilder(24);
+
+ if (Math.copySign(1.0, d) == -1.0) // value is negative,
+ answer.append("-"); // so append sign info
+
+ answer.append("0x");
+
+ d = Math.abs(d);
+
+ if(d == 0.0) {
+ answer.append("0.0p0");
+ } else {
+ boolean subnormal = (d < DoubleConsts.MIN_NORMAL);
+
+ // Isolate significand bits and OR in a high-order bit
+ // so that the string representation has a known
+ // length.
+ long signifBits = (Double.doubleToLongBits(d)
+ & DoubleConsts.SIGNIF_BIT_MASK) |
+ 0x1000000000000000L;
+
+ // Subnormal values have a 0 implicit bit; normal
+ // values have a 1 implicit bit.
+ answer.append(subnormal ? "0." : "1.");
+
+ // Isolate the low-order 13 digits of the hex
+ // representation. If all the digits are zero,
+ // replace with a single 0; otherwise, remove all
+ // trailing zeros.
+ String signif = Long.toHexString(signifBits).substring(3,16);
+ answer.append(signif.equals("0000000000000") ? // 13 zeros
+ "0":
+ signif.replaceFirst("0{1,12}$", ""));
+
+ answer.append('p');
+ // If the value is subnormal, use the E_min exponent
+ // value for double; otherwise, extract and report d's
+ // exponent (the representation of a subnormal uses
+ // E_min -1).
+ answer.append(subnormal ?
+ DoubleConsts.MIN_EXPONENT:
+ Math.getExponent(d));
+ }
+ return answer.toString();
+ }
+ }
+
+ /**
+ * Returns a {@code Double} object holding the
+ * {@code double} value represented by the argument string
+ * {@code s}.
+ *
+ * <p>If {@code s} is {@code null}, then a
+ * {@code NullPointerException} is thrown.
+ *
+ * <p>Leading and trailing whitespace characters in {@code s}
+ * are ignored. Whitespace is removed as if by the {@link
+ * String#trim} method; that is, both ASCII space and control
+ * characters are removed. The rest of {@code s} should
+ * constitute a <i>FloatValue</i> as described by the lexical
+ * syntax rules:
+ *
+ * <blockquote>
+ * <dl>
+ * <dt><i>FloatValue:</i>
+ * <dd><i>Sign<sub>opt</sub></i> {@code NaN}
+ * <dd><i>Sign<sub>opt</sub></i> {@code Infinity}
+ * <dd><i>Sign<sub>opt</sub> FloatingPointLiteral</i>
+ * <dd><i>Sign<sub>opt</sub> HexFloatingPointLiteral</i>
+ * <dd><i>SignedInteger</i>
+ * </dl>
+ *
+ * <dl>
+ * <dt><i>HexFloatingPointLiteral</i>:
+ * <dd> <i>HexSignificand BinaryExponent FloatTypeSuffix<sub>opt</sub></i>
+ * </dl>
+ *
+ * <dl>
+ * <dt><i>HexSignificand:</i>
+ * <dd><i>HexNumeral</i>
+ * <dd><i>HexNumeral</i> {@code .}
+ * <dd>{@code 0x} <i>HexDigits<sub>opt</sub>
+ * </i>{@code .}<i> HexDigits</i>
+ * <dd>{@code 0X}<i> HexDigits<sub>opt</sub>
+ * </i>{@code .} <i>HexDigits</i>
+ * </dl>
+ *
+ * <dl>
+ * <dt><i>BinaryExponent:</i>
+ * <dd><i>BinaryExponentIndicator SignedInteger</i>
+ * </dl>
+ *
+ * <dl>
+ * <dt><i>BinaryExponentIndicator:</i>
+ * <dd>{@code p}
+ * <dd>{@code P}
+ * </dl>
+ *
+ * </blockquote>
+ *
+ * where <i>Sign</i>, <i>FloatingPointLiteral</i>,
+ * <i>HexNumeral</i>, <i>HexDigits</i>, <i>SignedInteger</i> and
+ * <i>FloatTypeSuffix</i> are as defined in the lexical structure
+ * sections of
+ * <cite>The Java™ Language Specification</cite>,
+ * except that underscores are not accepted between digits.
+ * If {@code s} does not have the form of
+ * a <i>FloatValue</i>, then a {@code NumberFormatException}
+ * is thrown. Otherwise, {@code s} is regarded as
+ * representing an exact decimal value in the usual
+ * "computerized scientific notation" or as an exact
+ * hexadecimal value; this exact numerical value is then
+ * conceptually converted to an "infinitely precise"
+ * binary value that is then rounded to type {@code double}
+ * by the usual round-to-nearest rule of IEEE 754 floating-point
+ * arithmetic, which includes preserving the sign of a zero
+ * value.
+ *
+ * Note that the round-to-nearest rule also implies overflow and
+ * underflow behaviour; if the exact value of {@code s} is large
+ * enough in magnitude (greater than or equal to ({@link
+ * #MAX_VALUE} + {@link Math#ulp(double) ulp(MAX_VALUE)}/2),
+ * rounding to {@code double} will result in an infinity and if the
+ * exact value of {@code s} is small enough in magnitude (less
+ * than or equal to {@link #MIN_VALUE}/2), rounding to float will
+ * result in a zero.
+ *
+ * Finally, after rounding a {@code Double} object representing
+ * this {@code double} value is returned.
+ *
+ * <p> To interpret localized string representations of a
+ * floating-point value, use subclasses of {@link
+ * java.text.NumberFormat}.
+ *
+ * <p>Note that trailing format specifiers, specifiers that
+ * determine the type of a floating-point literal
+ * ({@code 1.0f} is a {@code float} value;
+ * {@code 1.0d} is a {@code double} value), do
+ * <em>not</em> influence the results of this method. In other
+ * words, the numerical value of the input string is converted
+ * directly to the target floating-point type. The two-step
+ * sequence of conversions, string to {@code float} followed
+ * by {@code float} to {@code double}, is <em>not</em>
+ * equivalent to converting a string directly to
+ * {@code double}. For example, the {@code float}
+ * literal {@code 0.1f} is equal to the {@code double}
+ * value {@code 0.10000000149011612}; the {@code float}
+ * literal {@code 0.1f} represents a different numerical
+ * value than the {@code double} literal
+ * {@code 0.1}. (The numerical value 0.1 cannot be exactly
+ * represented in a binary floating-point number.)
+ *
+ * <p>To avoid calling this method on an invalid string and having
+ * a {@code NumberFormatException} be thrown, the regular
+ * expression below can be used to screen the input string:
+ *
+ * <pre>{@code
+ * final String Digits = "(\\p{Digit}+)";
+ * final String HexDigits = "(\\p{XDigit}+)";
+ * // an exponent is 'e' or 'E' followed by an optionally
+ * // signed decimal integer.
+ * final String Exp = "[eE][+-]?"+Digits;
+ * final String fpRegex =
+ * ("[\\x00-\\x20]*"+ // Optional leading "whitespace"
+ * "[+-]?(" + // Optional sign character
+ * "NaN|" + // "NaN" string
+ * "Infinity|" + // "Infinity" string
+ *
+ * // A decimal floating-point string representing a finite positive
+ * // number without a leading sign has at most five basic pieces:
+ * // Digits . Digits ExponentPart FloatTypeSuffix
+ * //
+ * // Since this method allows integer-only strings as input
+ * // in addition to strings of floating-point literals, the
+ * // two sub-patterns below are simplifications of the grammar
+ * // productions from section 3.10.2 of
+ * // The Java Language Specification.
+ *
+ * // Digits ._opt Digits_opt ExponentPart_opt FloatTypeSuffix_opt
+ * "((("+Digits+"(\\.)?("+Digits+"?)("+Exp+")?)|"+
+ *
+ * // . Digits ExponentPart_opt FloatTypeSuffix_opt
+ * "(\\.("+Digits+")("+Exp+")?)|"+
+ *
+ * // Hexadecimal strings
+ * "((" +
+ * // 0[xX] HexDigits ._opt BinaryExponent FloatTypeSuffix_opt
+ * "(0[xX]" + HexDigits + "(\\.)?)|" +
+ *
+ * // 0[xX] HexDigits_opt . HexDigits BinaryExponent FloatTypeSuffix_opt
+ * "(0[xX]" + HexDigits + "?(\\.)" + HexDigits + ")" +
+ *
+ * ")[pP][+-]?" + Digits + "))" +
+ * "[fFdD]?))" +
+ * "[\\x00-\\x20]*");// Optional trailing "whitespace"
+ *
+ * if (Pattern.matches(fpRegex, myString))
+ * Double.valueOf(myString); // Will not throw NumberFormatException
+ * else {
+ * // Perform suitable alternative action
+ * }
+ * }</pre>
+ *
+ * @param s the string to be parsed.
+ * @return a {@code Double} object holding the value
+ * represented by the {@code String} argument.
+ * @throws NumberFormatException if the string does not contain a
+ * parsable number.
+ */
+ public static Double valueOf(String s) throws NumberFormatException {
+ return new Double(parseDouble(s));
+ }
+
+ /**
+ * Returns a {@code Double} instance representing the specified
+ * {@code double} value.
+ * If a new {@code Double} instance is not required, this method
+ * should generally be used in preference to the constructor
+ * {@link #Double(double)}, as this method is likely to yield
+ * significantly better space and time performance by caching
+ * frequently requested values.
+ *
+ * @param d a double value.
+ * @return a {@code Double} instance representing {@code d}.
+ * @since 1.5
+ */
+ public static Double valueOf(double d) {
+ return new Double(d);
+ }
+
+ /**
+ * Returns a new {@code double} initialized to the value
+ * represented by the specified {@code String}, as performed
+ * by the {@code valueOf} method of class
+ * {@code Double}.
+ *
+ * @param s the string to be parsed.
+ * @return the {@code double} value represented by the string
+ * argument.
+ * @throws NullPointerException if the string is null
+ * @throws NumberFormatException if the string does not contain
+ * a parsable {@code double}.
+ * @see java.lang.Double#valueOf(String)
+ * @since 1.2
+ */
+ public static double parseDouble(String s) throws NumberFormatException {
+ return FloatingDecimal.parseDouble(s);
+ }
+
+ /**
+ * Returns {@code true} if the specified number is a
+ * Not-a-Number (NaN) value, {@code false} otherwise.
+ *
+ * @param v the value to be tested.
+ * @return {@code true} if the value of the argument is NaN;
+ * {@code false} otherwise.
+ */
+ public static boolean isNaN(double v) {
+ return (v != v);
+ }
+
+ /**
+ * Returns {@code true} if the specified number is infinitely
+ * large in magnitude, {@code false} otherwise.
+ *
+ * @param v the value to be tested.
+ * @return {@code true} if the value of the argument is positive
+ * infinity or negative infinity; {@code false} otherwise.
+ */
+ public static boolean isInfinite(double v) {
+ return (v == POSITIVE_INFINITY) || (v == NEGATIVE_INFINITY);
+ }
+
+ /**
+ * Returns {@code true} if the argument is a finite floating-point
+ * value; returns {@code false} otherwise (for NaN and infinity
+ * arguments).
+ *
+ * @param d the {@code double} value to be tested
+ * @return {@code true} if the argument is a finite
+ * floating-point value, {@code false} otherwise.
+ * @since 1.8
+ */
+ public static boolean isFinite(double d) {
+ return Math.abs(d) <= DoubleConsts.MAX_VALUE;
+ }
+
+ /**
+ * The value of the Double.
+ *
+ * @serial
+ */
+ private final double value;
+
+ /**
+ * Constructs a newly allocated {@code Double} object that
+ * represents the primitive {@code double} argument.
+ *
+ * @param value the value to be represented by the {@code Double}.
+ */
+ public Double(double value) {
+ this.value = value;
+ }
+
+ /**
+ * Constructs a newly allocated {@code Double} object that
+ * represents the floating-point value of type {@code double}
+ * represented by the string. The string is converted to a
+ * {@code double} value as if by the {@code valueOf} method.
+ *
+ * @param s a string to be converted to a {@code Double}.
+ * @throws NumberFormatException if the string does not contain a
+ * parsable number.
+ * @see java.lang.Double#valueOf(java.lang.String)
+ */
+ public Double(String s) throws NumberFormatException {
+ value = parseDouble(s);
+ }
+
+ /**
+ * Returns {@code true} if this {@code Double} value is
+ * a Not-a-Number (NaN), {@code false} otherwise.
+ *
+ * @return {@code true} if the value represented by this object is
+ * NaN; {@code false} otherwise.
+ */
+ public boolean isNaN() {
+ return isNaN(value);
+ }
+
+ /**
+ * Returns {@code true} if this {@code Double} value is
+ * infinitely large in magnitude, {@code false} otherwise.
+ *
+ * @return {@code true} if the value represented by this object is
+ * positive infinity or negative infinity;
+ * {@code false} otherwise.
+ */
+ public boolean isInfinite() {
+ return isInfinite(value);
+ }
+
+ /**
+ * Returns a string representation of this {@code Double} object.
+ * The primitive {@code double} value represented by this
+ * object is converted to a string exactly as if by the method
+ * {@code toString} of one argument.
+ *
+ * @return a {@code String} representation of this object.
+ * @see java.lang.Double#toString(double)
+ */
+ public String toString() {
+ return toString(value);
+ }
+
+ /**
+ * Returns the value of this {@code Double} as a {@code byte}
+ * after a narrowing primitive conversion.
+ *
+ * @return the {@code double} value represented by this object
+ * converted to type {@code byte}
+ * @jls 5.1.3 Narrowing Primitive Conversions
+ * @since JDK1.1
+ */
+ public byte byteValue() {
+ return (byte)value;
+ }
+
+ /**
+ * Returns the value of this {@code Double} as a {@code short}
+ * after a narrowing primitive conversion.
+ *
+ * @return the {@code double} value represented by this object
+ * converted to type {@code short}
+ * @jls 5.1.3 Narrowing Primitive Conversions
+ * @since JDK1.1
+ */
+ public short shortValue() {
+ return (short)value;
+ }
+
+ /**
+ * Returns the value of this {@code Double} as an {@code int}
+ * after a narrowing primitive conversion.
+ * @jls 5.1.3 Narrowing Primitive Conversions
+ *
+ * @return the {@code double} value represented by this object
+ * converted to type {@code int}
+ */
+ public int intValue() {
+ return (int)value;
+ }
+
+ /**
+ * Returns the value of this {@code Double} as a {@code long}
+ * after a narrowing primitive conversion.
+ *
+ * @return the {@code double} value represented by this object
+ * converted to type {@code long}
+ * @jls 5.1.3 Narrowing Primitive Conversions
+ */
+ public long longValue() {
+ return (long)value;
+ }
+
+ /**
+ * Returns the value of this {@code Double} as a {@code float}
+ * after a narrowing primitive conversion.
+ *
+ * @return the {@code double} value represented by this object
+ * converted to type {@code float}
+ * @jls 5.1.3 Narrowing Primitive Conversions
+ * @since JDK1.0
+ */
+ public float floatValue() {
+ return (float)value;
+ }
+
+ /**
+ * Returns the {@code double} value of this {@code Double} object.
+ *
+ * @return the {@code double} value represented by this object
+ */
+ public double doubleValue() {
+ return value;
+ }
+
+ /**
+ * Returns a hash code for this {@code Double} object. The
+ * result is the exclusive OR of the two halves of the
+ * {@code long} integer bit representation, exactly as
+ * produced by the method {@link #doubleToLongBits(double)}, of
+ * the primitive {@code double} value represented by this
+ * {@code Double} object. That is, the hash code is the value
+ * of the expression:
+ *
+ * <blockquote>
+ * {@code (int)(v^(v>>>32))}
+ * </blockquote>
+ *
+ * where {@code v} is defined by:
+ *
+ * <blockquote>
+ * {@code long v = Double.doubleToLongBits(this.doubleValue());}
+ * </blockquote>
+ *
+ * @return a {@code hash code} value for this object.
+ */
+ @Override
+ public int hashCode() {
+ return Double.hashCode(value);
+ }
+
+ /**
+ * Returns a hash code for a {@code double} value; compatible with
+ * {@code Double.hashCode()}.
+ *
+ * @param value the value to hash
+ * @return a hash code value for a {@code double} value.
+ * @since 1.8
+ */
+ public static int hashCode(double value) {
+ long bits = doubleToLongBits(value);
+ return (int)(bits ^ (bits >>> 32));
+ }
+
+ /**
+ * Compares this object against the specified object. The result
+ * is {@code true} if and only if the argument is not
+ * {@code null} and is a {@code Double} object that
+ * represents a {@code double} that has the same value as the
+ * {@code double} represented by this object. For this
+ * purpose, two {@code double} values are considered to be
+ * the same if and only if the method {@link
+ * #doubleToLongBits(double)} returns the identical
+ * {@code long} value when applied to each.
+ *
+ * <p>Note that in most cases, for two instances of class
+ * {@code Double}, {@code d1} and {@code d2}, the
+ * value of {@code d1.equals(d2)} is {@code true} if and
+ * only if
+ *
+ * <blockquote>
+ * {@code d1.doubleValue() == d2.doubleValue()}
+ * </blockquote>
+ *
+ * <p>also has the value {@code true}. However, there are two
+ * exceptions:
+ * <ul>
+ * <li>If {@code d1} and {@code d2} both represent
+ * {@code Double.NaN}, then the {@code equals} method
+ * returns {@code true}, even though
+ * {@code Double.NaN==Double.NaN} has the value
+ * {@code false}.
+ * <li>If {@code d1} represents {@code +0.0} while
+ * {@code d2} represents {@code -0.0}, or vice versa,
+ * the {@code equal} test has the value {@code false},
+ * even though {@code +0.0==-0.0} has the value {@code true}.
+ * </ul>
+ * This definition allows hash tables to operate properly.
+ * @param obj the object to compare with.
+ * @return {@code true} if the objects are the same;
+ * {@code false} otherwise.
+ * @see java.lang.Double#doubleToLongBits(double)
+ */
+ public boolean equals(Object obj) {
+ return (obj instanceof Double)
+ && (doubleToLongBits(((Double)obj).value) ==
+ doubleToLongBits(value));
+ }
+
+ /**
+ * Returns a representation of the specified floating-point value
+ * according to the IEEE 754 floating-point "double
+ * format" bit layout.
+ *
+ * <p>Bit 63 (the bit that is selected by the mask
+ * {@code 0x8000000000000000L}) represents the sign of the
+ * floating-point number. Bits
+ * 62-52 (the bits that are selected by the mask
+ * {@code 0x7ff0000000000000L}) represent the exponent. Bits 51-0
+ * (the bits that are selected by the mask
+ * {@code 0x000fffffffffffffL}) represent the significand
+ * (sometimes called the mantissa) of the floating-point number.
+ *
+ * <p>If the argument is positive infinity, the result is
+ * {@code 0x7ff0000000000000L}.
+ *
+ * <p>If the argument is negative infinity, the result is
+ * {@code 0xfff0000000000000L}.
+ *
+ * <p>If the argument is NaN, the result is
+ * {@code 0x7ff8000000000000L}.
+ *
+ * <p>In all cases, the result is a {@code long} integer that, when
+ * given to the {@link #longBitsToDouble(long)} method, will produce a
+ * floating-point value the same as the argument to
+ * {@code doubleToLongBits} (except all NaN values are
+ * collapsed to a single "canonical" NaN value).
+ *
+ * @param value a {@code double} precision floating-point number.
+ * @return the bits that represent the floating-point number.
+ */
+ public static long doubleToLongBits(double value) {
+ long result = doubleToRawLongBits(value);
+ // Check for NaN based on values of bit fields, maximum
+ // exponent and nonzero significand.
+ if ( ((result & DoubleConsts.EXP_BIT_MASK) ==
+ DoubleConsts.EXP_BIT_MASK) &&
+ (result & DoubleConsts.SIGNIF_BIT_MASK) != 0L)
+ result = 0x7ff8000000000000L;
+ return result;
+ }
+
+ /**
+ * Returns a representation of the specified floating-point value
+ * according to the IEEE 754 floating-point "double
+ * format" bit layout, preserving Not-a-Number (NaN) values.
+ *
+ * <p>Bit 63 (the bit that is selected by the mask
+ * {@code 0x8000000000000000L}) represents the sign of the
+ * floating-point number. Bits
+ * 62-52 (the bits that are selected by the mask
+ * {@code 0x7ff0000000000000L}) represent the exponent. Bits 51-0
+ * (the bits that are selected by the mask
+ * {@code 0x000fffffffffffffL}) represent the significand
+ * (sometimes called the mantissa) of the floating-point number.
+ *
+ * <p>If the argument is positive infinity, the result is
+ * {@code 0x7ff0000000000000L}.
+ *
+ * <p>If the argument is negative infinity, the result is
+ * {@code 0xfff0000000000000L}.
+ *
+ * <p>If the argument is NaN, the result is the {@code long}
+ * integer representing the actual NaN value. Unlike the
+ * {@code doubleToLongBits} method,
+ * {@code doubleToRawLongBits} does not collapse all the bit
+ * patterns encoding a NaN to a single "canonical" NaN
+ * value.
+ *
+ * <p>In all cases, the result is a {@code long} integer that,
+ * when given to the {@link #longBitsToDouble(long)} method, will
+ * produce a floating-point value the same as the argument to
+ * {@code doubleToRawLongBits}.
+ *
+ * @param value a {@code double} precision floating-point number.
+ * @return the bits that represent the floating-point number.
+ * @since 1.3
+ */
+ public static native long doubleToRawLongBits(double value);
+
+ /**
+ * Returns the {@code double} value corresponding to a given
+ * bit representation.
+ * The argument is considered to be a representation of a
+ * floating-point value according to the IEEE 754 floating-point
+ * "double format" bit layout.
+ *
+ * <p>If the argument is {@code 0x7ff0000000000000L}, the result
+ * is positive infinity.
+ *
+ * <p>If the argument is {@code 0xfff0000000000000L}, the result
+ * is negative infinity.
+ *
+ * <p>If the argument is any value in the range
+ * {@code 0x7ff0000000000001L} through
+ * {@code 0x7fffffffffffffffL} or in the range
+ * {@code 0xfff0000000000001L} through
+ * {@code 0xffffffffffffffffL}, the result is a NaN. No IEEE
+ * 754 floating-point operation provided by Java can distinguish
+ * between two NaN values of the same type with different bit
+ * patterns. Distinct values of NaN are only distinguishable by
+ * use of the {@code Double.doubleToRawLongBits} method.
+ *
+ * <p>In all other cases, let <i>s</i>, <i>e</i>, and <i>m</i> be three
+ * values that can be computed from the argument:
+ *
+ * <blockquote><pre>{@code
+ * int s = ((bits >> 63) == 0) ? 1 : -1;
+ * int e = (int)((bits >> 52) & 0x7ffL);
+ * long m = (e == 0) ?
+ * (bits & 0xfffffffffffffL) << 1 :
+ * (bits & 0xfffffffffffffL) | 0x10000000000000L;
+ * }</pre></blockquote>
+ *
+ * Then the floating-point result equals the value of the mathematical
+ * expression <i>s</i>·<i>m</i>·2<sup><i>e</i>-1075</sup>.
+ *
+ * <p>Note that this method may not be able to return a
+ * {@code double} NaN with exactly same bit pattern as the
+ * {@code long} argument. IEEE 754 distinguishes between two
+ * kinds of NaNs, quiet NaNs and <i>signaling NaNs</i>. The
+ * differences between the two kinds of NaN are generally not
+ * visible in Java. Arithmetic operations on signaling NaNs turn
+ * them into quiet NaNs with a different, but often similar, bit
+ * pattern. However, on some processors merely copying a
+ * signaling NaN also performs that conversion. In particular,
+ * copying a signaling NaN to return it to the calling method
+ * may perform this conversion. So {@code longBitsToDouble}
+ * may not be able to return a {@code double} with a
+ * signaling NaN bit pattern. Consequently, for some
+ * {@code long} values,
+ * {@code doubleToRawLongBits(longBitsToDouble(start))} may
+ * <i>not</i> equal {@code start}. Moreover, which
+ * particular bit patterns represent signaling NaNs is platform
+ * dependent; although all NaN bit patterns, quiet or signaling,
+ * must be in the NaN range identified above.
+ *
+ * @param bits any {@code long} integer.
+ * @return the {@code double} floating-point value with the same
+ * bit pattern.
+ */
+ public static native double longBitsToDouble(long bits);
+
+ /**
+ * Compares two {@code Double} objects numerically. There
+ * are two ways in which comparisons performed by this method
+ * differ from those performed by the Java language numerical
+ * comparison operators ({@code <, <=, ==, >=, >})
+ * when applied to primitive {@code double} values:
+ * <ul><li>
+ * {@code Double.NaN} is considered by this method
+ * to be equal to itself and greater than all other
+ * {@code double} values (including
+ * {@code Double.POSITIVE_INFINITY}).
+ * <li>
+ * {@code 0.0d} is considered by this method to be greater
+ * than {@code -0.0d}.
+ * </ul>
+ * This ensures that the <i>natural ordering</i> of
+ * {@code Double} objects imposed by this method is <i>consistent
+ * with equals</i>.
+ *
+ * @param anotherDouble the {@code Double} to be compared.
+ * @return the value {@code 0} if {@code anotherDouble} is
+ * numerically equal to this {@code Double}; a value
+ * less than {@code 0} if this {@code Double}
+ * is numerically less than {@code anotherDouble};
+ * and a value greater than {@code 0} if this
+ * {@code Double} is numerically greater than
+ * {@code anotherDouble}.
+ *
+ * @since 1.2
+ */
+ public int compareTo(Double anotherDouble) {
+ return Double.compare(value, anotherDouble.value);
+ }
+
+ /**
+ * Compares the two specified {@code double} values. The sign
+ * of the integer value returned is the same as that of the
+ * integer that would be returned by the call:
+ * <pre>
+ * new Double(d1).compareTo(new Double(d2))
+ * </pre>
+ *
+ * @param d1 the first {@code double} to compare
+ * @param d2 the second {@code double} to compare
+ * @return the value {@code 0} if {@code d1} is
+ * numerically equal to {@code d2}; a value less than
+ * {@code 0} if {@code d1} is numerically less than
+ * {@code d2}; and a value greater than {@code 0}
+ * if {@code d1} is numerically greater than
+ * {@code d2}.
+ * @since 1.4
+ */
+ public static int compare(double d1, double d2) {
+ if (d1 < d2)
+ return -1; // Neither val is NaN, thisVal is smaller
+ if (d1 > d2)
+ return 1; // Neither val is NaN, thisVal is larger
+
+ // Cannot use doubleToRawLongBits because of possibility of NaNs.
+ long thisBits = Double.doubleToLongBits(d1);
+ long anotherBits = Double.doubleToLongBits(d2);
+
+ return (thisBits == anotherBits ? 0 : // Values are equal
+ (thisBits < anotherBits ? -1 : // (-0.0, 0.0) or (!NaN, NaN)
+ 1)); // (0.0, -0.0) or (NaN, !NaN)
+ }
+
+ /**
+ * Adds two {@code double} values together as per the + operator.
+ *
+ * @param a the first operand
+ * @param b the second operand
+ * @return the sum of {@code a} and {@code b}
+ * @jls 4.2.4 Floating-Point Operations
+ * @see java.util.function.BinaryOperator
+ * @since 1.8
+ */
+ public static double sum(double a, double b) {
+ return a + b;
+ }
+
+ /**
+ * Returns the greater of two {@code double} values
+ * as if by calling {@link Math#max(double, double) Math.max}.
+ *
+ * @param a the first operand
+ * @param b the second operand
+ * @return the greater of {@code a} and {@code b}
+ * @see java.util.function.BinaryOperator
+ * @since 1.8
+ */
+ public static double max(double a, double b) {
+ return Math.max(a, b);
+ }
+
+ /**
+ * Returns the smaller of two {@code double} values
+ * as if by calling {@link Math#min(double, double) Math.min}.
+ *
+ * @param a the first operand
+ * @param b the second operand
+ * @return the smaller of {@code a} and {@code b}.
+ * @see java.util.function.BinaryOperator
+ * @since 1.8
+ */
+ public static double min(double a, double b) {
+ return Math.min(a, b);
+ }
+
+ /** use serialVersionUID from JDK 1.0.2 for interoperability */
+ private static final long serialVersionUID = -9172774392245257468L;
+}
diff --git a/java/lang/Enum.annotated.java b/java/lang/Enum.annotated.java
new file mode 100644
index 0000000..b49785e
--- /dev/null
+++ b/java/lang/Enum.annotated.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2003, 2011, 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;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class Enum<E extends java.lang.Enum<E>> implements java.lang.Comparable<E>, java.io.Serializable {
+
+protected Enum(@libcore.util.NonNull java.lang.String name, int ordinal) { throw new RuntimeException("Stub!"); }
+
[email protected] public final java.lang.String name() { throw new RuntimeException("Stub!"); }
+
+public final int ordinal() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public final boolean equals(@libcore.util.Nullable java.lang.Object other) { throw new RuntimeException("Stub!"); }
+
+public final int hashCode() { throw new RuntimeException("Stub!"); }
+
[email protected] protected final java.lang.Object clone() throws java.lang.CloneNotSupportedException { throw new RuntimeException("Stub!"); }
+
+public final int compareTo(@libcore.util.NullFromTypeParam E o) { throw new RuntimeException("Stub!"); }
+
[email protected] public final java.lang.Class<E> getDeclaringClass() { throw new RuntimeException("Stub!"); }
+
[email protected] public static <T extends java.lang.Enum<T>> T valueOf(@libcore.util.NonNull java.lang.Class<T> enumType, @libcore.util.NonNull java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+protected final void finalize() { throw new RuntimeException("Stub!"); }
+}
diff --git a/java/lang/Enum.java b/java/lang/Enum.java
new file mode 100644
index 0000000..988c133
--- /dev/null
+++ b/java/lang/Enum.java
@@ -0,0 +1,309 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2003, 2011, 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;
+
+import java.io.Serializable;
+import java.io.IOException;
+import java.io.InvalidObjectException;
+import java.io.ObjectInputStream;
+import java.io.ObjectStreamException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Objects;
+import libcore.util.BasicLruCache;
+import libcore.util.EmptyArray;
+
+/**
+ * This is the common base class of all Java language enumeration types.
+ *
+ * More information about enums, including descriptions of the
+ * implicitly declared methods synthesized by the compiler, can be
+ * found in section 8.9 of
+ * <cite>The Java™ Language Specification</cite>.
+ *
+ * <p> Note that when using an enumeration type as the type of a set
+ * or as the type of the keys in a map, specialized and efficient
+ * {@linkplain java.util.EnumSet set} and {@linkplain
+ * java.util.EnumMap map} implementations are available.
+ *
+ * @param <E> The enum type subclass
+ * @author Josh Bloch
+ * @author Neal Gafter
+ * @see Class#getEnumConstants()
+ * @see java.util.EnumSet
+ * @see java.util.EnumMap
+ * @since 1.5
+ */
+public abstract class Enum<E extends Enum<E>>
+ implements Comparable<E>, Serializable {
+ /**
+ * The name of this enum constant, as declared in the enum declaration.
+ * Most programmers should use the {@link #toString} method rather than
+ * accessing this field.
+ */
+ private final String name;
+
+ /**
+ * Returns the name of this enum constant, exactly as declared in its
+ * enum declaration.
+ *
+ * <b>Most programmers should use the {@link #toString} method in
+ * preference to this one, as the toString method may return
+ * a more user-friendly name.</b> This method is designed primarily for
+ * use in specialized situations where correctness depends on getting the
+ * exact name, which will not vary from release to release.
+ *
+ * @return the name of this enum constant
+ */
+ public final String name() {
+ return name;
+ }
+
+ /**
+ * The ordinal of this enumeration constant (its position
+ * in the enum declaration, where the initial constant is assigned
+ * an ordinal of zero).
+ *
+ * Most programmers will have no use for this field. It is designed
+ * for use by sophisticated enum-based data structures, such as
+ * {@link java.util.EnumSet} and {@link java.util.EnumMap}.
+ */
+ private final int ordinal;
+
+ /**
+ * Returns the ordinal of this enumeration constant (its position
+ * in its enum declaration, where the initial constant is assigned
+ * an ordinal of zero).
+ *
+ * Most programmers will have no use for this method. It is
+ * designed for use by sophisticated enum-based data structures, such
+ * as {@link java.util.EnumSet} and {@link java.util.EnumMap}.
+ *
+ * @return the ordinal of this enumeration constant
+ */
+ public final int ordinal() {
+ return ordinal;
+ }
+
+ /**
+ * Sole constructor. Programmers cannot invoke this constructor.
+ * It is for use by code emitted by the compiler in response to
+ * enum type declarations.
+ *
+ * @param name - The name of this enum constant, which is the identifier
+ * used to declare it.
+ * @param ordinal - The ordinal of this enumeration constant (its position
+ * in the enum declaration, where the initial constant is assigned
+ * an ordinal of zero).
+ */
+ protected Enum(String name, int ordinal) {
+ this.name = name;
+ this.ordinal = ordinal;
+ }
+
+ /**
+ * Returns the name of this enum constant, as contained in the
+ * declaration. This method may be overridden, though it typically
+ * isn't necessary or desirable. An enum type should override this
+ * method when a more "programmer-friendly" string form exists.
+ *
+ * @return the name of this enum constant
+ */
+ public String toString() {
+ return name;
+ }
+
+ /**
+ * Returns true if the specified object is equal to this
+ * enum constant.
+ *
+ * @param other the object to be compared for equality with this object.
+ * @return true if the specified object is equal to this
+ * enum constant.
+ */
+ public final boolean equals(Object other) {
+ return this==other;
+ }
+
+ /**
+ * Returns a hash code for this enum constant.
+ *
+ * @return a hash code for this enum constant.
+ */
+ public final int hashCode() {
+ return super.hashCode();
+ }
+
+ /**
+ * Throws CloneNotSupportedException. This guarantees that enums
+ * are never cloned, which is necessary to preserve their "singleton"
+ * status.
+ *
+ * @return (never returns)
+ */
+ protected final Object clone() throws CloneNotSupportedException {
+ throw new CloneNotSupportedException();
+ }
+
+ /**
+ * Compares this enum with the specified object for order. Returns a
+ * negative integer, zero, or a positive integer as this object is less
+ * than, equal to, or greater than the specified object.
+ *
+ * Enum constants are only comparable to other enum constants of the
+ * same enum type. The natural order implemented by this
+ * method is the order in which the constants are declared.
+ */
+ public final int compareTo(E o) {
+ Enum<?> other = (Enum<?>)o;
+ Enum<E> self = this;
+ if (self.getClass() != other.getClass() && // optimization
+ self.getDeclaringClass() != other.getDeclaringClass())
+ throw new ClassCastException();
+ return self.ordinal - other.ordinal;
+ }
+
+ /**
+ * Returns the Class object corresponding to this enum constant's
+ * enum type. Two enum constants e1 and e2 are of the
+ * same enum type if and only if
+ * e1.getDeclaringClass() == e2.getDeclaringClass().
+ * (The value returned by this method may differ from the one returned
+ * by the {@link Object#getClass} method for enum constants with
+ * constant-specific class bodies.)
+ *
+ * @return the Class object corresponding to this enum constant's
+ * enum type
+ */
+ @SuppressWarnings("unchecked")
+ public final Class<E> getDeclaringClass() {
+ Class<?> clazz = getClass();
+ Class<?> zuper = clazz.getSuperclass();
+ return (zuper == Enum.class) ? (Class<E>)clazz : (Class<E>)zuper;
+ }
+
+ /**
+ * Returns the enum constant of the specified enum type with the
+ * specified name. The name must match exactly an identifier used
+ * to declare an enum constant in this type. (Extraneous whitespace
+ * characters are not permitted.)
+ *
+ * <p>Note that for a particular enum type {@code T}, the
+ * implicitly declared {@code public static T valueOf(String)}
+ * method on that enum may be used instead of this method to map
+ * from a name to the corresponding enum constant. All the
+ * constants of an enum type can be obtained by calling the
+ * implicit {@code public static T[] values()} method of that
+ * type.
+ *
+ * @param <T> The enum type whose constant is to be returned
+ * @param enumType the {@code Class} object of the enum type from which
+ * to return a constant
+ * @param name the name of the constant to return
+ * @return the enum constant of the specified enum type with the
+ * specified name
+ * @throws IllegalArgumentException if the specified enum type has
+ * no constant with the specified name, or the specified
+ * class object does not represent an enum type
+ * @throws NullPointerException if {@code enumType} or {@code name}
+ * is null
+ * @since 1.5
+ */
+ // BEGIN Android-changed: Use a static BasicLruCache mapping Enum class -> Enum instance array.
+ // This change was made to fix a performance regression. See b/4087759 and b/109791362 for more
+ // background information.
+ public static <T extends Enum<T>> T valueOf(Class<T> enumType,
+ String name) {
+ Objects.requireNonNull(enumType, "enumType == null");
+ Objects.requireNonNull(enumType, "name == null");
+ T[] values = getSharedConstants(enumType);
+ if (values == null) {
+ throw new IllegalArgumentException(enumType.toString() + " is not an enum type.");
+ }
+
+ // Iterate backwards through the array to retain historic Android behavior in the
+ // unexpected / likely invalid case where there are multiple values with the same name.
+ for (int i = values.length - 1; i >= 0; --i) {
+ T value = values[i];
+ if (name.equals(value.name())) {
+ return value;
+ }
+ }
+ throw new IllegalArgumentException(
+ "No enum constant " + enumType.getCanonicalName() + "." + name);
+ }
+
+ private static Object[] enumValues(Class<? extends Enum> clazz) {
+ if (!clazz.isEnum()) {
+ // Either clazz is Enum.class itself, or it is not an enum class and the method was
+ // called unsafely e.g. using an unchecked cast or via reflection.
+ return null;
+ }
+ try {
+ Method valueMethod = clazz.getDeclaredMethod("values");
+ return (Object[]) valueMethod.invoke(null);
+ } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private static final BasicLruCache<Class<? extends Enum>, Object[]> sharedConstantsCache
+ = new BasicLruCache<Class<? extends Enum>, Object[]>(64) {
+ @Override protected Object[] create(Class<? extends Enum> enumType) {
+ return enumValues(enumType);
+ }
+ };
+
+ /**
+ * Returns a shared, mutable array containing the constants of this enum. It
+ * is an error to modify the returned array.
+ *
+ * @hide
+ */
+ @SuppressWarnings("unchecked") // the cache always returns the type matching enumType
+ public static <T extends Enum<T>> T[] getSharedConstants(Class<T> enumType) {
+ return (T[]) sharedConstantsCache.get(enumType);
+ }
+ // END Android-changed: Use a static BasicLruCache mapping Enum class -> Enum instance array.
+
+ /**
+ * enum classes cannot have finalize methods.
+ */
+ protected final void finalize() { }
+
+ /**
+ * prevent default deserialization
+ */
+ private void readObject(ObjectInputStream in) throws IOException,
+ ClassNotFoundException {
+ throw new InvalidObjectException("can't deserialize enum");
+ }
+
+ private void readObjectNoData() throws ObjectStreamException {
+ throw new InvalidObjectException("can't deserialize enum");
+ }
+}
diff --git a/java/lang/EnumConstantNotPresentException.java b/java/lang/EnumConstantNotPresentException.java
new file mode 100644
index 0000000..1773160
--- /dev/null
+++ b/java/lang/EnumConstantNotPresentException.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2004, 2011, 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;
+
+/**
+ * Thrown when an application tries to access an enum constant by name
+ * and the enum type contains no constant with the specified name.
+ * This exception can be thrown by the {@linkplain
+ * java.lang.reflect.AnnotatedElement API used to read annotations
+ * reflectively}.
+ *
+ * @author Josh Bloch
+ * @see java.lang.reflect.AnnotatedElement
+ * @since 1.5
+ */
+@SuppressWarnings("rawtypes") /* rawtypes are part of the public api */
+public class EnumConstantNotPresentException extends RuntimeException {
+ private static final long serialVersionUID = -6046998521960521108L;
+
+ /**
+ * The type of the missing enum constant.
+ */
+ private Class<? extends Enum> enumType;
+
+ /**
+ * The name of the missing enum constant.
+ */
+ private String constantName;
+
+ /**
+ * Constructs an <tt>EnumConstantNotPresentException</tt> for the
+ * specified constant.
+ *
+ * @param enumType the type of the missing enum constant
+ * @param constantName the name of the missing enum constant
+ */
+ public EnumConstantNotPresentException(Class<? extends Enum> enumType,
+ String constantName) {
+ super(enumType.getName() + "." + constantName);
+ this.enumType = enumType;
+ this.constantName = constantName;
+ }
+
+ /**
+ * Returns the type of the missing enum constant.
+ *
+ * @return the type of the missing enum constant
+ */
+ public Class<? extends Enum> enumType() { return enumType; }
+
+ /**
+ * Returns the name of the missing enum constant.
+ *
+ * @return the name of the missing enum constant
+ */
+ public String constantName() { return constantName; }
+}
diff --git a/java/lang/Error.java b/java/lang/Error.java
new file mode 100644
index 0000000..d18c15f
--- /dev/null
+++ b/java/lang/Error.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 1995, 2011, 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;
+
+/**
+ * An {@code Error} is a subclass of {@code Throwable}
+ * that indicates serious problems that a reasonable application
+ * should not try to catch. Most such errors are abnormal conditions.
+ * The {@code ThreadDeath} error, though a "normal" condition,
+ * is also a subclass of {@code Error} because most applications
+ * should not try to catch it.
+ * <p>
+ * A method is not required to declare in its {@code throws}
+ * clause any subclasses of {@code Error} that might be thrown
+ * during the execution of the method but not caught, since these
+ * errors are abnormal conditions that should never occur.
+ *
+ * That is, {@code Error} and its subclasses are regarded as unchecked
+ * exceptions for the purposes of compile-time checking of exceptions.
+ *
+ * @author Frank Yellin
+ * @see java.lang.ThreadDeath
+ * @jls 11.2 Compile-Time Checking of Exceptions
+ * @since JDK1.0
+ */
+public class Error extends Throwable {
+ static final long serialVersionUID = 4980196508277280342L;
+
+ /**
+ * Constructs a new error with {@code null} as its detail message.
+ * The cause is not initialized, and may subsequently be initialized by a
+ * call to {@link #initCause}.
+ */
+ public Error() {
+ super();
+ }
+
+ /**
+ * Constructs a new error with the specified detail message. The
+ * cause is not initialized, and may subsequently be initialized by
+ * a call to {@link #initCause}.
+ *
+ * @param message the detail message. The detail message is saved for
+ * later retrieval by the {@link #getMessage()} method.
+ */
+ public Error(String message) {
+ super(message);
+ }
+
+ /**
+ * Constructs a new error with the specified detail message and
+ * cause. <p>Note that the detail message associated with
+ * {@code cause} is <i>not</i> automatically incorporated in
+ * this error's detail message.
+ *
+ * @param message the detail message (which is saved for later retrieval
+ * by the {@link #getMessage()} method).
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link #getCause()} method). (A {@code null} value is
+ * permitted, and indicates that the cause is nonexistent or
+ * unknown.)
+ * @since 1.4
+ */
+ public Error(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * Constructs a new error with the specified cause and a detail
+ * message of {@code (cause==null ? null : cause.toString())} (which
+ * typically contains the class and detail message of {@code cause}).
+ * This constructor is useful for errors that are little more than
+ * wrappers for other throwables.
+ *
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link #getCause()} method). (A {@code null} value is
+ * permitted, and indicates that the cause is nonexistent or
+ * unknown.)
+ * @since 1.4
+ */
+ public Error(Throwable cause) {
+ super(cause);
+ }
+
+ /**
+ * Constructs a new error with the specified detail message,
+ * cause, suppression enabled or disabled, and writable stack
+ * trace enabled or disabled.
+ *
+ * @param message the detail message.
+ * @param cause the cause. (A {@code null} value is permitted,
+ * and indicates that the cause is nonexistent or unknown.)
+ * @param enableSuppression whether or not suppression is enabled
+ * or disabled
+ * @param writableStackTrace whether or not the stack trace should
+ * be writable
+ *
+ * @since 1.7
+ */
+ protected Error(String message, Throwable cause,
+ boolean enableSuppression,
+ boolean writableStackTrace) {
+ super(message, cause, enableSuppression, writableStackTrace);
+ }
+}
diff --git a/java/lang/Exception.java b/java/lang/Exception.java
new file mode 100644
index 0000000..0bcbf9c
--- /dev/null
+++ b/java/lang/Exception.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 1994, 2011, 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;
+
+/**
+ * The class {@code Exception} and its subclasses are a form of
+ * {@code Throwable} that indicates conditions that a reasonable
+ * application might want to catch.
+ *
+ * <p>The class {@code Exception} and any subclasses that are not also
+ * subclasses of {@link RuntimeException} are <em>checked
+ * exceptions</em>. Checked exceptions need to be declared in a
+ * method or constructor's {@code throws} clause if they can be thrown
+ * by the execution of the method or constructor and propagate outside
+ * the method or constructor boundary.
+ *
+ * @author Frank Yellin
+ * @see java.lang.Error
+ * @jls 11.2 Compile-Time Checking of Exceptions
+ * @since JDK1.0
+ */
+public class Exception extends Throwable {
+ static final long serialVersionUID = -3387516993124229948L;
+
+ /**
+ * Constructs a new exception with {@code null} as its detail message.
+ * The cause is not initialized, and may subsequently be initialized by a
+ * call to {@link #initCause}.
+ */
+ public Exception() {
+ super();
+ }
+
+ /**
+ * Constructs a new exception with the specified detail message. The
+ * cause is not initialized, and may subsequently be initialized by
+ * a call to {@link #initCause}.
+ *
+ * @param message the detail message. The detail message is saved for
+ * later retrieval by the {@link #getMessage()} method.
+ */
+ public Exception(String message) {
+ super(message);
+ }
+
+ /**
+ * Constructs a new exception with the specified detail message and
+ * cause. <p>Note that the detail message associated with
+ * {@code cause} is <i>not</i> automatically incorporated in
+ * this exception's detail message.
+ *
+ * @param message the detail message (which is saved for later retrieval
+ * by the {@link #getMessage()} method).
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link #getCause()} method). (A <tt>null</tt> value is
+ * permitted, and indicates that the cause is nonexistent or
+ * unknown.)
+ * @since 1.4
+ */
+ public Exception(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * Constructs a new exception with the specified cause and a detail
+ * message of <tt>(cause==null ? null : cause.toString())</tt> (which
+ * typically contains the class and detail message of <tt>cause</tt>).
+ * This constructor is useful for exceptions that are little more than
+ * wrappers for other throwables (for example, {@link
+ * java.security.PrivilegedActionException}).
+ *
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link #getCause()} method). (A <tt>null</tt> value is
+ * permitted, and indicates that the cause is nonexistent or
+ * unknown.)
+ * @since 1.4
+ */
+ public Exception(Throwable cause) {
+ super(cause);
+ }
+
+ /**
+ * Constructs a new exception with the specified detail message,
+ * cause, suppression enabled or disabled, and writable stack
+ * trace enabled or disabled.
+ *
+ * @param message the detail message.
+ * @param cause the cause. (A {@code null} value is permitted,
+ * and indicates that the cause is nonexistent or unknown.)
+ * @param enableSuppression whether or not suppression is enabled
+ * or disabled
+ * @param writableStackTrace whether or not the stack trace should
+ * be writable
+ * @since 1.7
+ */
+ protected Exception(String message, Throwable cause,
+ boolean enableSuppression,
+ boolean writableStackTrace) {
+ super(message, cause, enableSuppression, writableStackTrace);
+ }
+}
diff --git a/java/lang/ExceptionInInitializerError.java b/java/lang/ExceptionInInitializerError.java
new file mode 100644
index 0000000..0259766
--- /dev/null
+++ b/java/lang/ExceptionInInitializerError.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 1996, 2000, 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;
+
+/**
+ * Signals that an unexpected exception has occurred in a static initializer.
+ * An <code>ExceptionInInitializerError</code> is thrown to indicate that an
+ * exception occurred during evaluation of a static initializer or the
+ * initializer for a static variable.
+ *
+ * <p>As of release 1.4, this exception has been retrofitted to conform to
+ * the general purpose exception-chaining mechanism. The "saved throwable
+ * object" that may be provided at construction time and accessed via
+ * the {@link #getException()} method is now known as the <i>cause</i>,
+ * and may be accessed via the {@link Throwable#getCause()} method, as well
+ * as the aforementioned "legacy method."
+ *
+ * @author Frank Yellin
+ * @since JDK1.1
+ */
+public class ExceptionInInitializerError extends LinkageError {
+ /**
+ * Use serialVersionUID from JDK 1.1.X for interoperability
+ */
+ private static final long serialVersionUID = 1521711792217232256L;
+
+ /**
+ * This field holds the exception if the
+ * ExceptionInInitializerError(Throwable thrown) constructor was
+ * used to instantiate the object
+ *
+ * @serial
+ *
+ */
+ private Throwable exception;
+
+ /**
+ * Constructs an <code>ExceptionInInitializerError</code> with
+ * <code>null</code> as its detail message string and with no saved
+ * throwable object.
+ * A detail message is a String that describes this particular exception.
+ */
+ public ExceptionInInitializerError() {
+ initCause(null); // Disallow subsequent initCause
+ }
+
+ /**
+ * Constructs a new <code>ExceptionInInitializerError</code> class by
+ * saving a reference to the <code>Throwable</code> object thrown for
+ * later retrieval by the {@link #getException()} method. The detail
+ * message string is set to <code>null</code>.
+ *
+ * @param thrown The exception thrown
+ */
+ public ExceptionInInitializerError(Throwable thrown) {
+ initCause(null); // Disallow subsequent initCause
+ this.exception = thrown;
+ }
+
+ /**
+ * Constructs an ExceptionInInitializerError with the specified detail
+ * message string. A detail message is a String that describes this
+ * particular exception. The detail message string is saved for later
+ * retrieval by the {@link Throwable#getMessage()} method. There is no
+ * saved throwable object.
+ *
+ *
+ * @param s the detail message
+ */
+ public ExceptionInInitializerError(String s) {
+ super(s);
+ initCause(null); // Disallow subsequent initCause
+ }
+
+ /**
+ * Returns the exception that occurred during a static initialization that
+ * caused this error to be created.
+ *
+ * <p>This method predates the general-purpose exception chaining facility.
+ * The {@link Throwable#getCause()} method is now the preferred means of
+ * obtaining this information.
+ *
+ * @return the saved throwable object of this
+ * <code>ExceptionInInitializerError</code>, or <code>null</code>
+ * if this <code>ExceptionInInitializerError</code> has no saved
+ * throwable object.
+ */
+ public Throwable getException() {
+ return exception;
+ }
+
+ /**
+ * Returns the cause of this error (the exception that occurred
+ * during a static initialization that caused this error to be created).
+ *
+ * @return the cause of this error or <code>null</code> if the
+ * cause is nonexistent or unknown.
+ * @since 1.4
+ */
+ public Throwable getCause() {
+ return exception;
+ }
+}
diff --git a/java/lang/FindBugsSuppressWarnings.java b/java/lang/FindBugsSuppressWarnings.java
new file mode 100644
index 0000000..ac753bd
--- /dev/null
+++ b/java/lang/FindBugsSuppressWarnings.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.lang;
+
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.ElementType.TYPE;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.CLASS;
+import java.lang.annotation.Target;
+
+/**
+ * Suppress FindBugs warnings on the annotated element. FindBugs will recognize
+ * any annotation that has class retention and whose name ends with
+ * "SuppressWarnings".
+ *
+ * @hide
+ */
+@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
+@Retention(CLASS)
+public @interface FindBugsSuppressWarnings {
+
+ /**
+ * The <a href="http://findbugs.sourceforge.net/bugDescriptions.html">FindBugs
+ * Patterns</a> to suppress, such as {@code SE_TRANSIENT_FIELD_NOT_RESTORED}
+ * or {@code Se}. Full, upper case names are preferred.
+ */
+ String[] value();
+}
diff --git a/java/lang/Float.annotated.java b/java/lang/Float.annotated.java
new file mode 100644
index 0000000..a459ec1
--- /dev/null
+++ b/java/lang/Float.annotated.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 1994, 2013, 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;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Float extends java.lang.Number implements java.lang.Comparable<java.lang.Float> {
+
+public Float(float value) { throw new RuntimeException("Stub!"); }
+
+public Float(double value) { throw new RuntimeException("Stub!"); }
+
+public Float(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String toString(float f) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String toHexString(float f) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Float valueOf(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Float valueOf(float f) { throw new RuntimeException("Stub!"); }
+
+public static float parseFloat(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public static boolean isNaN(float v) { throw new RuntimeException("Stub!"); }
+
+public static boolean isInfinite(float v) { throw new RuntimeException("Stub!"); }
+
+public static boolean isFinite(float f) { throw new RuntimeException("Stub!"); }
+
+public boolean isNaN() { throw new RuntimeException("Stub!"); }
+
+public boolean isInfinite() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public byte byteValue() { throw new RuntimeException("Stub!"); }
+
+public short shortValue() { throw new RuntimeException("Stub!"); }
+
+public int intValue() { throw new RuntimeException("Stub!"); }
+
+public long longValue() { throw new RuntimeException("Stub!"); }
+
+public float floatValue() { throw new RuntimeException("Stub!"); }
+
+public double doubleValue() { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public static int hashCode(float value) { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public static int floatToIntBits(float value) { throw new RuntimeException("Stub!"); }
+
+public static native int floatToRawIntBits(float value);
+
+public static native float intBitsToFloat(int bits);
+
+public int compareTo(@libcore.util.NonNull java.lang.Float anotherFloat) { throw new RuntimeException("Stub!"); }
+
+public static int compare(float f1, float f2) { throw new RuntimeException("Stub!"); }
+
+public static float sum(float a, float b) { throw new RuntimeException("Stub!"); }
+
+public static float max(float a, float b) { throw new RuntimeException("Stub!"); }
+
+public static float min(float a, float b) { throw new RuntimeException("Stub!"); }
+
+public static final int BYTES = 4; // 0x4
+
+public static final int MAX_EXPONENT = 127; // 0x7f
+
+public static final float MAX_VALUE = 3.4028235E38f;
+
+public static final int MIN_EXPONENT = -126; // 0xffffff82
+
+public static final float MIN_NORMAL = 1.17549435E-38f;
+
+public static final float MIN_VALUE = 1.4E-45f;
+
+public static final float NEGATIVE_INFINITY = (-1.0f/0.0f);
+
+public static final float NaN = (0.0f/0.0f);
+
+public static final float POSITIVE_INFINITY = (1.0f/0.0f);
+
+public static final int SIZE = 32; // 0x20
+
+public static final java.lang.Class<java.lang.Float> TYPE;
+static { TYPE = null; }
+}
+
diff --git a/java/lang/Float.java b/java/lang/Float.java
new file mode 100644
index 0000000..5cc28f9
--- /dev/null
+++ b/java/lang/Float.java
@@ -0,0 +1,965 @@
+/*
+ * Copyright (c) 1994, 2013, 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;
+
+import sun.misc.FloatingDecimal;
+import sun.misc.FloatConsts;
+import sun.misc.DoubleConsts;
+
+/**
+ * The {@code Float} class wraps a value of primitive type
+ * {@code float} in an object. An object of type
+ * {@code Float} contains a single field whose type is
+ * {@code float}.
+ *
+ * <p>In addition, this class provides several methods for converting a
+ * {@code float} to a {@code String} and a
+ * {@code String} to a {@code float}, as well as other
+ * constants and methods useful when dealing with a
+ * {@code float}.
+ *
+ * @author Lee Boynton
+ * @author Arthur van Hoff
+ * @author Joseph D. Darcy
+ * @since JDK1.0
+ */
+public final class Float extends Number implements Comparable<Float> {
+ /**
+ * A constant holding the positive infinity of type
+ * {@code float}. It is equal to the value returned by
+ * {@code Float.intBitsToFloat(0x7f800000)}.
+ */
+ public static final float POSITIVE_INFINITY = 1.0f / 0.0f;
+
+ /**
+ * A constant holding the negative infinity of type
+ * {@code float}. It is equal to the value returned by
+ * {@code Float.intBitsToFloat(0xff800000)}.
+ */
+ public static final float NEGATIVE_INFINITY = -1.0f / 0.0f;
+
+ /**
+ * A constant holding a Not-a-Number (NaN) value of type
+ * {@code float}. It is equivalent to the value returned by
+ * {@code Float.intBitsToFloat(0x7fc00000)}.
+ */
+ public static final float NaN = 0.0f / 0.0f;
+
+ /**
+ * A constant holding the largest positive finite value of type
+ * {@code float}, (2-2<sup>-23</sup>)·2<sup>127</sup>.
+ * It is equal to the hexadecimal floating-point literal
+ * {@code 0x1.fffffeP+127f} and also equal to
+ * {@code Float.intBitsToFloat(0x7f7fffff)}.
+ */
+ public static final float MAX_VALUE = 0x1.fffffeP+127f; // 3.4028235e+38f
+
+ /**
+ * A constant holding the smallest positive normal value of type
+ * {@code float}, 2<sup>-126</sup>. It is equal to the
+ * hexadecimal floating-point literal {@code 0x1.0p-126f} and also
+ * equal to {@code Float.intBitsToFloat(0x00800000)}.
+ *
+ * @since 1.6
+ */
+ public static final float MIN_NORMAL = 0x1.0p-126f; // 1.17549435E-38f
+
+ /**
+ * A constant holding the smallest positive nonzero value of type
+ * {@code float}, 2<sup>-149</sup>. It is equal to the
+ * hexadecimal floating-point literal {@code 0x0.000002P-126f}
+ * and also equal to {@code Float.intBitsToFloat(0x1)}.
+ */
+ public static final float MIN_VALUE = 0x0.000002P-126f; // 1.4e-45f
+
+ /**
+ * Maximum exponent a finite {@code float} variable may have. It
+ * is equal to the value returned by {@code
+ * Math.getExponent(Float.MAX_VALUE)}.
+ *
+ * @since 1.6
+ */
+ public static final int MAX_EXPONENT = 127;
+
+ /**
+ * Minimum exponent a normalized {@code float} variable may have.
+ * It is equal to the value returned by {@code
+ * Math.getExponent(Float.MIN_NORMAL)}.
+ *
+ * @since 1.6
+ */
+ public static final int MIN_EXPONENT = -126;
+
+ /**
+ * The number of bits used to represent a {@code float} value.
+ *
+ * @since 1.5
+ */
+ public static final int SIZE = 32;
+
+ /**
+ * The number of bytes used to represent a {@code float} value.
+ *
+ * @since 1.8
+ */
+ public static final int BYTES = SIZE / Byte.SIZE;
+
+ /**
+ * The {@code Class} instance representing the primitive type
+ * {@code float}.
+ *
+ * @since JDK1.1
+ */
+ @SuppressWarnings("unchecked")
+ public static final Class<Float> TYPE = (Class<Float>) Class.getPrimitiveClass("float");
+
+ /**
+ * Returns a string representation of the {@code float}
+ * argument. All characters mentioned below are ASCII characters.
+ * <ul>
+ * <li>If the argument is NaN, the result is the string
+ * "{@code NaN}".
+ * <li>Otherwise, the result is a string that represents the sign and
+ * magnitude (absolute value) of the argument. If the sign is
+ * negative, the first character of the result is
+ * '{@code -}' ({@code '\u005Cu002D'}); if the sign is
+ * positive, no sign character appears in the result. As for
+ * the magnitude <i>m</i>:
+ * <ul>
+ * <li>If <i>m</i> is infinity, it is represented by the characters
+ * {@code "Infinity"}; thus, positive infinity produces
+ * the result {@code "Infinity"} and negative infinity
+ * produces the result {@code "-Infinity"}.
+ * <li>If <i>m</i> is zero, it is represented by the characters
+ * {@code "0.0"}; thus, negative zero produces the result
+ * {@code "-0.0"} and positive zero produces the result
+ * {@code "0.0"}.
+ * <li> If <i>m</i> is greater than or equal to 10<sup>-3</sup> but
+ * less than 10<sup>7</sup>, then it is represented as the
+ * integer part of <i>m</i>, in decimal form with no leading
+ * zeroes, followed by '{@code .}'
+ * ({@code '\u005Cu002E'}), followed by one or more
+ * decimal digits representing the fractional part of
+ * <i>m</i>.
+ * <li> If <i>m</i> is less than 10<sup>-3</sup> or greater than or
+ * equal to 10<sup>7</sup>, then it is represented in
+ * so-called "computerized scientific notation." Let <i>n</i>
+ * be the unique integer such that 10<sup><i>n</i> </sup>≤
+ * <i>m</i> {@literal <} 10<sup><i>n</i>+1</sup>; then let <i>a</i>
+ * be the mathematically exact quotient of <i>m</i> and
+ * 10<sup><i>n</i></sup> so that 1 ≤ <i>a</i> {@literal <} 10.
+ * The magnitude is then represented as the integer part of
+ * <i>a</i>, as a single decimal digit, followed by
+ * '{@code .}' ({@code '\u005Cu002E'}), followed by
+ * decimal digits representing the fractional part of
+ * <i>a</i>, followed by the letter '{@code E}'
+ * ({@code '\u005Cu0045'}), followed by a representation
+ * of <i>n</i> as a decimal integer, as produced by the
+ * method {@link java.lang.Integer#toString(int)}.
+ *
+ * </ul>
+ * </ul>
+ * How many digits must be printed for the fractional part of
+ * <i>m</i> or <i>a</i>? There must be at least one digit
+ * to represent the fractional part, and beyond that as many, but
+ * only as many, more digits as are needed to uniquely distinguish
+ * the argument value from adjacent values of type
+ * {@code float}. That is, suppose that <i>x</i> is the
+ * exact mathematical value represented by the decimal
+ * representation produced by this method for a finite nonzero
+ * argument <i>f</i>. Then <i>f</i> must be the {@code float}
+ * value nearest to <i>x</i>; or, if two {@code float} values are
+ * equally close to <i>x</i>, then <i>f</i> must be one of
+ * them and the least significant bit of the significand of
+ * <i>f</i> must be {@code 0}.
+ *
+ * <p>To create localized string representations of a floating-point
+ * value, use subclasses of {@link java.text.NumberFormat}.
+ *
+ * @param f the float to be converted.
+ * @return a string representation of the argument.
+ */
+ public static String toString(float f) {
+ return FloatingDecimal.toJavaFormatString(f);
+ }
+
+ /**
+ * Returns a hexadecimal string representation of the
+ * {@code float} argument. All characters mentioned below are
+ * ASCII characters.
+ *
+ * <ul>
+ * <li>If the argument is NaN, the result is the string
+ * "{@code NaN}".
+ * <li>Otherwise, the result is a string that represents the sign and
+ * magnitude (absolute value) of the argument. If the sign is negative,
+ * the first character of the result is '{@code -}'
+ * ({@code '\u005Cu002D'}); if the sign is positive, no sign character
+ * appears in the result. As for the magnitude <i>m</i>:
+ *
+ * <ul>
+ * <li>If <i>m</i> is infinity, it is represented by the string
+ * {@code "Infinity"}; thus, positive infinity produces the
+ * result {@code "Infinity"} and negative infinity produces
+ * the result {@code "-Infinity"}.
+ *
+ * <li>If <i>m</i> is zero, it is represented by the string
+ * {@code "0x0.0p0"}; thus, negative zero produces the result
+ * {@code "-0x0.0p0"} and positive zero produces the result
+ * {@code "0x0.0p0"}.
+ *
+ * <li>If <i>m</i> is a {@code float} value with a
+ * normalized representation, substrings are used to represent the
+ * significand and exponent fields. The significand is
+ * represented by the characters {@code "0x1."}
+ * followed by a lowercase hexadecimal representation of the rest
+ * of the significand as a fraction. Trailing zeros in the
+ * hexadecimal representation are removed unless all the digits
+ * are zero, in which case a single zero is used. Next, the
+ * exponent is represented by {@code "p"} followed
+ * by a decimal string of the unbiased exponent as if produced by
+ * a call to {@link Integer#toString(int) Integer.toString} on the
+ * exponent value.
+ *
+ * <li>If <i>m</i> is a {@code float} value with a subnormal
+ * representation, the significand is represented by the
+ * characters {@code "0x0."} followed by a
+ * hexadecimal representation of the rest of the significand as a
+ * fraction. Trailing zeros in the hexadecimal representation are
+ * removed. Next, the exponent is represented by
+ * {@code "p-126"}. Note that there must be at
+ * least one nonzero digit in a subnormal significand.
+ *
+ * </ul>
+ *
+ * </ul>
+ *
+ * <table border>
+ * <caption>Examples</caption>
+ * <tr><th>Floating-point Value</th><th>Hexadecimal String</th>
+ * <tr><td>{@code 1.0}</td> <td>{@code 0x1.0p0}</td>
+ * <tr><td>{@code -1.0}</td> <td>{@code -0x1.0p0}</td>
+ * <tr><td>{@code 2.0}</td> <td>{@code 0x1.0p1}</td>
+ * <tr><td>{@code 3.0}</td> <td>{@code 0x1.8p1}</td>
+ * <tr><td>{@code 0.5}</td> <td>{@code 0x1.0p-1}</td>
+ * <tr><td>{@code 0.25}</td> <td>{@code 0x1.0p-2}</td>
+ * <tr><td>{@code Float.MAX_VALUE}</td>
+ * <td>{@code 0x1.fffffep127}</td>
+ * <tr><td>{@code Minimum Normal Value}</td>
+ * <td>{@code 0x1.0p-126}</td>
+ * <tr><td>{@code Maximum Subnormal Value}</td>
+ * <td>{@code 0x0.fffffep-126}</td>
+ * <tr><td>{@code Float.MIN_VALUE}</td>
+ * <td>{@code 0x0.000002p-126}</td>
+ * </table>
+ * @param f the {@code float} to be converted.
+ * @return a hex string representation of the argument.
+ * @since 1.5
+ * @author Joseph D. Darcy
+ */
+ public static String toHexString(float f) {
+ if (Math.abs(f) < FloatConsts.MIN_NORMAL
+ && f != 0.0f ) {// float subnormal
+ // Adjust exponent to create subnormal double, then
+ // replace subnormal double exponent with subnormal float
+ // exponent
+ String s = Double.toHexString(Math.scalb((double)f,
+ /* -1022+126 */
+ DoubleConsts.MIN_EXPONENT-
+ FloatConsts.MIN_EXPONENT));
+ return s.replaceFirst("p-1022$", "p-126");
+ }
+ else // double string will be the same as float string
+ return Double.toHexString(f);
+ }
+
+ /**
+ * Returns a {@code Float} object holding the
+ * {@code float} value represented by the argument string
+ * {@code s}.
+ *
+ * <p>If {@code s} is {@code null}, then a
+ * {@code NullPointerException} is thrown.
+ *
+ * <p>Leading and trailing whitespace characters in {@code s}
+ * are ignored. Whitespace is removed as if by the {@link
+ * String#trim} method; that is, both ASCII space and control
+ * characters are removed. The rest of {@code s} should
+ * constitute a <i>FloatValue</i> as described by the lexical
+ * syntax rules:
+ *
+ * <blockquote>
+ * <dl>
+ * <dt><i>FloatValue:</i>
+ * <dd><i>Sign<sub>opt</sub></i> {@code NaN}
+ * <dd><i>Sign<sub>opt</sub></i> {@code Infinity}
+ * <dd><i>Sign<sub>opt</sub> FloatingPointLiteral</i>
+ * <dd><i>Sign<sub>opt</sub> HexFloatingPointLiteral</i>
+ * <dd><i>SignedInteger</i>
+ * </dl>
+ *
+ * <dl>
+ * <dt><i>HexFloatingPointLiteral</i>:
+ * <dd> <i>HexSignificand BinaryExponent FloatTypeSuffix<sub>opt</sub></i>
+ * </dl>
+ *
+ * <dl>
+ * <dt><i>HexSignificand:</i>
+ * <dd><i>HexNumeral</i>
+ * <dd><i>HexNumeral</i> {@code .}
+ * <dd>{@code 0x} <i>HexDigits<sub>opt</sub>
+ * </i>{@code .}<i> HexDigits</i>
+ * <dd>{@code 0X}<i> HexDigits<sub>opt</sub>
+ * </i>{@code .} <i>HexDigits</i>
+ * </dl>
+ *
+ * <dl>
+ * <dt><i>BinaryExponent:</i>
+ * <dd><i>BinaryExponentIndicator SignedInteger</i>
+ * </dl>
+ *
+ * <dl>
+ * <dt><i>BinaryExponentIndicator:</i>
+ * <dd>{@code p}
+ * <dd>{@code P}
+ * </dl>
+ *
+ * </blockquote>
+ *
+ * where <i>Sign</i>, <i>FloatingPointLiteral</i>,
+ * <i>HexNumeral</i>, <i>HexDigits</i>, <i>SignedInteger</i> and
+ * <i>FloatTypeSuffix</i> are as defined in the lexical structure
+ * sections of
+ * <cite>The Java™ Language Specification</cite>,
+ * except that underscores are not accepted between digits.
+ * If {@code s} does not have the form of
+ * a <i>FloatValue</i>, then a {@code NumberFormatException}
+ * is thrown. Otherwise, {@code s} is regarded as
+ * representing an exact decimal value in the usual
+ * "computerized scientific notation" or as an exact
+ * hexadecimal value; this exact numerical value is then
+ * conceptually converted to an "infinitely precise"
+ * binary value that is then rounded to type {@code float}
+ * by the usual round-to-nearest rule of IEEE 754 floating-point
+ * arithmetic, which includes preserving the sign of a zero
+ * value.
+ *
+ * Note that the round-to-nearest rule also implies overflow and
+ * underflow behaviour; if the exact value of {@code s} is large
+ * enough in magnitude (greater than or equal to ({@link
+ * #MAX_VALUE} + {@link Math#ulp(float) ulp(MAX_VALUE)}/2),
+ * rounding to {@code float} will result in an infinity and if the
+ * exact value of {@code s} is small enough in magnitude (less
+ * than or equal to {@link #MIN_VALUE}/2), rounding to float will
+ * result in a zero.
+ *
+ * Finally, after rounding a {@code Float} object representing
+ * this {@code float} value is returned.
+ *
+ * <p>To interpret localized string representations of a
+ * floating-point value, use subclasses of {@link
+ * java.text.NumberFormat}.
+ *
+ * <p>Note that trailing format specifiers, specifiers that
+ * determine the type of a floating-point literal
+ * ({@code 1.0f} is a {@code float} value;
+ * {@code 1.0d} is a {@code double} value), do
+ * <em>not</em> influence the results of this method. In other
+ * words, the numerical value of the input string is converted
+ * directly to the target floating-point type. In general, the
+ * two-step sequence of conversions, string to {@code double}
+ * followed by {@code double} to {@code float}, is
+ * <em>not</em> equivalent to converting a string directly to
+ * {@code float}. For example, if first converted to an
+ * intermediate {@code double} and then to
+ * {@code float}, the string<br>
+ * {@code "1.00000017881393421514957253748434595763683319091796875001d"}<br>
+ * results in the {@code float} value
+ * {@code 1.0000002f}; if the string is converted directly to
+ * {@code float}, <code>1.000000<b>1</b>f</code> results.
+ *
+ * <p>To avoid calling this method on an invalid string and having
+ * a {@code NumberFormatException} be thrown, the documentation
+ * for {@link Double#valueOf Double.valueOf} lists a regular
+ * expression which can be used to screen the input.
+ *
+ * @param s the string to be parsed.
+ * @return a {@code Float} object holding the value
+ * represented by the {@code String} argument.
+ * @throws NumberFormatException if the string does not contain a
+ * parsable number.
+ */
+ public static Float valueOf(String s) throws NumberFormatException {
+ return new Float(parseFloat(s));
+ }
+
+ /**
+ * Returns a {@code Float} instance representing the specified
+ * {@code float} value.
+ * If a new {@code Float} instance is not required, this method
+ * should generally be used in preference to the constructor
+ * {@link #Float(float)}, as this method is likely to yield
+ * significantly better space and time performance by caching
+ * frequently requested values.
+ *
+ * @param f a float value.
+ * @return a {@code Float} instance representing {@code f}.
+ * @since 1.5
+ */
+ public static Float valueOf(float f) {
+ return new Float(f);
+ }
+
+ /**
+ * Returns a new {@code float} initialized to the value
+ * represented by the specified {@code String}, as performed
+ * by the {@code valueOf} method of class {@code Float}.
+ *
+ * @param s the string to be parsed.
+ * @return the {@code float} value represented by the string
+ * argument.
+ * @throws NullPointerException if the string is null
+ * @throws NumberFormatException if the string does not contain a
+ * parsable {@code float}.
+ * @see java.lang.Float#valueOf(String)
+ * @since 1.2
+ */
+ public static float parseFloat(String s) throws NumberFormatException {
+ return FloatingDecimal.parseFloat(s);
+ }
+
+ /**
+ * Returns {@code true} if the specified number is a
+ * Not-a-Number (NaN) value, {@code false} otherwise.
+ *
+ * @param v the value to be tested.
+ * @return {@code true} if the argument is NaN;
+ * {@code false} otherwise.
+ */
+ public static boolean isNaN(float v) {
+ return (v != v);
+ }
+
+ /**
+ * Returns {@code true} if the specified number is infinitely
+ * large in magnitude, {@code false} otherwise.
+ *
+ * @param v the value to be tested.
+ * @return {@code true} if the argument is positive infinity or
+ * negative infinity; {@code false} otherwise.
+ */
+ public static boolean isInfinite(float v) {
+ return (v == POSITIVE_INFINITY) || (v == NEGATIVE_INFINITY);
+ }
+
+
+ /**
+ * Returns {@code true} if the argument is a finite floating-point
+ * value; returns {@code false} otherwise (for NaN and infinity
+ * arguments).
+ *
+ * @param f the {@code float} value to be tested
+ * @return {@code true} if the argument is a finite
+ * floating-point value, {@code false} otherwise.
+ * @since 1.8
+ */
+ public static boolean isFinite(float f) {
+ return Math.abs(f) <= FloatConsts.MAX_VALUE;
+ }
+
+ /**
+ * The value of the Float.
+ *
+ * @serial
+ */
+ private final float value;
+
+ /**
+ * Constructs a newly allocated {@code Float} object that
+ * represents the primitive {@code float} argument.
+ *
+ * @param value the value to be represented by the {@code Float}.
+ */
+ public Float(float value) {
+ this.value = value;
+ }
+
+ /**
+ * Constructs a newly allocated {@code Float} object that
+ * represents the argument converted to type {@code float}.
+ *
+ * @param value the value to be represented by the {@code Float}.
+ */
+ public Float(double value) {
+ this.value = (float)value;
+ }
+
+ /**
+ * Constructs a newly allocated {@code Float} object that
+ * represents the floating-point value of type {@code float}
+ * represented by the string. The string is converted to a
+ * {@code float} value as if by the {@code valueOf} method.
+ *
+ * @param s a string to be converted to a {@code Float}.
+ * @throws NumberFormatException if the string does not contain a
+ * parsable number.
+ * @see java.lang.Float#valueOf(java.lang.String)
+ */
+ public Float(String s) throws NumberFormatException {
+ value = parseFloat(s);
+ }
+
+ /**
+ * Returns {@code true} if this {@code Float} value is a
+ * Not-a-Number (NaN), {@code false} otherwise.
+ *
+ * @return {@code true} if the value represented by this object is
+ * NaN; {@code false} otherwise.
+ */
+ public boolean isNaN() {
+ return isNaN(value);
+ }
+
+ /**
+ * Returns {@code true} if this {@code Float} value is
+ * infinitely large in magnitude, {@code false} otherwise.
+ *
+ * @return {@code true} if the value represented by this object is
+ * positive infinity or negative infinity;
+ * {@code false} otherwise.
+ */
+ public boolean isInfinite() {
+ return isInfinite(value);
+ }
+
+ /**
+ * Returns a string representation of this {@code Float} object.
+ * The primitive {@code float} value represented by this object
+ * is converted to a {@code String} exactly as if by the method
+ * {@code toString} of one argument.
+ *
+ * @return a {@code String} representation of this object.
+ * @see java.lang.Float#toString(float)
+ */
+ public String toString() {
+ return Float.toString(value);
+ }
+
+ /**
+ * Returns the value of this {@code Float} as a {@code byte} after
+ * a narrowing primitive conversion.
+ *
+ * @return the {@code float} value represented by this object
+ * converted to type {@code byte}
+ * @jls 5.1.3 Narrowing Primitive Conversions
+ */
+ public byte byteValue() {
+ return (byte)value;
+ }
+
+ /**
+ * Returns the value of this {@code Float} as a {@code short}
+ * after a narrowing primitive conversion.
+ *
+ * @return the {@code float} value represented by this object
+ * converted to type {@code short}
+ * @jls 5.1.3 Narrowing Primitive Conversions
+ * @since JDK1.1
+ */
+ public short shortValue() {
+ return (short)value;
+ }
+
+ /**
+ * Returns the value of this {@code Float} as an {@code int} after
+ * a narrowing primitive conversion.
+ *
+ * @return the {@code float} value represented by this object
+ * converted to type {@code int}
+ * @jls 5.1.3 Narrowing Primitive Conversions
+ */
+ public int intValue() {
+ return (int)value;
+ }
+
+ /**
+ * Returns value of this {@code Float} as a {@code long} after a
+ * narrowing primitive conversion.
+ *
+ * @return the {@code float} value represented by this object
+ * converted to type {@code long}
+ * @jls 5.1.3 Narrowing Primitive Conversions
+ */
+ public long longValue() {
+ return (long)value;
+ }
+
+ /**
+ * Returns the {@code float} value of this {@code Float} object.
+ *
+ * @return the {@code float} value represented by this object
+ */
+ public float floatValue() {
+ return value;
+ }
+
+ /**
+ * Returns the value of this {@code Float} as a {@code double}
+ * after a widening primitive conversion.
+ *
+ * @return the {@code float} value represented by this
+ * object converted to type {@code double}
+ * @jls 5.1.2 Widening Primitive Conversions
+ */
+ public double doubleValue() {
+ return (double)value;
+ }
+
+ /**
+ * Returns a hash code for this {@code Float} object. The
+ * result is the integer bit representation, exactly as produced
+ * by the method {@link #floatToIntBits(float)}, of the primitive
+ * {@code float} value represented by this {@code Float}
+ * object.
+ *
+ * @return a hash code value for this object.
+ */
+ @Override
+ public int hashCode() {
+ return Float.hashCode(value);
+ }
+
+ /**
+ * Returns a hash code for a {@code float} value; compatible with
+ * {@code Float.hashCode()}.
+ *
+ * @param value the value to hash
+ * @return a hash code value for a {@code float} value.
+ * @since 1.8
+ */
+ public static int hashCode(float value) {
+ return floatToIntBits(value);
+ }
+
+ /**
+
+ * Compares this object against the specified object. The result
+ * is {@code true} if and only if the argument is not
+ * {@code null} and is a {@code Float} object that
+ * represents a {@code float} with the same value as the
+ * {@code float} represented by this object. For this
+ * purpose, two {@code float} values are considered to be the
+ * same if and only if the method {@link #floatToIntBits(float)}
+ * returns the identical {@code int} value when applied to
+ * each.
+ *
+ * <p>Note that in most cases, for two instances of class
+ * {@code Float}, {@code f1} and {@code f2}, the value
+ * of {@code f1.equals(f2)} is {@code true} if and only if
+ *
+ * <blockquote><pre>
+ * f1.floatValue() == f2.floatValue()
+ * </pre></blockquote>
+ *
+ * <p>also has the value {@code true}. However, there are two exceptions:
+ * <ul>
+ * <li>If {@code f1} and {@code f2} both represent
+ * {@code Float.NaN}, then the {@code equals} method returns
+ * {@code true}, even though {@code Float.NaN==Float.NaN}
+ * has the value {@code false}.
+ * <li>If {@code f1} represents {@code +0.0f} while
+ * {@code f2} represents {@code -0.0f}, or vice
+ * versa, the {@code equal} test has the value
+ * {@code false}, even though {@code 0.0f==-0.0f}
+ * has the value {@code true}.
+ * </ul>
+ *
+ * This definition allows hash tables to operate properly.
+ *
+ * @param obj the object to be compared
+ * @return {@code true} if the objects are the same;
+ * {@code false} otherwise.
+ * @see java.lang.Float#floatToIntBits(float)
+ */
+ public boolean equals(Object obj) {
+ return (obj instanceof Float)
+ && (floatToIntBits(((Float)obj).value) == floatToIntBits(value));
+ }
+
+ /**
+ * Returns a representation of the specified floating-point value
+ * according to the IEEE 754 floating-point "single format" bit
+ * layout.
+ *
+ * <p>Bit 31 (the bit that is selected by the mask
+ * {@code 0x80000000}) represents the sign of the floating-point
+ * number.
+ * Bits 30-23 (the bits that are selected by the mask
+ * {@code 0x7f800000}) represent the exponent.
+ * Bits 22-0 (the bits that are selected by the mask
+ * {@code 0x007fffff}) represent the significand (sometimes called
+ * the mantissa) of the floating-point number.
+ *
+ * <p>If the argument is positive infinity, the result is
+ * {@code 0x7f800000}.
+ *
+ * <p>If the argument is negative infinity, the result is
+ * {@code 0xff800000}.
+ *
+ * <p>If the argument is NaN, the result is {@code 0x7fc00000}.
+ *
+ * <p>In all cases, the result is an integer that, when given to the
+ * {@link #intBitsToFloat(int)} method, will produce a floating-point
+ * value the same as the argument to {@code floatToIntBits}
+ * (except all NaN values are collapsed to a single
+ * "canonical" NaN value).
+ *
+ * @param value a floating-point number.
+ * @return the bits that represent the floating-point number.
+ */
+ public static int floatToIntBits(float value) {
+ int result = floatToRawIntBits(value);
+ // Check for NaN based on values of bit fields, maximum
+ // exponent and nonzero significand.
+ if ( ((result & FloatConsts.EXP_BIT_MASK) ==
+ FloatConsts.EXP_BIT_MASK) &&
+ (result & FloatConsts.SIGNIF_BIT_MASK) != 0)
+ result = 0x7fc00000;
+ return result;
+ }
+
+ /**
+ * Returns a representation of the specified floating-point value
+ * according to the IEEE 754 floating-point "single format" bit
+ * layout, preserving Not-a-Number (NaN) values.
+ *
+ * <p>Bit 31 (the bit that is selected by the mask
+ * {@code 0x80000000}) represents the sign of the floating-point
+ * number.
+ * Bits 30-23 (the bits that are selected by the mask
+ * {@code 0x7f800000}) represent the exponent.
+ * Bits 22-0 (the bits that are selected by the mask
+ * {@code 0x007fffff}) represent the significand (sometimes called
+ * the mantissa) of the floating-point number.
+ *
+ * <p>If the argument is positive infinity, the result is
+ * {@code 0x7f800000}.
+ *
+ * <p>If the argument is negative infinity, the result is
+ * {@code 0xff800000}.
+ *
+ * <p>If the argument is NaN, the result is the integer representing
+ * the actual NaN value. Unlike the {@code floatToIntBits}
+ * method, {@code floatToRawIntBits} does not collapse all the
+ * bit patterns encoding a NaN to a single "canonical"
+ * NaN value.
+ *
+ * <p>In all cases, the result is an integer that, when given to the
+ * {@link #intBitsToFloat(int)} method, will produce a
+ * floating-point value the same as the argument to
+ * {@code floatToRawIntBits}.
+ *
+ * @param value a floating-point number.
+ * @return the bits that represent the floating-point number.
+ * @since 1.3
+ */
+ public static native int floatToRawIntBits(float value);
+
+ /**
+ * Returns the {@code float} value corresponding to a given
+ * bit representation.
+ * The argument is considered to be a representation of a
+ * floating-point value according to the IEEE 754 floating-point
+ * "single format" bit layout.
+ *
+ * <p>If the argument is {@code 0x7f800000}, the result is positive
+ * infinity.
+ *
+ * <p>If the argument is {@code 0xff800000}, the result is negative
+ * infinity.
+ *
+ * <p>If the argument is any value in the range
+ * {@code 0x7f800001} through {@code 0x7fffffff} or in
+ * the range {@code 0xff800001} through
+ * {@code 0xffffffff}, the result is a NaN. No IEEE 754
+ * floating-point operation provided by Java can distinguish
+ * between two NaN values of the same type with different bit
+ * patterns. Distinct values of NaN are only distinguishable by
+ * use of the {@code Float.floatToRawIntBits} method.
+ *
+ * <p>In all other cases, let <i>s</i>, <i>e</i>, and <i>m</i> be three
+ * values that can be computed from the argument:
+ *
+ * <blockquote><pre>{@code
+ * int s = ((bits >> 31) == 0) ? 1 : -1;
+ * int e = ((bits >> 23) & 0xff);
+ * int m = (e == 0) ?
+ * (bits & 0x7fffff) << 1 :
+ * (bits & 0x7fffff) | 0x800000;
+ * }</pre></blockquote>
+ *
+ * Then the floating-point result equals the value of the mathematical
+ * expression <i>s</i>·<i>m</i>·2<sup><i>e</i>-150</sup>.
+ *
+ * <p>Note that this method may not be able to return a
+ * {@code float} NaN with exactly same bit pattern as the
+ * {@code int} argument. IEEE 754 distinguishes between two
+ * kinds of NaNs, quiet NaNs and <i>signaling NaNs</i>. The
+ * differences between the two kinds of NaN are generally not
+ * visible in Java. Arithmetic operations on signaling NaNs turn
+ * them into quiet NaNs with a different, but often similar, bit
+ * pattern. However, on some processors merely copying a
+ * signaling NaN also performs that conversion. In particular,
+ * copying a signaling NaN to return it to the calling method may
+ * perform this conversion. So {@code intBitsToFloat} may
+ * not be able to return a {@code float} with a signaling NaN
+ * bit pattern. Consequently, for some {@code int} values,
+ * {@code floatToRawIntBits(intBitsToFloat(start))} may
+ * <i>not</i> equal {@code start}. Moreover, which
+ * particular bit patterns represent signaling NaNs is platform
+ * dependent; although all NaN bit patterns, quiet or signaling,
+ * must be in the NaN range identified above.
+ *
+ * @param bits an integer.
+ * @return the {@code float} floating-point value with the same bit
+ * pattern.
+ */
+ public static native float intBitsToFloat(int bits);
+
+ /**
+ * Compares two {@code Float} objects numerically. There are
+ * two ways in which comparisons performed by this method differ
+ * from those performed by the Java language numerical comparison
+ * operators ({@code <, <=, ==, >=, >}) when
+ * applied to primitive {@code float} values:
+ *
+ * <ul><li>
+ * {@code Float.NaN} is considered by this method to
+ * be equal to itself and greater than all other
+ * {@code float} values
+ * (including {@code Float.POSITIVE_INFINITY}).
+ * <li>
+ * {@code 0.0f} is considered by this method to be greater
+ * than {@code -0.0f}.
+ * </ul>
+ *
+ * This ensures that the <i>natural ordering</i> of {@code Float}
+ * objects imposed by this method is <i>consistent with equals</i>.
+ *
+ * @param anotherFloat the {@code Float} to be compared.
+ * @return the value {@code 0} if {@code anotherFloat} is
+ * numerically equal to this {@code Float}; a value
+ * less than {@code 0} if this {@code Float}
+ * is numerically less than {@code anotherFloat};
+ * and a value greater than {@code 0} if this
+ * {@code Float} is numerically greater than
+ * {@code anotherFloat}.
+ *
+ * @since 1.2
+ * @see Comparable#compareTo(Object)
+ */
+ public int compareTo(Float anotherFloat) {
+ return Float.compare(value, anotherFloat.value);
+ }
+
+ /**
+ * Compares the two specified {@code float} values. The sign
+ * of the integer value returned is the same as that of the
+ * integer that would be returned by the call:
+ * <pre>
+ * new Float(f1).compareTo(new Float(f2))
+ * </pre>
+ *
+ * @param f1 the first {@code float} to compare.
+ * @param f2 the second {@code float} to compare.
+ * @return the value {@code 0} if {@code f1} is
+ * numerically equal to {@code f2}; a value less than
+ * {@code 0} if {@code f1} is numerically less than
+ * {@code f2}; and a value greater than {@code 0}
+ * if {@code f1} is numerically greater than
+ * {@code f2}.
+ * @since 1.4
+ */
+ public static int compare(float f1, float f2) {
+ if (f1 < f2)
+ return -1; // Neither val is NaN, thisVal is smaller
+ if (f1 > f2)
+ return 1; // Neither val is NaN, thisVal is larger
+
+ // Cannot use floatToRawIntBits because of possibility of NaNs.
+ int thisBits = Float.floatToIntBits(f1);
+ int anotherBits = Float.floatToIntBits(f2);
+
+ return (thisBits == anotherBits ? 0 : // Values are equal
+ (thisBits < anotherBits ? -1 : // (-0.0, 0.0) or (!NaN, NaN)
+ 1)); // (0.0, -0.0) or (NaN, !NaN)
+ }
+
+ /**
+ * Adds two {@code float} values together as per the + operator.
+ *
+ * @param a the first operand
+ * @param b the second operand
+ * @return the sum of {@code a} and {@code b}
+ * @jls 4.2.4 Floating-Point Operations
+ * @see java.util.function.BinaryOperator
+ * @since 1.8
+ */
+ public static float sum(float a, float b) {
+ return a + b;
+ }
+
+ /**
+ * Returns the greater of two {@code float} values
+ * as if by calling {@link Math#max(float, float) Math.max}.
+ *
+ * @param a the first operand
+ * @param b the second operand
+ * @return the greater of {@code a} and {@code b}
+ * @see java.util.function.BinaryOperator
+ * @since 1.8
+ */
+ public static float max(float a, float b) {
+ return Math.max(a, b);
+ }
+
+ /**
+ * Returns the smaller of two {@code float} values
+ * as if by calling {@link Math#min(float, float) Math.min}.
+ *
+ * @param a the first operand
+ * @param b the second operand
+ * @return the smaller of {@code a} and {@code b}
+ * @see java.util.function.BinaryOperator
+ * @since 1.8
+ */
+ public static float min(float a, float b) {
+ return Math.min(a, b);
+ }
+
+ /** use serialVersionUID from JDK 1.0.2 for interoperability */
+ private static final long serialVersionUID = -2671257302660747028L;
+}
diff --git a/java/lang/FunctionalInterface.java b/java/lang/FunctionalInterface.java
new file mode 100644
index 0000000..a93ed51
--- /dev/null
+++ b/java/lang/FunctionalInterface.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2012, 2013, 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;
+
+import java.lang.annotation.*;
+
+/**
+ * An informative annotation type used to indicate that an interface
+ * type declaration is intended to be a <i>functional interface</i> as
+ * defined by the Java Language Specification.
+ *
+ * Conceptually, a functional interface has exactly one abstract
+ * method. Since {@linkplain java.lang.reflect.Method#isDefault()
+ * default methods} have an implementation, they are not abstract. If
+ * an interface declares an abstract method overriding one of the
+ * public methods of {@code java.lang.Object}, that also does
+ * <em>not</em> count toward the interface's abstract method count
+ * since any implementation of the interface will have an
+ * implementation from {@code java.lang.Object} or elsewhere.
+ *
+ * <p>Note that instances of functional interfaces can be created with
+ * lambda expressions, method references, or constructor references.
+ *
+ * <p>If a type is annotated with this annotation type, compilers are
+ * required to generate an error message unless:
+ *
+ * <ul>
+ * <li> The type is an interface type and not an annotation type, enum, or class.
+ * <li> The annotated type satisfies the requirements of a functional interface.
+ * </ul>
+ *
+ * <p>However, the compiler will treat any interface meeting the
+ * definition of a functional interface as a functional interface
+ * regardless of whether or not a {@code FunctionalInterface}
+ * annotation is present on the interface declaration.
+ *
+ * @jls 4.3.2. The Class Object
+ * @jls 9.8 Functional Interfaces
+ * @jls 9.4.3 Interface Method Body
+ * @since 1.8
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface FunctionalInterface {}
diff --git a/java/lang/IllegalAccessError.java b/java/lang/IllegalAccessError.java
new file mode 100644
index 0000000..ce045cd
--- /dev/null
+++ b/java/lang/IllegalAccessError.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1995, 2008, 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;
+
+/**
+ * Thrown if an application attempts to access or modify a field, or
+ * to call a method that it does not have access to.
+ * <p>
+ * Normally, this error is caught by the compiler; this error can
+ * only occur at run time if the definition of a class has
+ * incompatibly changed.
+ *
+ * @author unascribed
+ * @since JDK1.0
+ */
+public class IllegalAccessError extends IncompatibleClassChangeError {
+ private static final long serialVersionUID = -8988904074992417891L;
+
+ /**
+ * Constructs an <code>IllegalAccessError</code> with no detail message.
+ */
+ public IllegalAccessError() {
+ super();
+ }
+
+ /**
+ * Constructs an <code>IllegalAccessError</code> with the specified
+ * detail message.
+ *
+ * @param s the detail message.
+ */
+ public IllegalAccessError(String s) {
+ super(s);
+ }
+}
diff --git a/java/lang/IllegalAccessException.java b/java/lang/IllegalAccessException.java
new file mode 100644
index 0000000..c7b1df8
--- /dev/null
+++ b/java/lang/IllegalAccessException.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 1995, 2008, 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;
+
+/**
+ * An IllegalAccessException is thrown when an application tries
+ * to reflectively create an instance (other than an array),
+ * set or get a field, or invoke a method, but the currently
+ * executing method does not have access to the definition of
+ * the specified class, field, method or constructor.
+ *
+ * @author unascribed
+ * @see Class#newInstance()
+ * @see java.lang.reflect.Field#set(Object, Object)
+ * @see java.lang.reflect.Field#setBoolean(Object, boolean)
+ * @see java.lang.reflect.Field#setByte(Object, byte)
+ * @see java.lang.reflect.Field#setShort(Object, short)
+ * @see java.lang.reflect.Field#setChar(Object, char)
+ * @see java.lang.reflect.Field#setInt(Object, int)
+ * @see java.lang.reflect.Field#setLong(Object, long)
+ * @see java.lang.reflect.Field#setFloat(Object, float)
+ * @see java.lang.reflect.Field#setDouble(Object, double)
+ * @see java.lang.reflect.Field#get(Object)
+ * @see java.lang.reflect.Field#getBoolean(Object)
+ * @see java.lang.reflect.Field#getByte(Object)
+ * @see java.lang.reflect.Field#getShort(Object)
+ * @see java.lang.reflect.Field#getChar(Object)
+ * @see java.lang.reflect.Field#getInt(Object)
+ * @see java.lang.reflect.Field#getLong(Object)
+ * @see java.lang.reflect.Field#getFloat(Object)
+ * @see java.lang.reflect.Field#getDouble(Object)
+ * @see java.lang.reflect.Method#invoke(Object, Object[])
+ * @see java.lang.reflect.Constructor#newInstance(Object[])
+ * @since JDK1.0
+ */
+public class IllegalAccessException extends ReflectiveOperationException {
+ private static final long serialVersionUID = 6616958222490762034L;
+
+ /**
+ * Constructs an <code>IllegalAccessException</code> without a
+ * detail message.
+ */
+ public IllegalAccessException() {
+ super();
+ }
+
+ /**
+ * Constructs an <code>IllegalAccessException</code> with a detail message.
+ *
+ * @param s the detail message.
+ */
+ public IllegalAccessException(String s) {
+ super(s);
+ }
+}
diff --git a/java/lang/IllegalArgumentException.java b/java/lang/IllegalArgumentException.java
new file mode 100644
index 0000000..c29a9d5
--- /dev/null
+++ b/java/lang/IllegalArgumentException.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 1994, 2012, 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;
+
+/**
+ * Thrown to indicate that a method has been passed an illegal or
+ * inappropriate argument.
+ *
+ * @author unascribed
+ * @since JDK1.0
+ */
+public
+class IllegalArgumentException extends RuntimeException {
+ /**
+ * Constructs an <code>IllegalArgumentException</code> with no
+ * detail message.
+ */
+ public IllegalArgumentException() {
+ super();
+ }
+
+ /**
+ * Constructs an <code>IllegalArgumentException</code> with the
+ * specified detail message.
+ *
+ * @param s the detail message.
+ */
+ public IllegalArgumentException(String s) {
+ super(s);
+ }
+
+ /**
+ * Constructs a new exception with the specified detail message and
+ * cause.
+ *
+ * <p>Note that the detail message associated with <code>cause</code> is
+ * <i>not</i> automatically incorporated in this exception's detail
+ * message.
+ *
+ * @param message the detail message (which is saved for later retrieval
+ * by the {@link Throwable#getMessage()} method).
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link Throwable#getCause()} method). (A <tt>null</tt> value
+ * is permitted, and indicates that the cause is nonexistent or
+ * unknown.)
+ * @since 1.5
+ */
+ public IllegalArgumentException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * Constructs a new exception with the specified cause and a detail
+ * message of <tt>(cause==null ? null : cause.toString())</tt> (which
+ * typically contains the class and detail message of <tt>cause</tt>).
+ * This constructor is useful for exceptions that are little more than
+ * wrappers for other throwables (for example, {@link
+ * java.security.PrivilegedActionException}).
+ *
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link Throwable#getCause()} method). (A <tt>null</tt> value is
+ * permitted, and indicates that the cause is nonexistent or
+ * unknown.)
+ * @since 1.5
+ */
+ public IllegalArgumentException(Throwable cause) {
+ super(cause);
+ }
+
+ private static final long serialVersionUID = -5365630128856068164L;
+}
diff --git a/java/lang/IllegalMonitorStateException.java b/java/lang/IllegalMonitorStateException.java
new file mode 100644
index 0000000..3985066
--- /dev/null
+++ b/java/lang/IllegalMonitorStateException.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 1995, 2008, 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;
+
+/**
+ * Thrown to indicate that a thread has attempted to wait on an
+ * object's monitor or to notify other threads waiting on an object's
+ * monitor without owning the specified monitor.
+ *
+ * @author unascribed
+ * @see java.lang.Object#notify()
+ * @see java.lang.Object#notifyAll()
+ * @see java.lang.Object#wait()
+ * @see java.lang.Object#wait(long)
+ * @see java.lang.Object#wait(long, int)
+ * @since JDK1.0
+ */
+public
+class IllegalMonitorStateException extends RuntimeException {
+ private static final long serialVersionUID = 3713306369498869069L;
+
+ /**
+ * Constructs an <code>IllegalMonitorStateException</code> with no
+ * detail message.
+ */
+ public IllegalMonitorStateException() {
+ super();
+ }
+
+ /**
+ * Constructs an <code>IllegalMonitorStateException</code> with the
+ * specified detail message.
+ *
+ * @param s the detail message.
+ */
+ public IllegalMonitorStateException(String s) {
+ super(s);
+ }
+}
diff --git a/java/lang/IllegalStateException.java b/java/lang/IllegalStateException.java
new file mode 100644
index 0000000..9c0c06a
--- /dev/null
+++ b/java/lang/IllegalStateException.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 1996, 2003, 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;
+
+/**
+ * Signals that a method has been invoked at an illegal or
+ * inappropriate time. In other words, the Java environment or
+ * Java application is not in an appropriate state for the requested
+ * operation.
+ *
+ * @author Jonni Kanerva
+ * @since JDK1.1
+ */
+public
+class IllegalStateException extends RuntimeException {
+ /**
+ * Constructs an IllegalStateException with no detail message.
+ * A detail message is a String that describes this particular exception.
+ */
+ public IllegalStateException() {
+ super();
+ }
+
+ /**
+ * Constructs an IllegalStateException with the specified detail
+ * message. A detail message is a String that describes this particular
+ * exception.
+ *
+ * @param s the String that contains a detailed message
+ */
+ public IllegalStateException(String s) {
+ super(s);
+ }
+
+ /**
+ * Constructs a new exception with the specified detail message and
+ * cause.
+ *
+ * <p>Note that the detail message associated with <code>cause</code> is
+ * <i>not</i> automatically incorporated in this exception's detail
+ * message.
+ *
+ * @param message the detail message (which is saved for later retrieval
+ * by the {@link Throwable#getMessage()} method).
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link Throwable#getCause()} method). (A <tt>null</tt> value
+ * is permitted, and indicates that the cause is nonexistent or
+ * unknown.)
+ * @since 1.5
+ */
+ public IllegalStateException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * Constructs a new exception with the specified cause and a detail
+ * message of <tt>(cause==null ? null : cause.toString())</tt> (which
+ * typically contains the class and detail message of <tt>cause</tt>).
+ * This constructor is useful for exceptions that are little more than
+ * wrappers for other throwables (for example, {@link
+ * java.security.PrivilegedActionException}).
+ *
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link Throwable#getCause()} method). (A <tt>null</tt> value is
+ * permitted, and indicates that the cause is nonexistent or
+ * unknown.)
+ * @since 1.5
+ */
+ public IllegalStateException(Throwable cause) {
+ super(cause);
+ }
+
+ static final long serialVersionUID = -1848914673093119416L;
+}
diff --git a/java/lang/IllegalThreadStateException.java b/java/lang/IllegalThreadStateException.java
new file mode 100644
index 0000000..c59ab59
--- /dev/null
+++ b/java/lang/IllegalThreadStateException.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 1994, 2008, 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;
+
+/**
+ * Thrown to indicate that a thread is not in an appropriate state
+ * for the requested operation. See, for example, the
+ * <code>suspend</code> and <code>resume</code> methods in class
+ * <code>Thread</code>.
+ *
+ * @author unascribed
+ * @see java.lang.Thread#resume()
+ * @see java.lang.Thread#suspend()
+ * @since JDK1.0
+ */
+public class IllegalThreadStateException extends IllegalArgumentException {
+ private static final long serialVersionUID = -7626246362397460174L;
+
+ /**
+ * Constructs an <code>IllegalThreadStateException</code> with no
+ * detail message.
+ */
+ public IllegalThreadStateException() {
+ super();
+ }
+
+ /**
+ * Constructs an <code>IllegalThreadStateException</code> with the
+ * specified detail message.
+ *
+ * @param s the detail message.
+ */
+ public IllegalThreadStateException(String s) {
+ super(s);
+ }
+}
diff --git a/java/lang/IncompatibleClassChangeError.java b/java/lang/IncompatibleClassChangeError.java
new file mode 100644
index 0000000..edffaee
--- /dev/null
+++ b/java/lang/IncompatibleClassChangeError.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 1994, 2008, 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;
+
+/**
+ * Thrown when an incompatible class change has occurred to some class
+ * definition. The definition of some class, on which the currently
+ * executing method depends, has since changed.
+ *
+ * @author unascribed
+ * @since JDK1.0
+ */
+public
+class IncompatibleClassChangeError extends LinkageError {
+ private static final long serialVersionUID = -4914975503642802119L;
+
+ /**
+ * Constructs an <code>IncompatibleClassChangeError</code> with no
+ * detail message.
+ */
+ public IncompatibleClassChangeError () {
+ super();
+ }
+
+ /**
+ * Constructs an <code>IncompatibleClassChangeError</code> with the
+ * specified detail message.
+ *
+ * @param s the detail message.
+ */
+ public IncompatibleClassChangeError(String s) {
+ super(s);
+ }
+}
diff --git a/java/lang/IndexOutOfBoundsException.java b/java/lang/IndexOutOfBoundsException.java
new file mode 100644
index 0000000..4dc7948
--- /dev/null
+++ b/java/lang/IndexOutOfBoundsException.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1995, 2008, 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;
+
+/**
+ * Thrown to indicate that an index of some sort (such as to an array, to a
+ * string, or to a vector) is out of range.
+ * <p>
+ * Applications can subclass this class to indicate similar exceptions.
+ *
+ * @author Frank Yellin
+ * @since JDK1.0
+ */
+public
+class IndexOutOfBoundsException extends RuntimeException {
+ private static final long serialVersionUID = 234122996006267687L;
+
+ /**
+ * Constructs an <code>IndexOutOfBoundsException</code> with no
+ * detail message.
+ */
+ public IndexOutOfBoundsException() {
+ super();
+ }
+
+ /**
+ * Constructs an <code>IndexOutOfBoundsException</code> with the
+ * specified detail message.
+ *
+ * @param s the detail message.
+ */
+ public IndexOutOfBoundsException(String s) {
+ super(s);
+ }
+}
diff --git a/java/lang/InheritableThreadLocal.java b/java/lang/InheritableThreadLocal.java
new file mode 100644
index 0000000..935c5f1
--- /dev/null
+++ b/java/lang/InheritableThreadLocal.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 1998, 2012, 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;
+import java.lang.ref.*;
+
+/**
+ * This class extends <tt>ThreadLocal</tt> to provide inheritance of values
+ * from parent thread to child thread: when a child thread is created, the
+ * child receives initial values for all inheritable thread-local variables
+ * for which the parent has values. Normally the child's values will be
+ * identical to the parent's; however, the child's value can be made an
+ * arbitrary function of the parent's by overriding the <tt>childValue</tt>
+ * method in this class.
+ *
+ * <p>Inheritable thread-local variables are used in preference to
+ * ordinary thread-local variables when the per-thread-attribute being
+ * maintained in the variable (e.g., User ID, Transaction ID) must be
+ * automatically transmitted to any child threads that are created.
+ *
+ * @author Josh Bloch and Doug Lea
+ * @see ThreadLocal
+ * @since 1.2
+ */
+
+public class InheritableThreadLocal<T> extends ThreadLocal<T> {
+ /**
+ * Computes the child's initial value for this inheritable thread-local
+ * variable as a function of the parent's value at the time the child
+ * thread is created. This method is called from within the parent
+ * thread before the child is started.
+ * <p>
+ * This method merely returns its input argument, and should be overridden
+ * if a different behavior is desired.
+ *
+ * @param parentValue the parent thread's value
+ * @return the child thread's initial value
+ */
+ protected T childValue(T parentValue) {
+ return parentValue;
+ }
+
+ /**
+ * Get the map associated with a ThreadLocal.
+ *
+ * @param t the current thread
+ */
+ ThreadLocalMap getMap(Thread t) {
+ return t.inheritableThreadLocals;
+ }
+
+ /**
+ * Create the map associated with a ThreadLocal.
+ *
+ * @param t the current thread
+ * @param firstValue value for the initial entry of the table.
+ */
+ void createMap(Thread t, T firstValue) {
+ t.inheritableThreadLocals = new ThreadLocalMap(this, firstValue);
+ }
+}
diff --git a/java/lang/InstantiationError.java b/java/lang/InstantiationError.java
new file mode 100644
index 0000000..89c10b3
--- /dev/null
+++ b/java/lang/InstantiationError.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 1995, 2008, 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;
+
+/**
+ * Thrown when an application tries to use the Java <code>new</code>
+ * construct to instantiate an abstract class or an interface.
+ * <p>
+ * Normally, this error is caught by the compiler; this error can
+ * only occur at run time if the definition of a class has
+ * incompatibly changed.
+ *
+ * @author unascribed
+ * @since JDK1.0
+ */
+
+
+public
+class InstantiationError extends IncompatibleClassChangeError {
+ private static final long serialVersionUID = -4885810657349421204L;
+
+ /**
+ * Constructs an <code>InstantiationError</code> with no detail message.
+ */
+ public InstantiationError() {
+ super();
+ }
+
+ /**
+ * Constructs an <code>InstantiationError</code> with the specified
+ * detail message.
+ *
+ * @param s the detail message.
+ */
+ public InstantiationError(String s) {
+ super(s);
+ }
+}
diff --git a/java/lang/InstantiationException.java b/java/lang/InstantiationException.java
new file mode 100644
index 0000000..afeeb17
--- /dev/null
+++ b/java/lang/InstantiationException.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 1995, 2008, 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;
+
+/**
+ * Thrown when an application tries to create an instance of a class
+ * using the {@code newInstance} method in class
+ * {@code Class}, but the specified class object cannot be
+ * instantiated. The instantiation can fail for a variety of
+ * reasons including but not limited to:
+ *
+ * <ul>
+ * <li> the class object represents an abstract class, an interface,
+ * an array class, a primitive type, or {@code void}
+ * <li> the class has no nullary constructor
+ *</ul>
+ *
+ * @author unascribed
+ * @see java.lang.Class#newInstance()
+ * @since JDK1.0
+ */
+public
+class InstantiationException extends ReflectiveOperationException {
+ private static final long serialVersionUID = -8441929162975509110L;
+
+ /**
+ * Constructs an {@code InstantiationException} with no detail message.
+ */
+ public InstantiationException() {
+ super();
+ }
+
+ /**
+ * Constructs an {@code InstantiationException} with the
+ * specified detail message.
+ *
+ * @param s the detail message.
+ */
+ public InstantiationException(String s) {
+ super(s);
+ }
+}
diff --git a/java/lang/Integer.annotated.java b/java/lang/Integer.annotated.java
new file mode 100644
index 0000000..d3f6753
--- /dev/null
+++ b/java/lang/Integer.annotated.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 2013, 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;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Integer extends java.lang.Number implements java.lang.Comparable<java.lang.Integer> {
+
+public Integer(int value) { throw new RuntimeException("Stub!"); }
+
+public Integer(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String toString(int i, int radix) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String toUnsignedString(int i, int radix) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String toHexString(int i) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String toOctalString(int i) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String toBinaryString(int i) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String toString(int i) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String toUnsignedString(int i) { throw new RuntimeException("Stub!"); }
+
+public static int parseInt(@libcore.util.NonNull java.lang.String s, int radix) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public static int parseInt(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public static int parseUnsignedInt(@libcore.util.NonNull java.lang.String s, int radix) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public static int parseUnsignedInt(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Integer valueOf(@libcore.util.NonNull java.lang.String s, int radix) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Integer valueOf(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Integer valueOf(int i) { throw new RuntimeException("Stub!"); }
+
+public byte byteValue() { throw new RuntimeException("Stub!"); }
+
+public short shortValue() { throw new RuntimeException("Stub!"); }
+
+public int intValue() { throw new RuntimeException("Stub!"); }
+
+public long longValue() { throw new RuntimeException("Stub!"); }
+
+public float floatValue() { throw new RuntimeException("Stub!"); }
+
+public double doubleValue() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public static int hashCode(int value) { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Integer getInteger(@libcore.util.NonNull java.lang.String nm) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Integer getInteger(@libcore.util.NonNull java.lang.String nm, int val) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Integer getInteger(@libcore.util.NonNull java.lang.String nm, @libcore.util.Nullable java.lang.Integer val) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Integer decode(@libcore.util.NonNull java.lang.String nm) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public int compareTo(@libcore.util.NonNull java.lang.Integer anotherInteger) { throw new RuntimeException("Stub!"); }
+
+public static int compare(int x, int y) { throw new RuntimeException("Stub!"); }
+
+public static int compareUnsigned(int x, int y) { throw new RuntimeException("Stub!"); }
+
+public static long toUnsignedLong(int x) { throw new RuntimeException("Stub!"); }
+
+public static int divideUnsigned(int dividend, int divisor) { throw new RuntimeException("Stub!"); }
+
+public static int remainderUnsigned(int dividend, int divisor) { throw new RuntimeException("Stub!"); }
+
+public static int highestOneBit(int i) { throw new RuntimeException("Stub!"); }
+
+public static int lowestOneBit(int i) { throw new RuntimeException("Stub!"); }
+
+public static int numberOfLeadingZeros(int i) { throw new RuntimeException("Stub!"); }
+
+public static int numberOfTrailingZeros(int i) { throw new RuntimeException("Stub!"); }
+
+public static int bitCount(int i) { throw new RuntimeException("Stub!"); }
+
+public static int rotateLeft(int i, int distance) { throw new RuntimeException("Stub!"); }
+
+public static int rotateRight(int i, int distance) { throw new RuntimeException("Stub!"); }
+
+public static int reverse(int i) { throw new RuntimeException("Stub!"); }
+
+public static int signum(int i) { throw new RuntimeException("Stub!"); }
+
+public static int reverseBytes(int i) { throw new RuntimeException("Stub!"); }
+
+public static int sum(int a, int b) { throw new RuntimeException("Stub!"); }
+
+public static int max(int a, int b) { throw new RuntimeException("Stub!"); }
+
+public static int min(int a, int b) { throw new RuntimeException("Stub!"); }
+
+public static final int BYTES = 4; // 0x4
+
+public static final int MAX_VALUE = 2147483647; // 0x7fffffff
+
+public static final int MIN_VALUE = -2147483648; // 0x80000000
+
+public static final int SIZE = 32; // 0x20
+
+public static final java.lang.Class<java.lang.Integer> TYPE;
+static { TYPE = null; }
+}
+
diff --git a/java/lang/Integer.java b/java/lang/Integer.java
new file mode 100644
index 0000000..93ae24c
--- /dev/null
+++ b/java/lang/Integer.java
@@ -0,0 +1,1630 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 2013, 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;
+
+import java.lang.annotation.Native;
+
+/**
+ * The {@code Integer} class wraps a value of the primitive type
+ * {@code int} in an object. An object of type {@code Integer}
+ * contains a single field whose type is {@code int}.
+ *
+ * <p>In addition, this class provides several methods for converting
+ * an {@code int} to a {@code String} and a {@code String} to an
+ * {@code int}, as well as other constants and methods useful when
+ * dealing with an {@code int}.
+ *
+ * <p>Implementation note: The implementations of the "bit twiddling"
+ * methods (such as {@link #highestOneBit(int) highestOneBit} and
+ * {@link #numberOfTrailingZeros(int) numberOfTrailingZeros}) are
+ * based on material from Henry S. Warren, Jr.'s <i>Hacker's
+ * Delight</i>, (Addison Wesley, 2002).
+ *
+ * @author Lee Boynton
+ * @author Arthur van Hoff
+ * @author Josh Bloch
+ * @author Joseph D. Darcy
+ * @since JDK1.0
+ */
+public final class Integer extends Number implements Comparable<Integer> {
+ /**
+ * A constant holding the minimum value an {@code int} can
+ * have, -2<sup>31</sup>.
+ */
+ @Native public static final int MIN_VALUE = 0x80000000;
+
+ /**
+ * A constant holding the maximum value an {@code int} can
+ * have, 2<sup>31</sup>-1.
+ */
+ @Native public static final int MAX_VALUE = 0x7fffffff;
+
+ /**
+ * The {@code Class} instance representing the primitive type
+ * {@code int}.
+ *
+ * @since JDK1.1
+ */
+ @SuppressWarnings("unchecked")
+ public static final Class<Integer> TYPE = (Class<Integer>) Class.getPrimitiveClass("int");
+
+ /**
+ * All possible chars for representing a number as a String
+ */
+ final static char[] digits = {
+ '0' , '1' , '2' , '3' , '4' , '5' ,
+ '6' , '7' , '8' , '9' , 'a' , 'b' ,
+ 'c' , 'd' , 'e' , 'f' , 'g' , 'h' ,
+ 'i' , 'j' , 'k' , 'l' , 'm' , 'n' ,
+ 'o' , 'p' , 'q' , 'r' , 's' , 't' ,
+ 'u' , 'v' , 'w' , 'x' , 'y' , 'z'
+ };
+
+ /**
+ * Returns a string representation of the first argument in the
+ * radix specified by the second argument.
+ *
+ * <p>If the radix is smaller than {@code Character.MIN_RADIX}
+ * or larger than {@code Character.MAX_RADIX}, then the radix
+ * {@code 10} is used instead.
+ *
+ * <p>If the first argument is negative, the first element of the
+ * result is the ASCII minus character {@code '-'}
+ * ({@code '\u005Cu002D'}). If the first argument is not
+ * negative, no sign character appears in the result.
+ *
+ * <p>The remaining characters of the result represent the magnitude
+ * of the first argument. If the magnitude is zero, it is
+ * represented by a single zero character {@code '0'}
+ * ({@code '\u005Cu0030'}); otherwise, the first character of
+ * the representation of the magnitude will not be the zero
+ * character. The following ASCII characters are used as digits:
+ *
+ * <blockquote>
+ * {@code 0123456789abcdefghijklmnopqrstuvwxyz}
+ * </blockquote>
+ *
+ * These are {@code '\u005Cu0030'} through
+ * {@code '\u005Cu0039'} and {@code '\u005Cu0061'} through
+ * {@code '\u005Cu007A'}. If {@code radix} is
+ * <var>N</var>, then the first <var>N</var> of these characters
+ * are used as radix-<var>N</var> digits in the order shown. Thus,
+ * the digits for hexadecimal (radix 16) are
+ * {@code 0123456789abcdef}. If uppercase letters are
+ * desired, the {@link java.lang.String#toUpperCase()} method may
+ * be called on the result:
+ *
+ * <blockquote>
+ * {@code Integer.toString(n, 16).toUpperCase()}
+ * </blockquote>
+ *
+ * @param i an integer to be converted to a string.
+ * @param radix the radix to use in the string representation.
+ * @return a string representation of the argument in the specified radix.
+ * @see java.lang.Character#MAX_RADIX
+ * @see java.lang.Character#MIN_RADIX
+ */
+ public static String toString(int i, int radix) {
+ if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
+ radix = 10;
+
+ /* Use the faster version */
+ if (radix == 10) {
+ return toString(i);
+ }
+
+ char buf[] = new char[33];
+ boolean negative = (i < 0);
+ int charPos = 32;
+
+ if (!negative) {
+ i = -i;
+ }
+
+ while (i <= -radix) {
+ buf[charPos--] = digits[-(i % radix)];
+ i = i / radix;
+ }
+ buf[charPos] = digits[-i];
+
+ if (negative) {
+ buf[--charPos] = '-';
+ }
+
+ return new String(buf, charPos, (33 - charPos));
+ }
+
+ /**
+ * Returns a string representation of the first argument as an
+ * unsigned integer value in the radix specified by the second
+ * argument.
+ *
+ * <p>If the radix is smaller than {@code Character.MIN_RADIX}
+ * or larger than {@code Character.MAX_RADIX}, then the radix
+ * {@code 10} is used instead.
+ *
+ * <p>Note that since the first argument is treated as an unsigned
+ * value, no leading sign character is printed.
+ *
+ * <p>If the magnitude is zero, it is represented by a single zero
+ * character {@code '0'} ({@code '\u005Cu0030'}); otherwise,
+ * the first character of the representation of the magnitude will
+ * not be the zero character.
+ *
+ * <p>The behavior of radixes and the characters used as digits
+ * are the same as {@link #toString(int, int) toString}.
+ *
+ * @param i an integer to be converted to an unsigned string.
+ * @param radix the radix to use in the string representation.
+ * @return an unsigned string representation of the argument in the specified radix.
+ * @see #toString(int, int)
+ * @since 1.8
+ */
+ public static String toUnsignedString(int i, int radix) {
+ return Long.toUnsignedString(toUnsignedLong(i), radix);
+ }
+
+ /**
+ * Returns a string representation of the integer argument as an
+ * unsigned integer in base 16.
+ *
+ * <p>The unsigned integer value is the argument plus 2<sup>32</sup>
+ * if the argument is negative; otherwise, it is equal to the
+ * argument. This value is converted to a string of ASCII digits
+ * in hexadecimal (base 16) with no extra leading
+ * {@code 0}s.
+ *
+ * <p>The value of the argument can be recovered from the returned
+ * string {@code s} by calling {@link
+ * Integer#parseUnsignedInt(String, int)
+ * Integer.parseUnsignedInt(s, 16)}.
+ *
+ * <p>If the unsigned magnitude is zero, it is represented by a
+ * single zero character {@code '0'} ({@code '\u005Cu0030'});
+ * otherwise, the first character of the representation of the
+ * unsigned magnitude will not be the zero character. The
+ * following characters are used as hexadecimal digits:
+ *
+ * <blockquote>
+ * {@code 0123456789abcdef}
+ * </blockquote>
+ *
+ * These are the characters {@code '\u005Cu0030'} through
+ * {@code '\u005Cu0039'} and {@code '\u005Cu0061'} through
+ * {@code '\u005Cu0066'}. If uppercase letters are
+ * desired, the {@link java.lang.String#toUpperCase()} method may
+ * be called on the result:
+ *
+ * <blockquote>
+ * {@code Integer.toHexString(n).toUpperCase()}
+ * </blockquote>
+ *
+ * @param i an integer to be converted to a string.
+ * @return the string representation of the unsigned integer value
+ * represented by the argument in hexadecimal (base 16).
+ * @see #parseUnsignedInt(String, int)
+ * @see #toUnsignedString(int, int)
+ * @since JDK1.0.2
+ */
+ public static String toHexString(int i) {
+ return toUnsignedString0(i, 4);
+ }
+
+ /**
+ * Returns a string representation of the integer argument as an
+ * unsigned integer in base 8.
+ *
+ * <p>The unsigned integer value is the argument plus 2<sup>32</sup>
+ * if the argument is negative; otherwise, it is equal to the
+ * argument. This value is converted to a string of ASCII digits
+ * in octal (base 8) with no extra leading {@code 0}s.
+ *
+ * <p>The value of the argument can be recovered from the returned
+ * string {@code s} by calling {@link
+ * Integer#parseUnsignedInt(String, int)
+ * Integer.parseUnsignedInt(s, 8)}.
+ *
+ * <p>If the unsigned magnitude is zero, it is represented by a
+ * single zero character {@code '0'} ({@code '\u005Cu0030'});
+ * otherwise, the first character of the representation of the
+ * unsigned magnitude will not be the zero character. The
+ * following characters are used as octal digits:
+ *
+ * <blockquote>
+ * {@code 01234567}
+ * </blockquote>
+ *
+ * These are the characters {@code '\u005Cu0030'} through
+ * {@code '\u005Cu0037'}.
+ *
+ * @param i an integer to be converted to a string.
+ * @return the string representation of the unsigned integer value
+ * represented by the argument in octal (base 8).
+ * @see #parseUnsignedInt(String, int)
+ * @see #toUnsignedString(int, int)
+ * @since JDK1.0.2
+ */
+ public static String toOctalString(int i) {
+ return toUnsignedString0(i, 3);
+ }
+
+ /**
+ * Returns a string representation of the integer argument as an
+ * unsigned integer in base 2.
+ *
+ * <p>The unsigned integer value is the argument plus 2<sup>32</sup>
+ * if the argument is negative; otherwise it is equal to the
+ * argument. This value is converted to a string of ASCII digits
+ * in binary (base 2) with no extra leading {@code 0}s.
+ *
+ * <p>The value of the argument can be recovered from the returned
+ * string {@code s} by calling {@link
+ * Integer#parseUnsignedInt(String, int)
+ * Integer.parseUnsignedInt(s, 2)}.
+ *
+ * <p>If the unsigned magnitude is zero, it is represented by a
+ * single zero character {@code '0'} ({@code '\u005Cu0030'});
+ * otherwise, the first character of the representation of the
+ * unsigned magnitude will not be the zero character. The
+ * characters {@code '0'} ({@code '\u005Cu0030'}) and {@code
+ * '1'} ({@code '\u005Cu0031'}) are used as binary digits.
+ *
+ * @param i an integer to be converted to a string.
+ * @return the string representation of the unsigned integer value
+ * represented by the argument in binary (base 2).
+ * @see #parseUnsignedInt(String, int)
+ * @see #toUnsignedString(int, int)
+ * @since JDK1.0.2
+ */
+ public static String toBinaryString(int i) {
+ return toUnsignedString0(i, 1);
+ }
+
+ /**
+ * Convert the integer to an unsigned number.
+ */
+ private static String toUnsignedString0(int val, int shift) {
+ // assert shift > 0 && shift <=5 : "Illegal shift value";
+ int mag = Integer.SIZE - Integer.numberOfLeadingZeros(val);
+ int chars = Math.max(((mag + (shift - 1)) / shift), 1);
+ char[] buf = new char[chars];
+
+ formatUnsignedInt(val, shift, buf, 0, chars);
+
+ // Android-changed: Use regular constructor instead of one which takes over "buf".
+ // return new String(buf, true);
+ return new String(buf);
+ }
+
+ /**
+ * Format a long (treated as unsigned) into a character buffer.
+ * @param val the unsigned int to format
+ * @param shift the log2 of the base to format in (4 for hex, 3 for octal, 1 for binary)
+ * @param buf the character buffer to write to
+ * @param offset the offset in the destination buffer to start at
+ * @param len the number of characters to write
+ * @return the lowest character location used
+ */
+ static int formatUnsignedInt(int val, int shift, char[] buf, int offset, int len) {
+ int charPos = len;
+ int radix = 1 << shift;
+ int mask = radix - 1;
+ do {
+ buf[offset + --charPos] = Integer.digits[val & mask];
+ val >>>= shift;
+ } while (val != 0 && charPos > 0);
+
+ return charPos;
+ }
+
+ // BEGIN Android-changed: Cache the toString() result for small values.
+ private static final String[] SMALL_NEG_VALUES = new String[100];
+ private static final String[] SMALL_NONNEG_VALUES = new String[100];
+ // END Android-changed: Cache the toString() result for small values.
+
+ final static char [] DigitTens = {
+ '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
+ '1', '1', '1', '1', '1', '1', '1', '1', '1', '1',
+ '2', '2', '2', '2', '2', '2', '2', '2', '2', '2',
+ '3', '3', '3', '3', '3', '3', '3', '3', '3', '3',
+ '4', '4', '4', '4', '4', '4', '4', '4', '4', '4',
+ '5', '5', '5', '5', '5', '5', '5', '5', '5', '5',
+ '6', '6', '6', '6', '6', '6', '6', '6', '6', '6',
+ '7', '7', '7', '7', '7', '7', '7', '7', '7', '7',
+ '8', '8', '8', '8', '8', '8', '8', '8', '8', '8',
+ '9', '9', '9', '9', '9', '9', '9', '9', '9', '9',
+ } ;
+
+ final static char [] DigitOnes = {
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ } ;
+
+ // I use the "invariant division by multiplication" trick to
+ // accelerate Integer.toString. In particular we want to
+ // avoid division by 10.
+ //
+ // The "trick" has roughly the same performance characteristics
+ // as the "classic" Integer.toString code on a non-JIT VM.
+ // The trick avoids .rem and .div calls but has a longer code
+ // path and is thus dominated by dispatch overhead. In the
+ // JIT case the dispatch overhead doesn't exist and the
+ // "trick" is considerably faster than the classic code.
+ //
+ // TODO-FIXME: convert (x * 52429) into the equiv shift-add
+ // sequence.
+ //
+ // RE: Division by Invariant Integers using Multiplication
+ // T Gralund, P Montgomery
+ // ACM PLDI 1994
+ //
+
+ /**
+ * Returns a {@code String} object representing the
+ * specified integer. The argument is converted to signed decimal
+ * representation and returned as a string, exactly as if the
+ * argument and radix 10 were given as arguments to the {@link
+ * #toString(int, int)} method.
+ *
+ * @param i an integer to be converted.
+ * @return a string representation of the argument in base 10.
+ */
+ public static String toString(int i) {
+ if (i == Integer.MIN_VALUE)
+ return "-2147483648";
+
+ // BEGIN Android-changed: Cache the String for small values.
+ // int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
+ boolean negative = i < 0;
+ boolean small = negative ? i > -100 : i < 100;
+ if (small) {
+ final String[] smallValues = negative ? SMALL_NEG_VALUES : SMALL_NONNEG_VALUES;
+
+ if (negative) {
+ i = -i;
+ if (smallValues[i] == null) {
+ smallValues[i] =
+ i < 10 ? new String(new char[]{'-', DigitOnes[i]})
+ : new String(new char[]{'-', DigitTens[i], DigitOnes[i]});
+ }
+ } else {
+ if (smallValues[i] == null) {
+ smallValues[i] =
+ i < 10 ? new String(new char[]{DigitOnes[i]})
+ : new String(new char[]{DigitTens[i], DigitOnes[i]});
+ }
+ }
+ return smallValues[i];
+ }
+ int size = negative ? stringSize(-i) + 1 : stringSize(i);
+ // END Android-changed: Cache the String for small values.
+ char[] buf = new char[size];
+ getChars(i, size, buf);
+ // Android-changed: Use regular constructor instead of one which takes over "buf".
+ // return new String(buf, true);
+ return new String(buf);
+ }
+
+ /**
+ * Returns a string representation of the argument as an unsigned
+ * decimal value.
+ *
+ * The argument is converted to unsigned decimal representation
+ * and returned as a string exactly as if the argument and radix
+ * 10 were given as arguments to the {@link #toUnsignedString(int,
+ * int)} method.
+ *
+ * @param i an integer to be converted to an unsigned string.
+ * @return an unsigned string representation of the argument.
+ * @see #toUnsignedString(int, int)
+ * @since 1.8
+ */
+ public static String toUnsignedString(int i) {
+ return Long.toString(toUnsignedLong(i));
+ }
+
+ /**
+ * Places characters representing the integer i into the
+ * character array buf. The characters are placed into
+ * the buffer backwards starting with the least significant
+ * digit at the specified index (exclusive), and working
+ * backwards from there.
+ *
+ * Will fail if i == Integer.MIN_VALUE
+ */
+ static void getChars(int i, int index, char[] buf) {
+ int q, r;
+ int charPos = index;
+ char sign = 0;
+
+ if (i < 0) {
+ sign = '-';
+ i = -i;
+ }
+
+ // Generate two digits per iteration
+ while (i >= 65536) {
+ q = i / 100;
+ // really: r = i - (q * 100);
+ r = i - ((q << 6) + (q << 5) + (q << 2));
+ i = q;
+ buf [--charPos] = DigitOnes[r];
+ buf [--charPos] = DigitTens[r];
+ }
+
+ // Fall thru to fast mode for smaller numbers
+ // assert(i <= 65536, i);
+ for (;;) {
+ q = (i * 52429) >>> (16+3);
+ r = i - ((q << 3) + (q << 1)); // r = i-(q*10) ...
+ buf [--charPos] = digits [r];
+ i = q;
+ if (i == 0) break;
+ }
+ if (sign != 0) {
+ buf [--charPos] = sign;
+ }
+ }
+
+ final static int [] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999,
+ 99999999, 999999999, Integer.MAX_VALUE };
+
+ // Requires positive x
+ static int stringSize(int x) {
+ for (int i=0; ; i++)
+ if (x <= sizeTable[i])
+ return i+1;
+ }
+
+ /**
+ * Parses the string argument as a signed integer in the radix
+ * specified by the second argument. The characters in the string
+ * must all be digits of the specified radix (as determined by
+ * whether {@link java.lang.Character#digit(char, int)} returns a
+ * nonnegative value), except that the first character may be an
+ * ASCII minus sign {@code '-'} ({@code '\u005Cu002D'}) to
+ * indicate a negative value or an ASCII plus sign {@code '+'}
+ * ({@code '\u005Cu002B'}) to indicate a positive value. The
+ * resulting integer value is returned.
+ *
+ * <p>An exception of type {@code NumberFormatException} is
+ * thrown if any of the following situations occurs:
+ * <ul>
+ * <li>The first argument is {@code null} or is a string of
+ * length zero.
+ *
+ * <li>The radix is either smaller than
+ * {@link java.lang.Character#MIN_RADIX} or
+ * larger than {@link java.lang.Character#MAX_RADIX}.
+ *
+ * <li>Any character of the string is not a digit of the specified
+ * radix, except that the first character may be a minus sign
+ * {@code '-'} ({@code '\u005Cu002D'}) or plus sign
+ * {@code '+'} ({@code '\u005Cu002B'}) provided that the
+ * string is longer than length 1.
+ *
+ * <li>The value represented by the string is not a value of type
+ * {@code int}.
+ * </ul>
+ *
+ * <p>Examples:
+ * <blockquote><pre>
+ * parseInt("0", 10) returns 0
+ * parseInt("473", 10) returns 473
+ * parseInt("+42", 10) returns 42
+ * parseInt("-0", 10) returns 0
+ * parseInt("-FF", 16) returns -255
+ * parseInt("1100110", 2) returns 102
+ * parseInt("2147483647", 10) returns 2147483647
+ * parseInt("-2147483648", 10) returns -2147483648
+ * parseInt("2147483648", 10) throws a NumberFormatException
+ * parseInt("99", 8) throws a NumberFormatException
+ * parseInt("Kona", 10) throws a NumberFormatException
+ * parseInt("Kona", 27) returns 411787
+ * </pre></blockquote>
+ *
+ * @param s the {@code String} containing the integer
+ * representation to be parsed
+ * @param radix the radix to be used while parsing {@code s}.
+ * @return the integer represented by the string argument in the
+ * specified radix.
+ * @exception NumberFormatException if the {@code String}
+ * does not contain a parsable {@code int}.
+ */
+ public static int parseInt(String s, int radix)
+ throws NumberFormatException
+ {
+ /*
+ * WARNING: This method may be invoked early during VM initialization
+ * before IntegerCache is initialized. Care must be taken to not use
+ * the valueOf method.
+ */
+
+ if (s == null) {
+ // Android-changed: Improve exception message for parseInt.
+ throw new NumberFormatException("s == null");
+ }
+
+ if (radix < Character.MIN_RADIX) {
+ throw new NumberFormatException("radix " + radix +
+ " less than Character.MIN_RADIX");
+ }
+
+ if (radix > Character.MAX_RADIX) {
+ throw new NumberFormatException("radix " + radix +
+ " greater than Character.MAX_RADIX");
+ }
+
+ int result = 0;
+ boolean negative = false;
+ int i = 0, len = s.length();
+ int limit = -Integer.MAX_VALUE;
+ int multmin;
+ int digit;
+
+ if (len > 0) {
+ char firstChar = s.charAt(0);
+ if (firstChar < '0') { // Possible leading "+" or "-"
+ if (firstChar == '-') {
+ negative = true;
+ limit = Integer.MIN_VALUE;
+ } else if (firstChar != '+')
+ throw NumberFormatException.forInputString(s);
+
+ if (len == 1) // Cannot have lone "+" or "-"
+ throw NumberFormatException.forInputString(s);
+ i++;
+ }
+ multmin = limit / radix;
+ while (i < len) {
+ // Accumulating negatively avoids surprises near MAX_VALUE
+ digit = Character.digit(s.charAt(i++),radix);
+ if (digit < 0) {
+ throw NumberFormatException.forInputString(s);
+ }
+ if (result < multmin) {
+ throw NumberFormatException.forInputString(s);
+ }
+ result *= radix;
+ if (result < limit + digit) {
+ throw NumberFormatException.forInputString(s);
+ }
+ result -= digit;
+ }
+ } else {
+ throw NumberFormatException.forInputString(s);
+ }
+ return negative ? result : -result;
+ }
+
+ /**
+ * Parses the string argument as a signed decimal integer. The
+ * characters in the string must all be decimal digits, except
+ * that the first character may be an ASCII minus sign {@code '-'}
+ * ({@code '\u005Cu002D'}) to indicate a negative value or an
+ * ASCII plus sign {@code '+'} ({@code '\u005Cu002B'}) to
+ * indicate a positive value. The resulting integer value is
+ * returned, exactly as if the argument and the radix 10 were
+ * given as arguments to the {@link #parseInt(java.lang.String,
+ * int)} method.
+ *
+ * @param s a {@code String} containing the {@code int}
+ * representation to be parsed
+ * @return the integer value represented by the argument in decimal.
+ * @exception NumberFormatException if the string does not contain a
+ * parsable integer.
+ */
+ public static int parseInt(String s) throws NumberFormatException {
+ return parseInt(s,10);
+ }
+
+ /**
+ * Parses the string argument as an unsigned integer in the radix
+ * specified by the second argument. An unsigned integer maps the
+ * values usually associated with negative numbers to positive
+ * numbers larger than {@code MAX_VALUE}.
+ *
+ * The characters in the string must all be digits of the
+ * specified radix (as determined by whether {@link
+ * java.lang.Character#digit(char, int)} returns a nonnegative
+ * value), except that the first character may be an ASCII plus
+ * sign {@code '+'} ({@code '\u005Cu002B'}). The resulting
+ * integer value is returned.
+ *
+ * <p>An exception of type {@code NumberFormatException} is
+ * thrown if any of the following situations occurs:
+ * <ul>
+ * <li>The first argument is {@code null} or is a string of
+ * length zero.
+ *
+ * <li>The radix is either smaller than
+ * {@link java.lang.Character#MIN_RADIX} or
+ * larger than {@link java.lang.Character#MAX_RADIX}.
+ *
+ * <li>Any character of the string is not a digit of the specified
+ * radix, except that the first character may be a plus sign
+ * {@code '+'} ({@code '\u005Cu002B'}) provided that the
+ * string is longer than length 1.
+ *
+ * <li>The value represented by the string is larger than the
+ * largest unsigned {@code int}, 2<sup>32</sup>-1.
+ *
+ * </ul>
+ *
+ *
+ * @param s the {@code String} containing the unsigned integer
+ * representation to be parsed
+ * @param radix the radix to be used while parsing {@code s}.
+ * @return the integer represented by the string argument in the
+ * specified radix.
+ * @throws NumberFormatException if the {@code String}
+ * does not contain a parsable {@code int}.
+ * @since 1.8
+ */
+ public static int parseUnsignedInt(String s, int radix)
+ throws NumberFormatException {
+ if (s == null) {
+ throw new NumberFormatException("null");
+ }
+
+ int len = s.length();
+ if (len > 0) {
+ char firstChar = s.charAt(0);
+ if (firstChar == '-') {
+ throw new
+ NumberFormatException(String.format("Illegal leading minus sign " +
+ "on unsigned string %s.", s));
+ } else {
+ if (len <= 5 || // Integer.MAX_VALUE in Character.MAX_RADIX is 6 digits
+ (radix == 10 && len <= 9) ) { // Integer.MAX_VALUE in base 10 is 10 digits
+ return parseInt(s, radix);
+ } else {
+ long ell = Long.parseLong(s, radix);
+ if ((ell & 0xffff_ffff_0000_0000L) == 0) {
+ return (int) ell;
+ } else {
+ throw new
+ NumberFormatException(String.format("String value %s exceeds " +
+ "range of unsigned int.", s));
+ }
+ }
+ }
+ } else {
+ throw NumberFormatException.forInputString(s);
+ }
+ }
+
+ /**
+ * Parses the string argument as an unsigned decimal integer. The
+ * characters in the string must all be decimal digits, except
+ * that the first character may be an an ASCII plus sign {@code
+ * '+'} ({@code '\u005Cu002B'}). The resulting integer value
+ * is returned, exactly as if the argument and the radix 10 were
+ * given as arguments to the {@link
+ * #parseUnsignedInt(java.lang.String, int)} method.
+ *
+ * @param s a {@code String} containing the unsigned {@code int}
+ * representation to be parsed
+ * @return the unsigned integer value represented by the argument in decimal.
+ * @throws NumberFormatException if the string does not contain a
+ * parsable unsigned integer.
+ * @since 1.8
+ */
+ public static int parseUnsignedInt(String s) throws NumberFormatException {
+ return parseUnsignedInt(s, 10);
+ }
+
+ /**
+ * Returns an {@code Integer} object holding the value
+ * extracted from the specified {@code String} when parsed
+ * with the radix given by the second argument. The first argument
+ * is interpreted as representing a signed integer in the radix
+ * specified by the second argument, exactly as if the arguments
+ * were given to the {@link #parseInt(java.lang.String, int)}
+ * method. The result is an {@code Integer} object that
+ * represents the integer value specified by the string.
+ *
+ * <p>In other words, this method returns an {@code Integer}
+ * object equal to the value of:
+ *
+ * <blockquote>
+ * {@code new Integer(Integer.parseInt(s, radix))}
+ * </blockquote>
+ *
+ * @param s the string to be parsed.
+ * @param radix the radix to be used in interpreting {@code s}
+ * @return an {@code Integer} object holding the value
+ * represented by the string argument in the specified
+ * radix.
+ * @exception NumberFormatException if the {@code String}
+ * does not contain a parsable {@code int}.
+ */
+ public static Integer valueOf(String s, int radix) throws NumberFormatException {
+ return Integer.valueOf(parseInt(s,radix));
+ }
+
+ /**
+ * Returns an {@code Integer} object holding the
+ * value of the specified {@code String}. The argument is
+ * interpreted as representing a signed decimal integer, exactly
+ * as if the argument were given to the {@link
+ * #parseInt(java.lang.String)} method. The result is an
+ * {@code Integer} object that represents the integer value
+ * specified by the string.
+ *
+ * <p>In other words, this method returns an {@code Integer}
+ * object equal to the value of:
+ *
+ * <blockquote>
+ * {@code new Integer(Integer.parseInt(s))}
+ * </blockquote>
+ *
+ * @param s the string to be parsed.
+ * @return an {@code Integer} object holding the value
+ * represented by the string argument.
+ * @exception NumberFormatException if the string cannot be parsed
+ * as an integer.
+ */
+ public static Integer valueOf(String s) throws NumberFormatException {
+ return Integer.valueOf(parseInt(s, 10));
+ }
+
+ /**
+ * Cache to support the object identity semantics of autoboxing for values between
+ * -128 and 127 (inclusive) as required by JLS.
+ *
+ * The cache is initialized on first usage. The size of the cache
+ * may be controlled by the {@code -XX:AutoBoxCacheMax=<size>} option.
+ * During VM initialization, java.lang.Integer.IntegerCache.high property
+ * may be set and saved in the private system properties in the
+ * sun.misc.VM class.
+ */
+
+ private static class IntegerCache {
+ static final int low = -128;
+ static final int high;
+ static final Integer cache[];
+
+ static {
+ // high value may be configured by property
+ int h = 127;
+ String integerCacheHighPropValue =
+ sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
+ if (integerCacheHighPropValue != null) {
+ try {
+ int i = parseInt(integerCacheHighPropValue);
+ i = Math.max(i, 127);
+ // Maximum array size is Integer.MAX_VALUE
+ h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
+ } catch( NumberFormatException nfe) {
+ // If the property cannot be parsed into an int, ignore it.
+ }
+ }
+ high = h;
+
+ cache = new Integer[(high - low) + 1];
+ int j = low;
+ for(int k = 0; k < cache.length; k++)
+ cache[k] = new Integer(j++);
+
+ // range [-128, 127] must be interned (JLS7 5.1.7)
+ assert IntegerCache.high >= 127;
+ }
+
+ private IntegerCache() {}
+ }
+
+ /**
+ * Returns an {@code Integer} instance representing the specified
+ * {@code int} value. If a new {@code Integer} instance is not
+ * required, this method should generally be used in preference to
+ * the constructor {@link #Integer(int)}, as this method is likely
+ * to yield significantly better space and time performance by
+ * caching frequently requested values.
+ *
+ * This method will always cache values in the range -128 to 127,
+ * inclusive, and may cache other values outside of this range.
+ *
+ * @param i an {@code int} value.
+ * @return an {@code Integer} instance representing {@code i}.
+ * @since 1.5
+ */
+ public static Integer valueOf(int i) {
+ if (i >= IntegerCache.low && i <= IntegerCache.high)
+ return IntegerCache.cache[i + (-IntegerCache.low)];
+ return new Integer(i);
+ }
+
+ /**
+ * The value of the {@code Integer}.
+ *
+ * @serial
+ */
+ private final int value;
+
+ /**
+ * Constructs a newly allocated {@code Integer} object that
+ * represents the specified {@code int} value.
+ *
+ * @param value the value to be represented by the
+ * {@code Integer} object.
+ */
+ public Integer(int value) {
+ this.value = value;
+ }
+
+ /**
+ * Constructs a newly allocated {@code Integer} object that
+ * represents the {@code int} value indicated by the
+ * {@code String} parameter. The string is converted to an
+ * {@code int} value in exactly the manner used by the
+ * {@code parseInt} method for radix 10.
+ *
+ * @param s the {@code String} to be converted to an
+ * {@code Integer}.
+ * @exception NumberFormatException if the {@code String} does not
+ * contain a parsable integer.
+ * @see java.lang.Integer#parseInt(java.lang.String, int)
+ */
+ public Integer(String s) throws NumberFormatException {
+ this.value = parseInt(s, 10);
+ }
+
+ /**
+ * Returns the value of this {@code Integer} as a {@code byte}
+ * after a narrowing primitive conversion.
+ * @jls 5.1.3 Narrowing Primitive Conversions
+ */
+ public byte byteValue() {
+ return (byte)value;
+ }
+
+ /**
+ * Returns the value of this {@code Integer} as a {@code short}
+ * after a narrowing primitive conversion.
+ * @jls 5.1.3 Narrowing Primitive Conversions
+ */
+ public short shortValue() {
+ return (short)value;
+ }
+
+ /**
+ * Returns the value of this {@code Integer} as an
+ * {@code int}.
+ */
+ public int intValue() {
+ return value;
+ }
+
+ /**
+ * Returns the value of this {@code Integer} as a {@code long}
+ * after a widening primitive conversion.
+ * @jls 5.1.2 Widening Primitive Conversions
+ * @see Integer#toUnsignedLong(int)
+ */
+ public long longValue() {
+ return (long)value;
+ }
+
+ /**
+ * Returns the value of this {@code Integer} as a {@code float}
+ * after a widening primitive conversion.
+ * @jls 5.1.2 Widening Primitive Conversions
+ */
+ public float floatValue() {
+ return (float)value;
+ }
+
+ /**
+ * Returns the value of this {@code Integer} as a {@code double}
+ * after a widening primitive conversion.
+ * @jls 5.1.2 Widening Primitive Conversions
+ */
+ public double doubleValue() {
+ return (double)value;
+ }
+
+ /**
+ * Returns a {@code String} object representing this
+ * {@code Integer}'s value. The value is converted to signed
+ * decimal representation and returned as a string, exactly as if
+ * the integer value were given as an argument to the {@link
+ * java.lang.Integer#toString(int)} method.
+ *
+ * @return a string representation of the value of this object in
+ * base 10.
+ */
+ public String toString() {
+ return toString(value);
+ }
+
+ /**
+ * Returns a hash code for this {@code Integer}.
+ *
+ * @return a hash code value for this object, equal to the
+ * primitive {@code int} value represented by this
+ * {@code Integer} object.
+ */
+ @Override
+ public int hashCode() {
+ return Integer.hashCode(value);
+ }
+
+ /**
+ * Returns a hash code for a {@code int} value; compatible with
+ * {@code Integer.hashCode()}.
+ *
+ * @param value the value to hash
+ * @since 1.8
+ *
+ * @return a hash code value for a {@code int} value.
+ */
+ public static int hashCode(int value) {
+ return value;
+ }
+
+ /**
+ * Compares this object to the specified object. The result is
+ * {@code true} if and only if the argument is not
+ * {@code null} and is an {@code Integer} object that
+ * contains the same {@code int} value as this object.
+ *
+ * @param obj the object to compare with.
+ * @return {@code true} if the objects are the same;
+ * {@code false} otherwise.
+ */
+ public boolean equals(Object obj) {
+ if (obj instanceof Integer) {
+ return value == ((Integer)obj).intValue();
+ }
+ return false;
+ }
+
+ /**
+ * Determines the integer value of the system property with the
+ * specified name.
+ *
+ * <p>The first argument is treated as the name of a system
+ * property. System properties are accessible through the {@link
+ * java.lang.System#getProperty(java.lang.String)} method. The
+ * string value of this property is then interpreted as an integer
+ * value using the grammar supported by {@link Integer#decode decode} and
+ * an {@code Integer} object representing this value is returned.
+ *
+ * <p>If there is no property with the specified name, if the
+ * specified name is empty or {@code null}, or if the property
+ * does not have the correct numeric format, then {@code null} is
+ * returned.
+ *
+ * <p>In other words, this method returns an {@code Integer}
+ * object equal to the value of:
+ *
+ * <blockquote>
+ * {@code getInteger(nm, null)}
+ * </blockquote>
+ *
+ * @param nm property name.
+ * @return the {@code Integer} value of the property.
+ * @throws SecurityException for the same reasons as
+ * {@link System#getProperty(String) System.getProperty}
+ * @see java.lang.System#getProperty(java.lang.String)
+ * @see java.lang.System#getProperty(java.lang.String, java.lang.String)
+ */
+ public static Integer getInteger(String nm) {
+ return getInteger(nm, null);
+ }
+
+ /**
+ * Determines the integer value of the system property with the
+ * specified name.
+ *
+ * <p>The first argument is treated as the name of a system
+ * property. System properties are accessible through the {@link
+ * java.lang.System#getProperty(java.lang.String)} method. The
+ * string value of this property is then interpreted as an integer
+ * value using the grammar supported by {@link Integer#decode decode} and
+ * an {@code Integer} object representing this value is returned.
+ *
+ * <p>The second argument is the default value. An {@code Integer} object
+ * that represents the value of the second argument is returned if there
+ * is no property of the specified name, if the property does not have
+ * the correct numeric format, or if the specified name is empty or
+ * {@code null}.
+ *
+ * <p>In other words, this method returns an {@code Integer} object
+ * equal to the value of:
+ *
+ * <blockquote>
+ * {@code getInteger(nm, new Integer(val))}
+ * </blockquote>
+ *
+ * but in practice it may be implemented in a manner such as:
+ *
+ * <blockquote><pre>
+ * Integer result = getInteger(nm, null);
+ * return (result == null) ? new Integer(val) : result;
+ * </pre></blockquote>
+ *
+ * to avoid the unnecessary allocation of an {@code Integer}
+ * object when the default value is not needed.
+ *
+ * @param nm property name.
+ * @param val default value.
+ * @return the {@code Integer} value of the property.
+ * @throws SecurityException for the same reasons as
+ * {@link System#getProperty(String) System.getProperty}
+ * @see java.lang.System#getProperty(java.lang.String)
+ * @see java.lang.System#getProperty(java.lang.String, java.lang.String)
+ */
+ public static Integer getInteger(String nm, int val) {
+ Integer result = getInteger(nm, null);
+ return (result == null) ? Integer.valueOf(val) : result;
+ }
+
+ /**
+ * Returns the integer value of the system property with the
+ * specified name. The first argument is treated as the name of a
+ * system property. System properties are accessible through the
+ * {@link java.lang.System#getProperty(java.lang.String)} method.
+ * The string value of this property is then interpreted as an
+ * integer value, as per the {@link Integer#decode decode} method,
+ * and an {@code Integer} object representing this value is
+ * returned; in summary:
+ *
+ * <ul><li>If the property value begins with the two ASCII characters
+ * {@code 0x} or the ASCII character {@code #}, not
+ * followed by a minus sign, then the rest of it is parsed as a
+ * hexadecimal integer exactly as by the method
+ * {@link #valueOf(java.lang.String, int)} with radix 16.
+ * <li>If the property value begins with the ASCII character
+ * {@code 0} followed by another character, it is parsed as an
+ * octal integer exactly as by the method
+ * {@link #valueOf(java.lang.String, int)} with radix 8.
+ * <li>Otherwise, the property value is parsed as a decimal integer
+ * exactly as by the method {@link #valueOf(java.lang.String, int)}
+ * with radix 10.
+ * </ul>
+ *
+ * <p>The second argument is the default value. The default value is
+ * returned if there is no property of the specified name, if the
+ * property does not have the correct numeric format, or if the
+ * specified name is empty or {@code null}.
+ *
+ * @param nm property name.
+ * @param val default value.
+ * @return the {@code Integer} value of the property.
+ * @throws SecurityException for the same reasons as
+ * {@link System#getProperty(String) System.getProperty}
+ * @see System#getProperty(java.lang.String)
+ * @see System#getProperty(java.lang.String, java.lang.String)
+ */
+ public static Integer getInteger(String nm, Integer val) {
+ String v = null;
+ try {
+ v = System.getProperty(nm);
+ } catch (IllegalArgumentException | NullPointerException e) {
+ }
+ if (v != null) {
+ try {
+ return Integer.decode(v);
+ } catch (NumberFormatException e) {
+ }
+ }
+ return val;
+ }
+
+ /**
+ * Decodes a {@code String} into an {@code Integer}.
+ * Accepts decimal, hexadecimal, and octal numbers given
+ * by the following grammar:
+ *
+ * <blockquote>
+ * <dl>
+ * <dt><i>DecodableString:</i>
+ * <dd><i>Sign<sub>opt</sub> DecimalNumeral</i>
+ * <dd><i>Sign<sub>opt</sub></i> {@code 0x} <i>HexDigits</i>
+ * <dd><i>Sign<sub>opt</sub></i> {@code 0X} <i>HexDigits</i>
+ * <dd><i>Sign<sub>opt</sub></i> {@code #} <i>HexDigits</i>
+ * <dd><i>Sign<sub>opt</sub></i> {@code 0} <i>OctalDigits</i>
+ *
+ * <dt><i>Sign:</i>
+ * <dd>{@code -}
+ * <dd>{@code +}
+ * </dl>
+ * </blockquote>
+ *
+ * <i>DecimalNumeral</i>, <i>HexDigits</i>, and <i>OctalDigits</i>
+ * are as defined in section 3.10.1 of
+ * <cite>The Java™ Language Specification</cite>,
+ * except that underscores are not accepted between digits.
+ *
+ * <p>The sequence of characters following an optional
+ * sign and/or radix specifier ("{@code 0x}", "{@code 0X}",
+ * "{@code #}", or leading zero) is parsed as by the {@code
+ * Integer.parseInt} method with the indicated radix (10, 16, or
+ * 8). This sequence of characters must represent a positive
+ * value or a {@link NumberFormatException} will be thrown. The
+ * result is negated if first character of the specified {@code
+ * String} is the minus sign. No whitespace characters are
+ * permitted in the {@code String}.
+ *
+ * @param nm the {@code String} to decode.
+ * @return an {@code Integer} object holding the {@code int}
+ * value represented by {@code nm}
+ * @exception NumberFormatException if the {@code String} does not
+ * contain a parsable integer.
+ * @see java.lang.Integer#parseInt(java.lang.String, int)
+ */
+ public static Integer decode(String nm) throws NumberFormatException {
+ int radix = 10;
+ int index = 0;
+ boolean negative = false;
+ Integer result;
+
+ if (nm.length() == 0)
+ throw new NumberFormatException("Zero length string");
+ char firstChar = nm.charAt(0);
+ // Handle sign, if present
+ if (firstChar == '-') {
+ negative = true;
+ index++;
+ } else if (firstChar == '+')
+ index++;
+
+ // Handle radix specifier, if present
+ if (nm.startsWith("0x", index) || nm.startsWith("0X", index)) {
+ index += 2;
+ radix = 16;
+ }
+ else if (nm.startsWith("#", index)) {
+ index ++;
+ radix = 16;
+ }
+ else if (nm.startsWith("0", index) && nm.length() > 1 + index) {
+ index ++;
+ radix = 8;
+ }
+
+ if (nm.startsWith("-", index) || nm.startsWith("+", index))
+ throw new NumberFormatException("Sign character in wrong position");
+
+ try {
+ result = Integer.valueOf(nm.substring(index), radix);
+ result = negative ? Integer.valueOf(-result.intValue()) : result;
+ } catch (NumberFormatException e) {
+ // If number is Integer.MIN_VALUE, we'll end up here. The next line
+ // handles this case, and causes any genuine format error to be
+ // rethrown.
+ String constant = negative ? ("-" + nm.substring(index))
+ : nm.substring(index);
+ result = Integer.valueOf(constant, radix);
+ }
+ return result;
+ }
+
+ /**
+ * Compares two {@code Integer} objects numerically.
+ *
+ * @param anotherInteger the {@code Integer} to be compared.
+ * @return the value {@code 0} if this {@code Integer} is
+ * equal to the argument {@code Integer}; a value less than
+ * {@code 0} if this {@code Integer} is numerically less
+ * than the argument {@code Integer}; and a value greater
+ * than {@code 0} if this {@code Integer} is numerically
+ * greater than the argument {@code Integer} (signed
+ * comparison).
+ * @since 1.2
+ */
+ public int compareTo(Integer anotherInteger) {
+ return compare(this.value, anotherInteger.value);
+ }
+
+ /**
+ * Compares two {@code int} values numerically.
+ * The value returned is identical to what would be returned by:
+ * <pre>
+ * Integer.valueOf(x).compareTo(Integer.valueOf(y))
+ * </pre>
+ *
+ * @param x the first {@code int} to compare
+ * @param y the second {@code int} to compare
+ * @return the value {@code 0} if {@code x == y};
+ * a value less than {@code 0} if {@code x < y}; and
+ * a value greater than {@code 0} if {@code x > y}
+ * @since 1.7
+ */
+ public static int compare(int x, int y) {
+ return (x < y) ? -1 : ((x == y) ? 0 : 1);
+ }
+
+ /**
+ * Compares two {@code int} values numerically treating the values
+ * as unsigned.
+ *
+ * @param x the first {@code int} to compare
+ * @param y the second {@code int} to compare
+ * @return the value {@code 0} if {@code x == y}; a value less
+ * than {@code 0} if {@code x < y} as unsigned values; and
+ * a value greater than {@code 0} if {@code x > y} as
+ * unsigned values
+ * @since 1.8
+ */
+ public static int compareUnsigned(int x, int y) {
+ return compare(x + MIN_VALUE, y + MIN_VALUE);
+ }
+
+ /**
+ * Converts the argument to a {@code long} by an unsigned
+ * conversion. In an unsigned conversion to a {@code long}, the
+ * high-order 32 bits of the {@code long} are zero and the
+ * low-order 32 bits are equal to the bits of the integer
+ * argument.
+ *
+ * Consequently, zero and positive {@code int} values are mapped
+ * to a numerically equal {@code long} value and negative {@code
+ * int} values are mapped to a {@code long} value equal to the
+ * input plus 2<sup>32</sup>.
+ *
+ * @param x the value to convert to an unsigned {@code long}
+ * @return the argument converted to {@code long} by an unsigned
+ * conversion
+ * @since 1.8
+ */
+ public static long toUnsignedLong(int x) {
+ return ((long) x) & 0xffffffffL;
+ }
+
+ /**
+ * Returns the unsigned quotient of dividing the first argument by
+ * the second where each argument and the result is interpreted as
+ * an unsigned value.
+ *
+ * <p>Note that in two's complement arithmetic, the three other
+ * basic arithmetic operations of add, subtract, and multiply are
+ * bit-wise identical if the two operands are regarded as both
+ * being signed or both being unsigned. Therefore separate {@code
+ * addUnsigned}, etc. methods are not provided.
+ *
+ * @param dividend the value to be divided
+ * @param divisor the value doing the dividing
+ * @return the unsigned quotient of the first argument divided by
+ * the second argument
+ * @see #remainderUnsigned
+ * @since 1.8
+ */
+ public static int divideUnsigned(int dividend, int divisor) {
+ // In lieu of tricky code, for now just use long arithmetic.
+ return (int)(toUnsignedLong(dividend) / toUnsignedLong(divisor));
+ }
+
+ /**
+ * Returns the unsigned remainder from dividing the first argument
+ * by the second where each argument and the result is interpreted
+ * as an unsigned value.
+ *
+ * @param dividend the value to be divided
+ * @param divisor the value doing the dividing
+ * @return the unsigned remainder of the first argument divided by
+ * the second argument
+ * @see #divideUnsigned
+ * @since 1.8
+ */
+ public static int remainderUnsigned(int dividend, int divisor) {
+ // In lieu of tricky code, for now just use long arithmetic.
+ return (int)(toUnsignedLong(dividend) % toUnsignedLong(divisor));
+ }
+
+
+ // Bit twiddling
+
+ /**
+ * The number of bits used to represent an {@code int} value in two's
+ * complement binary form.
+ *
+ * @since 1.5
+ */
+ @Native public static final int SIZE = 32;
+
+ /**
+ * The number of bytes used to represent a {@code int} value in two's
+ * complement binary form.
+ *
+ * @since 1.8
+ */
+ public static final int BYTES = SIZE / Byte.SIZE;
+
+ /**
+ * Returns an {@code int} value with at most a single one-bit, in the
+ * position of the highest-order ("leftmost") one-bit in the specified
+ * {@code int} value. Returns zero if the specified value has no
+ * one-bits in its two's complement binary representation, that is, if it
+ * is equal to zero.
+ *
+ * @param i the value whose highest one bit is to be computed
+ * @return an {@code int} value with a single one-bit, in the position
+ * of the highest-order one-bit in the specified value, or zero if
+ * the specified value is itself equal to zero.
+ * @since 1.5
+ */
+ public static int highestOneBit(int i) {
+ // HD, Figure 3-1
+ i |= (i >> 1);
+ i |= (i >> 2);
+ i |= (i >> 4);
+ i |= (i >> 8);
+ i |= (i >> 16);
+ return i - (i >>> 1);
+ }
+
+ /**
+ * Returns an {@code int} value with at most a single one-bit, in the
+ * position of the lowest-order ("rightmost") one-bit in the specified
+ * {@code int} value. Returns zero if the specified value has no
+ * one-bits in its two's complement binary representation, that is, if it
+ * is equal to zero.
+ *
+ * @param i the value whose lowest one bit is to be computed
+ * @return an {@code int} value with a single one-bit, in the position
+ * of the lowest-order one-bit in the specified value, or zero if
+ * the specified value is itself equal to zero.
+ * @since 1.5
+ */
+ public static int lowestOneBit(int i) {
+ // HD, Section 2-1
+ return i & -i;
+ }
+
+ /**
+ * Returns the number of zero bits preceding the highest-order
+ * ("leftmost") one-bit in the two's complement binary representation
+ * of the specified {@code int} value. Returns 32 if the
+ * specified value has no one-bits in its two's complement representation,
+ * in other words if it is equal to zero.
+ *
+ * <p>Note that this method is closely related to the logarithm base 2.
+ * For all positive {@code int} values x:
+ * <ul>
+ * <li>floor(log<sub>2</sub>(x)) = {@code 31 - numberOfLeadingZeros(x)}
+ * <li>ceil(log<sub>2</sub>(x)) = {@code 32 - numberOfLeadingZeros(x - 1)}
+ * </ul>
+ *
+ * @param i the value whose number of leading zeros is to be computed
+ * @return the number of zero bits preceding the highest-order
+ * ("leftmost") one-bit in the two's complement binary representation
+ * of the specified {@code int} value, or 32 if the value
+ * is equal to zero.
+ * @since 1.5
+ */
+ public static int numberOfLeadingZeros(int i) {
+ // HD, Figure 5-6
+ if (i == 0)
+ return 32;
+ int n = 1;
+ if (i >>> 16 == 0) { n += 16; i <<= 16; }
+ if (i >>> 24 == 0) { n += 8; i <<= 8; }
+ if (i >>> 28 == 0) { n += 4; i <<= 4; }
+ if (i >>> 30 == 0) { n += 2; i <<= 2; }
+ n -= i >>> 31;
+ return n;
+ }
+
+ /**
+ * Returns the number of zero bits following the lowest-order ("rightmost")
+ * one-bit in the two's complement binary representation of the specified
+ * {@code int} value. Returns 32 if the specified value has no
+ * one-bits in its two's complement representation, in other words if it is
+ * equal to zero.
+ *
+ * @param i the value whose number of trailing zeros is to be computed
+ * @return the number of zero bits following the lowest-order ("rightmost")
+ * one-bit in the two's complement binary representation of the
+ * specified {@code int} value, or 32 if the value is equal
+ * to zero.
+ * @since 1.5
+ */
+ public static int numberOfTrailingZeros(int i) {
+ // HD, Figure 5-14
+ int y;
+ if (i == 0) return 32;
+ int n = 31;
+ y = i <<16; if (y != 0) { n = n -16; i = y; }
+ y = i << 8; if (y != 0) { n = n - 8; i = y; }
+ y = i << 4; if (y != 0) { n = n - 4; i = y; }
+ y = i << 2; if (y != 0) { n = n - 2; i = y; }
+ return n - ((i << 1) >>> 31);
+ }
+
+ /**
+ * Returns the number of one-bits in the two's complement binary
+ * representation of the specified {@code int} value. This function is
+ * sometimes referred to as the <i>population count</i>.
+ *
+ * @param i the value whose bits are to be counted
+ * @return the number of one-bits in the two's complement binary
+ * representation of the specified {@code int} value.
+ * @since 1.5
+ */
+ public static int bitCount(int i) {
+ // HD, Figure 5-2
+ i = i - ((i >>> 1) & 0x55555555);
+ i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
+ i = (i + (i >>> 4)) & 0x0f0f0f0f;
+ i = i + (i >>> 8);
+ i = i + (i >>> 16);
+ return i & 0x3f;
+ }
+
+ /**
+ * Returns the value obtained by rotating the two's complement binary
+ * representation of the specified {@code int} value left by the
+ * specified number of bits. (Bits shifted out of the left hand, or
+ * high-order, side reenter on the right, or low-order.)
+ *
+ * <p>Note that left rotation with a negative distance is equivalent to
+ * right rotation: {@code rotateLeft(val, -distance) == rotateRight(val,
+ * distance)}. Note also that rotation by any multiple of 32 is a
+ * no-op, so all but the last five bits of the rotation distance can be
+ * ignored, even if the distance is negative: {@code rotateLeft(val,
+ * distance) == rotateLeft(val, distance & 0x1F)}.
+ *
+ * @param i the value whose bits are to be rotated left
+ * @param distance the number of bit positions to rotate left
+ * @return the value obtained by rotating the two's complement binary
+ * representation of the specified {@code int} value left by the
+ * specified number of bits.
+ * @since 1.5
+ */
+ public static int rotateLeft(int i, int distance) {
+ return (i << distance) | (i >>> -distance);
+ }
+
+ /**
+ * Returns the value obtained by rotating the two's complement binary
+ * representation of the specified {@code int} value right by the
+ * specified number of bits. (Bits shifted out of the right hand, or
+ * low-order, side reenter on the left, or high-order.)
+ *
+ * <p>Note that right rotation with a negative distance is equivalent to
+ * left rotation: {@code rotateRight(val, -distance) == rotateLeft(val,
+ * distance)}. Note also that rotation by any multiple of 32 is a
+ * no-op, so all but the last five bits of the rotation distance can be
+ * ignored, even if the distance is negative: {@code rotateRight(val,
+ * distance) == rotateRight(val, distance & 0x1F)}.
+ *
+ * @param i the value whose bits are to be rotated right
+ * @param distance the number of bit positions to rotate right
+ * @return the value obtained by rotating the two's complement binary
+ * representation of the specified {@code int} value right by the
+ * specified number of bits.
+ * @since 1.5
+ */
+ public static int rotateRight(int i, int distance) {
+ return (i >>> distance) | (i << -distance);
+ }
+
+ /**
+ * Returns the value obtained by reversing the order of the bits in the
+ * two's complement binary representation of the specified {@code int}
+ * value.
+ *
+ * @param i the value to be reversed
+ * @return the value obtained by reversing order of the bits in the
+ * specified {@code int} value.
+ * @since 1.5
+ */
+ public static int reverse(int i) {
+ // HD, Figure 7-1
+ i = (i & 0x55555555) << 1 | (i >>> 1) & 0x55555555;
+ i = (i & 0x33333333) << 2 | (i >>> 2) & 0x33333333;
+ i = (i & 0x0f0f0f0f) << 4 | (i >>> 4) & 0x0f0f0f0f;
+ i = (i << 24) | ((i & 0xff00) << 8) |
+ ((i >>> 8) & 0xff00) | (i >>> 24);
+ return i;
+ }
+
+ /**
+ * Returns the signum function of the specified {@code int} value. (The
+ * return value is -1 if the specified value is negative; 0 if the
+ * specified value is zero; and 1 if the specified value is positive.)
+ *
+ * @param i the value whose signum is to be computed
+ * @return the signum function of the specified {@code int} value.
+ * @since 1.5
+ */
+ public static int signum(int i) {
+ // HD, Section 2-7
+ return (i >> 31) | (-i >>> 31);
+ }
+
+ /**
+ * Returns the value obtained by reversing the order of the bytes in the
+ * two's complement representation of the specified {@code int} value.
+ *
+ * @param i the value whose bytes are to be reversed
+ * @return the value obtained by reversing the bytes in the specified
+ * {@code int} value.
+ * @since 1.5
+ */
+ public static int reverseBytes(int i) {
+ return ((i >>> 24) ) |
+ ((i >> 8) & 0xFF00) |
+ ((i << 8) & 0xFF0000) |
+ ((i << 24));
+ }
+
+ /**
+ * Adds two integers together as per the + operator.
+ *
+ * @param a the first operand
+ * @param b the second operand
+ * @return the sum of {@code a} and {@code b}
+ * @see java.util.function.BinaryOperator
+ * @since 1.8
+ */
+ public static int sum(int a, int b) {
+ return a + b;
+ }
+
+ /**
+ * Returns the greater of two {@code int} values
+ * as if by calling {@link Math#max(int, int) Math.max}.
+ *
+ * @param a the first operand
+ * @param b the second operand
+ * @return the greater of {@code a} and {@code b}
+ * @see java.util.function.BinaryOperator
+ * @since 1.8
+ */
+ public static int max(int a, int b) {
+ return Math.max(a, b);
+ }
+
+ /**
+ * Returns the smaller of two {@code int} values
+ * as if by calling {@link Math#min(int, int) Math.min}.
+ *
+ * @param a the first operand
+ * @param b the second operand
+ * @return the smaller of {@code a} and {@code b}
+ * @see java.util.function.BinaryOperator
+ * @since 1.8
+ */
+ public static int min(int a, int b) {
+ return Math.min(a, b);
+ }
+
+ /** use serialVersionUID from JDK 1.0.2 for interoperability */
+ @Native private static final long serialVersionUID = 1360826667806852920L;
+}
diff --git a/java/lang/InternalError.java b/java/lang/InternalError.java
new file mode 100644
index 0000000..8d33821
--- /dev/null
+++ b/java/lang/InternalError.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 1994, 2011, 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;
+
+/**
+ * Thrown to indicate some unexpected internal error has occurred in
+ * the Java Virtual Machine.
+ *
+ * @author unascribed
+ * @since JDK1.0
+ */
+public class InternalError extends VirtualMachineError {
+ private static final long serialVersionUID = -9062593416125562365L;
+
+ /**
+ * Constructs an <code>InternalError</code> with no detail message.
+ */
+ public InternalError() {
+ super();
+ }
+
+ /**
+ * Constructs an <code>InternalError</code> with the specified
+ * detail message.
+ *
+ * @param message the detail message.
+ */
+ public InternalError(String message) {
+ super(message);
+ }
+
+
+ /**
+ * Constructs an {@code InternalError} with the specified detail
+ * message and cause. <p>Note that the detail message associated
+ * with {@code cause} is <i>not</i> automatically incorporated in
+ * this error's detail message.
+ *
+ * @param message the detail message (which is saved for later retrieval
+ * by the {@link #getMessage()} method).
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link #getCause()} method). (A {@code null} value is
+ * permitted, and indicates that the cause is nonexistent or
+ * unknown.)
+ * @since 1.8
+ */
+ public InternalError(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * Constructs an {@code InternalError} with the specified cause
+ * and a detail message of {@code (cause==null ? null :
+ * cause.toString())} (which typically contains the class and
+ * detail message of {@code cause}).
+ *
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link #getCause()} method). (A {@code null} value is
+ * permitted, and indicates that the cause is nonexistent or
+ * unknown.)
+ * @since 1.8
+ */
+ public InternalError(Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git a/java/lang/InterruptedException.java b/java/lang/InterruptedException.java
new file mode 100644
index 0000000..27bc5a8
--- /dev/null
+++ b/java/lang/InterruptedException.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 1995, 2008, 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;
+
+/**
+ * Thrown when a thread is waiting, sleeping, or otherwise occupied,
+ * and the thread is interrupted, either before or during the activity.
+ * Occasionally a method may wish to test whether the current
+ * thread has been interrupted, and if so, to immediately throw
+ * this exception. The following code can be used to achieve
+ * this effect:
+ * <pre>
+ * if (Thread.interrupted()) // Clears interrupted status!
+ * throw new InterruptedException();
+ * </pre>
+ *
+ * @author Frank Yellin
+ * @see java.lang.Object#wait()
+ * @see java.lang.Object#wait(long)
+ * @see java.lang.Object#wait(long, int)
+ * @see java.lang.Thread#sleep(long)
+ * @see java.lang.Thread#interrupt()
+ * @see java.lang.Thread#interrupted()
+ * @since JDK1.0
+ */
+public
+class InterruptedException extends Exception {
+ private static final long serialVersionUID = 6700697376100628473L;
+
+ /**
+ * Constructs an <code>InterruptedException</code> with no detail message.
+ */
+ public InterruptedException() {
+ super();
+ }
+
+ /**
+ * Constructs an <code>InterruptedException</code> with the
+ * specified detail message.
+ *
+ * @param s the detail message.
+ */
+ public InterruptedException(String s) {
+ super(s);
+ }
+}
diff --git a/java/lang/Iterable.annotated.java b/java/lang/Iterable.annotated.java
new file mode 100644
index 0000000..8986b35
--- /dev/null
+++ b/java/lang/Iterable.annotated.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2003, 2013, 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;
+
+import java.util.Iterator;
+import java.util.Spliterator;
+import java.util.function.Consumer;
+import libcore.util.NonNull;
+import libcore.util.NullFromTypeParam;
+
+public interface Iterable<T> {
+
+ public @NonNull Iterator<@NullFromTypeParam T> iterator();
+ public default void forEach(@NonNull Consumer<? super T> action) { throw new RuntimeException("Stub!"); }
+ @NonNull public default Spliterator<T> spliterator() { throw new RuntimeException("Stub!"); }
+}
diff --git a/java/lang/Iterable.java b/java/lang/Iterable.java
new file mode 100644
index 0000000..eed3938
--- /dev/null
+++ b/java/lang/Iterable.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2003, 2013, 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;
+
+import java.util.Iterator;
+import java.util.Objects;
+import java.util.Spliterator;
+import java.util.Spliterators;
+import java.util.function.Consumer;
+
+/**
+ * Implementing this interface allows an object to be the target of
+ * the "for-each loop" statement. See
+ * <strong>
+ * <a href="{@docRoot}/../technotes/guides/language/foreach.html">For-each Loop</a>
+ * </strong>
+ *
+ * @param <T> the type of elements returned by the iterator
+ *
+ * @since 1.5
+ * @jls 14.14.2 The enhanced for statement
+ */
+public interface Iterable<T> {
+ /**
+ * Returns an iterator over elements of type {@code T}.
+ *
+ * @return an Iterator.
+ */
+ Iterator<T> iterator();
+
+ /**
+ * Performs the given action for each element of the {@code Iterable}
+ * until all elements have been processed or the action throws an
+ * exception. Unless otherwise specified by the implementing class,
+ * actions are performed in the order of iteration (if an iteration order
+ * is specified). Exceptions thrown by the action are relayed to the
+ * caller.
+ *
+ * @implSpec
+ * <p>The default implementation behaves as if:
+ * <pre>{@code
+ * for (T t : this)
+ * action.accept(t);
+ * }</pre>
+ *
+ * @param action The action to be performed for each element
+ * @throws NullPointerException if the specified action is null
+ * @since 1.8
+ */
+ default void forEach(Consumer<? super T> action) {
+ Objects.requireNonNull(action);
+ for (T t : this) {
+ action.accept(t);
+ }
+ }
+
+ /**
+ * Creates a {@link Spliterator} over the elements described by this
+ * {@code Iterable}.
+ *
+ * @implSpec
+ * The default implementation creates an
+ * <em><a href="Spliterator.html#binding">early-binding</a></em>
+ * spliterator from the iterable's {@code Iterator}. The spliterator
+ * inherits the <em>fail-fast</em> properties of the iterable's iterator.
+ *
+ * @implNote
+ * The default implementation should usually be overridden. The
+ * spliterator returned by the default implementation has poor splitting
+ * capabilities, is unsized, and does not report any spliterator
+ * characteristics. Implementing classes can nearly always provide a
+ * better implementation.
+ *
+ * @return a {@code Spliterator} over the elements described by this
+ * {@code Iterable}.
+ * @since 1.8
+ */
+ default Spliterator<T> spliterator() {
+ return Spliterators.spliteratorUnknownSize(iterator(), 0);
+ }
+}
diff --git a/java/lang/LinkageError.java b/java/lang/LinkageError.java
new file mode 100644
index 0000000..6b5f060
--- /dev/null
+++ b/java/lang/LinkageError.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 1995, 2010, 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;
+
+/**
+ * Subclasses of {@code LinkageError} indicate that a class has
+ * some dependency on another class; however, the latter class has
+ * incompatibly changed after the compilation of the former class.
+ *
+ *
+ * @author Frank Yellin
+ * @since JDK1.0
+ */
+public
+class LinkageError extends Error {
+ private static final long serialVersionUID = 3579600108157160122L;
+
+ /**
+ * Constructs a {@code LinkageError} with no detail message.
+ */
+ public LinkageError() {
+ super();
+ }
+
+ /**
+ * Constructs a {@code LinkageError} with the specified detail
+ * message.
+ *
+ * @param s the detail message.
+ */
+ public LinkageError(String s) {
+ super(s);
+ }
+
+ /**
+ * Constructs a {@code LinkageError} with the specified detail
+ * message and cause.
+ *
+ * @param s the detail message.
+ * @param cause the cause, may be {@code null}
+ * @since 1.7
+ */
+ public LinkageError(String s, Throwable cause) {
+ super(s, cause);
+ }
+}
diff --git a/java/lang/Long.annotated.java b/java/lang/Long.annotated.java
new file mode 100644
index 0000000..b077ef5
--- /dev/null
+++ b/java/lang/Long.annotated.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 2013, 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;
+
+import java.math.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Long extends java.lang.Number implements java.lang.Comparable<java.lang.Long> {
+
+public Long(long value) { throw new RuntimeException("Stub!"); }
+
+public Long(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String toString(long i, int radix) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String toUnsignedString(long i, int radix) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String toHexString(long i) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String toOctalString(long i) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String toBinaryString(long i) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String toString(long i) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String toUnsignedString(long i) { throw new RuntimeException("Stub!"); }
+
+public static long parseLong(@libcore.util.NonNull java.lang.String s, int radix) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public static long parseLong(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public static long parseUnsignedLong(@libcore.util.NonNull java.lang.String s, int radix) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public static long parseUnsignedLong(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Long valueOf(@libcore.util.NonNull java.lang.String s, int radix) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Long valueOf(@libcore.util.NonNull java.lang.String s) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Long valueOf(long l) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Long decode(@libcore.util.NonNull java.lang.String nm) throws java.lang.NumberFormatException { throw new RuntimeException("Stub!"); }
+
+public byte byteValue() { throw new RuntimeException("Stub!"); }
+
+public short shortValue() { throw new RuntimeException("Stub!"); }
+
+public int intValue() { throw new RuntimeException("Stub!"); }
+
+public long longValue() { throw new RuntimeException("Stub!"); }
+
+public float floatValue() { throw new RuntimeException("Stub!"); }
+
+public double doubleValue() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public static int hashCode(long value) { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Long getLong(@libcore.util.NonNull java.lang.String nm) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Long getLong(@libcore.util.NonNull java.lang.String nm, long val) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Long getLong(@libcore.util.NonNull java.lang.String nm, @libcore.util.Nullable java.lang.Long val) { throw new RuntimeException("Stub!"); }
+
+public int compareTo(@libcore.util.NonNull java.lang.Long anotherLong) { throw new RuntimeException("Stub!"); }
+
+public static int compare(long x, long y) { throw new RuntimeException("Stub!"); }
+
+public static int compareUnsigned(long x, long y) { throw new RuntimeException("Stub!"); }
+
+public static long divideUnsigned(long dividend, long divisor) { throw new RuntimeException("Stub!"); }
+
+public static long remainderUnsigned(long dividend, long divisor) { throw new RuntimeException("Stub!"); }
+
+public static long highestOneBit(long i) { throw new RuntimeException("Stub!"); }
+
+public static long lowestOneBit(long i) { throw new RuntimeException("Stub!"); }
+
+public static int numberOfLeadingZeros(long i) { throw new RuntimeException("Stub!"); }
+
+public static int numberOfTrailingZeros(long i) { throw new RuntimeException("Stub!"); }
+
+public static int bitCount(long i) { throw new RuntimeException("Stub!"); }
+
+public static long rotateLeft(long i, int distance) { throw new RuntimeException("Stub!"); }
+
+public static long rotateRight(long i, int distance) { throw new RuntimeException("Stub!"); }
+
+public static long reverse(long i) { throw new RuntimeException("Stub!"); }
+
+public static int signum(long i) { throw new RuntimeException("Stub!"); }
+
+public static long reverseBytes(long i) { throw new RuntimeException("Stub!"); }
+
+public static long sum(long a, long b) { throw new RuntimeException("Stub!"); }
+
+public static long max(long a, long b) { throw new RuntimeException("Stub!"); }
+
+public static long min(long a, long b) { throw new RuntimeException("Stub!"); }
+
+public static final int BYTES = 8; // 0x8
+
+public static final long MAX_VALUE = 9223372036854775807L; // 0x7fffffffffffffffL
+
+public static final long MIN_VALUE = -9223372036854775808L; // 0x8000000000000000L
+
+public static final int SIZE = 64; // 0x40
+
+public static final java.lang.Class<java.lang.Long> TYPE;
+static { TYPE = null; }
+}
+
diff --git a/java/lang/Long.java b/java/lang/Long.java
new file mode 100644
index 0000000..0047125
--- /dev/null
+++ b/java/lang/Long.java
@@ -0,0 +1,1625 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 2013, 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;
+
+import java.lang.annotation.Native;
+import java.math.*;
+
+
+/**
+ * The {@code Long} class wraps a value of the primitive type {@code
+ * long} in an object. An object of type {@code Long} contains a
+ * single field whose type is {@code long}.
+ *
+ * <p> In addition, this class provides several methods for converting
+ * a {@code long} to a {@code String} and a {@code String} to a {@code
+ * long}, as well as other constants and methods useful when dealing
+ * with a {@code long}.
+ *
+ * <p>Implementation note: The implementations of the "bit twiddling"
+ * methods (such as {@link #highestOneBit(long) highestOneBit} and
+ * {@link #numberOfTrailingZeros(long) numberOfTrailingZeros}) are
+ * based on material from Henry S. Warren, Jr.'s <i>Hacker's
+ * Delight</i>, (Addison Wesley, 2002).
+ *
+ * @author Lee Boynton
+ * @author Arthur van Hoff
+ * @author Josh Bloch
+ * @author Joseph D. Darcy
+ * @since JDK1.0
+ */
+public final class Long extends Number implements Comparable<Long> {
+ /**
+ * A constant holding the minimum value a {@code long} can
+ * have, -2<sup>63</sup>.
+ */
+ @Native public static final long MIN_VALUE = 0x8000000000000000L;
+
+ /**
+ * A constant holding the maximum value a {@code long} can
+ * have, 2<sup>63</sup>-1.
+ */
+ @Native public static final long MAX_VALUE = 0x7fffffffffffffffL;
+
+ /**
+ * The {@code Class} instance representing the primitive type
+ * {@code long}.
+ *
+ * @since JDK1.1
+ */
+ @SuppressWarnings("unchecked")
+ public static final Class<Long> TYPE = (Class<Long>) Class.getPrimitiveClass("long");
+
+ /**
+ * Returns a string representation of the first argument in the
+ * radix specified by the second argument.
+ *
+ * <p>If the radix is smaller than {@code Character.MIN_RADIX}
+ * or larger than {@code Character.MAX_RADIX}, then the radix
+ * {@code 10} is used instead.
+ *
+ * <p>If the first argument is negative, the first element of the
+ * result is the ASCII minus sign {@code '-'}
+ * ({@code '\u005Cu002d'}). If the first argument is not
+ * negative, no sign character appears in the result.
+ *
+ * <p>The remaining characters of the result represent the magnitude
+ * of the first argument. If the magnitude is zero, it is
+ * represented by a single zero character {@code '0'}
+ * ({@code '\u005Cu0030'}); otherwise, the first character of
+ * the representation of the magnitude will not be the zero
+ * character. The following ASCII characters are used as digits:
+ *
+ * <blockquote>
+ * {@code 0123456789abcdefghijklmnopqrstuvwxyz}
+ * </blockquote>
+ *
+ * These are {@code '\u005Cu0030'} through
+ * {@code '\u005Cu0039'} and {@code '\u005Cu0061'} through
+ * {@code '\u005Cu007a'}. If {@code radix} is
+ * <var>N</var>, then the first <var>N</var> of these characters
+ * are used as radix-<var>N</var> digits in the order shown. Thus,
+ * the digits for hexadecimal (radix 16) are
+ * {@code 0123456789abcdef}. If uppercase letters are
+ * desired, the {@link java.lang.String#toUpperCase()} method may
+ * be called on the result:
+ *
+ * <blockquote>
+ * {@code Long.toString(n, 16).toUpperCase()}
+ * </blockquote>
+ *
+ * @param i a {@code long} to be converted to a string.
+ * @param radix the radix to use in the string representation.
+ * @return a string representation of the argument in the specified radix.
+ * @see java.lang.Character#MAX_RADIX
+ * @see java.lang.Character#MIN_RADIX
+ */
+ public static String toString(long i, int radix) {
+ if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
+ radix = 10;
+ if (radix == 10)
+ return toString(i);
+ char[] buf = new char[65];
+ int charPos = 64;
+ boolean negative = (i < 0);
+
+ if (!negative) {
+ i = -i;
+ }
+
+ while (i <= -radix) {
+ buf[charPos--] = Integer.digits[(int)(-(i % radix))];
+ i = i / radix;
+ }
+ buf[charPos] = Integer.digits[(int)(-i)];
+
+ if (negative) {
+ buf[--charPos] = '-';
+ }
+
+ return new String(buf, charPos, (65 - charPos));
+ }
+
+ /**
+ * Returns a string representation of the first argument as an
+ * unsigned integer value in the radix specified by the second
+ * argument.
+ *
+ * <p>If the radix is smaller than {@code Character.MIN_RADIX}
+ * or larger than {@code Character.MAX_RADIX}, then the radix
+ * {@code 10} is used instead.
+ *
+ * <p>Note that since the first argument is treated as an unsigned
+ * value, no leading sign character is printed.
+ *
+ * <p>If the magnitude is zero, it is represented by a single zero
+ * character {@code '0'} ({@code '\u005Cu0030'}); otherwise,
+ * the first character of the representation of the magnitude will
+ * not be the zero character.
+ *
+ * <p>The behavior of radixes and the characters used as digits
+ * are the same as {@link #toString(long, int) toString}.
+ *
+ * @param i an integer to be converted to an unsigned string.
+ * @param radix the radix to use in the string representation.
+ * @return an unsigned string representation of the argument in the specified radix.
+ * @see #toString(long, int)
+ * @since 1.8
+ */
+ public static String toUnsignedString(long i, int radix) {
+ if (i >= 0)
+ return toString(i, radix);
+ else {
+ switch (radix) {
+ case 2:
+ return toBinaryString(i);
+
+ case 4:
+ return toUnsignedString0(i, 2);
+
+ case 8:
+ return toOctalString(i);
+
+ case 10:
+ /*
+ * We can get the effect of an unsigned division by 10
+ * on a long value by first shifting right, yielding a
+ * positive value, and then dividing by 5. This
+ * allows the last digit and preceding digits to be
+ * isolated more quickly than by an initial conversion
+ * to BigInteger.
+ */
+ long quot = (i >>> 1) / 5;
+ long rem = i - quot * 10;
+ return toString(quot) + rem;
+
+ case 16:
+ return toHexString(i);
+
+ case 32:
+ return toUnsignedString0(i, 5);
+
+ default:
+ return toUnsignedBigInteger(i).toString(radix);
+ }
+ }
+ }
+
+ /**
+ * Return a BigInteger equal to the unsigned value of the
+ * argument.
+ */
+ private static BigInteger toUnsignedBigInteger(long i) {
+ if (i >= 0L)
+ return BigInteger.valueOf(i);
+ else {
+ int upper = (int) (i >>> 32);
+ int lower = (int) i;
+
+ // return (upper << 32) + lower
+ return (BigInteger.valueOf(Integer.toUnsignedLong(upper))).shiftLeft(32).
+ add(BigInteger.valueOf(Integer.toUnsignedLong(lower)));
+ }
+ }
+
+ /**
+ * Returns a string representation of the {@code long}
+ * argument as an unsigned integer in base 16.
+ *
+ * <p>The unsigned {@code long} value is the argument plus
+ * 2<sup>64</sup> if the argument is negative; otherwise, it is
+ * equal to the argument. This value is converted to a string of
+ * ASCII digits in hexadecimal (base 16) with no extra
+ * leading {@code 0}s.
+ *
+ * <p>The value of the argument can be recovered from the returned
+ * string {@code s} by calling {@link
+ * Long#parseUnsignedLong(String, int) Long.parseUnsignedLong(s,
+ * 16)}.
+ *
+ * <p>If the unsigned magnitude is zero, it is represented by a
+ * single zero character {@code '0'} ({@code '\u005Cu0030'});
+ * otherwise, the first character of the representation of the
+ * unsigned magnitude will not be the zero character. The
+ * following characters are used as hexadecimal digits:
+ *
+ * <blockquote>
+ * {@code 0123456789abcdef}
+ * </blockquote>
+ *
+ * These are the characters {@code '\u005Cu0030'} through
+ * {@code '\u005Cu0039'} and {@code '\u005Cu0061'} through
+ * {@code '\u005Cu0066'}. If uppercase letters are desired,
+ * the {@link java.lang.String#toUpperCase()} method may be called
+ * on the result:
+ *
+ * <blockquote>
+ * {@code Long.toHexString(n).toUpperCase()}
+ * </blockquote>
+ *
+ * @param i a {@code long} to be converted to a string.
+ * @return the string representation of the unsigned {@code long}
+ * value represented by the argument in hexadecimal
+ * (base 16).
+ * @see #parseUnsignedLong(String, int)
+ * @see #toUnsignedString(long, int)
+ * @since JDK 1.0.2
+ */
+ public static String toHexString(long i) {
+ return toUnsignedString0(i, 4);
+ }
+
+ /**
+ * Returns a string representation of the {@code long}
+ * argument as an unsigned integer in base 8.
+ *
+ * <p>The unsigned {@code long} value is the argument plus
+ * 2<sup>64</sup> if the argument is negative; otherwise, it is
+ * equal to the argument. This value is converted to a string of
+ * ASCII digits in octal (base 8) with no extra leading
+ * {@code 0}s.
+ *
+ * <p>The value of the argument can be recovered from the returned
+ * string {@code s} by calling {@link
+ * Long#parseUnsignedLong(String, int) Long.parseUnsignedLong(s,
+ * 8)}.
+ *
+ * <p>If the unsigned magnitude is zero, it is represented by a
+ * single zero character {@code '0'} ({@code '\u005Cu0030'});
+ * otherwise, the first character of the representation of the
+ * unsigned magnitude will not be the zero character. The
+ * following characters are used as octal digits:
+ *
+ * <blockquote>
+ * {@code 01234567}
+ * </blockquote>
+ *
+ * These are the characters {@code '\u005Cu0030'} through
+ * {@code '\u005Cu0037'}.
+ *
+ * @param i a {@code long} to be converted to a string.
+ * @return the string representation of the unsigned {@code long}
+ * value represented by the argument in octal (base 8).
+ * @see #parseUnsignedLong(String, int)
+ * @see #toUnsignedString(long, int)
+ * @since JDK 1.0.2
+ */
+ public static String toOctalString(long i) {
+ return toUnsignedString0(i, 3);
+ }
+
+ /**
+ * Returns a string representation of the {@code long}
+ * argument as an unsigned integer in base 2.
+ *
+ * <p>The unsigned {@code long} value is the argument plus
+ * 2<sup>64</sup> if the argument is negative; otherwise, it is
+ * equal to the argument. This value is converted to a string of
+ * ASCII digits in binary (base 2) with no extra leading
+ * {@code 0}s.
+ *
+ * <p>The value of the argument can be recovered from the returned
+ * string {@code s} by calling {@link
+ * Long#parseUnsignedLong(String, int) Long.parseUnsignedLong(s,
+ * 2)}.
+ *
+ * <p>If the unsigned magnitude is zero, it is represented by a
+ * single zero character {@code '0'} ({@code '\u005Cu0030'});
+ * otherwise, the first character of the representation of the
+ * unsigned magnitude will not be the zero character. The
+ * characters {@code '0'} ({@code '\u005Cu0030'}) and {@code
+ * '1'} ({@code '\u005Cu0031'}) are used as binary digits.
+ *
+ * @param i a {@code long} to be converted to a string.
+ * @return the string representation of the unsigned {@code long}
+ * value represented by the argument in binary (base 2).
+ * @see #parseUnsignedLong(String, int)
+ * @see #toUnsignedString(long, int)
+ * @since JDK 1.0.2
+ */
+ public static String toBinaryString(long i) {
+ return toUnsignedString0(i, 1);
+ }
+
+ /**
+ * Format a long (treated as unsigned) into a String.
+ * @param val the value to format
+ * @param shift the log2 of the base to format in (4 for hex, 3 for octal, 1 for binary)
+ */
+ static String toUnsignedString0(long val, int shift) {
+ // assert shift > 0 && shift <=5 : "Illegal shift value";
+ int mag = Long.SIZE - Long.numberOfLeadingZeros(val);
+ int chars = Math.max(((mag + (shift - 1)) / shift), 1);
+ char[] buf = new char[chars];
+
+ formatUnsignedLong(val, shift, buf, 0, chars);
+ // Android-changed: Use regular constructor instead of one which takes over "buf".
+ // return new String(buf, true);
+ return new String(buf);
+ }
+
+ /**
+ * Format a long (treated as unsigned) into a character buffer.
+ * @param val the unsigned long to format
+ * @param shift the log2 of the base to format in (4 for hex, 3 for octal, 1 for binary)
+ * @param buf the character buffer to write to
+ * @param offset the offset in the destination buffer to start at
+ * @param len the number of characters to write
+ * @return the lowest character location used
+ */
+ static int formatUnsignedLong(long val, int shift, char[] buf, int offset, int len) {
+ int charPos = len;
+ int radix = 1 << shift;
+ int mask = radix - 1;
+ do {
+ buf[offset + --charPos] = Integer.digits[((int) val) & mask];
+ val >>>= shift;
+ } while (val != 0 && charPos > 0);
+
+ return charPos;
+ }
+
+ /**
+ * Returns a {@code String} object representing the specified
+ * {@code long}. The argument is converted to signed decimal
+ * representation and returned as a string, exactly as if the
+ * argument and the radix 10 were given as arguments to the {@link
+ * #toString(long, int)} method.
+ *
+ * @param i a {@code long} to be converted.
+ * @return a string representation of the argument in base 10.
+ */
+ public static String toString(long i) {
+ if (i == Long.MIN_VALUE)
+ return "-9223372036854775808";
+ int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
+ char[] buf = new char[size];
+ getChars(i, size, buf);
+ // Android-changed: Use regular constructor instead of one which takes over "buf".
+ // return new String(buf, true);
+ return new String(buf);
+ }
+
+ /**
+ * Returns a string representation of the argument as an unsigned
+ * decimal value.
+ *
+ * The argument is converted to unsigned decimal representation
+ * and returned as a string exactly as if the argument and radix
+ * 10 were given as arguments to the {@link #toUnsignedString(long,
+ * int)} method.
+ *
+ * @param i an integer to be converted to an unsigned string.
+ * @return an unsigned string representation of the argument.
+ * @see #toUnsignedString(long, int)
+ * @since 1.8
+ */
+ public static String toUnsignedString(long i) {
+ return toUnsignedString(i, 10);
+ }
+
+ /**
+ * Places characters representing the integer i into the
+ * character array buf. The characters are placed into
+ * the buffer backwards starting with the least significant
+ * digit at the specified index (exclusive), and working
+ * backwards from there.
+ *
+ * Will fail if i == Long.MIN_VALUE
+ */
+ static void getChars(long i, int index, char[] buf) {
+ long q;
+ int r;
+ int charPos = index;
+ char sign = 0;
+
+ if (i < 0) {
+ sign = '-';
+ i = -i;
+ }
+
+ // Get 2 digits/iteration using longs until quotient fits into an int
+ while (i > Integer.MAX_VALUE) {
+ q = i / 100;
+ // really: r = i - (q * 100);
+ r = (int)(i - ((q << 6) + (q << 5) + (q << 2)));
+ i = q;
+ buf[--charPos] = Integer.DigitOnes[r];
+ buf[--charPos] = Integer.DigitTens[r];
+ }
+
+ // Get 2 digits/iteration using ints
+ int q2;
+ int i2 = (int)i;
+ while (i2 >= 65536) {
+ q2 = i2 / 100;
+ // really: r = i2 - (q * 100);
+ r = i2 - ((q2 << 6) + (q2 << 5) + (q2 << 2));
+ i2 = q2;
+ buf[--charPos] = Integer.DigitOnes[r];
+ buf[--charPos] = Integer.DigitTens[r];
+ }
+
+ // Fall thru to fast mode for smaller numbers
+ // assert(i2 <= 65536, i2);
+ for (;;) {
+ q2 = (i2 * 52429) >>> (16+3);
+ r = i2 - ((q2 << 3) + (q2 << 1)); // r = i2-(q2*10) ...
+ buf[--charPos] = Integer.digits[r];
+ i2 = q2;
+ if (i2 == 0) break;
+ }
+ if (sign != 0) {
+ buf[--charPos] = sign;
+ }
+ }
+
+ // Requires positive x
+ static int stringSize(long x) {
+ long p = 10;
+ for (int i=1; i<19; i++) {
+ if (x < p)
+ return i;
+ p = 10*p;
+ }
+ return 19;
+ }
+
+ /**
+ * Parses the string argument as a signed {@code long} in the
+ * radix specified by the second argument. The characters in the
+ * string must all be digits of the specified radix (as determined
+ * by whether {@link java.lang.Character#digit(char, int)} returns
+ * a nonnegative value), except that the first character may be an
+ * ASCII minus sign {@code '-'} ({@code '\u005Cu002D'}) to
+ * indicate a negative value or an ASCII plus sign {@code '+'}
+ * ({@code '\u005Cu002B'}) to indicate a positive value. The
+ * resulting {@code long} value is returned.
+ *
+ * <p>Note that neither the character {@code L}
+ * ({@code '\u005Cu004C'}) nor {@code l}
+ * ({@code '\u005Cu006C'}) is permitted to appear at the end
+ * of the string as a type indicator, as would be permitted in
+ * Java programming language source code - except that either
+ * {@code L} or {@code l} may appear as a digit for a
+ * radix greater than or equal to 22.
+ *
+ * <p>An exception of type {@code NumberFormatException} is
+ * thrown if any of the following situations occurs:
+ * <ul>
+ *
+ * <li>The first argument is {@code null} or is a string of
+ * length zero.
+ *
+ * <li>The {@code radix} is either smaller than {@link
+ * java.lang.Character#MIN_RADIX} or larger than {@link
+ * java.lang.Character#MAX_RADIX}.
+ *
+ * <li>Any character of the string is not a digit of the specified
+ * radix, except that the first character may be a minus sign
+ * {@code '-'} ({@code '\u005Cu002d'}) or plus sign {@code
+ * '+'} ({@code '\u005Cu002B'}) provided that the string is
+ * longer than length 1.
+ *
+ * <li>The value represented by the string is not a value of type
+ * {@code long}.
+ * </ul>
+ *
+ * <p>Examples:
+ * <blockquote><pre>
+ * parseLong("0", 10) returns 0L
+ * parseLong("473", 10) returns 473L
+ * parseLong("+42", 10) returns 42L
+ * parseLong("-0", 10) returns 0L
+ * parseLong("-FF", 16) returns -255L
+ * parseLong("1100110", 2) returns 102L
+ * parseLong("99", 8) throws a NumberFormatException
+ * parseLong("Hazelnut", 10) throws a NumberFormatException
+ * parseLong("Hazelnut", 36) returns 1356099454469L
+ * </pre></blockquote>
+ *
+ * @param s the {@code String} containing the
+ * {@code long} representation to be parsed.
+ * @param radix the radix to be used while parsing {@code s}.
+ * @return the {@code long} represented by the string argument in
+ * the specified radix.
+ * @throws NumberFormatException if the string does not contain a
+ * parsable {@code long}.
+ */
+ public static long parseLong(String s, int radix)
+ throws NumberFormatException
+ {
+ if (s == null) {
+ throw new NumberFormatException("null");
+ }
+
+ if (radix < Character.MIN_RADIX) {
+ throw new NumberFormatException("radix " + radix +
+ " less than Character.MIN_RADIX");
+ }
+ if (radix > Character.MAX_RADIX) {
+ throw new NumberFormatException("radix " + radix +
+ " greater than Character.MAX_RADIX");
+ }
+
+ long result = 0;
+ boolean negative = false;
+ int i = 0, len = s.length();
+ long limit = -Long.MAX_VALUE;
+ long multmin;
+ int digit;
+
+ if (len > 0) {
+ char firstChar = s.charAt(0);
+ if (firstChar < '0') { // Possible leading "+" or "-"
+ if (firstChar == '-') {
+ negative = true;
+ limit = Long.MIN_VALUE;
+ } else if (firstChar != '+')
+ throw NumberFormatException.forInputString(s);
+
+ if (len == 1) // Cannot have lone "+" or "-"
+ throw NumberFormatException.forInputString(s);
+ i++;
+ }
+ multmin = limit / radix;
+ while (i < len) {
+ // Accumulating negatively avoids surprises near MAX_VALUE
+ digit = Character.digit(s.charAt(i++),radix);
+ if (digit < 0) {
+ throw NumberFormatException.forInputString(s);
+ }
+ if (result < multmin) {
+ throw NumberFormatException.forInputString(s);
+ }
+ result *= radix;
+ if (result < limit + digit) {
+ throw NumberFormatException.forInputString(s);
+ }
+ result -= digit;
+ }
+ } else {
+ throw NumberFormatException.forInputString(s);
+ }
+ return negative ? result : -result;
+ }
+
+ /**
+ * Parses the string argument as a signed decimal {@code long}.
+ * The characters in the string must all be decimal digits, except
+ * that the first character may be an ASCII minus sign {@code '-'}
+ * ({@code \u005Cu002D'}) to indicate a negative value or an
+ * ASCII plus sign {@code '+'} ({@code '\u005Cu002B'}) to
+ * indicate a positive value. The resulting {@code long} value is
+ * returned, exactly as if the argument and the radix {@code 10}
+ * were given as arguments to the {@link
+ * #parseLong(java.lang.String, int)} method.
+ *
+ * <p>Note that neither the character {@code L}
+ * ({@code '\u005Cu004C'}) nor {@code l}
+ * ({@code '\u005Cu006C'}) is permitted to appear at the end
+ * of the string as a type indicator, as would be permitted in
+ * Java programming language source code.
+ *
+ * @param s a {@code String} containing the {@code long}
+ * representation to be parsed
+ * @return the {@code long} represented by the argument in
+ * decimal.
+ * @throws NumberFormatException if the string does not contain a
+ * parsable {@code long}.
+ */
+ public static long parseLong(String s) throws NumberFormatException {
+ return parseLong(s, 10);
+ }
+
+ /**
+ * Parses the string argument as an unsigned {@code long} in the
+ * radix specified by the second argument. An unsigned integer
+ * maps the values usually associated with negative numbers to
+ * positive numbers larger than {@code MAX_VALUE}.
+ *
+ * The characters in the string must all be digits of the
+ * specified radix (as determined by whether {@link
+ * java.lang.Character#digit(char, int)} returns a nonnegative
+ * value), except that the first character may be an ASCII plus
+ * sign {@code '+'} ({@code '\u005Cu002B'}). The resulting
+ * integer value is returned.
+ *
+ * <p>An exception of type {@code NumberFormatException} is
+ * thrown if any of the following situations occurs:
+ * <ul>
+ * <li>The first argument is {@code null} or is a string of
+ * length zero.
+ *
+ * <li>The radix is either smaller than
+ * {@link java.lang.Character#MIN_RADIX} or
+ * larger than {@link java.lang.Character#MAX_RADIX}.
+ *
+ * <li>Any character of the string is not a digit of the specified
+ * radix, except that the first character may be a plus sign
+ * {@code '+'} ({@code '\u005Cu002B'}) provided that the
+ * string is longer than length 1.
+ *
+ * <li>The value represented by the string is larger than the
+ * largest unsigned {@code long}, 2<sup>64</sup>-1.
+ *
+ * </ul>
+ *
+ *
+ * @param s the {@code String} containing the unsigned integer
+ * representation to be parsed
+ * @param radix the radix to be used while parsing {@code s}.
+ * @return the unsigned {@code long} represented by the string
+ * argument in the specified radix.
+ * @throws NumberFormatException if the {@code String}
+ * does not contain a parsable {@code long}.
+ * @since 1.8
+ */
+ public static long parseUnsignedLong(String s, int radix)
+ throws NumberFormatException {
+ if (s == null) {
+ throw new NumberFormatException("null");
+ }
+
+ int len = s.length();
+ if (len > 0) {
+ char firstChar = s.charAt(0);
+ if (firstChar == '-') {
+ throw new
+ NumberFormatException(String.format("Illegal leading minus sign " +
+ "on unsigned string %s.", s));
+ } else {
+ if (len <= 12 || // Long.MAX_VALUE in Character.MAX_RADIX is 13 digits
+ (radix == 10 && len <= 18) ) { // Long.MAX_VALUE in base 10 is 19 digits
+ return parseLong(s, radix);
+ }
+
+ // No need for range checks on len due to testing above.
+ long first = parseLong(s.substring(0, len - 1), radix);
+ int second = Character.digit(s.charAt(len - 1), radix);
+ if (second < 0) {
+ throw new NumberFormatException("Bad digit at end of " + s);
+ }
+ long result = first * radix + second;
+ if (compareUnsigned(result, first) < 0) {
+ /*
+ * The maximum unsigned value, (2^64)-1, takes at
+ * most one more digit to represent than the
+ * maximum signed value, (2^63)-1. Therefore,
+ * parsing (len - 1) digits will be appropriately
+ * in-range of the signed parsing. In other
+ * words, if parsing (len -1) digits overflows
+ * signed parsing, parsing len digits will
+ * certainly overflow unsigned parsing.
+ *
+ * The compareUnsigned check above catches
+ * situations where an unsigned overflow occurs
+ * incorporating the contribution of the final
+ * digit.
+ */
+ throw new NumberFormatException(String.format("String value %s exceeds " +
+ "range of unsigned long.", s));
+ }
+ return result;
+ }
+ } else {
+ throw NumberFormatException.forInputString(s);
+ }
+ }
+
+ /**
+ * Parses the string argument as an unsigned decimal {@code long}. The
+ * characters in the string must all be decimal digits, except
+ * that the first character may be an an ASCII plus sign {@code
+ * '+'} ({@code '\u005Cu002B'}). The resulting integer value
+ * is returned, exactly as if the argument and the radix 10 were
+ * given as arguments to the {@link
+ * #parseUnsignedLong(java.lang.String, int)} method.
+ *
+ * @param s a {@code String} containing the unsigned {@code long}
+ * representation to be parsed
+ * @return the unsigned {@code long} value represented by the decimal string argument
+ * @throws NumberFormatException if the string does not contain a
+ * parsable unsigned integer.
+ * @since 1.8
+ */
+ public static long parseUnsignedLong(String s) throws NumberFormatException {
+ return parseUnsignedLong(s, 10);
+ }
+
+ /**
+ * Returns a {@code Long} object holding the value
+ * extracted from the specified {@code String} when parsed
+ * with the radix given by the second argument. The first
+ * argument is interpreted as representing a signed
+ * {@code long} in the radix specified by the second
+ * argument, exactly as if the arguments were given to the {@link
+ * #parseLong(java.lang.String, int)} method. The result is a
+ * {@code Long} object that represents the {@code long}
+ * value specified by the string.
+ *
+ * <p>In other words, this method returns a {@code Long} object equal
+ * to the value of:
+ *
+ * <blockquote>
+ * {@code new Long(Long.parseLong(s, radix))}
+ * </blockquote>
+ *
+ * @param s the string to be parsed
+ * @param radix the radix to be used in interpreting {@code s}
+ * @return a {@code Long} object holding the value
+ * represented by the string argument in the specified
+ * radix.
+ * @throws NumberFormatException If the {@code String} does not
+ * contain a parsable {@code long}.
+ */
+ public static Long valueOf(String s, int radix) throws NumberFormatException {
+ return Long.valueOf(parseLong(s, radix));
+ }
+
+ /**
+ * Returns a {@code Long} object holding the value
+ * of the specified {@code String}. The argument is
+ * interpreted as representing a signed decimal {@code long},
+ * exactly as if the argument were given to the {@link
+ * #parseLong(java.lang.String)} method. The result is a
+ * {@code Long} object that represents the integer value
+ * specified by the string.
+ *
+ * <p>In other words, this method returns a {@code Long} object
+ * equal to the value of:
+ *
+ * <blockquote>
+ * {@code new Long(Long.parseLong(s))}
+ * </blockquote>
+ *
+ * @param s the string to be parsed.
+ * @return a {@code Long} object holding the value
+ * represented by the string argument.
+ * @throws NumberFormatException If the string cannot be parsed
+ * as a {@code long}.
+ */
+ public static Long valueOf(String s) throws NumberFormatException
+ {
+ return Long.valueOf(parseLong(s, 10));
+ }
+
+ private static class LongCache {
+ private LongCache(){}
+
+ static final Long cache[] = new Long[-(-128) + 127 + 1];
+
+ static {
+ for(int i = 0; i < cache.length; i++)
+ cache[i] = new Long(i - 128);
+ }
+ }
+
+ /**
+ * Returns a {@code Long} instance representing the specified
+ * {@code long} value.
+ * If a new {@code Long} instance is not required, this method
+ * should generally be used in preference to the constructor
+ * {@link #Long(long)}, as this method is likely to yield
+ * significantly better space and time performance by caching
+ * frequently requested values.
+ *
+ * Note that unlike the {@linkplain Integer#valueOf(int)
+ * corresponding method} in the {@code Integer} class, this method
+ * is <em>not</em> required to cache values within a particular
+ * range.
+ *
+ * @param l a long value.
+ * @return a {@code Long} instance representing {@code l}.
+ * @since 1.5
+ */
+ public static Long valueOf(long l) {
+ final int offset = 128;
+ if (l >= -128 && l <= 127) { // will cache
+ return LongCache.cache[(int)l + offset];
+ }
+ return new Long(l);
+ }
+
+ /**
+ * Decodes a {@code String} into a {@code Long}.
+ * Accepts decimal, hexadecimal, and octal numbers given by the
+ * following grammar:
+ *
+ * <blockquote>
+ * <dl>
+ * <dt><i>DecodableString:</i>
+ * <dd><i>Sign<sub>opt</sub> DecimalNumeral</i>
+ * <dd><i>Sign<sub>opt</sub></i> {@code 0x} <i>HexDigits</i>
+ * <dd><i>Sign<sub>opt</sub></i> {@code 0X} <i>HexDigits</i>
+ * <dd><i>Sign<sub>opt</sub></i> {@code #} <i>HexDigits</i>
+ * <dd><i>Sign<sub>opt</sub></i> {@code 0} <i>OctalDigits</i>
+ *
+ * <dt><i>Sign:</i>
+ * <dd>{@code -}
+ * <dd>{@code +}
+ * </dl>
+ * </blockquote>
+ *
+ * <i>DecimalNumeral</i>, <i>HexDigits</i>, and <i>OctalDigits</i>
+ * are as defined in section 3.10.1 of
+ * <cite>The Java™ Language Specification</cite>,
+ * except that underscores are not accepted between digits.
+ *
+ * <p>The sequence of characters following an optional
+ * sign and/or radix specifier ("{@code 0x}", "{@code 0X}",
+ * "{@code #}", or leading zero) is parsed as by the {@code
+ * Long.parseLong} method with the indicated radix (10, 16, or 8).
+ * This sequence of characters must represent a positive value or
+ * a {@link NumberFormatException} will be thrown. The result is
+ * negated if first character of the specified {@code String} is
+ * the minus sign. No whitespace characters are permitted in the
+ * {@code String}.
+ *
+ * @param nm the {@code String} to decode.
+ * @return a {@code Long} object holding the {@code long}
+ * value represented by {@code nm}
+ * @throws NumberFormatException if the {@code String} does not
+ * contain a parsable {@code long}.
+ * @see java.lang.Long#parseLong(String, int)
+ * @since 1.2
+ */
+ public static Long decode(String nm) throws NumberFormatException {
+ int radix = 10;
+ int index = 0;
+ boolean negative = false;
+ Long result;
+
+ if (nm.length() == 0)
+ throw new NumberFormatException("Zero length string");
+ char firstChar = nm.charAt(0);
+ // Handle sign, if present
+ if (firstChar == '-') {
+ negative = true;
+ index++;
+ } else if (firstChar == '+')
+ index++;
+
+ // Handle radix specifier, if present
+ if (nm.startsWith("0x", index) || nm.startsWith("0X", index)) {
+ index += 2;
+ radix = 16;
+ }
+ else if (nm.startsWith("#", index)) {
+ index ++;
+ radix = 16;
+ }
+ else if (nm.startsWith("0", index) && nm.length() > 1 + index) {
+ index ++;
+ radix = 8;
+ }
+
+ if (nm.startsWith("-", index) || nm.startsWith("+", index))
+ throw new NumberFormatException("Sign character in wrong position");
+
+ try {
+ result = Long.valueOf(nm.substring(index), radix);
+ result = negative ? Long.valueOf(-result.longValue()) : result;
+ } catch (NumberFormatException e) {
+ // If number is Long.MIN_VALUE, we'll end up here. The next line
+ // handles this case, and causes any genuine format error to be
+ // rethrown.
+ String constant = negative ? ("-" + nm.substring(index))
+ : nm.substring(index);
+ result = Long.valueOf(constant, radix);
+ }
+ return result;
+ }
+
+ /**
+ * The value of the {@code Long}.
+ *
+ * @serial
+ */
+ private final long value;
+
+ /**
+ * Constructs a newly allocated {@code Long} object that
+ * represents the specified {@code long} argument.
+ *
+ * @param value the value to be represented by the
+ * {@code Long} object.
+ */
+ public Long(long value) {
+ this.value = value;
+ }
+
+ /**
+ * Constructs a newly allocated {@code Long} object that
+ * represents the {@code long} value indicated by the
+ * {@code String} parameter. The string is converted to a
+ * {@code long} value in exactly the manner used by the
+ * {@code parseLong} method for radix 10.
+ *
+ * @param s the {@code String} to be converted to a
+ * {@code Long}.
+ * @throws NumberFormatException if the {@code String} does not
+ * contain a parsable {@code long}.
+ * @see java.lang.Long#parseLong(java.lang.String, int)
+ */
+ public Long(String s) throws NumberFormatException {
+ this.value = parseLong(s, 10);
+ }
+
+ /**
+ * Returns the value of this {@code Long} as a {@code byte} after
+ * a narrowing primitive conversion.
+ * @jls 5.1.3 Narrowing Primitive Conversions
+ */
+ public byte byteValue() {
+ return (byte)value;
+ }
+
+ /**
+ * Returns the value of this {@code Long} as a {@code short} after
+ * a narrowing primitive conversion.
+ * @jls 5.1.3 Narrowing Primitive Conversions
+ */
+ public short shortValue() {
+ return (short)value;
+ }
+
+ /**
+ * Returns the value of this {@code Long} as an {@code int} after
+ * a narrowing primitive conversion.
+ * @jls 5.1.3 Narrowing Primitive Conversions
+ */
+ public int intValue() {
+ return (int)value;
+ }
+
+ /**
+ * Returns the value of this {@code Long} as a
+ * {@code long} value.
+ */
+ public long longValue() {
+ return value;
+ }
+
+ /**
+ * Returns the value of this {@code Long} as a {@code float} after
+ * a widening primitive conversion.
+ * @jls 5.1.2 Widening Primitive Conversions
+ */
+ public float floatValue() {
+ return (float)value;
+ }
+
+ /**
+ * Returns the value of this {@code Long} as a {@code double}
+ * after a widening primitive conversion.
+ * @jls 5.1.2 Widening Primitive Conversions
+ */
+ public double doubleValue() {
+ return (double)value;
+ }
+
+ /**
+ * Returns a {@code String} object representing this
+ * {@code Long}'s value. The value is converted to signed
+ * decimal representation and returned as a string, exactly as if
+ * the {@code long} value were given as an argument to the
+ * {@link java.lang.Long#toString(long)} method.
+ *
+ * @return a string representation of the value of this object in
+ * base 10.
+ */
+ public String toString() {
+ return toString(value);
+ }
+
+ /**
+ * Returns a hash code for this {@code Long}. The result is
+ * the exclusive OR of the two halves of the primitive
+ * {@code long} value held by this {@code Long}
+ * object. That is, the hashcode is the value of the expression:
+ *
+ * <blockquote>
+ * {@code (int)(this.longValue()^(this.longValue()>>>32))}
+ * </blockquote>
+ *
+ * @return a hash code value for this object.
+ */
+ @Override
+ public int hashCode() {
+ return Long.hashCode(value);
+ }
+
+ /**
+ * Returns a hash code for a {@code long} value; compatible with
+ * {@code Long.hashCode()}.
+ *
+ * @param value the value to hash
+ * @return a hash code value for a {@code long} value.
+ * @since 1.8
+ */
+ public static int hashCode(long value) {
+ return (int)(value ^ (value >>> 32));
+ }
+
+ /**
+ * Compares this object to the specified object. The result is
+ * {@code true} if and only if the argument is not
+ * {@code null} and is a {@code Long} object that
+ * contains the same {@code long} value as this object.
+ *
+ * @param obj the object to compare with.
+ * @return {@code true} if the objects are the same;
+ * {@code false} otherwise.
+ */
+ public boolean equals(Object obj) {
+ if (obj instanceof Long) {
+ return value == ((Long)obj).longValue();
+ }
+ return false;
+ }
+
+ /**
+ * Determines the {@code long} value of the system property
+ * with the specified name.
+ *
+ * <p>The first argument is treated as the name of a system
+ * property. System properties are accessible through the {@link
+ * java.lang.System#getProperty(java.lang.String)} method. The
+ * string value of this property is then interpreted as a {@code
+ * long} value using the grammar supported by {@link Long#decode decode}
+ * and a {@code Long} object representing this value is returned.
+ *
+ * <p>If there is no property with the specified name, if the
+ * specified name is empty or {@code null}, or if the property
+ * does not have the correct numeric format, then {@code null} is
+ * returned.
+ *
+ * <p>In other words, this method returns a {@code Long} object
+ * equal to the value of:
+ *
+ * <blockquote>
+ * {@code getLong(nm, null)}
+ * </blockquote>
+ *
+ * @param nm property name.
+ * @return the {@code Long} value of the property.
+ * @throws SecurityException for the same reasons as
+ * {@link System#getProperty(String) System.getProperty}
+ * @see java.lang.System#getProperty(java.lang.String)
+ * @see java.lang.System#getProperty(java.lang.String, java.lang.String)
+ */
+ public static Long getLong(String nm) {
+ return getLong(nm, null);
+ }
+
+ /**
+ * Determines the {@code long} value of the system property
+ * with the specified name.
+ *
+ * <p>The first argument is treated as the name of a system
+ * property. System properties are accessible through the {@link
+ * java.lang.System#getProperty(java.lang.String)} method. The
+ * string value of this property is then interpreted as a {@code
+ * long} value using the grammar supported by {@link Long#decode decode}
+ * and a {@code Long} object representing this value is returned.
+ *
+ * <p>The second argument is the default value. A {@code Long} object
+ * that represents the value of the second argument is returned if there
+ * is no property of the specified name, if the property does not have
+ * the correct numeric format, or if the specified name is empty or null.
+ *
+ * <p>In other words, this method returns a {@code Long} object equal
+ * to the value of:
+ *
+ * <blockquote>
+ * {@code getLong(nm, new Long(val))}
+ * </blockquote>
+ *
+ * but in practice it may be implemented in a manner such as:
+ *
+ * <blockquote><pre>
+ * Long result = getLong(nm, null);
+ * return (result == null) ? new Long(val) : result;
+ * </pre></blockquote>
+ *
+ * to avoid the unnecessary allocation of a {@code Long} object when
+ * the default value is not needed.
+ *
+ * @param nm property name.
+ * @param val default value.
+ * @return the {@code Long} value of the property.
+ * @throws SecurityException for the same reasons as
+ * {@link System#getProperty(String) System.getProperty}
+ * @see java.lang.System#getProperty(java.lang.String)
+ * @see java.lang.System#getProperty(java.lang.String, java.lang.String)
+ */
+ public static Long getLong(String nm, long val) {
+ Long result = Long.getLong(nm, null);
+ return (result == null) ? Long.valueOf(val) : result;
+ }
+
+ /**
+ * Returns the {@code long} value of the system property with
+ * the specified name. The first argument is treated as the name
+ * of a system property. System properties are accessible through
+ * the {@link java.lang.System#getProperty(java.lang.String)}
+ * method. The string value of this property is then interpreted
+ * as a {@code long} value, as per the
+ * {@link Long#decode decode} method, and a {@code Long} object
+ * representing this value is returned; in summary:
+ *
+ * <ul>
+ * <li>If the property value begins with the two ASCII characters
+ * {@code 0x} or the ASCII character {@code #}, not followed by
+ * a minus sign, then the rest of it is parsed as a hexadecimal integer
+ * exactly as for the method {@link #valueOf(java.lang.String, int)}
+ * with radix 16.
+ * <li>If the property value begins with the ASCII character
+ * {@code 0} followed by another character, it is parsed as
+ * an octal integer exactly as by the method {@link
+ * #valueOf(java.lang.String, int)} with radix 8.
+ * <li>Otherwise the property value is parsed as a decimal
+ * integer exactly as by the method
+ * {@link #valueOf(java.lang.String, int)} with radix 10.
+ * </ul>
+ *
+ * <p>Note that, in every case, neither {@code L}
+ * ({@code '\u005Cu004C'}) nor {@code l}
+ * ({@code '\u005Cu006C'}) is permitted to appear at the end
+ * of the property value as a type indicator, as would be
+ * permitted in Java programming language source code.
+ *
+ * <p>The second argument is the default value. The default value is
+ * returned if there is no property of the specified name, if the
+ * property does not have the correct numeric format, or if the
+ * specified name is empty or {@code null}.
+ *
+ * @param nm property name.
+ * @param val default value.
+ * @return the {@code Long} value of the property.
+ * @throws SecurityException for the same reasons as
+ * {@link System#getProperty(String) System.getProperty}
+ * @see System#getProperty(java.lang.String)
+ * @see System#getProperty(java.lang.String, java.lang.String)
+ */
+ public static Long getLong(String nm, Long val) {
+ String v = null;
+ try {
+ v = System.getProperty(nm);
+ } catch (IllegalArgumentException | NullPointerException e) {
+ }
+ if (v != null) {
+ try {
+ return Long.decode(v);
+ } catch (NumberFormatException e) {
+ }
+ }
+ return val;
+ }
+
+ /**
+ * Compares two {@code Long} objects numerically.
+ *
+ * @param anotherLong the {@code Long} to be compared.
+ * @return the value {@code 0} if this {@code Long} is
+ * equal to the argument {@code Long}; a value less than
+ * {@code 0} if this {@code Long} is numerically less
+ * than the argument {@code Long}; and a value greater
+ * than {@code 0} if this {@code Long} is numerically
+ * greater than the argument {@code Long} (signed
+ * comparison).
+ * @since 1.2
+ */
+ public int compareTo(Long anotherLong) {
+ return compare(this.value, anotherLong.value);
+ }
+
+ /**
+ * Compares two {@code long} values numerically.
+ * The value returned is identical to what would be returned by:
+ * <pre>
+ * Long.valueOf(x).compareTo(Long.valueOf(y))
+ * </pre>
+ *
+ * @param x the first {@code long} to compare
+ * @param y the second {@code long} to compare
+ * @return the value {@code 0} if {@code x == y};
+ * a value less than {@code 0} if {@code x < y}; and
+ * a value greater than {@code 0} if {@code x > y}
+ * @since 1.7
+ */
+ public static int compare(long x, long y) {
+ return (x < y) ? -1 : ((x == y) ? 0 : 1);
+ }
+
+ /**
+ * Compares two {@code long} values numerically treating the values
+ * as unsigned.
+ *
+ * @param x the first {@code long} to compare
+ * @param y the second {@code long} to compare
+ * @return the value {@code 0} if {@code x == y}; a value less
+ * than {@code 0} if {@code x < y} as unsigned values; and
+ * a value greater than {@code 0} if {@code x > y} as
+ * unsigned values
+ * @since 1.8
+ */
+ public static int compareUnsigned(long x, long y) {
+ return compare(x + MIN_VALUE, y + MIN_VALUE);
+ }
+
+
+ /**
+ * Returns the unsigned quotient of dividing the first argument by
+ * the second where each argument and the result is interpreted as
+ * an unsigned value.
+ *
+ * <p>Note that in two's complement arithmetic, the three other
+ * basic arithmetic operations of add, subtract, and multiply are
+ * bit-wise identical if the two operands are regarded as both
+ * being signed or both being unsigned. Therefore separate {@code
+ * addUnsigned}, etc. methods are not provided.
+ *
+ * @param dividend the value to be divided
+ * @param divisor the value doing the dividing
+ * @return the unsigned quotient of the first argument divided by
+ * the second argument
+ * @see #remainderUnsigned
+ * @since 1.8
+ */
+ public static long divideUnsigned(long dividend, long divisor) {
+ if (divisor < 0L) { // signed comparison
+ // Answer must be 0 or 1 depending on relative magnitude
+ // of dividend and divisor.
+ return (compareUnsigned(dividend, divisor)) < 0 ? 0L :1L;
+ }
+
+ if (dividend > 0) // Both inputs non-negative
+ return dividend/divisor;
+ else {
+ /*
+ * For simple code, leveraging BigInteger. Longer and faster
+ * code written directly in terms of operations on longs is
+ * possible; see "Hacker's Delight" for divide and remainder
+ * algorithms.
+ */
+ return toUnsignedBigInteger(dividend).
+ divide(toUnsignedBigInteger(divisor)).longValue();
+ }
+ }
+
+ /**
+ * Returns the unsigned remainder from dividing the first argument
+ * by the second where each argument and the result is interpreted
+ * as an unsigned value.
+ *
+ * @param dividend the value to be divided
+ * @param divisor the value doing the dividing
+ * @return the unsigned remainder of the first argument divided by
+ * the second argument
+ * @see #divideUnsigned
+ * @since 1.8
+ */
+ public static long remainderUnsigned(long dividend, long divisor) {
+ if (dividend > 0 && divisor > 0) { // signed comparisons
+ return dividend % divisor;
+ } else {
+ if (compareUnsigned(dividend, divisor) < 0) // Avoid explicit check for 0 divisor
+ return dividend;
+ else
+ return toUnsignedBigInteger(dividend).
+ remainder(toUnsignedBigInteger(divisor)).longValue();
+ }
+ }
+
+ // Bit Twiddling
+
+ /**
+ * The number of bits used to represent a {@code long} value in two's
+ * complement binary form.
+ *
+ * @since 1.5
+ */
+ @Native public static final int SIZE = 64;
+
+ /**
+ * The number of bytes used to represent a {@code long} value in two's
+ * complement binary form.
+ *
+ * @since 1.8
+ */
+ public static final int BYTES = SIZE / Byte.SIZE;
+
+ /**
+ * Returns a {@code long} value with at most a single one-bit, in the
+ * position of the highest-order ("leftmost") one-bit in the specified
+ * {@code long} value. Returns zero if the specified value has no
+ * one-bits in its two's complement binary representation, that is, if it
+ * is equal to zero.
+ *
+ * @param i the value whose highest one bit is to be computed
+ * @return a {@code long} value with a single one-bit, in the position
+ * of the highest-order one-bit in the specified value, or zero if
+ * the specified value is itself equal to zero.
+ * @since 1.5
+ */
+ public static long highestOneBit(long i) {
+ // HD, Figure 3-1
+ i |= (i >> 1);
+ i |= (i >> 2);
+ i |= (i >> 4);
+ i |= (i >> 8);
+ i |= (i >> 16);
+ i |= (i >> 32);
+ return i - (i >>> 1);
+ }
+
+ /**
+ * Returns a {@code long} value with at most a single one-bit, in the
+ * position of the lowest-order ("rightmost") one-bit in the specified
+ * {@code long} value. Returns zero if the specified value has no
+ * one-bits in its two's complement binary representation, that is, if it
+ * is equal to zero.
+ *
+ * @param i the value whose lowest one bit is to be computed
+ * @return a {@code long} value with a single one-bit, in the position
+ * of the lowest-order one-bit in the specified value, or zero if
+ * the specified value is itself equal to zero.
+ * @since 1.5
+ */
+ public static long lowestOneBit(long i) {
+ // HD, Section 2-1
+ return i & -i;
+ }
+
+ /**
+ * Returns the number of zero bits preceding the highest-order
+ * ("leftmost") one-bit in the two's complement binary representation
+ * of the specified {@code long} value. Returns 64 if the
+ * specified value has no one-bits in its two's complement representation,
+ * in other words if it is equal to zero.
+ *
+ * <p>Note that this method is closely related to the logarithm base 2.
+ * For all positive {@code long} values x:
+ * <ul>
+ * <li>floor(log<sub>2</sub>(x)) = {@code 63 - numberOfLeadingZeros(x)}
+ * <li>ceil(log<sub>2</sub>(x)) = {@code 64 - numberOfLeadingZeros(x - 1)}
+ * </ul>
+ *
+ * @param i the value whose number of leading zeros is to be computed
+ * @return the number of zero bits preceding the highest-order
+ * ("leftmost") one-bit in the two's complement binary representation
+ * of the specified {@code long} value, or 64 if the value
+ * is equal to zero.
+ * @since 1.5
+ */
+ public static int numberOfLeadingZeros(long i) {
+ // HD, Figure 5-6
+ if (i == 0)
+ return 64;
+ int n = 1;
+ int x = (int)(i >>> 32);
+ if (x == 0) { n += 32; x = (int)i; }
+ if (x >>> 16 == 0) { n += 16; x <<= 16; }
+ if (x >>> 24 == 0) { n += 8; x <<= 8; }
+ if (x >>> 28 == 0) { n += 4; x <<= 4; }
+ if (x >>> 30 == 0) { n += 2; x <<= 2; }
+ n -= x >>> 31;
+ return n;
+ }
+
+ /**
+ * Returns the number of zero bits following the lowest-order ("rightmost")
+ * one-bit in the two's complement binary representation of the specified
+ * {@code long} value. Returns 64 if the specified value has no
+ * one-bits in its two's complement representation, in other words if it is
+ * equal to zero.
+ *
+ * @param i the value whose number of trailing zeros is to be computed
+ * @return the number of zero bits following the lowest-order ("rightmost")
+ * one-bit in the two's complement binary representation of the
+ * specified {@code long} value, or 64 if the value is equal
+ * to zero.
+ * @since 1.5
+ */
+ public static int numberOfTrailingZeros(long i) {
+ // HD, Figure 5-14
+ int x, y;
+ if (i == 0) return 64;
+ int n = 63;
+ y = (int)i; if (y != 0) { n = n -32; x = y; } else x = (int)(i>>>32);
+ y = x <<16; if (y != 0) { n = n -16; x = y; }
+ y = x << 8; if (y != 0) { n = n - 8; x = y; }
+ y = x << 4; if (y != 0) { n = n - 4; x = y; }
+ y = x << 2; if (y != 0) { n = n - 2; x = y; }
+ return n - ((x << 1) >>> 31);
+ }
+
+ /**
+ * Returns the number of one-bits in the two's complement binary
+ * representation of the specified {@code long} value. This function is
+ * sometimes referred to as the <i>population count</i>.
+ *
+ * @param i the value whose bits are to be counted
+ * @return the number of one-bits in the two's complement binary
+ * representation of the specified {@code long} value.
+ * @since 1.5
+ */
+ public static int bitCount(long i) {
+ // HD, Figure 5-14
+ i = i - ((i >>> 1) & 0x5555555555555555L);
+ i = (i & 0x3333333333333333L) + ((i >>> 2) & 0x3333333333333333L);
+ i = (i + (i >>> 4)) & 0x0f0f0f0f0f0f0f0fL;
+ i = i + (i >>> 8);
+ i = i + (i >>> 16);
+ i = i + (i >>> 32);
+ return (int)i & 0x7f;
+ }
+
+ /**
+ * Returns the value obtained by rotating the two's complement binary
+ * representation of the specified {@code long} value left by the
+ * specified number of bits. (Bits shifted out of the left hand, or
+ * high-order, side reenter on the right, or low-order.)
+ *
+ * <p>Note that left rotation with a negative distance is equivalent to
+ * right rotation: {@code rotateLeft(val, -distance) == rotateRight(val,
+ * distance)}. Note also that rotation by any multiple of 64 is a
+ * no-op, so all but the last six bits of the rotation distance can be
+ * ignored, even if the distance is negative: {@code rotateLeft(val,
+ * distance) == rotateLeft(val, distance & 0x3F)}.
+ *
+ * @param i the value whose bits are to be rotated left
+ * @param distance the number of bit positions to rotate left
+ * @return the value obtained by rotating the two's complement binary
+ * representation of the specified {@code long} value left by the
+ * specified number of bits.
+ * @since 1.5
+ */
+ public static long rotateLeft(long i, int distance) {
+ return (i << distance) | (i >>> -distance);
+ }
+
+ /**
+ * Returns the value obtained by rotating the two's complement binary
+ * representation of the specified {@code long} value right by the
+ * specified number of bits. (Bits shifted out of the right hand, or
+ * low-order, side reenter on the left, or high-order.)
+ *
+ * <p>Note that right rotation with a negative distance is equivalent to
+ * left rotation: {@code rotateRight(val, -distance) == rotateLeft(val,
+ * distance)}. Note also that rotation by any multiple of 64 is a
+ * no-op, so all but the last six bits of the rotation distance can be
+ * ignored, even if the distance is negative: {@code rotateRight(val,
+ * distance) == rotateRight(val, distance & 0x3F)}.
+ *
+ * @param i the value whose bits are to be rotated right
+ * @param distance the number of bit positions to rotate right
+ * @return the value obtained by rotating the two's complement binary
+ * representation of the specified {@code long} value right by the
+ * specified number of bits.
+ * @since 1.5
+ */
+ public static long rotateRight(long i, int distance) {
+ return (i >>> distance) | (i << -distance);
+ }
+
+ /**
+ * Returns the value obtained by reversing the order of the bits in the
+ * two's complement binary representation of the specified {@code long}
+ * value.
+ *
+ * @param i the value to be reversed
+ * @return the value obtained by reversing order of the bits in the
+ * specified {@code long} value.
+ * @since 1.5
+ */
+ public static long reverse(long i) {
+ // HD, Figure 7-1
+ i = (i & 0x5555555555555555L) << 1 | (i >>> 1) & 0x5555555555555555L;
+ i = (i & 0x3333333333333333L) << 2 | (i >>> 2) & 0x3333333333333333L;
+ i = (i & 0x0f0f0f0f0f0f0f0fL) << 4 | (i >>> 4) & 0x0f0f0f0f0f0f0f0fL;
+ i = (i & 0x00ff00ff00ff00ffL) << 8 | (i >>> 8) & 0x00ff00ff00ff00ffL;
+ i = (i << 48) | ((i & 0xffff0000L) << 16) |
+ ((i >>> 16) & 0xffff0000L) | (i >>> 48);
+ return i;
+ }
+
+ /**
+ * Returns the signum function of the specified {@code long} value. (The
+ * return value is -1 if the specified value is negative; 0 if the
+ * specified value is zero; and 1 if the specified value is positive.)
+ *
+ * @param i the value whose signum is to be computed
+ * @return the signum function of the specified {@code long} value.
+ * @since 1.5
+ */
+ public static int signum(long i) {
+ // HD, Section 2-7
+ return (int) ((i >> 63) | (-i >>> 63));
+ }
+
+ /**
+ * Returns the value obtained by reversing the order of the bytes in the
+ * two's complement representation of the specified {@code long} value.
+ *
+ * @param i the value whose bytes are to be reversed
+ * @return the value obtained by reversing the bytes in the specified
+ * {@code long} value.
+ * @since 1.5
+ */
+ public static long reverseBytes(long i) {
+ i = (i & 0x00ff00ff00ff00ffL) << 8 | (i >>> 8) & 0x00ff00ff00ff00ffL;
+ return (i << 48) | ((i & 0xffff0000L) << 16) |
+ ((i >>> 16) & 0xffff0000L) | (i >>> 48);
+ }
+
+ /**
+ * Adds two {@code long} values together as per the + operator.
+ *
+ * @param a the first operand
+ * @param b the second operand
+ * @return the sum of {@code a} and {@code b}
+ * @see java.util.function.BinaryOperator
+ * @since 1.8
+ */
+ public static long sum(long a, long b) {
+ return a + b;
+ }
+
+ /**
+ * Returns the greater of two {@code long} values
+ * as if by calling {@link Math#max(long, long) Math.max}.
+ *
+ * @param a the first operand
+ * @param b the second operand
+ * @return the greater of {@code a} and {@code b}
+ * @see java.util.function.BinaryOperator
+ * @since 1.8
+ */
+ public static long max(long a, long b) {
+ return Math.max(a, b);
+ }
+
+ /**
+ * Returns the smaller of two {@code long} values
+ * as if by calling {@link Math#min(long, long) Math.min}.
+ *
+ * @param a the first operand
+ * @param b the second operand
+ * @return the smaller of {@code a} and {@code b}
+ * @see java.util.function.BinaryOperator
+ * @since 1.8
+ */
+ public static long min(long a, long b) {
+ return Math.min(a, b);
+ }
+
+ /** use serialVersionUID from JDK 1.0.2 for interoperability */
+ @Native private static final long serialVersionUID = 4290774380558885855L;
+}
diff --git a/java/lang/Math.annotated.java b/java/lang/Math.annotated.java
new file mode 100644
index 0000000..46fae4e
--- /dev/null
+++ b/java/lang/Math.annotated.java
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 2013, 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;
+
+import java.util.Random;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Math {
+
+Math() { throw new RuntimeException("Stub!"); }
+
+public static native double sin(double a);
+
+public static native double cos(double a);
+
+public static native double tan(double a);
+
+public static native double asin(double a);
+
+public static native double acos(double a);
+
+public static native double atan(double a);
+
+public static double toRadians(double angdeg) { throw new RuntimeException("Stub!"); }
+
+public static double toDegrees(double angrad) { throw new RuntimeException("Stub!"); }
+
+public static native double exp(double a);
+
+public static native double log(double a);
+
+public static native double log10(double a);
+
+public static native double sqrt(double a);
+
+public static native double cbrt(double a);
+
+public static native double IEEEremainder(double f1, double f2);
+
+public static native double ceil(double a);
+
+public static native double floor(double a);
+
+public static native double rint(double a);
+
+public static native double atan2(double y, double x);
+
+public static native double pow(double a, double b);
+
+public static int round(float a) { throw new RuntimeException("Stub!"); }
+
+public static long round(double a) { throw new RuntimeException("Stub!"); }
+
+public static double random() { throw new RuntimeException("Stub!"); }
+
[email protected]
+public static long randomLongInternal() { throw new RuntimeException("Stub!"); }
+
+public static int addExact(int x, int y) { throw new RuntimeException("Stub!"); }
+
+public static long addExact(long x, long y) { throw new RuntimeException("Stub!"); }
+
+public static int subtractExact(int x, int y) { throw new RuntimeException("Stub!"); }
+
+public static long subtractExact(long x, long y) { throw new RuntimeException("Stub!"); }
+
+public static int multiplyExact(int x, int y) { throw new RuntimeException("Stub!"); }
+
+public static long multiplyExact(long x, long y) { throw new RuntimeException("Stub!"); }
+
+public static int incrementExact(int a) { throw new RuntimeException("Stub!"); }
+
+public static long incrementExact(long a) { throw new RuntimeException("Stub!"); }
+
+public static int decrementExact(int a) { throw new RuntimeException("Stub!"); }
+
+public static long decrementExact(long a) { throw new RuntimeException("Stub!"); }
+
+public static int negateExact(int a) { throw new RuntimeException("Stub!"); }
+
+public static long negateExact(long a) { throw new RuntimeException("Stub!"); }
+
+public static int toIntExact(long value) { throw new RuntimeException("Stub!"); }
+
+public static int floorDiv(int x, int y) { throw new RuntimeException("Stub!"); }
+
+public static long floorDiv(long x, long y) { throw new RuntimeException("Stub!"); }
+
+public static int floorMod(int x, int y) { throw new RuntimeException("Stub!"); }
+
+public static long floorMod(long x, long y) { throw new RuntimeException("Stub!"); }
+
+public static int abs(int a) { throw new RuntimeException("Stub!"); }
+
+public static long abs(long a) { throw new RuntimeException("Stub!"); }
+
+public static float abs(float a) { throw new RuntimeException("Stub!"); }
+
+public static double abs(double a) { throw new RuntimeException("Stub!"); }
+
+public static int max(int a, int b) { throw new RuntimeException("Stub!"); }
+
+public static long max(long a, long b) { throw new RuntimeException("Stub!"); }
+
+public static float max(float a, float b) { throw new RuntimeException("Stub!"); }
+
+public static double max(double a, double b) { throw new RuntimeException("Stub!"); }
+
+public static int min(int a, int b) { throw new RuntimeException("Stub!"); }
+
+public static long min(long a, long b) { throw new RuntimeException("Stub!"); }
+
+public static float min(float a, float b) { throw new RuntimeException("Stub!"); }
+
+public static double min(double a, double b) { throw new RuntimeException("Stub!"); }
+
+public static double ulp(double d) { throw new RuntimeException("Stub!"); }
+
+public static float ulp(float f) { throw new RuntimeException("Stub!"); }
+
+public static double signum(double d) { throw new RuntimeException("Stub!"); }
+
+public static float signum(float f) { throw new RuntimeException("Stub!"); }
+
+public static native double sinh(double x);
+
+public static native double cosh(double x);
+
+public static native double tanh(double x);
+
+public static native double hypot(double x, double y);
+
+public static native double expm1(double x);
+
+public static native double log1p(double x);
+
+public static double copySign(double magnitude, double sign) { throw new RuntimeException("Stub!"); }
+
+public static float copySign(float magnitude, float sign) { throw new RuntimeException("Stub!"); }
+
+public static int getExponent(float f) { throw new RuntimeException("Stub!"); }
+
+public static int getExponent(double d) { throw new RuntimeException("Stub!"); }
+
+public static double nextAfter(double start, double direction) { throw new RuntimeException("Stub!"); }
+
+public static float nextAfter(float start, double direction) { throw new RuntimeException("Stub!"); }
+
+public static double nextUp(double d) { throw new RuntimeException("Stub!"); }
+
+public static float nextUp(float f) { throw new RuntimeException("Stub!"); }
+
+public static double nextDown(double d) { throw new RuntimeException("Stub!"); }
+
+public static float nextDown(float f) { throw new RuntimeException("Stub!"); }
+
+public static double scalb(double d, int scaleFactor) { throw new RuntimeException("Stub!"); }
+
+public static float scalb(float f, int scaleFactor) { throw new RuntimeException("Stub!"); }
+
+public static final double E = 2.718281828459045;
+
+public static final double PI = 3.141592653589793;
+}
+
diff --git a/java/lang/Math.java b/java/lang/Math.java
new file mode 100644
index 0000000..17cbf6d
--- /dev/null
+++ b/java/lang/Math.java
@@ -0,0 +1,2397 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 2013, 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;
+import dalvik.annotation.optimization.CriticalNative;
+import java.util.Random;
+
+import sun.misc.FloatConsts;
+import sun.misc.DoubleConsts;
+
+// Android-note: Document that the results from Math are based on libm's behavior.
+// For performance, Android implements many of the methods in this class in terms of the underlying
+// OS's libm functions. libm has well-defined behavior for special cases. Where known these are
+// marked with the tag above and the documentation has been modified as needed.
+/**
+ * The class {@code Math} contains methods for performing basic
+ * numeric operations such as the elementary exponential, logarithm,
+ * square root, and trigonometric functions.
+ *
+ * <p>Unlike some of the numeric methods of class
+ * {@code StrictMath}, all implementations of the equivalent
+ * functions of class {@code Math} are not defined to return the
+ * bit-for-bit same results. This relaxation permits
+ * better-performing implementations where strict reproducibility is
+ * not required.
+ *
+ * <p>By default many of the {@code Math} methods simply call
+ * the equivalent method in {@code StrictMath} for their
+ * implementation. Code generators are encouraged to use
+ * platform-specific native libraries or microprocessor instructions,
+ * where available, to provide higher-performance implementations of
+ * {@code Math} methods. Such higher-performance
+ * implementations still must conform to the specification for
+ * {@code Math}.
+ *
+ * <p>The quality of implementation specifications concern two
+ * properties, accuracy of the returned result and monotonicity of the
+ * method. Accuracy of the floating-point {@code Math} methods is
+ * measured in terms of <i>ulps</i>, units in the last place. For a
+ * given floating-point format, an {@linkplain #ulp(double) ulp} of a
+ * specific real number value is the distance between the two
+ * floating-point values bracketing that numerical value. When
+ * discussing the accuracy of a method as a whole rather than at a
+ * specific argument, the number of ulps cited is for the worst-case
+ * error at any argument. If a method always has an error less than
+ * 0.5 ulps, the method always returns the floating-point number
+ * nearest the exact result; such a method is <i>correctly
+ * rounded</i>. A correctly rounded method is generally the best a
+ * floating-point approximation can be; however, it is impractical for
+ * many floating-point methods to be correctly rounded. Instead, for
+ * the {@code Math} class, a larger error bound of 1 or 2 ulps is
+ * allowed for certain methods. Informally, with a 1 ulp error bound,
+ * when the exact result is a representable number, the exact result
+ * should be returned as the computed result; otherwise, either of the
+ * two floating-point values which bracket the exact result may be
+ * returned. For exact results large in magnitude, one of the
+ * endpoints of the bracket may be infinite. Besides accuracy at
+ * individual arguments, maintaining proper relations between the
+ * method at different arguments is also important. Therefore, most
+ * methods with more than 0.5 ulp errors are required to be
+ * <i>semi-monotonic</i>: whenever the mathematical function is
+ * non-decreasing, so is the floating-point approximation, likewise,
+ * whenever the mathematical function is non-increasing, so is the
+ * floating-point approximation. Not all approximations that have 1
+ * ulp accuracy will automatically meet the monotonicity requirements.
+ *
+ * <p>
+ * The platform uses signed two's complement integer arithmetic with
+ * int and long primitive types. The developer should choose
+ * the primitive type to ensure that arithmetic operations consistently
+ * produce correct results, which in some cases means the operations
+ * will not overflow the range of values of the computation.
+ * The best practice is to choose the primitive type and algorithm to avoid
+ * overflow. In cases where the size is {@code int} or {@code long} and
+ * overflow errors need to be detected, the methods {@code addExact},
+ * {@code subtractExact}, {@code multiplyExact}, and {@code toIntExact}
+ * throw an {@code ArithmeticException} when the results overflow.
+ * For other arithmetic operations such as divide, absolute value,
+ * increment, decrement, and negation overflow occurs only with
+ * a specific minimum or maximum value and should be checked against
+ * the minimum or maximum as appropriate.
+ *
+ * @author unascribed
+ * @author Joseph D. Darcy
+ * @since JDK1.0
+ */
+
+public final class Math {
+
+ // Android-changed: Numerous methods in this class are re-implemented in native for performance.
+ // Those methods are also annotated @CriticalNative.
+
+ /**
+ * Don't let anyone instantiate this class.
+ */
+ private Math() {}
+
+ /**
+ * The {@code double} value that is closer than any other to
+ * <i>e</i>, the base of the natural logarithms.
+ */
+ public static final double E = 2.7182818284590452354;
+
+ /**
+ * The {@code double} value that is closer than any other to
+ * <i>pi</i>, the ratio of the circumference of a circle to its
+ * diameter.
+ */
+ public static final double PI = 3.14159265358979323846;
+
+ /**
+ * Returns the trigonometric sine of an angle. Special cases:
+ * <ul><li>If the argument is NaN or an infinity, then the
+ * result is NaN.
+ * <li>If the argument is zero, then the result is a zero with the
+ * same sign as the argument.</ul>
+ *
+ * <p>The computed result must be within 1 ulp of the exact result.
+ * Results must be semi-monotonic.
+ *
+ * @param a an angle, in radians.
+ * @return the sine of the argument.
+ */
+ @CriticalNative
+ public static native double sin(double a);
+
+ /**
+ * Returns the trigonometric cosine of an angle. Special cases:
+ * <ul><li>If the argument is NaN or an infinity, then the
+ * result is NaN.</ul>
+ *
+ * <p>The computed result must be within 1 ulp of the exact result.
+ * Results must be semi-monotonic.
+ *
+ * @param a an angle, in radians.
+ * @return the cosine of the argument.
+ */
+ @CriticalNative
+ public static native double cos(double a);
+
+ /**
+ * Returns the trigonometric tangent of an angle. Special cases:
+ * <ul><li>If the argument is NaN or an infinity, then the result
+ * is NaN.
+ * <li>If the argument is zero, then the result is a zero with the
+ * same sign as the argument.</ul>
+ *
+ * <p>The computed result must be within 1 ulp of the exact result.
+ * Results must be semi-monotonic.
+ *
+ * @param a an angle, in radians.
+ * @return the tangent of the argument.
+ */
+ @CriticalNative
+ public static native double tan(double a);
+
+ /**
+ * Returns the arc sine of a value; the returned angle is in the
+ * range -<i>pi</i>/2 through <i>pi</i>/2. Special cases:
+ * <ul><li>If the argument is NaN or its absolute value is greater
+ * than 1, then the result is NaN.
+ * <li>If the argument is zero, then the result is a zero with the
+ * same sign as the argument.</ul>
+ *
+ * <p>The computed result must be within 1 ulp of the exact result.
+ * Results must be semi-monotonic.
+ *
+ * @param a the value whose arc sine is to be returned.
+ * @return the arc sine of the argument.
+ */
+ @CriticalNative
+ public static native double asin(double a);
+
+ /**
+ * Returns the arc cosine of a value; the returned angle is in the
+ * range 0.0 through <i>pi</i>. Special case:
+ * <ul><li>If the argument is NaN or its absolute value is greater
+ * than 1, then the result is NaN.</ul>
+ *
+ * <p>The computed result must be within 1 ulp of the exact result.
+ * Results must be semi-monotonic.
+ *
+ * @param a the value whose arc cosine is to be returned.
+ * @return the arc cosine of the argument.
+ */
+ @CriticalNative
+ public static native double acos(double a);
+
+ /**
+ * Returns the arc tangent of a value; the returned angle is in the
+ * range -<i>pi</i>/2 through <i>pi</i>/2. Special cases:
+ * <ul><li>If the argument is NaN, then the result is NaN.
+ * <li>If the argument is zero, then the result is a zero with the
+ * same sign as the argument.</ul>
+ *
+ * <p>The computed result must be within 1 ulp of the exact result.
+ * Results must be semi-monotonic.
+ *
+ * @param a the value whose arc tangent is to be returned.
+ * @return the arc tangent of the argument.
+ */
+ @CriticalNative
+ public static native double atan(double a);
+
+ /**
+ * Converts an angle measured in degrees to an approximately
+ * equivalent angle measured in radians. The conversion from
+ * degrees to radians is generally inexact.
+ *
+ * @param angdeg an angle, in degrees
+ * @return the measurement of the angle {@code angdeg}
+ * in radians.
+ * @since 1.2
+ */
+ public static double toRadians(double angdeg) {
+ return angdeg / 180.0 * PI;
+ }
+
+ /**
+ * Converts an angle measured in radians to an approximately
+ * equivalent angle measured in degrees. The conversion from
+ * radians to degrees is generally inexact; users should
+ * <i>not</i> expect {@code cos(toRadians(90.0))} to exactly
+ * equal {@code 0.0}.
+ *
+ * @param angrad an angle, in radians
+ * @return the measurement of the angle {@code angrad}
+ * in degrees.
+ * @since 1.2
+ */
+ public static double toDegrees(double angrad) {
+ return angrad * 180.0 / PI;
+ }
+
+ /**
+ * Returns Euler's number <i>e</i> raised to the power of a
+ * {@code double} value. Special cases:
+ * <ul><li>If the argument is NaN, the result is NaN.
+ * <li>If the argument is positive infinity, then the result is
+ * positive infinity.
+ * <li>If the argument is negative infinity, then the result is
+ * positive zero.</ul>
+ *
+ * <p>The computed result must be within 1 ulp of the exact result.
+ * Results must be semi-monotonic.
+ *
+ * @param a the exponent to raise <i>e</i> to.
+ * @return the value <i>e</i><sup>{@code a}</sup>,
+ * where <i>e</i> is the base of the natural logarithms.
+ */
+ @CriticalNative
+ public static native double exp(double a);
+
+ /**
+ * Returns the natural logarithm (base <i>e</i>) of a {@code double}
+ * value. Special cases:
+ * <ul><li>If the argument is NaN or less than zero, then the result
+ * is NaN.
+ * <li>If the argument is positive infinity, then the result is
+ * positive infinity.
+ * <li>If the argument is positive zero or negative zero, then the
+ * result is negative infinity.</ul>
+ *
+ * <p>The computed result must be within 1 ulp of the exact result.
+ * Results must be semi-monotonic.
+ *
+ * @param a a value
+ * @return the value ln {@code a}, the natural logarithm of
+ * {@code a}.
+ */
+ @CriticalNative
+ public static native double log(double a);
+
+ /**
+ * Returns the base 10 logarithm of a {@code double} value.
+ * Special cases:
+ *
+ * <ul><li>If the argument is NaN or less than zero, then the result
+ * is NaN.
+ * <li>If the argument is positive infinity, then the result is
+ * positive infinity.
+ * <li>If the argument is positive zero or negative zero, then the
+ * result is negative infinity.
+ * <li> If the argument is equal to 10<sup><i>n</i></sup> for
+ * integer <i>n</i>, then the result is <i>n</i>.
+ * </ul>
+ *
+ * <p>The computed result must be within 1 ulp of the exact result.
+ * Results must be semi-monotonic.
+ *
+ * @param a a value
+ * @return the base 10 logarithm of {@code a}.
+ * @since 1.5
+ */
+ @CriticalNative
+ public static native double log10(double a);
+
+ /**
+ * Returns the correctly rounded positive square root of a
+ * {@code double} value.
+ * Special cases:
+ * <ul><li>If the argument is NaN or less than zero, then the result
+ * is NaN.
+ * <li>If the argument is positive infinity, then the result is positive
+ * infinity.
+ * <li>If the argument is positive zero or negative zero, then the
+ * result is the same as the argument.</ul>
+ * Otherwise, the result is the {@code double} value closest to
+ * the true mathematical square root of the argument value.
+ *
+ * @param a a value.
+ * @return the positive square root of {@code a}.
+ * If the argument is NaN or less than zero, the result is NaN.
+ */
+ @CriticalNative
+ public static native double sqrt(double a);
+
+
+ /**
+ * Returns the cube root of a {@code double} value. For
+ * positive finite {@code x}, {@code cbrt(-x) ==
+ * -cbrt(x)}; that is, the cube root of a negative value is
+ * the negative of the cube root of that value's magnitude.
+ *
+ * Special cases:
+ *
+ * <ul>
+ *
+ * <li>If the argument is NaN, then the result is NaN.
+ *
+ * <li>If the argument is infinite, then the result is an infinity
+ * with the same sign as the argument.
+ *
+ * <li>If the argument is zero, then the result is a zero with the
+ * same sign as the argument.
+ *
+ * </ul>
+ *
+ * <p>The computed result must be within 1 ulp of the exact result.
+ *
+ * @param a a value.
+ * @return the cube root of {@code a}.
+ * @since 1.5
+ */
+ @CriticalNative
+ public static native double cbrt(double a);
+
+ /**
+ * Computes the remainder operation on two arguments as prescribed
+ * by the IEEE 754 standard.
+ * The remainder value is mathematically equal to
+ * <code>f1 - f2</code> × <i>n</i>,
+ * where <i>n</i> is the mathematical integer closest to the exact
+ * mathematical value of the quotient {@code f1/f2}, and if two
+ * mathematical integers are equally close to {@code f1/f2},
+ * then <i>n</i> is the integer that is even. If the remainder is
+ * zero, its sign is the same as the sign of the first argument.
+ * Special cases:
+ * <ul><li>If either argument is NaN, or the first argument is infinite,
+ * or the second argument is positive zero or negative zero, then the
+ * result is NaN.
+ * <li>If the first argument is finite and the second argument is
+ * infinite, then the result is the same as the first argument.</ul>
+ *
+ * @param f1 the dividend.
+ * @param f2 the divisor.
+ * @return the remainder when {@code f1} is divided by
+ * {@code f2}.
+ */
+ @CriticalNative
+ public static native double IEEEremainder(double f1, double f2);
+
+ /**
+ * Returns the smallest (closest to negative infinity)
+ * {@code double} value that is greater than or equal to the
+ * argument and is equal to a mathematical integer. Special cases:
+ * <ul><li>If the argument value is already equal to a
+ * mathematical integer, then the result is the same as the
+ * argument. <li>If the argument is NaN or an infinity or
+ * positive zero or negative zero, then the result is the same as
+ * the argument. <li>If the argument value is less than zero but
+ * greater than -1.0, then the result is negative zero.</ul> Note
+ * that the value of {@code Math.ceil(x)} is exactly the
+ * value of {@code -Math.floor(-x)}.
+ *
+ *
+ * @param a a value.
+ * @return the smallest (closest to negative infinity)
+ * floating-point value that is greater than or equal to
+ * the argument and is equal to a mathematical integer.
+ */
+ @CriticalNative
+ public static native double ceil(double a);
+
+ /**
+ * Returns the largest (closest to positive infinity)
+ * {@code double} value that is less than or equal to the
+ * argument and is equal to a mathematical integer. Special cases:
+ * <ul><li>If the argument value is already equal to a
+ * mathematical integer, then the result is the same as the
+ * argument. <li>If the argument is NaN or an infinity or
+ * positive zero or negative zero, then the result is the same as
+ * the argument.</ul>
+ *
+ * @param a a value.
+ * @return the largest (closest to positive infinity)
+ * floating-point value that less than or equal to the argument
+ * and is equal to a mathematical integer.
+ */
+ @CriticalNative
+ public static native double floor(double a);
+
+ /**
+ * Returns the {@code double} value that is closest in value
+ * to the argument and is equal to a mathematical integer. If two
+ * {@code double} values that are mathematical integers are
+ * equally close, the result is the integer value that is
+ * even. Special cases:
+ * <ul><li>If the argument value is already equal to a mathematical
+ * integer, then the result is the same as the argument.
+ * <li>If the argument is NaN or an infinity or positive zero or negative
+ * zero, then the result is the same as the argument.</ul>
+ *
+ * @param a a {@code double} value.
+ * @return the closest floating-point value to {@code a} that is
+ * equal to a mathematical integer.
+ */
+ @CriticalNative
+ public static native double rint(double a);
+
+ /**
+ * Returns the angle <i>theta</i> from the conversion of rectangular
+ * coordinates ({@code x}, {@code y}) to polar
+ * coordinates (r, <i>theta</i>).
+ * This method computes the phase <i>theta</i> by computing an arc tangent
+ * of {@code y/x} in the range of -<i>pi</i> to <i>pi</i>. Special
+ * cases:
+ * <ul><li>If either argument is NaN, then the result is NaN.
+ * <li>If the first argument is positive zero and the second argument
+ * is positive, or the first argument is positive and finite and the
+ * second argument is positive infinity, then the result is positive
+ * zero.
+ * <li>If the first argument is negative zero and the second argument
+ * is positive, or the first argument is negative and finite and the
+ * second argument is positive infinity, then the result is negative zero.
+ * <li>If the first argument is positive zero and the second argument
+ * is negative, or the first argument is positive and finite and the
+ * second argument is negative infinity, then the result is the
+ * {@code double} value closest to <i>pi</i>.
+ * <li>If the first argument is negative zero and the second argument
+ * is negative, or the first argument is negative and finite and the
+ * second argument is negative infinity, then the result is the
+ * {@code double} value closest to -<i>pi</i>.
+ * <li>If the first argument is positive and the second argument is
+ * positive zero or negative zero, or the first argument is positive
+ * infinity and the second argument is finite, then the result is the
+ * {@code double} value closest to <i>pi</i>/2.
+ * <li>If the first argument is negative and the second argument is
+ * positive zero or negative zero, or the first argument is negative
+ * infinity and the second argument is finite, then the result is the
+ * {@code double} value closest to -<i>pi</i>/2.
+ * <li>If both arguments are positive infinity, then the result is the
+ * {@code double} value closest to <i>pi</i>/4.
+ * <li>If the first argument is positive infinity and the second argument
+ * is negative infinity, then the result is the {@code double}
+ * value closest to 3*<i>pi</i>/4.
+ * <li>If the first argument is negative infinity and the second argument
+ * is positive infinity, then the result is the {@code double} value
+ * closest to -<i>pi</i>/4.
+ * <li>If both arguments are negative infinity, then the result is the
+ * {@code double} value closest to -3*<i>pi</i>/4.</ul>
+ *
+ * <p>The computed result must be within 2 ulps of the exact result.
+ * Results must be semi-monotonic.
+ *
+ * @param y the ordinate coordinate
+ * @param x the abscissa coordinate
+ * @return the <i>theta</i> component of the point
+ * (<i>r</i>, <i>theta</i>)
+ * in polar coordinates that corresponds to the point
+ * (<i>x</i>, <i>y</i>) in Cartesian coordinates.
+ */
+ @CriticalNative
+ public static native double atan2(double y, double x);
+
+ // Android-changed: Document that the results from Math are based on libm's behavior.
+ // The cases known to differ with libm's pow():
+ // If the first argument is 1.0 then result is always 1.0 (not NaN).
+ // If the first argument is -1.0 and the second argument is infinite, the result is 1.0 (not
+ // NaN).
+ /**
+ * Returns the value of the first argument raised to the power of the
+ * second argument. Special cases:
+ *
+ * <ul><li>If the second argument is positive or negative zero, then the
+ * result is 1.0.
+ * <li>If the second argument is 1.0, then the result is the same as the
+ * first argument.
+ * <li>If the first argument is 1.0, then the result is 1.0.
+ * <li>If the second argument is NaN, then the result is NaN except where the first argument is
+ * 1.0.
+ * <li>If the first argument is NaN and the second argument is nonzero,
+ * then the result is NaN.
+ *
+ * <li>If
+ * <ul>
+ * <li>the absolute value of the first argument is greater than 1
+ * and the second argument is positive infinity, or
+ * <li>the absolute value of the first argument is less than 1 and
+ * the second argument is negative infinity,
+ * </ul>
+ * then the result is positive infinity.
+ *
+ * <li>If
+ * <ul>
+ * <li>the absolute value of the first argument is greater than 1 and
+ * the second argument is negative infinity, or
+ * <li>the absolute value of the
+ * first argument is less than 1 and the second argument is positive
+ * infinity,
+ * </ul>
+ * then the result is positive zero.
+ *
+ * <li>If the absolute value of the first argument equals 1 and the
+ * second argument is infinite, then the result is 1.0.
+ *
+ * <li>If
+ * <ul>
+ * <li>the first argument is positive zero and the second argument
+ * is greater than zero, or
+ * <li>the first argument is positive infinity and the second
+ * argument is less than zero,
+ * </ul>
+ * then the result is positive zero.
+ *
+ * <li>If
+ * <ul>
+ * <li>the first argument is positive zero and the second argument
+ * is less than zero, or
+ * <li>the first argument is positive infinity and the second
+ * argument is greater than zero,
+ * </ul>
+ * then the result is positive infinity.
+ *
+ * <li>If
+ * <ul>
+ * <li>the first argument is negative zero and the second argument
+ * is greater than zero but not a finite odd integer, or
+ * <li>the first argument is negative infinity and the second
+ * argument is less than zero but not a finite odd integer,
+ * </ul>
+ * then the result is positive zero.
+ *
+ * <li>If
+ * <ul>
+ * <li>the first argument is negative zero and the second argument
+ * is a positive finite odd integer, or
+ * <li>the first argument is negative infinity and the second
+ * argument is a negative finite odd integer,
+ * </ul>
+ * then the result is negative zero.
+ *
+ * <li>If
+ * <ul>
+ * <li>the first argument is negative zero and the second argument
+ * is less than zero but not a finite odd integer, or
+ * <li>the first argument is negative infinity and the second
+ * argument is greater than zero but not a finite odd integer,
+ * </ul>
+ * then the result is positive infinity.
+ *
+ * <li>If
+ * <ul>
+ * <li>the first argument is negative zero and the second argument
+ * is a negative finite odd integer, or
+ * <li>the first argument is negative infinity and the second
+ * argument is a positive finite odd integer,
+ * </ul>
+ * then the result is negative infinity.
+ *
+ * <li>If the first argument is finite and less than zero
+ * <ul>
+ * <li> if the second argument is a finite even integer, the
+ * result is equal to the result of raising the absolute value of
+ * the first argument to the power of the second argument
+ *
+ * <li>if the second argument is a finite odd integer, the result
+ * is equal to the negative of the result of raising the absolute
+ * value of the first argument to the power of the second
+ * argument
+ *
+ * <li>if the second argument is finite and not an integer, then
+ * the result is NaN.
+ * </ul>
+ *
+ * <li>If both arguments are integers, then the result is exactly equal
+ * to the mathematical result of raising the first argument to the power
+ * of the second argument if that result can in fact be represented
+ * exactly as a {@code double} value.</ul>
+ *
+ * <p>(In the foregoing descriptions, a floating-point value is
+ * considered to be an integer if and only if it is finite and a
+ * fixed point of the method {@link #ceil ceil} or,
+ * equivalently, a fixed point of the method {@link #floor
+ * floor}. A value is a fixed point of a one-argument
+ * method if and only if the result of applying the method to the
+ * value is equal to the value.)
+ *
+ * <p>The computed result must be within 1 ulp of the exact result.
+ * Results must be semi-monotonic.
+ *
+ * @param a the base.
+ * @param b the exponent.
+ * @return the value {@code a}<sup>{@code b}</sup>.
+ */
+ @CriticalNative
+ public static native double pow(double a, double b);
+
+ /**
+ * Returns the closest {@code int} to the argument, with ties
+ * rounding to positive infinity.
+ *
+ * <p>
+ * Special cases:
+ * <ul><li>If the argument is NaN, the result is 0.
+ * <li>If the argument is negative infinity or any value less than or
+ * equal to the value of {@code Integer.MIN_VALUE}, the result is
+ * equal to the value of {@code Integer.MIN_VALUE}.
+ * <li>If the argument is positive infinity or any value greater than or
+ * equal to the value of {@code Integer.MAX_VALUE}, the result is
+ * equal to the value of {@code Integer.MAX_VALUE}.</ul>
+ *
+ * @param a a floating-point value to be rounded to an integer.
+ * @return the value of the argument rounded to the nearest
+ * {@code int} value.
+ * @see java.lang.Integer#MAX_VALUE
+ * @see java.lang.Integer#MIN_VALUE
+ */
+ public static int round(float a) {
+ int intBits = Float.floatToRawIntBits(a);
+ int biasedExp = (intBits & FloatConsts.EXP_BIT_MASK)
+ >> (FloatConsts.SIGNIFICAND_WIDTH - 1);
+ int shift = (FloatConsts.SIGNIFICAND_WIDTH - 2
+ + FloatConsts.EXP_BIAS) - biasedExp;
+ if ((shift & -32) == 0) { // shift >= 0 && shift < 32
+ // a is a finite number such that pow(2,-32) <= ulp(a) < 1
+ int r = ((intBits & FloatConsts.SIGNIF_BIT_MASK)
+ | (FloatConsts.SIGNIF_BIT_MASK + 1));
+ if (intBits < 0) {
+ r = -r;
+ }
+ // In the comments below each Java expression evaluates to the value
+ // the corresponding mathematical expression:
+ // (r) evaluates to a / ulp(a)
+ // (r >> shift) evaluates to floor(a * 2)
+ // ((r >> shift) + 1) evaluates to floor((a + 1/2) * 2)
+ // (((r >> shift) + 1) >> 1) evaluates to floor(a + 1/2)
+ return ((r >> shift) + 1) >> 1;
+ } else {
+ // a is either
+ // - a finite number with abs(a) < exp(2,FloatConsts.SIGNIFICAND_WIDTH-32) < 1/2
+ // - a finite number with ulp(a) >= 1 and hence a is a mathematical integer
+ // - an infinity or NaN
+ return (int) a;
+ }
+ }
+
+ /**
+ * Returns the closest {@code long} to the argument, with ties
+ * rounding to positive infinity.
+ *
+ * <p>Special cases:
+ * <ul><li>If the argument is NaN, the result is 0.
+ * <li>If the argument is negative infinity or any value less than or
+ * equal to the value of {@code Long.MIN_VALUE}, the result is
+ * equal to the value of {@code Long.MIN_VALUE}.
+ * <li>If the argument is positive infinity or any value greater than or
+ * equal to the value of {@code Long.MAX_VALUE}, the result is
+ * equal to the value of {@code Long.MAX_VALUE}.</ul>
+ *
+ * @param a a floating-point value to be rounded to a
+ * {@code long}.
+ * @return the value of the argument rounded to the nearest
+ * {@code long} value.
+ * @see java.lang.Long#MAX_VALUE
+ * @see java.lang.Long#MIN_VALUE
+ */
+ public static long round(double a) {
+ long longBits = Double.doubleToRawLongBits(a);
+ long biasedExp = (longBits & DoubleConsts.EXP_BIT_MASK)
+ >> (DoubleConsts.SIGNIFICAND_WIDTH - 1);
+ long shift = (DoubleConsts.SIGNIFICAND_WIDTH - 2
+ + DoubleConsts.EXP_BIAS) - biasedExp;
+ if ((shift & -64) == 0) { // shift >= 0 && shift < 64
+ // a is a finite number such that pow(2,-64) <= ulp(a) < 1
+ long r = ((longBits & DoubleConsts.SIGNIF_BIT_MASK)
+ | (DoubleConsts.SIGNIF_BIT_MASK + 1));
+ if (longBits < 0) {
+ r = -r;
+ }
+ // In the comments below each Java expression evaluates to the value
+ // the corresponding mathematical expression:
+ // (r) evaluates to a / ulp(a)
+ // (r >> shift) evaluates to floor(a * 2)
+ // ((r >> shift) + 1) evaluates to floor((a + 1/2) * 2)
+ // (((r >> shift) + 1) >> 1) evaluates to floor(a + 1/2)
+ return ((r >> shift) + 1) >> 1;
+ } else {
+ // a is either
+ // - a finite number with abs(a) < exp(2,DoubleConsts.SIGNIFICAND_WIDTH-64) < 1/2
+ // - a finite number with ulp(a) >= 1 and hence a is a mathematical integer
+ // - an infinity or NaN
+ return (long) a;
+ }
+ }
+
+ private static final class RandomNumberGeneratorHolder {
+ static final Random randomNumberGenerator = new Random();
+ }
+
+ /**
+ * Returns a {@code double} value with a positive sign, greater
+ * than or equal to {@code 0.0} and less than {@code 1.0}.
+ * Returned values are chosen pseudorandomly with (approximately)
+ * uniform distribution from that range.
+ *
+ * <p>When this method is first called, it creates a single new
+ * pseudorandom-number generator, exactly as if by the expression
+ *
+ * <blockquote>{@code new java.util.Random()}</blockquote>
+ *
+ * This new pseudorandom-number generator is used thereafter for
+ * all calls to this method and is used nowhere else.
+ *
+ * <p>This method is properly synchronized to allow correct use by
+ * more than one thread. However, if many threads need to generate
+ * pseudorandom numbers at a great rate, it may reduce contention
+ * for each thread to have its own pseudorandom-number generator.
+ *
+ * @return a pseudorandom {@code double} greater than or equal
+ * to {@code 0.0} and less than {@code 1.0}.
+ * @see Random#nextDouble()
+ */
+ public static double random() {
+ return RandomNumberGeneratorHolder.randomNumberGenerator.nextDouble();
+ }
+
+ // Android-added: setRandomSeedInternal(long), called after zygote forks.
+ // This allows different processes to have different random seeds.
+ /**
+ * Set the seed for the pseudo random generator used by {@link #random()}
+ * and {@link #randomIntInternal()}.
+ *
+ * @hide for internal use only.
+ */
+ public static void setRandomSeedInternal(long seed) {
+ RandomNumberGeneratorHolder.randomNumberGenerator.setSeed(seed);
+ }
+
+ // Android-added: randomIntInternal() method: like random() but for int.
+ /**
+ * @hide for internal use only.
+ */
+ public static int randomIntInternal() {
+ return RandomNumberGeneratorHolder.randomNumberGenerator.nextInt();
+ }
+
+ // Android-added: randomLongInternal() method: like random() but for long.
+ /**
+ * @hide for internal use only.
+ */
+ public static long randomLongInternal() {
+ return RandomNumberGeneratorHolder.randomNumberGenerator.nextLong();
+ }
+
+ /**
+ * Returns the sum of its arguments,
+ * throwing an exception if the result overflows an {@code int}.
+ *
+ * @param x the first value
+ * @param y the second value
+ * @return the result
+ * @throws ArithmeticException if the result overflows an int
+ * @since 1.8
+ */
+ public static int addExact(int x, int y) {
+ int r = x + y;
+ // HD 2-12 Overflow iff both arguments have the opposite sign of the result
+ if (((x ^ r) & (y ^ r)) < 0) {
+ throw new ArithmeticException("integer overflow");
+ }
+ return r;
+ }
+
+ /**
+ * Returns the sum of its arguments,
+ * throwing an exception if the result overflows a {@code long}.
+ *
+ * @param x the first value
+ * @param y the second value
+ * @return the result
+ * @throws ArithmeticException if the result overflows a long
+ * @since 1.8
+ */
+ public static long addExact(long x, long y) {
+ long r = x + y;
+ // HD 2-12 Overflow iff both arguments have the opposite sign of the result
+ if (((x ^ r) & (y ^ r)) < 0) {
+ throw new ArithmeticException("long overflow");
+ }
+ return r;
+ }
+
+ /**
+ * Returns the difference of the arguments,
+ * throwing an exception if the result overflows an {@code int}.
+ *
+ * @param x the first value
+ * @param y the second value to subtract from the first
+ * @return the result
+ * @throws ArithmeticException if the result overflows an int
+ * @since 1.8
+ */
+ public static int subtractExact(int x, int y) {
+ int r = x - y;
+ // HD 2-12 Overflow iff the arguments have different signs and
+ // the sign of the result is different than the sign of x
+ if (((x ^ y) & (x ^ r)) < 0) {
+ throw new ArithmeticException("integer overflow");
+ }
+ return r;
+ }
+
+ /**
+ * Returns the difference of the arguments,
+ * throwing an exception if the result overflows a {@code long}.
+ *
+ * @param x the first value
+ * @param y the second value to subtract from the first
+ * @return the result
+ * @throws ArithmeticException if the result overflows a long
+ * @since 1.8
+ */
+ public static long subtractExact(long x, long y) {
+ long r = x - y;
+ // HD 2-12 Overflow iff the arguments have different signs and
+ // the sign of the result is different than the sign of x
+ if (((x ^ y) & (x ^ r)) < 0) {
+ throw new ArithmeticException("long overflow");
+ }
+ return r;
+ }
+
+ /**
+ * Returns the product of the arguments,
+ * throwing an exception if the result overflows an {@code int}.
+ *
+ * @param x the first value
+ * @param y the second value
+ * @return the result
+ * @throws ArithmeticException if the result overflows an int
+ * @since 1.8
+ */
+ public static int multiplyExact(int x, int y) {
+ long r = (long)x * (long)y;
+ if ((int)r != r) {
+ throw new ArithmeticException("integer overflow");
+ }
+ return (int)r;
+ }
+
+ /**
+ * Returns the product of the arguments,
+ * throwing an exception if the result overflows a {@code long}.
+ *
+ * @param x the first value
+ * @param y the second value
+ * @return the result
+ * @throws ArithmeticException if the result overflows a long
+ * @since 1.8
+ */
+ public static long multiplyExact(long x, long y) {
+ long r = x * y;
+ long ax = Math.abs(x);
+ long ay = Math.abs(y);
+ if (((ax | ay) >>> 31 != 0)) {
+ // Some bits greater than 2^31 that might cause overflow
+ // Check the result using the divide operator
+ // and check for the special case of Long.MIN_VALUE * -1
+ if (((y != 0) && (r / y != x)) ||
+ (x == Long.MIN_VALUE && y == -1)) {
+ throw new ArithmeticException("long overflow");
+ }
+ }
+ return r;
+ }
+
+ /**
+ * Returns the argument incremented by one, throwing an exception if the
+ * result overflows an {@code int}.
+ *
+ * @param a the value to increment
+ * @return the result
+ * @throws ArithmeticException if the result overflows an int
+ * @since 1.8
+ */
+ public static int incrementExact(int a) {
+ if (a == Integer.MAX_VALUE) {
+ throw new ArithmeticException("integer overflow");
+ }
+
+ return a + 1;
+ }
+
+ /**
+ * Returns the argument incremented by one, throwing an exception if the
+ * result overflows a {@code long}.
+ *
+ * @param a the value to increment
+ * @return the result
+ * @throws ArithmeticException if the result overflows a long
+ * @since 1.8
+ */
+ public static long incrementExact(long a) {
+ if (a == Long.MAX_VALUE) {
+ throw new ArithmeticException("long overflow");
+ }
+
+ return a + 1L;
+ }
+
+ /**
+ * Returns the argument decremented by one, throwing an exception if the
+ * result overflows an {@code int}.
+ *
+ * @param a the value to decrement
+ * @return the result
+ * @throws ArithmeticException if the result overflows an int
+ * @since 1.8
+ */
+ public static int decrementExact(int a) {
+ if (a == Integer.MIN_VALUE) {
+ throw new ArithmeticException("integer overflow");
+ }
+
+ return a - 1;
+ }
+
+ /**
+ * Returns the argument decremented by one, throwing an exception if the
+ * result overflows a {@code long}.
+ *
+ * @param a the value to decrement
+ * @return the result
+ * @throws ArithmeticException if the result overflows a long
+ * @since 1.8
+ */
+ public static long decrementExact(long a) {
+ if (a == Long.MIN_VALUE) {
+ throw new ArithmeticException("long overflow");
+ }
+
+ return a - 1L;
+ }
+
+ /**
+ * Returns the negation of the argument, throwing an exception if the
+ * result overflows an {@code int}.
+ *
+ * @param a the value to negate
+ * @return the result
+ * @throws ArithmeticException if the result overflows an int
+ * @since 1.8
+ */
+ public static int negateExact(int a) {
+ if (a == Integer.MIN_VALUE) {
+ throw new ArithmeticException("integer overflow");
+ }
+
+ return -a;
+ }
+
+ /**
+ * Returns the negation of the argument, throwing an exception if the
+ * result overflows a {@code long}.
+ *
+ * @param a the value to negate
+ * @return the result
+ * @throws ArithmeticException if the result overflows a long
+ * @since 1.8
+ */
+ public static long negateExact(long a) {
+ if (a == Long.MIN_VALUE) {
+ throw new ArithmeticException("long overflow");
+ }
+
+ return -a;
+ }
+
+ /**
+ * Returns the value of the {@code long} argument;
+ * throwing an exception if the value overflows an {@code int}.
+ *
+ * @param value the long value
+ * @return the argument as an int
+ * @throws ArithmeticException if the {@code argument} overflows an int
+ * @since 1.8
+ */
+ public static int toIntExact(long value) {
+ if ((int)value != value) {
+ throw new ArithmeticException("integer overflow");
+ }
+ return (int)value;
+ }
+
+ /**
+ * Returns the largest (closest to positive infinity)
+ * {@code int} value that is less than or equal to the algebraic quotient.
+ * There is one special case, if the dividend is the
+ * {@linkplain Integer#MIN_VALUE Integer.MIN_VALUE} and the divisor is {@code -1},
+ * then integer overflow occurs and
+ * the result is equal to the {@code Integer.MIN_VALUE}.
+ * <p>
+ * Normal integer division operates under the round to zero rounding mode
+ * (truncation). This operation instead acts under the round toward
+ * negative infinity (floor) rounding mode.
+ * The floor rounding mode gives different results than truncation
+ * when the exact result is negative.
+ * <ul>
+ * <li>If the signs of the arguments are the same, the results of
+ * {@code floorDiv} and the {@code /} operator are the same. <br>
+ * For example, {@code floorDiv(4, 3) == 1} and {@code (4 / 3) == 1}.</li>
+ * <li>If the signs of the arguments are different, the quotient is negative and
+ * {@code floorDiv} returns the integer less than or equal to the quotient
+ * and the {@code /} operator returns the integer closest to zero.<br>
+ * For example, {@code floorDiv(-4, 3) == -2},
+ * whereas {@code (-4 / 3) == -1}.
+ * </li>
+ * </ul>
+ * <p>
+ *
+ * @param x the dividend
+ * @param y the divisor
+ * @return the largest (closest to positive infinity)
+ * {@code int} value that is less than or equal to the algebraic quotient.
+ * @throws ArithmeticException if the divisor {@code y} is zero
+ * @see #floorMod(int, int)
+ * @see #floor(double)
+ * @since 1.8
+ */
+ public static int floorDiv(int x, int y) {
+ int r = x / y;
+ // if the signs are different and modulo not zero, round down
+ if ((x ^ y) < 0 && (r * y != x)) {
+ r--;
+ }
+ return r;
+ }
+
+ /**
+ * Returns the largest (closest to positive infinity)
+ * {@code long} value that is less than or equal to the algebraic quotient.
+ * There is one special case, if the dividend is the
+ * {@linkplain Long#MIN_VALUE Long.MIN_VALUE} and the divisor is {@code -1},
+ * then integer overflow occurs and
+ * the result is equal to the {@code Long.MIN_VALUE}.
+ * <p>
+ * Normal integer division operates under the round to zero rounding mode
+ * (truncation). This operation instead acts under the round toward
+ * negative infinity (floor) rounding mode.
+ * The floor rounding mode gives different results than truncation
+ * when the exact result is negative.
+ * <p>
+ * For examples, see {@link #floorDiv(int, int)}.
+ *
+ * @param x the dividend
+ * @param y the divisor
+ * @return the largest (closest to positive infinity)
+ * {@code long} value that is less than or equal to the algebraic quotient.
+ * @throws ArithmeticException if the divisor {@code y} is zero
+ * @see #floorMod(long, long)
+ * @see #floor(double)
+ * @since 1.8
+ */
+ public static long floorDiv(long x, long y) {
+ long r = x / y;
+ // if the signs are different and modulo not zero, round down
+ if ((x ^ y) < 0 && (r * y != x)) {
+ r--;
+ }
+ return r;
+ }
+
+ /**
+ * Returns the floor modulus of the {@code int} arguments.
+ * <p>
+ * The floor modulus is {@code x - (floorDiv(x, y) * y)},
+ * has the same sign as the divisor {@code y}, and
+ * is in the range of {@code -abs(y) < r < +abs(y)}.
+ *
+ * <p>
+ * The relationship between {@code floorDiv} and {@code floorMod} is such that:
+ * <ul>
+ * <li>{@code floorDiv(x, y) * y + floorMod(x, y) == x}
+ * </ul>
+ * <p>
+ * The difference in values between {@code floorMod} and
+ * the {@code %} operator is due to the difference between
+ * {@code floorDiv} that returns the integer less than or equal to the quotient
+ * and the {@code /} operator that returns the integer closest to zero.
+ * <p>
+ * Examples:
+ * <ul>
+ * <li>If the signs of the arguments are the same, the results
+ * of {@code floorMod} and the {@code %} operator are the same. <br>
+ * <ul>
+ * <li>{@code floorMod(4, 3) == 1}; and {@code (4 % 3) == 1}</li>
+ * </ul>
+ * <li>If the signs of the arguments are different, the results differ from the {@code %} operator.<br>
+ * <ul>
+ * <li>{@code floorMod(+4, -3) == -2}; and {@code (+4 % -3) == +1} </li>
+ * <li>{@code floorMod(-4, +3) == +2}; and {@code (-4 % +3) == -1} </li>
+ * <li>{@code floorMod(-4, -3) == -1}; and {@code (-4 % -3) == -1 } </li>
+ * </ul>
+ * </li>
+ * </ul>
+ * <p>
+ * If the signs of arguments are unknown and a positive modulus
+ * is needed it can be computed as {@code (floorMod(x, y) + abs(y)) % abs(y)}.
+ *
+ * @param x the dividend
+ * @param y the divisor
+ * @return the floor modulus {@code x - (floorDiv(x, y) * y)}
+ * @throws ArithmeticException if the divisor {@code y} is zero
+ * @see #floorDiv(int, int)
+ * @since 1.8
+ */
+ public static int floorMod(int x, int y) {
+ int r = x - floorDiv(x, y) * y;
+ return r;
+ }
+
+ /**
+ * Returns the floor modulus of the {@code long} arguments.
+ * <p>
+ * The floor modulus is {@code x - (floorDiv(x, y) * y)},
+ * has the same sign as the divisor {@code y}, and
+ * is in the range of {@code -abs(y) < r < +abs(y)}.
+ *
+ * <p>
+ * The relationship between {@code floorDiv} and {@code floorMod} is such that:
+ * <ul>
+ * <li>{@code floorDiv(x, y) * y + floorMod(x, y) == x}
+ * </ul>
+ * <p>
+ * For examples, see {@link #floorMod(int, int)}.
+ *
+ * @param x the dividend
+ * @param y the divisor
+ * @return the floor modulus {@code x - (floorDiv(x, y) * y)}
+ * @throws ArithmeticException if the divisor {@code y} is zero
+ * @see #floorDiv(long, long)
+ * @since 1.8
+ */
+ public static long floorMod(long x, long y) {
+ return x - floorDiv(x, y) * y;
+ }
+
+ /**
+ * Returns the absolute value of an {@code int} value.
+ * If the argument is not negative, the argument is returned.
+ * If the argument is negative, the negation of the argument is returned.
+ *
+ * <p>Note that if the argument is equal to the value of
+ * {@link Integer#MIN_VALUE}, the most negative representable
+ * {@code int} value, the result is that same value, which is
+ * negative.
+ *
+ * @param a the argument whose absolute value is to be determined
+ * @return the absolute value of the argument.
+ */
+ public static int abs(int a) {
+ return (a < 0) ? -a : a;
+ }
+
+ /**
+ * Returns the absolute value of a {@code long} value.
+ * If the argument is not negative, the argument is returned.
+ * If the argument is negative, the negation of the argument is returned.
+ *
+ * <p>Note that if the argument is equal to the value of
+ * {@link Long#MIN_VALUE}, the most negative representable
+ * {@code long} value, the result is that same value, which
+ * is negative.
+ *
+ * @param a the argument whose absolute value is to be determined
+ * @return the absolute value of the argument.
+ */
+ public static long abs(long a) {
+ return (a < 0) ? -a : a;
+ }
+
+ /**
+ * Returns the absolute value of a {@code float} value.
+ * If the argument is not negative, the argument is returned.
+ * If the argument is negative, the negation of the argument is returned.
+ * Special cases:
+ * <ul><li>If the argument is positive zero or negative zero, the
+ * result is positive zero.
+ * <li>If the argument is infinite, the result is positive infinity.
+ * <li>If the argument is NaN, the result is NaN.</ul>
+ * In other words, the result is the same as the value of the expression:
+ * <p>{@code Float.intBitsToFloat(0x7fffffff & Float.floatToIntBits(a))}
+ *
+ * @param a the argument whose absolute value is to be determined
+ * @return the absolute value of the argument.
+ */
+ public static float abs(float a) {
+ // Android-changed: Implementation modified to exactly match ART intrinsics behavior.
+ // Note, as a "quality of implementation", rather than pure "spec compliance",
+ // we require that Math.abs() clears the sign bit (but changes nothing else)
+ // for all numbers, including NaN (signaling NaN may become quiet though).
+ // http://b/30758343
+ return Float.intBitsToFloat(0x7fffffff & Float.floatToRawIntBits(a));
+ }
+
+ /**
+ * Returns the absolute value of a {@code double} value.
+ * If the argument is not negative, the argument is returned.
+ * If the argument is negative, the negation of the argument is returned.
+ * Special cases:
+ * <ul><li>If the argument is positive zero or negative zero, the result
+ * is positive zero.
+ * <li>If the argument is infinite, the result is positive infinity.
+ * <li>If the argument is NaN, the result is NaN.</ul>
+ * In other words, the result is the same as the value of the expression:
+ * <p>{@code Double.longBitsToDouble((Double.doubleToLongBits(a)<<1)>>>1)}
+ *
+ * @param a the argument whose absolute value is to be determined
+ * @return the absolute value of the argument.
+ */
+ public static double abs(double a) {
+ // Android-changed: Implementation modified to exactly match ART intrinsics behavior.
+ // Note, as a "quality of implementation", rather than pure "spec compliance",
+ // we require that Math.abs() clears the sign bit (but changes nothing else)
+ // for all numbers, including NaN (signaling NaN may become quiet though).
+ // http://b/30758343
+ return Double.longBitsToDouble(0x7fffffffffffffffL & Double.doubleToRawLongBits(a));
+ }
+
+ /**
+ * Returns the greater of two {@code int} values. That is, the
+ * result is the argument closer to the value of
+ * {@link Integer#MAX_VALUE}. If the arguments have the same value,
+ * the result is that same value.
+ *
+ * @param a an argument.
+ * @param b another argument.
+ * @return the larger of {@code a} and {@code b}.
+ */
+ public static int max(int a, int b) {
+ return (a >= b) ? a : b;
+ }
+
+ /**
+ * Returns the greater of two {@code long} values. That is, the
+ * result is the argument closer to the value of
+ * {@link Long#MAX_VALUE}. If the arguments have the same value,
+ * the result is that same value.
+ *
+ * @param a an argument.
+ * @param b another argument.
+ * @return the larger of {@code a} and {@code b}.
+ */
+ public static long max(long a, long b) {
+ return (a >= b) ? a : b;
+ }
+
+ // Use raw bit-wise conversions on guaranteed non-NaN arguments.
+ private static long negativeZeroFloatBits = Float.floatToRawIntBits(-0.0f);
+ private static long negativeZeroDoubleBits = Double.doubleToRawLongBits(-0.0d);
+
+ /**
+ * Returns the greater of two {@code float} values. That is,
+ * the result is the argument closer to positive infinity. If the
+ * arguments have the same value, the result is that same
+ * value. If either value is NaN, then the result is NaN. Unlike
+ * the numerical comparison operators, this method considers
+ * negative zero to be strictly smaller than positive zero. If one
+ * argument is positive zero and the other negative zero, the
+ * result is positive zero.
+ *
+ * @param a an argument.
+ * @param b another argument.
+ * @return the larger of {@code a} and {@code b}.
+ */
+ public static float max(float a, float b) {
+ if (a != a)
+ return a; // a is NaN
+ if ((a == 0.0f) &&
+ (b == 0.0f) &&
+ (Float.floatToRawIntBits(a) == negativeZeroFloatBits)) {
+ // Raw conversion ok since NaN can't map to -0.0.
+ return b;
+ }
+ return (a >= b) ? a : b;
+ }
+
+ /**
+ * Returns the greater of two {@code double} values. That
+ * is, the result is the argument closer to positive infinity. If
+ * the arguments have the same value, the result is that same
+ * value. If either value is NaN, then the result is NaN. Unlike
+ * the numerical comparison operators, this method considers
+ * negative zero to be strictly smaller than positive zero. If one
+ * argument is positive zero and the other negative zero, the
+ * result is positive zero.
+ *
+ * @param a an argument.
+ * @param b another argument.
+ * @return the larger of {@code a} and {@code b}.
+ */
+ public static double max(double a, double b) {
+ if (a != a)
+ return a; // a is NaN
+ if ((a == 0.0d) &&
+ (b == 0.0d) &&
+ (Double.doubleToRawLongBits(a) == negativeZeroDoubleBits)) {
+ // Raw conversion ok since NaN can't map to -0.0.
+ return b;
+ }
+ return (a >= b) ? a : b;
+ }
+
+ /**
+ * Returns the smaller of two {@code int} values. That is,
+ * the result the argument closer to the value of
+ * {@link Integer#MIN_VALUE}. If the arguments have the same
+ * value, the result is that same value.
+ *
+ * @param a an argument.
+ * @param b another argument.
+ * @return the smaller of {@code a} and {@code b}.
+ */
+ public static int min(int a, int b) {
+ return (a <= b) ? a : b;
+ }
+
+ /**
+ * Returns the smaller of two {@code long} values. That is,
+ * the result is the argument closer to the value of
+ * {@link Long#MIN_VALUE}. If the arguments have the same
+ * value, the result is that same value.
+ *
+ * @param a an argument.
+ * @param b another argument.
+ * @return the smaller of {@code a} and {@code b}.
+ */
+ public static long min(long a, long b) {
+ return (a <= b) ? a : b;
+ }
+
+ /**
+ * Returns the smaller of two {@code float} values. That is,
+ * the result is the value closer to negative infinity. If the
+ * arguments have the same value, the result is that same
+ * value. If either value is NaN, then the result is NaN. Unlike
+ * the numerical comparison operators, this method considers
+ * negative zero to be strictly smaller than positive zero. If
+ * one argument is positive zero and the other is negative zero,
+ * the result is negative zero.
+ *
+ * @param a an argument.
+ * @param b another argument.
+ * @return the smaller of {@code a} and {@code b}.
+ */
+ public static float min(float a, float b) {
+ if (a != a)
+ return a; // a is NaN
+ if ((a == 0.0f) &&
+ (b == 0.0f) &&
+ (Float.floatToRawIntBits(b) == negativeZeroFloatBits)) {
+ // Raw conversion ok since NaN can't map to -0.0.
+ return b;
+ }
+ return (a <= b) ? a : b;
+ }
+
+ /**
+ * Returns the smaller of two {@code double} values. That
+ * is, the result is the value closer to negative infinity. If the
+ * arguments have the same value, the result is that same
+ * value. If either value is NaN, then the result is NaN. Unlike
+ * the numerical comparison operators, this method considers
+ * negative zero to be strictly smaller than positive zero. If one
+ * argument is positive zero and the other is negative zero, the
+ * result is negative zero.
+ *
+ * @param a an argument.
+ * @param b another argument.
+ * @return the smaller of {@code a} and {@code b}.
+ */
+ public static double min(double a, double b) {
+ if (a != a)
+ return a; // a is NaN
+ if ((a == 0.0d) &&
+ (b == 0.0d) &&
+ (Double.doubleToRawLongBits(b) == negativeZeroDoubleBits)) {
+ // Raw conversion ok since NaN can't map to -0.0.
+ return b;
+ }
+ return (a <= b) ? a : b;
+ }
+
+ /**
+ * Returns the size of an ulp of the argument. An ulp, unit in
+ * the last place, of a {@code double} value is the positive
+ * distance between this floating-point value and the {@code
+ * double} value next larger in magnitude. Note that for non-NaN
+ * <i>x</i>, <code>ulp(-<i>x</i>) == ulp(<i>x</i>)</code>.
+ *
+ * <p>Special Cases:
+ * <ul>
+ * <li> If the argument is NaN, then the result is NaN.
+ * <li> If the argument is positive or negative infinity, then the
+ * result is positive infinity.
+ * <li> If the argument is positive or negative zero, then the result is
+ * {@code Double.MIN_VALUE}.
+ * <li> If the argument is ±{@code Double.MAX_VALUE}, then
+ * the result is equal to 2<sup>971</sup>.
+ * </ul>
+ *
+ * @param d the floating-point value whose ulp is to be returned
+ * @return the size of an ulp of the argument
+ * @author Joseph D. Darcy
+ * @since 1.5
+ */
+ public static double ulp(double d) {
+ int exp = getExponent(d);
+
+ switch(exp) {
+ case DoubleConsts.MAX_EXPONENT+1: // NaN or infinity
+ return Math.abs(d);
+
+ case DoubleConsts.MIN_EXPONENT-1: // zero or subnormal
+ return Double.MIN_VALUE;
+
+ default:
+ assert exp <= DoubleConsts.MAX_EXPONENT && exp >= DoubleConsts.MIN_EXPONENT;
+
+ // ulp(x) is usually 2^(SIGNIFICAND_WIDTH-1)*(2^ilogb(x))
+ exp = exp - (DoubleConsts.SIGNIFICAND_WIDTH-1);
+ if (exp >= DoubleConsts.MIN_EXPONENT) {
+ return powerOfTwoD(exp);
+ }
+ else {
+ // return a subnormal result; left shift integer
+ // representation of Double.MIN_VALUE appropriate
+ // number of positions
+ return Double.longBitsToDouble(1L <<
+ (exp - (DoubleConsts.MIN_EXPONENT - (DoubleConsts.SIGNIFICAND_WIDTH-1)) ));
+ }
+ }
+ }
+
+ /**
+ * Returns the size of an ulp of the argument. An ulp, unit in
+ * the last place, of a {@code float} value is the positive
+ * distance between this floating-point value and the {@code
+ * float} value next larger in magnitude. Note that for non-NaN
+ * <i>x</i>, <code>ulp(-<i>x</i>) == ulp(<i>x</i>)</code>.
+ *
+ * <p>Special Cases:
+ * <ul>
+ * <li> If the argument is NaN, then the result is NaN.
+ * <li> If the argument is positive or negative infinity, then the
+ * result is positive infinity.
+ * <li> If the argument is positive or negative zero, then the result is
+ * {@code Float.MIN_VALUE}.
+ * <li> If the argument is ±{@code Float.MAX_VALUE}, then
+ * the result is equal to 2<sup>104</sup>.
+ * </ul>
+ *
+ * @param f the floating-point value whose ulp is to be returned
+ * @return the size of an ulp of the argument
+ * @author Joseph D. Darcy
+ * @since 1.5
+ */
+ public static float ulp(float f) {
+ int exp = getExponent(f);
+
+ switch(exp) {
+ case FloatConsts.MAX_EXPONENT+1: // NaN or infinity
+ return Math.abs(f);
+
+ case FloatConsts.MIN_EXPONENT-1: // zero or subnormal
+ return FloatConsts.MIN_VALUE;
+
+ default:
+ assert exp <= FloatConsts.MAX_EXPONENT && exp >= FloatConsts.MIN_EXPONENT;
+
+ // ulp(x) is usually 2^(SIGNIFICAND_WIDTH-1)*(2^ilogb(x))
+ exp = exp - (FloatConsts.SIGNIFICAND_WIDTH-1);
+ if (exp >= FloatConsts.MIN_EXPONENT) {
+ return powerOfTwoF(exp);
+ }
+ else {
+ // return a subnormal result; left shift integer
+ // representation of FloatConsts.MIN_VALUE appropriate
+ // number of positions
+ return Float.intBitsToFloat(1 <<
+ (exp - (FloatConsts.MIN_EXPONENT - (FloatConsts.SIGNIFICAND_WIDTH-1)) ));
+ }
+ }
+ }
+
+ /**
+ * Returns the signum function of the argument; zero if the argument
+ * is zero, 1.0 if the argument is greater than zero, -1.0 if the
+ * argument is less than zero.
+ *
+ * <p>Special Cases:
+ * <ul>
+ * <li> If the argument is NaN, then the result is NaN.
+ * <li> If the argument is positive zero or negative zero, then the
+ * result is the same as the argument.
+ * </ul>
+ *
+ * @param d the floating-point value whose signum is to be returned
+ * @return the signum function of the argument
+ * @author Joseph D. Darcy
+ * @since 1.5
+ */
+ public static double signum(double d) {
+ return (d == 0.0 || Double.isNaN(d))?d:copySign(1.0, d);
+ }
+
+ /**
+ * Returns the signum function of the argument; zero if the argument
+ * is zero, 1.0f if the argument is greater than zero, -1.0f if the
+ * argument is less than zero.
+ *
+ * <p>Special Cases:
+ * <ul>
+ * <li> If the argument is NaN, then the result is NaN.
+ * <li> If the argument is positive zero or negative zero, then the
+ * result is the same as the argument.
+ * </ul>
+ *
+ * @param f the floating-point value whose signum is to be returned
+ * @return the signum function of the argument
+ * @author Joseph D. Darcy
+ * @since 1.5
+ */
+ public static float signum(float f) {
+ return (f == 0.0f || Float.isNaN(f))?f:copySign(1.0f, f);
+ }
+
+ /**
+ * Returns the hyperbolic sine of a {@code double} value.
+ * The hyperbolic sine of <i>x</i> is defined to be
+ * (<i>e<sup>x</sup> - e<sup>-x</sup></i>)/2
+ * where <i>e</i> is {@linkplain Math#E Euler's number}.
+ *
+ * <p>Special cases:
+ * <ul>
+ *
+ * <li>If the argument is NaN, then the result is NaN.
+ *
+ * <li>If the argument is infinite, then the result is an infinity
+ * with the same sign as the argument.
+ *
+ * <li>If the argument is zero, then the result is a zero with the
+ * same sign as the argument.
+ *
+ * </ul>
+ *
+ * <p>The computed result must be within 2.5 ulps of the exact result.
+ *
+ * @param x The number whose hyperbolic sine is to be returned.
+ * @return The hyperbolic sine of {@code x}.
+ * @since 1.5
+ */
+ @CriticalNative
+ public static native double sinh(double x);
+
+ /**
+ * Returns the hyperbolic cosine of a {@code double} value.
+ * The hyperbolic cosine of <i>x</i> is defined to be
+ * (<i>e<sup>x</sup> + e<sup>-x</sup></i>)/2
+ * where <i>e</i> is {@linkplain Math#E Euler's number}.
+ *
+ * <p>Special cases:
+ * <ul>
+ *
+ * <li>If the argument is NaN, then the result is NaN.
+ *
+ * <li>If the argument is infinite, then the result is positive
+ * infinity.
+ *
+ * <li>If the argument is zero, then the result is {@code 1.0}.
+ *
+ * </ul>
+ *
+ * <p>The computed result must be within 2.5 ulps of the exact result.
+ *
+ * @param x The number whose hyperbolic cosine is to be returned.
+ * @return The hyperbolic cosine of {@code x}.
+ * @since 1.5
+ */
+ @CriticalNative
+ public static native double cosh(double x);
+
+ /**
+ * Returns the hyperbolic tangent of a {@code double} value.
+ * The hyperbolic tangent of <i>x</i> is defined to be
+ * (<i>e<sup>x</sup> - e<sup>-x</sup></i>)/(<i>e<sup>x</sup> + e<sup>-x</sup></i>),
+ * in other words, {@linkplain Math#sinh
+ * sinh(<i>x</i>)}/{@linkplain Math#cosh cosh(<i>x</i>)}. Note
+ * that the absolute value of the exact tanh is always less than
+ * 1.
+ *
+ * <p>Special cases:
+ * <ul>
+ *
+ * <li>If the argument is NaN, then the result is NaN.
+ *
+ * <li>If the argument is zero, then the result is a zero with the
+ * same sign as the argument.
+ *
+ * <li>If the argument is positive infinity, then the result is
+ * {@code +1.0}.
+ *
+ * <li>If the argument is negative infinity, then the result is
+ * {@code -1.0}.
+ *
+ * </ul>
+ *
+ * <p>The computed result must be within 2.5 ulps of the exact result.
+ * The result of {@code tanh} for any finite input must have
+ * an absolute value less than or equal to 1. Note that once the
+ * exact result of tanh is within 1/2 of an ulp of the limit value
+ * of ±1, correctly signed ±{@code 1.0} should
+ * be returned.
+ *
+ * @param x The number whose hyperbolic tangent is to be returned.
+ * @return The hyperbolic tangent of {@code x}.
+ * @since 1.5
+ */
+ @CriticalNative
+ public static native double tanh(double x);
+
+ /**
+ * Returns sqrt(<i>x</i><sup>2</sup> +<i>y</i><sup>2</sup>)
+ * without intermediate overflow or underflow.
+ *
+ * <p>Special cases:
+ * <ul>
+ *
+ * <li> If either argument is infinite, then the result
+ * is positive infinity.
+ *
+ * <li> If either argument is NaN and neither argument is infinite,
+ * then the result is NaN.
+ *
+ * </ul>
+ *
+ * <p>The computed result must be within 1 ulp of the exact
+ * result. If one parameter is held constant, the results must be
+ * semi-monotonic in the other parameter.
+ *
+ * @param x a value
+ * @param y a value
+ * @return sqrt(<i>x</i><sup>2</sup> +<i>y</i><sup>2</sup>)
+ * without intermediate overflow or underflow
+ * @since 1.5
+ */
+ @CriticalNative
+ public static native double hypot(double x, double y);
+
+ /**
+ * Returns <i>e</i><sup>x</sup> -1. Note that for values of
+ * <i>x</i> near 0, the exact sum of
+ * {@code expm1(x)} + 1 is much closer to the true
+ * result of <i>e</i><sup>x</sup> than {@code exp(x)}.
+ *
+ * <p>Special cases:
+ * <ul>
+ * <li>If the argument is NaN, the result is NaN.
+ *
+ * <li>If the argument is positive infinity, then the result is
+ * positive infinity.
+ *
+ * <li>If the argument is negative infinity, then the result is
+ * -1.0.
+ *
+ * <li>If the argument is zero, then the result is a zero with the
+ * same sign as the argument.
+ *
+ * </ul>
+ *
+ * <p>The computed result must be within 1 ulp of the exact result.
+ * Results must be semi-monotonic. The result of
+ * {@code expm1} for any finite input must be greater than or
+ * equal to {@code -1.0}. Note that once the exact result of
+ * <i>e</i><sup>{@code x}</sup> - 1 is within 1/2
+ * ulp of the limit value -1, {@code -1.0} should be
+ * returned.
+ *
+ * @param x the exponent to raise <i>e</i> to in the computation of
+ * <i>e</i><sup>{@code x}</sup> -1.
+ * @return the value <i>e</i><sup>{@code x}</sup> - 1.
+ * @since 1.5
+ */
+ @CriticalNative
+ public static native double expm1(double x);
+
+ /**
+ * Returns the natural logarithm of the sum of the argument and 1.
+ * Note that for small values {@code x}, the result of
+ * {@code log1p(x)} is much closer to the true result of ln(1
+ * + {@code x}) than the floating-point evaluation of
+ * {@code log(1.0+x)}.
+ *
+ * <p>Special cases:
+ *
+ * <ul>
+ *
+ * <li>If the argument is NaN or less than -1, then the result is
+ * NaN.
+ *
+ * <li>If the argument is positive infinity, then the result is
+ * positive infinity.
+ *
+ * <li>If the argument is negative one, then the result is
+ * negative infinity.
+ *
+ * <li>If the argument is zero, then the result is a zero with the
+ * same sign as the argument.
+ *
+ * </ul>
+ *
+ * <p>The computed result must be within 1 ulp of the exact result.
+ * Results must be semi-monotonic.
+ *
+ * @param x a value
+ * @return the value ln({@code x} + 1), the natural
+ * log of {@code x} + 1
+ * @since 1.5
+ */
+ @CriticalNative
+ public static native double log1p(double x);
+
+ /**
+ * Returns the first floating-point argument with the sign of the
+ * second floating-point argument. Note that unlike the {@link
+ * StrictMath#copySign(double, double) StrictMath.copySign}
+ * method, this method does not require NaN {@code sign}
+ * arguments to be treated as positive values; implementations are
+ * permitted to treat some NaN arguments as positive and other NaN
+ * arguments as negative to allow greater performance.
+ *
+ * @param magnitude the parameter providing the magnitude of the result
+ * @param sign the parameter providing the sign of the result
+ * @return a value with the magnitude of {@code magnitude}
+ * and the sign of {@code sign}.
+ * @since 1.6
+ */
+ public static double copySign(double magnitude, double sign) {
+ return Double.longBitsToDouble((Double.doubleToRawLongBits(sign) &
+ (DoubleConsts.SIGN_BIT_MASK)) |
+ (Double.doubleToRawLongBits(magnitude) &
+ (DoubleConsts.EXP_BIT_MASK |
+ DoubleConsts.SIGNIF_BIT_MASK)));
+ }
+
+ /**
+ * Returns the first floating-point argument with the sign of the
+ * second floating-point argument. Note that unlike the {@link
+ * StrictMath#copySign(float, float) StrictMath.copySign}
+ * method, this method does not require NaN {@code sign}
+ * arguments to be treated as positive values; implementations are
+ * permitted to treat some NaN arguments as positive and other NaN
+ * arguments as negative to allow greater performance.
+ *
+ * @param magnitude the parameter providing the magnitude of the result
+ * @param sign the parameter providing the sign of the result
+ * @return a value with the magnitude of {@code magnitude}
+ * and the sign of {@code sign}.
+ * @since 1.6
+ */
+ public static float copySign(float magnitude, float sign) {
+ return Float.intBitsToFloat((Float.floatToRawIntBits(sign) &
+ (FloatConsts.SIGN_BIT_MASK)) |
+ (Float.floatToRawIntBits(magnitude) &
+ (FloatConsts.EXP_BIT_MASK |
+ FloatConsts.SIGNIF_BIT_MASK)));
+ }
+
+ /**
+ * Returns the unbiased exponent used in the representation of a
+ * {@code float}. Special cases:
+ *
+ * <ul>
+ * <li>If the argument is NaN or infinite, then the result is
+ * {@link Float#MAX_EXPONENT} + 1.
+ * <li>If the argument is zero or subnormal, then the result is
+ * {@link Float#MIN_EXPONENT} -1.
+ * </ul>
+ * @param f a {@code float} value
+ * @return the unbiased exponent of the argument
+ * @since 1.6
+ */
+ public static int getExponent(float f) {
+ /*
+ * Bitwise convert f to integer, mask out exponent bits, shift
+ * to the right and then subtract out float's bias adjust to
+ * get true exponent value
+ */
+ return ((Float.floatToRawIntBits(f) & FloatConsts.EXP_BIT_MASK) >>
+ (FloatConsts.SIGNIFICAND_WIDTH - 1)) - FloatConsts.EXP_BIAS;
+ }
+
+ /**
+ * Returns the unbiased exponent used in the representation of a
+ * {@code double}. Special cases:
+ *
+ * <ul>
+ * <li>If the argument is NaN or infinite, then the result is
+ * {@link Double#MAX_EXPONENT} + 1.
+ * <li>If the argument is zero or subnormal, then the result is
+ * {@link Double#MIN_EXPONENT} -1.
+ * </ul>
+ * @param d a {@code double} value
+ * @return the unbiased exponent of the argument
+ * @since 1.6
+ */
+ public static int getExponent(double d) {
+ /*
+ * Bitwise convert d to long, mask out exponent bits, shift
+ * to the right and then subtract out double's bias adjust to
+ * get true exponent value.
+ */
+ return (int)(((Double.doubleToRawLongBits(d) & DoubleConsts.EXP_BIT_MASK) >>
+ (DoubleConsts.SIGNIFICAND_WIDTH - 1)) - DoubleConsts.EXP_BIAS);
+ }
+
+ /**
+ * Returns the floating-point number adjacent to the first
+ * argument in the direction of the second argument. If both
+ * arguments compare as equal the second argument is returned.
+ *
+ * <p>
+ * Special cases:
+ * <ul>
+ * <li> If either argument is a NaN, then NaN is returned.
+ *
+ * <li> If both arguments are signed zeros, {@code direction}
+ * is returned unchanged (as implied by the requirement of
+ * returning the second argument if the arguments compare as
+ * equal).
+ *
+ * <li> If {@code start} is
+ * ±{@link Double#MIN_VALUE} and {@code direction}
+ * has a value such that the result should have a smaller
+ * magnitude, then a zero with the same sign as {@code start}
+ * is returned.
+ *
+ * <li> If {@code start} is infinite and
+ * {@code direction} has a value such that the result should
+ * have a smaller magnitude, {@link Double#MAX_VALUE} with the
+ * same sign as {@code start} is returned.
+ *
+ * <li> If {@code start} is equal to ±
+ * {@link Double#MAX_VALUE} and {@code direction} has a
+ * value such that the result should have a larger magnitude, an
+ * infinity with same sign as {@code start} is returned.
+ * </ul>
+ *
+ * @param start starting floating-point value
+ * @param direction value indicating which of
+ * {@code start}'s neighbors or {@code start} should
+ * be returned
+ * @return The floating-point number adjacent to {@code start} in the
+ * direction of {@code direction}.
+ * @since 1.6
+ */
+ public static double nextAfter(double start, double direction) {
+ /*
+ * The cases:
+ *
+ * nextAfter(+infinity, 0) == MAX_VALUE
+ * nextAfter(+infinity, +infinity) == +infinity
+ * nextAfter(-infinity, 0) == -MAX_VALUE
+ * nextAfter(-infinity, -infinity) == -infinity
+ *
+ * are naturally handled without any additional testing
+ */
+
+ // First check for NaN values
+ if (Double.isNaN(start) || Double.isNaN(direction)) {
+ // return a NaN derived from the input NaN(s)
+ return start + direction;
+ } else if (start == direction) {
+ return direction;
+ } else { // start > direction or start < direction
+ // Add +0.0 to get rid of a -0.0 (+0.0 + -0.0 => +0.0)
+ // then bitwise convert start to integer.
+ long transducer = Double.doubleToRawLongBits(start + 0.0d);
+
+ /*
+ * IEEE 754 floating-point numbers are lexicographically
+ * ordered if treated as signed- magnitude integers .
+ * Since Java's integers are two's complement,
+ * incrementing" the two's complement representation of a
+ * logically negative floating-point value *decrements*
+ * the signed-magnitude representation. Therefore, when
+ * the integer representation of a floating-point values
+ * is less than zero, the adjustment to the representation
+ * is in the opposite direction than would be expected at
+ * first .
+ */
+ if (direction > start) { // Calculate next greater value
+ transducer = transducer + (transducer >= 0L ? 1L:-1L);
+ } else { // Calculate next lesser value
+ assert direction < start;
+ if (transducer > 0L)
+ --transducer;
+ else
+ if (transducer < 0L )
+ ++transducer;
+ /*
+ * transducer==0, the result is -MIN_VALUE
+ *
+ * The transition from zero (implicitly
+ * positive) to the smallest negative
+ * signed magnitude value must be done
+ * explicitly.
+ */
+ else
+ transducer = DoubleConsts.SIGN_BIT_MASK | 1L;
+ }
+
+ return Double.longBitsToDouble(transducer);
+ }
+ }
+
+ /**
+ * Returns the floating-point number adjacent to the first
+ * argument in the direction of the second argument. If both
+ * arguments compare as equal a value equivalent to the second argument
+ * is returned.
+ *
+ * <p>
+ * Special cases:
+ * <ul>
+ * <li> If either argument is a NaN, then NaN is returned.
+ *
+ * <li> If both arguments are signed zeros, a value equivalent
+ * to {@code direction} is returned.
+ *
+ * <li> If {@code start} is
+ * ±{@link Float#MIN_VALUE} and {@code direction}
+ * has a value such that the result should have a smaller
+ * magnitude, then a zero with the same sign as {@code start}
+ * is returned.
+ *
+ * <li> If {@code start} is infinite and
+ * {@code direction} has a value such that the result should
+ * have a smaller magnitude, {@link Float#MAX_VALUE} with the
+ * same sign as {@code start} is returned.
+ *
+ * <li> If {@code start} is equal to ±
+ * {@link Float#MAX_VALUE} and {@code direction} has a
+ * value such that the result should have a larger magnitude, an
+ * infinity with same sign as {@code start} is returned.
+ * </ul>
+ *
+ * @param start starting floating-point value
+ * @param direction value indicating which of
+ * {@code start}'s neighbors or {@code start} should
+ * be returned
+ * @return The floating-point number adjacent to {@code start} in the
+ * direction of {@code direction}.
+ * @since 1.6
+ */
+ public static float nextAfter(float start, double direction) {
+ /*
+ * The cases:
+ *
+ * nextAfter(+infinity, 0) == MAX_VALUE
+ * nextAfter(+infinity, +infinity) == +infinity
+ * nextAfter(-infinity, 0) == -MAX_VALUE
+ * nextAfter(-infinity, -infinity) == -infinity
+ *
+ * are naturally handled without any additional testing
+ */
+
+ // First check for NaN values
+ if (Float.isNaN(start) || Double.isNaN(direction)) {
+ // return a NaN derived from the input NaN(s)
+ return start + (float)direction;
+ } else if (start == direction) {
+ return (float)direction;
+ } else { // start > direction or start < direction
+ // Add +0.0 to get rid of a -0.0 (+0.0 + -0.0 => +0.0)
+ // then bitwise convert start to integer.
+ int transducer = Float.floatToRawIntBits(start + 0.0f);
+
+ /*
+ * IEEE 754 floating-point numbers are lexicographically
+ * ordered if treated as signed- magnitude integers .
+ * Since Java's integers are two's complement,
+ * incrementing" the two's complement representation of a
+ * logically negative floating-point value *decrements*
+ * the signed-magnitude representation. Therefore, when
+ * the integer representation of a floating-point values
+ * is less than zero, the adjustment to the representation
+ * is in the opposite direction than would be expected at
+ * first.
+ */
+ if (direction > start) {// Calculate next greater value
+ transducer = transducer + (transducer >= 0 ? 1:-1);
+ } else { // Calculate next lesser value
+ assert direction < start;
+ if (transducer > 0)
+ --transducer;
+ else
+ if (transducer < 0 )
+ ++transducer;
+ /*
+ * transducer==0, the result is -MIN_VALUE
+ *
+ * The transition from zero (implicitly
+ * positive) to the smallest negative
+ * signed magnitude value must be done
+ * explicitly.
+ */
+ else
+ transducer = FloatConsts.SIGN_BIT_MASK | 1;
+ }
+
+ return Float.intBitsToFloat(transducer);
+ }
+ }
+
+ /**
+ * Returns the floating-point value adjacent to {@code d} in
+ * the direction of positive infinity. This method is
+ * semantically equivalent to {@code nextAfter(d,
+ * Double.POSITIVE_INFINITY)}; however, a {@code nextUp}
+ * implementation may run faster than its equivalent
+ * {@code nextAfter} call.
+ *
+ * <p>Special Cases:
+ * <ul>
+ * <li> If the argument is NaN, the result is NaN.
+ *
+ * <li> If the argument is positive infinity, the result is
+ * positive infinity.
+ *
+ * <li> If the argument is zero, the result is
+ * {@link Double#MIN_VALUE}
+ *
+ * </ul>
+ *
+ * @param d starting floating-point value
+ * @return The adjacent floating-point value closer to positive
+ * infinity.
+ * @since 1.6
+ */
+ public static double nextUp(double d) {
+ if( Double.isNaN(d) || d == Double.POSITIVE_INFINITY)
+ return d;
+ else {
+ d += 0.0d;
+ return Double.longBitsToDouble(Double.doubleToRawLongBits(d) +
+ ((d >= 0.0d)?+1L:-1L));
+ }
+ }
+
+ /**
+ * Returns the floating-point value adjacent to {@code f} in
+ * the direction of positive infinity. This method is
+ * semantically equivalent to {@code nextAfter(f,
+ * Float.POSITIVE_INFINITY)}; however, a {@code nextUp}
+ * implementation may run faster than its equivalent
+ * {@code nextAfter} call.
+ *
+ * <p>Special Cases:
+ * <ul>
+ * <li> If the argument is NaN, the result is NaN.
+ *
+ * <li> If the argument is positive infinity, the result is
+ * positive infinity.
+ *
+ * <li> If the argument is zero, the result is
+ * {@link Float#MIN_VALUE}
+ *
+ * </ul>
+ *
+ * @param f starting floating-point value
+ * @return The adjacent floating-point value closer to positive
+ * infinity.
+ * @since 1.6
+ */
+ public static float nextUp(float f) {
+ if( Float.isNaN(f) || f == FloatConsts.POSITIVE_INFINITY)
+ return f;
+ else {
+ f += 0.0f;
+ return Float.intBitsToFloat(Float.floatToRawIntBits(f) +
+ ((f >= 0.0f)?+1:-1));
+ }
+ }
+
+ /**
+ * Returns the floating-point value adjacent to {@code d} in
+ * the direction of negative infinity. This method is
+ * semantically equivalent to {@code nextAfter(d,
+ * Double.NEGATIVE_INFINITY)}; however, a
+ * {@code nextDown} implementation may run faster than its
+ * equivalent {@code nextAfter} call.
+ *
+ * <p>Special Cases:
+ * <ul>
+ * <li> If the argument is NaN, the result is NaN.
+ *
+ * <li> If the argument is negative infinity, the result is
+ * negative infinity.
+ *
+ * <li> If the argument is zero, the result is
+ * {@code -Double.MIN_VALUE}
+ *
+ * </ul>
+ *
+ * @param d starting floating-point value
+ * @return The adjacent floating-point value closer to negative
+ * infinity.
+ * @since 1.8
+ */
+ public static double nextDown(double d) {
+ if (Double.isNaN(d) || d == Double.NEGATIVE_INFINITY)
+ return d;
+ else {
+ if (d == 0.0)
+ return -Double.MIN_VALUE;
+ else
+ return Double.longBitsToDouble(Double.doubleToRawLongBits(d) +
+ ((d > 0.0d)?-1L:+1L));
+ }
+ }
+
+ /**
+ * Returns the floating-point value adjacent to {@code f} in
+ * the direction of negative infinity. This method is
+ * semantically equivalent to {@code nextAfter(f,
+ * Float.NEGATIVE_INFINITY)}; however, a
+ * {@code nextDown} implementation may run faster than its
+ * equivalent {@code nextAfter} call.
+ *
+ * <p>Special Cases:
+ * <ul>
+ * <li> If the argument is NaN, the result is NaN.
+ *
+ * <li> If the argument is negative infinity, the result is
+ * negative infinity.
+ *
+ * <li> If the argument is zero, the result is
+ * {@code -Float.MIN_VALUE}
+ *
+ * </ul>
+ *
+ * @param f starting floating-point value
+ * @return The adjacent floating-point value closer to negative
+ * infinity.
+ * @since 1.8
+ */
+ public static float nextDown(float f) {
+ if (Float.isNaN(f) || f == Float.NEGATIVE_INFINITY)
+ return f;
+ else {
+ if (f == 0.0f)
+ return -Float.MIN_VALUE;
+ else
+ return Float.intBitsToFloat(Float.floatToRawIntBits(f) +
+ ((f > 0.0f)?-1:+1));
+ }
+ }
+
+ /**
+ * Returns {@code d} ×
+ * 2<sup>{@code scaleFactor}</sup> rounded as if performed
+ * by a single correctly rounded floating-point multiply to a
+ * member of the double value set. See the Java
+ * Language Specification for a discussion of floating-point
+ * value sets. If the exponent of the result is between {@link
+ * Double#MIN_EXPONENT} and {@link Double#MAX_EXPONENT}, the
+ * answer is calculated exactly. If the exponent of the result
+ * would be larger than {@code Double.MAX_EXPONENT}, an
+ * infinity is returned. Note that if the result is subnormal,
+ * precision may be lost; that is, when {@code scalb(x, n)}
+ * is subnormal, {@code scalb(scalb(x, n), -n)} may not equal
+ * <i>x</i>. When the result is non-NaN, the result has the same
+ * sign as {@code d}.
+ *
+ * <p>Special cases:
+ * <ul>
+ * <li> If the first argument is NaN, NaN is returned.
+ * <li> If the first argument is infinite, then an infinity of the
+ * same sign is returned.
+ * <li> If the first argument is zero, then a zero of the same
+ * sign is returned.
+ * </ul>
+ *
+ * @param d number to be scaled by a power of two.
+ * @param scaleFactor power of 2 used to scale {@code d}
+ * @return {@code d} × 2<sup>{@code scaleFactor}</sup>
+ * @since 1.6
+ */
+ public static double scalb(double d, int scaleFactor) {
+ /*
+ * This method does not need to be declared strictfp to
+ * compute the same correct result on all platforms. When
+ * scaling up, it does not matter what order the
+ * multiply-store operations are done; the result will be
+ * finite or overflow regardless of the operation ordering.
+ * However, to get the correct result when scaling down, a
+ * particular ordering must be used.
+ *
+ * When scaling down, the multiply-store operations are
+ * sequenced so that it is not possible for two consecutive
+ * multiply-stores to return subnormal results. If one
+ * multiply-store result is subnormal, the next multiply will
+ * round it away to zero. This is done by first multiplying
+ * by 2 ^ (scaleFactor % n) and then multiplying several
+ * times by by 2^n as needed where n is the exponent of number
+ * that is a covenient power of two. In this way, at most one
+ * real rounding error occurs. If the double value set is
+ * being used exclusively, the rounding will occur on a
+ * multiply. If the double-extended-exponent value set is
+ * being used, the products will (perhaps) be exact but the
+ * stores to d are guaranteed to round to the double value
+ * set.
+ *
+ * It is _not_ a valid implementation to first multiply d by
+ * 2^MIN_EXPONENT and then by 2 ^ (scaleFactor %
+ * MIN_EXPONENT) since even in a strictfp program double
+ * rounding on underflow could occur; e.g. if the scaleFactor
+ * argument was (MIN_EXPONENT - n) and the exponent of d was a
+ * little less than -(MIN_EXPONENT - n), meaning the final
+ * result would be subnormal.
+ *
+ * Since exact reproducibility of this method can be achieved
+ * without any undue performance burden, there is no
+ * compelling reason to allow double rounding on underflow in
+ * scalb.
+ */
+
+ // magnitude of a power of two so large that scaling a finite
+ // nonzero value by it would be guaranteed to over or
+ // underflow; due to rounding, scaling down takes takes an
+ // additional power of two which is reflected here
+ final int MAX_SCALE = DoubleConsts.MAX_EXPONENT + -DoubleConsts.MIN_EXPONENT +
+ DoubleConsts.SIGNIFICAND_WIDTH + 1;
+ int exp_adjust = 0;
+ int scale_increment = 0;
+ double exp_delta = Double.NaN;
+
+ // Make sure scaling factor is in a reasonable range
+
+ if(scaleFactor < 0) {
+ scaleFactor = Math.max(scaleFactor, -MAX_SCALE);
+ scale_increment = -512;
+ exp_delta = twoToTheDoubleScaleDown;
+ }
+ else {
+ scaleFactor = Math.min(scaleFactor, MAX_SCALE);
+ scale_increment = 512;
+ exp_delta = twoToTheDoubleScaleUp;
+ }
+
+ // Calculate (scaleFactor % +/-512), 512 = 2^9, using
+ // technique from "Hacker's Delight" section 10-2.
+ int t = (scaleFactor >> 9-1) >>> 32 - 9;
+ exp_adjust = ((scaleFactor + t) & (512 -1)) - t;
+
+ d *= powerOfTwoD(exp_adjust);
+ scaleFactor -= exp_adjust;
+
+ while(scaleFactor != 0) {
+ d *= exp_delta;
+ scaleFactor -= scale_increment;
+ }
+ return d;
+ }
+
+ /**
+ * Returns {@code f} ×
+ * 2<sup>{@code scaleFactor}</sup> rounded as if performed
+ * by a single correctly rounded floating-point multiply to a
+ * member of the float value set. See the Java
+ * Language Specification for a discussion of floating-point
+ * value sets. If the exponent of the result is between {@link
+ * Float#MIN_EXPONENT} and {@link Float#MAX_EXPONENT}, the
+ * answer is calculated exactly. If the exponent of the result
+ * would be larger than {@code Float.MAX_EXPONENT}, an
+ * infinity is returned. Note that if the result is subnormal,
+ * precision may be lost; that is, when {@code scalb(x, n)}
+ * is subnormal, {@code scalb(scalb(x, n), -n)} may not equal
+ * <i>x</i>. When the result is non-NaN, the result has the same
+ * sign as {@code f}.
+ *
+ * <p>Special cases:
+ * <ul>
+ * <li> If the first argument is NaN, NaN is returned.
+ * <li> If the first argument is infinite, then an infinity of the
+ * same sign is returned.
+ * <li> If the first argument is zero, then a zero of the same
+ * sign is returned.
+ * </ul>
+ *
+ * @param f number to be scaled by a power of two.
+ * @param scaleFactor power of 2 used to scale {@code f}
+ * @return {@code f} × 2<sup>{@code scaleFactor}</sup>
+ * @since 1.6
+ */
+ public static float scalb(float f, int scaleFactor) {
+ // magnitude of a power of two so large that scaling a finite
+ // nonzero value by it would be guaranteed to over or
+ // underflow; due to rounding, scaling down takes takes an
+ // additional power of two which is reflected here
+ final int MAX_SCALE = FloatConsts.MAX_EXPONENT + -FloatConsts.MIN_EXPONENT +
+ FloatConsts.SIGNIFICAND_WIDTH + 1;
+
+ // Make sure scaling factor is in a reasonable range
+ scaleFactor = Math.max(Math.min(scaleFactor, MAX_SCALE), -MAX_SCALE);
+
+ /*
+ * Since + MAX_SCALE for float fits well within the double
+ * exponent range and + float -> double conversion is exact
+ * the multiplication below will be exact. Therefore, the
+ * rounding that occurs when the double product is cast to
+ * float will be the correctly rounded float result. Since
+ * all operations other than the final multiply will be exact,
+ * it is not necessary to declare this method strictfp.
+ */
+ return (float)((double)f*powerOfTwoD(scaleFactor));
+ }
+
+ // Constants used in scalb
+ static double twoToTheDoubleScaleUp = powerOfTwoD(512);
+ static double twoToTheDoubleScaleDown = powerOfTwoD(-512);
+
+ /**
+ * Returns a floating-point power of two in the normal range.
+ */
+ static double powerOfTwoD(int n) {
+ assert(n >= DoubleConsts.MIN_EXPONENT && n <= DoubleConsts.MAX_EXPONENT);
+ return Double.longBitsToDouble((((long)n + (long)DoubleConsts.EXP_BIAS) <<
+ (DoubleConsts.SIGNIFICAND_WIDTH-1))
+ & DoubleConsts.EXP_BIT_MASK);
+ }
+
+ /**
+ * Returns a floating-point power of two in the normal range.
+ */
+ static float powerOfTwoF(int n) {
+ assert(n >= FloatConsts.MIN_EXPONENT && n <= FloatConsts.MAX_EXPONENT);
+ return Float.intBitsToFloat(((n + FloatConsts.EXP_BIAS) <<
+ (FloatConsts.SIGNIFICAND_WIDTH-1))
+ & FloatConsts.EXP_BIT_MASK);
+ }
+}
diff --git a/java/lang/NegativeArraySizeException.java b/java/lang/NegativeArraySizeException.java
new file mode 100644
index 0000000..a90c815
--- /dev/null
+++ b/java/lang/NegativeArraySizeException.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 1994, 2008, 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;
+
+/**
+ * Thrown if an application tries to create an array with negative size.
+ *
+ * @author unascribed
+ * @since JDK1.0
+ */
+public
+class NegativeArraySizeException extends RuntimeException {
+ private static final long serialVersionUID = -8960118058596991861L;
+
+ /**
+ * Constructs a <code>NegativeArraySizeException</code> with no
+ * detail message.
+ */
+ public NegativeArraySizeException() {
+ super();
+ }
+
+ /**
+ * Constructs a <code>NegativeArraySizeException</code> with the
+ * specified detail message.
+ *
+ * @param s the detail message.
+ */
+ public NegativeArraySizeException(String s) {
+ super(s);
+ }
+}
diff --git a/java/lang/NoClassDefFoundError.java b/java/lang/NoClassDefFoundError.java
new file mode 100644
index 0000000..e4f764f
--- /dev/null
+++ b/java/lang/NoClassDefFoundError.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 2008, 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;
+
+/**
+ * Thrown if the Java Virtual Machine or a <code>ClassLoader</code> instance
+ * tries to load in the definition of a class (as part of a normal method call
+ * or as part of creating a new instance using the <code>new</code> expression)
+ * and no definition of the class could be found.
+ * <p>
+ * The searched-for class definition existed when the currently
+ * executing class was compiled, but the definition can no longer be
+ * found.
+ *
+ * @author unascribed
+ * @since JDK1.0
+ */
+public
+class NoClassDefFoundError extends LinkageError {
+ private static final long serialVersionUID = 9095859863287012458L;
+
+ /**
+ * Constructs a <code>NoClassDefFoundError</code> with no detail message.
+ */
+ public NoClassDefFoundError() {
+ super();
+ }
+
+ /**
+ * Constructs a <code>NoClassDefFoundError</code> with the specified
+ * detail message.
+ *
+ * @param s the detail message.
+ */
+ public NoClassDefFoundError(String s) {
+ super(s);
+ }
+
+ // Android-added: A new constructor for use by the Android runtime.
+ /**
+ * Constructs a new {@code NoClassDefFoundError} with the current stack
+ * trace, the specified detail message and the specified cause. Used
+ * internally by the Android runtime.
+ *
+ * @param detailMessage
+ * the detail message for this error.
+ * @param throwable
+ * the cause of this error.
+ */
+ private NoClassDefFoundError(String detailMessage, Throwable throwable) {
+ super(detailMessage, throwable);
+ }
+}
diff --git a/java/lang/NoSuchFieldError.java b/java/lang/NoSuchFieldError.java
new file mode 100644
index 0000000..735adbb
--- /dev/null
+++ b/java/lang/NoSuchFieldError.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 1995, 2008, 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;
+
+/**
+ * Thrown if an application tries to access or modify a specified
+ * field of an object, and that object no longer has that field.
+ * <p>
+ * Normally, this error is caught by the compiler; this error can
+ * only occur at run time if the definition of a class has
+ * incompatibly changed.
+ *
+ * @author unascribed
+ * @since JDK1.0
+ */
+public
+class NoSuchFieldError extends IncompatibleClassChangeError {
+ private static final long serialVersionUID = -3456430195886129035L;
+
+ /**
+ * Constructs a <code>NoSuchFieldError</code> with no detail message.
+ */
+ public NoSuchFieldError() {
+ super();
+ }
+
+ /**
+ * Constructs a <code>NoSuchFieldError</code> with the specified
+ * detail message.
+ *
+ * @param s the detail message.
+ */
+ public NoSuchFieldError(String s) {
+ super(s);
+ }
+}
diff --git a/java/lang/NoSuchFieldException.java b/java/lang/NoSuchFieldException.java
new file mode 100644
index 0000000..0058264
--- /dev/null
+++ b/java/lang/NoSuchFieldException.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 1996, 2008, 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;
+
+/**
+ * Signals that the class doesn't have a field of a specified name.
+ *
+ * @author unascribed
+ * @since JDK1.1
+ */
+public class NoSuchFieldException extends ReflectiveOperationException {
+ private static final long serialVersionUID = -6143714805279938260L;
+
+ /**
+ * Constructor.
+ */
+ public NoSuchFieldException() {
+ super();
+ }
+
+ /**
+ * Constructor with a detail message.
+ *
+ * @param s the detail message
+ */
+ public NoSuchFieldException(String s) {
+ super(s);
+ }
+}
diff --git a/java/lang/NoSuchMethodError.java b/java/lang/NoSuchMethodError.java
new file mode 100644
index 0000000..248de62
--- /dev/null
+++ b/java/lang/NoSuchMethodError.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 1994, 2008, 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;
+
+/**
+ * Thrown if an application tries to call a specified method of a
+ * class (either static or instance), and that class no longer has a
+ * definition of that method.
+ * <p>
+ * Normally, this error is caught by the compiler; this error can
+ * only occur at run time if the definition of a class has
+ * incompatibly changed.
+ *
+ * @author unascribed
+ * @since JDK1.0
+ */
+public
+class NoSuchMethodError extends IncompatibleClassChangeError {
+ private static final long serialVersionUID = -3765521442372831335L;
+
+ /**
+ * Constructs a <code>NoSuchMethodError</code> with no detail message.
+ */
+ public NoSuchMethodError() {
+ super();
+ }
+
+ /**
+ * Constructs a <code>NoSuchMethodError</code> with the
+ * specified detail message.
+ *
+ * @param s the detail message.
+ */
+ public NoSuchMethodError(String s) {
+ super(s);
+ }
+}
diff --git a/java/lang/NoSuchMethodException.java b/java/lang/NoSuchMethodException.java
new file mode 100644
index 0000000..701437c
--- /dev/null
+++ b/java/lang/NoSuchMethodException.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 1995, 2008, 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;
+
+/**
+ * Thrown when a particular method cannot be found.
+ *
+ * @author unascribed
+ * @since JDK1.0
+ */
+public
+class NoSuchMethodException extends ReflectiveOperationException {
+ private static final long serialVersionUID = 5034388446362600923L;
+
+ /**
+ * Constructs a <code>NoSuchMethodException</code> without a detail message.
+ */
+ public NoSuchMethodException() {
+ super();
+ }
+
+ /**
+ * Constructs a <code>NoSuchMethodException</code> with a detail message.
+ *
+ * @param s the detail message.
+ */
+ public NoSuchMethodException(String s) {
+ super(s);
+ }
+}
diff --git a/java/lang/NullPointerException.java b/java/lang/NullPointerException.java
new file mode 100644
index 0000000..5b87ec4
--- /dev/null
+++ b/java/lang/NullPointerException.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 1994, 2011, 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;
+
+/**
+ * Thrown when an application attempts to use {@code null} in a
+ * case where an object is required. These include:
+ * <ul>
+ * <li>Calling the instance method of a {@code null} object.
+ * <li>Accessing or modifying the field of a {@code null} object.
+ * <li>Taking the length of {@code null} as if it were an array.
+ * <li>Accessing or modifying the slots of {@code null} as if it
+ * were an array.
+ * <li>Throwing {@code null} as if it were a {@code Throwable}
+ * value.
+ * </ul>
+ * <p>
+ * Applications should throw instances of this class to indicate
+ * other illegal uses of the {@code null} object.
+ *
+ * {@code NullPointerException} objects may be constructed by the
+ * virtual machine as if {@linkplain Throwable#Throwable(String,
+ * Throwable, boolean, boolean) suppression were disabled and/or the
+ * stack trace was not writable}.
+ *
+ * @author unascribed
+ * @since JDK1.0
+ */
+public
+class NullPointerException extends RuntimeException {
+ private static final long serialVersionUID = 5162710183389028792L;
+
+ /**
+ * Constructs a {@code NullPointerException} with no detail message.
+ */
+ public NullPointerException() {
+ super();
+ }
+
+ /**
+ * Constructs a {@code NullPointerException} with the specified
+ * detail message.
+ *
+ * @param s the detail message.
+ */
+ public NullPointerException(String s) {
+ super(s);
+ }
+}
diff --git a/java/lang/Number.java b/java/lang/Number.java
new file mode 100644
index 0000000..d901609
--- /dev/null
+++ b/java/lang/Number.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 1994, 2011, 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;
+
+/**
+ * The abstract class {@code Number} is the superclass of platform
+ * classes representing numeric values that are convertible to the
+ * primitive types {@code byte}, {@code double}, {@code float}, {@code
+ * int}, {@code long}, and {@code short}.
+ *
+ * The specific semantics of the conversion from the numeric value of
+ * a particular {@code Number} implementation to a given primitive
+ * type is defined by the {@code Number} implementation in question.
+ *
+ * For platform classes, the conversion is often analogous to a
+ * narrowing primitive conversion or a widening primitive conversion
+ * as defining in <cite>The Java™ Language Specification</cite>
+ * for converting between primitive types. Therefore, conversions may
+ * lose information about the overall magnitude of a numeric value, may
+ * lose precision, and may even return a result of a different sign
+ * than the input.
+ *
+ * See the documentation of a given {@code Number} implementation for
+ * conversion details.
+ *
+ * @author Lee Boynton
+ * @author Arthur van Hoff
+ * @jls 5.1.2 Widening Primitive Conversions
+ * @jls 5.1.3 Narrowing Primitive Conversions
+ * @since JDK1.0
+ */
+public abstract class Number implements java.io.Serializable {
+ /**
+ * Returns the value of the specified number as an {@code int},
+ * which may involve rounding or truncation.
+ *
+ * @return the numeric value represented by this object after conversion
+ * to type {@code int}.
+ */
+ public abstract int intValue();
+
+ /**
+ * Returns the value of the specified number as a {@code long},
+ * which may involve rounding or truncation.
+ *
+ * @return the numeric value represented by this object after conversion
+ * to type {@code long}.
+ */
+ public abstract long longValue();
+
+ /**
+ * Returns the value of the specified number as a {@code float},
+ * which may involve rounding.
+ *
+ * @return the numeric value represented by this object after conversion
+ * to type {@code float}.
+ */
+ public abstract float floatValue();
+
+ /**
+ * Returns the value of the specified number as a {@code double},
+ * which may involve rounding.
+ *
+ * @return the numeric value represented by this object after conversion
+ * to type {@code double}.
+ */
+ public abstract double doubleValue();
+
+ /**
+ * Returns the value of the specified number as a {@code byte},
+ * which may involve rounding or truncation.
+ *
+ * <p>This implementation returns the result of {@link #intValue} cast
+ * to a {@code byte}.
+ *
+ * @return the numeric value represented by this object after conversion
+ * to type {@code byte}.
+ * @since JDK1.1
+ */
+ public byte byteValue() {
+ return (byte)intValue();
+ }
+
+ /**
+ * Returns the value of the specified number as a {@code short},
+ * which may involve rounding or truncation.
+ *
+ * <p>This implementation returns the result of {@link #intValue} cast
+ * to a {@code short}.
+ *
+ * @return the numeric value represented by this object after conversion
+ * to type {@code short}.
+ * @since JDK1.1
+ */
+ public short shortValue() {
+ return (short)intValue();
+ }
+
+ /** use serialVersionUID from JDK 1.0.2 for interoperability */
+ private static final long serialVersionUID = -8742448824652078965L;
+}
diff --git a/java/lang/NumberFormatException.java b/java/lang/NumberFormatException.java
new file mode 100644
index 0000000..ea1ec9f
--- /dev/null
+++ b/java/lang/NumberFormatException.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 1994, 2012, 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;
+
+/**
+ * Thrown to indicate that the application has attempted to convert
+ * a string to one of the numeric types, but that the string does not
+ * have the appropriate format.
+ *
+ * @author unascribed
+ * @see java.lang.Integer#parseInt(String)
+ * @since JDK1.0
+ */
+public
+class NumberFormatException extends IllegalArgumentException {
+ static final long serialVersionUID = -2848938806368998894L;
+
+ /**
+ * Constructs a <code>NumberFormatException</code> with no detail message.
+ */
+ public NumberFormatException () {
+ super();
+ }
+
+ /**
+ * Constructs a <code>NumberFormatException</code> with the
+ * specified detail message.
+ *
+ * @param s the detail message.
+ */
+ public NumberFormatException (String s) {
+ super (s);
+ }
+
+ /**
+ * Factory method for making a <code>NumberFormatException</code>
+ * given the specified input which caused the error.
+ *
+ * @param s the input causing the error
+ */
+ static NumberFormatException forInputString(String s) {
+ return new NumberFormatException("For input string: \"" + s + "\"");
+ }
+}
diff --git a/java/lang/Object.annotated.java b/java/lang/Object.annotated.java
new file mode 100644
index 0000000..45939e8
--- /dev/null
+++ b/java/lang/Object.annotated.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 2012, 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;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class Object {
+
+public Object() { throw new RuntimeException("Stub!"); }
+
[email protected] public final java.lang.Class<?> getClass() { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
[email protected] protected java.lang.Object clone() throws java.lang.CloneNotSupportedException { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public final native void notify();
+
+public final native void notifyAll();
+
+public final void wait(long timeout) throws java.lang.InterruptedException { throw new RuntimeException("Stub!"); }
+
+public final native void wait(long timeout, int nanos) throws java.lang.InterruptedException;
+
+public final void wait() throws java.lang.InterruptedException { throw new RuntimeException("Stub!"); }
+
+protected void finalize() throws java.lang.Throwable { throw new RuntimeException("Stub!"); }
+}
diff --git a/java/lang/Object.java b/java/lang/Object.java
new file mode 100644
index 0000000..d307144
--- /dev/null
+++ b/java/lang/Object.java
@@ -0,0 +1,622 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 2012, 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;
+
+import dalvik.annotation.optimization.FastNative;
+
+/**
+ * Class {@code Object} is the root of the class hierarchy.
+ * Every class has {@code Object} as a superclass. All objects,
+ * including arrays, implement the methods of this class.
+ *
+ * @author unascribed
+ * @see java.lang.Class
+ * @since JDK1.0
+ */
+public class Object {
+
+ // Android-removed: registerNatives() not used on Android
+ // private static native void registerNatives();
+ // static {
+ // registerNatives();
+ // }
+
+ // Android-added: Use Android specific fields for Class and monitor.
+ private transient Class<?> shadow$_klass_;
+ private transient int shadow$_monitor_;
+
+ /**
+ * Returns the runtime class of this {@code Object}. The returned
+ * {@code Class} object is the object that is locked by {@code
+ * static synchronized} methods of the represented class.
+ *
+ * <p><b>The actual result type is {@code Class<? extends |X|>}
+ * where {@code |X|} is the erasure of the static type of the
+ * expression on which {@code getClass} is called.</b> For
+ * example, no cast is required in this code fragment:</p>
+ *
+ * <p>
+ * {@code Number n = 0; }<br>
+ * {@code Class<? extends Number> c = n.getClass(); }
+ * </p>
+ *
+ * @return The {@code Class} object that represents the runtime
+ * class of this object.
+ * @jls 15.8.2 Class Literals
+ */
+ // Android-changed: Use Android specific fields for Class and monitor.
+ // public final native Class<?> getClass();
+ public final Class<?> getClass() {
+ return shadow$_klass_;
+ }
+
+ /**
+ * Returns a hash code value for the object. This method is
+ * supported for the benefit of hash tables such as those provided by
+ * {@link java.util.HashMap}.
+ * <p>
+ * The general contract of {@code hashCode} is:
+ * <ul>
+ * <li>Whenever it is invoked on the same object more than once during
+ * an execution of a Java application, the {@code hashCode} method
+ * must consistently return the same integer, provided no information
+ * used in {@code equals} comparisons on the object is modified.
+ * This integer need not remain consistent from one execution of an
+ * application to another execution of the same application.
+ * <li>If two objects are equal according to the {@code equals(Object)}
+ * method, then calling the {@code hashCode} method on each of
+ * the two objects must produce the same integer result.
+ * <li>It is <em>not</em> required that if two objects are unequal
+ * according to the {@link java.lang.Object#equals(java.lang.Object)}
+ * method, then calling the {@code hashCode} method on each of the
+ * two objects must produce distinct integer results. However, the
+ * programmer should be aware that producing distinct integer results
+ * for unequal objects may improve the performance of hash tables.
+ * </ul>
+ * <p>
+ * As much as is reasonably practical, the hashCode method defined by
+ * class {@code Object} does return distinct integers for distinct
+ * objects. (This is typically implemented by converting the internal
+ * address of the object into an integer, but this implementation
+ * technique is not required by the
+ * Java™ programming language.)
+ *
+ * @return a hash code value for this object.
+ * @see java.lang.Object#equals(java.lang.Object)
+ * @see java.lang.System#identityHashCode
+ */
+ // BEGIN Android-changed: Added a local helper for identityHashCode.
+ // public native int hashCode();
+ public int hashCode() {
+ return identityHashCode(this);
+ }
+
+ // Package-private to be used by j.l.System. We do the implementation here
+ // to avoid Object.hashCode doing a clinit check on j.l.System, and also
+ // to avoid leaking shadow$_monitor_ outside of this class.
+ /* package-private */ static int identityHashCode(Object obj) {
+ int lockWord = obj.shadow$_monitor_;
+ final int lockWordStateMask = 0xC0000000; // Top 2 bits.
+ final int lockWordStateHash = 0x80000000; // Top 2 bits are value 2 (kStateHash).
+ final int lockWordHashMask = 0x0FFFFFFF; // Low 28 bits.
+ if ((lockWord & lockWordStateMask) == lockWordStateHash) {
+ return lockWord & lockWordHashMask;
+ }
+ return identityHashCodeNative(obj);
+ }
+
+ /**
+ * Return the identity hash code when the information in the monitor field
+ * is not sufficient.
+ */
+ @FastNative
+ private static native int identityHashCodeNative(Object obj);
+ // END Android-changed: Added a local helper for identityHashCode.
+
+ /**
+ * Indicates whether some other object is "equal to" this one.
+ * <p>
+ * The {@code equals} method implements an equivalence relation
+ * on non-null object references:
+ * <ul>
+ * <li>It is <i>reflexive</i>: for any non-null reference value
+ * {@code x}, {@code x.equals(x)} should return
+ * {@code true}.
+ * <li>It is <i>symmetric</i>: for any non-null reference values
+ * {@code x} and {@code y}, {@code x.equals(y)}
+ * should return {@code true} if and only if
+ * {@code y.equals(x)} returns {@code true}.
+ * <li>It is <i>transitive</i>: for any non-null reference values
+ * {@code x}, {@code y}, and {@code z}, if
+ * {@code x.equals(y)} returns {@code true} and
+ * {@code y.equals(z)} returns {@code true}, then
+ * {@code x.equals(z)} should return {@code true}.
+ * <li>It is <i>consistent</i>: for any non-null reference values
+ * {@code x} and {@code y}, multiple invocations of
+ * {@code x.equals(y)} consistently return {@code true}
+ * or consistently return {@code false}, provided no
+ * information used in {@code equals} comparisons on the
+ * objects is modified.
+ * <li>For any non-null reference value {@code x},
+ * {@code x.equals(null)} should return {@code false}.
+ * </ul>
+ * <p>
+ * The {@code equals} method for class {@code Object} implements
+ * the most discriminating possible equivalence relation on objects;
+ * that is, for any non-null reference values {@code x} and
+ * {@code y}, this method returns {@code true} if and only
+ * if {@code x} and {@code y} refer to the same object
+ * ({@code x == y} has the value {@code true}).
+ * <p>
+ * Note that it is generally necessary to override the {@code hashCode}
+ * method whenever this method is overridden, so as to maintain the
+ * general contract for the {@code hashCode} method, which states
+ * that equal objects must have equal hash codes.
+ *
+ * @param obj the reference object with which to compare.
+ * @return {@code true} if this object is the same as the obj
+ * argument; {@code false} otherwise.
+ * @see #hashCode()
+ * @see java.util.HashMap
+ */
+ public boolean equals(Object obj) {
+ return (this == obj);
+ }
+
+ /**
+ * Creates and returns a copy of this object. The precise meaning
+ * of "copy" may depend on the class of the object. The general
+ * intent is that, for any object {@code x}, the expression:
+ * <blockquote>
+ * <pre>
+ * x.clone() != x</pre></blockquote>
+ * will be true, and that the expression:
+ * <blockquote>
+ * <pre>
+ * x.clone().getClass() == x.getClass()</pre></blockquote>
+ * will be {@code true}, but these are not absolute requirements.
+ * While it is typically the case that:
+ * <blockquote>
+ * <pre>
+ * x.clone().equals(x)</pre></blockquote>
+ * will be {@code true}, this is not an absolute requirement.
+ * <p>
+ * By convention, the returned object should be obtained by calling
+ * {@code super.clone}. If a class and all of its superclasses (except
+ * {@code Object}) obey this convention, it will be the case that
+ * {@code x.clone().getClass() == x.getClass()}.
+ * <p>
+ * By convention, the object returned by this method should be independent
+ * of this object (which is being cloned). To achieve this independence,
+ * it may be necessary to modify one or more fields of the object returned
+ * by {@code super.clone} before returning it. Typically, this means
+ * copying any mutable objects that comprise the internal "deep structure"
+ * of the object being cloned and replacing the references to these
+ * objects with references to the copies. If a class contains only
+ * primitive fields or references to immutable objects, then it is usually
+ * the case that no fields in the object returned by {@code super.clone}
+ * need to be modified.
+ * <p>
+ * The method {@code clone} for class {@code Object} performs a
+ * specific cloning operation. First, if the class of this object does
+ * not implement the interface {@code Cloneable}, then a
+ * {@code CloneNotSupportedException} is thrown. Note that all arrays
+ * are considered to implement the interface {@code Cloneable} and that
+ * the return type of the {@code clone} method of an array type {@code T[]}
+ * is {@code T[]} where T is any reference or primitive type.
+ * Otherwise, this method creates a new instance of the class of this
+ * object and initializes all its fields with exactly the contents of
+ * the corresponding fields of this object, as if by assignment; the
+ * contents of the fields are not themselves cloned. Thus, this method
+ * performs a "shallow copy" of this object, not a "deep copy" operation.
+ * <p>
+ * The class {@code Object} does not itself implement the interface
+ * {@code Cloneable}, so calling the {@code clone} method on an object
+ * whose class is {@code Object} will result in throwing an
+ * exception at run time.
+ *
+ * @return a clone of this instance.
+ * @throws CloneNotSupportedException if the object's class does not
+ * support the {@code Cloneable} interface. Subclasses
+ * that override the {@code clone} method can also
+ * throw this exception to indicate that an instance cannot
+ * be cloned.
+ * @see java.lang.Cloneable
+ */
+ // BEGIN Android-changed: Use native local helper for clone()
+ // Checks whether cloning is allowed before calling native local helper.
+ // protected native Object clone() throws CloneNotSupportedException;
+ protected Object clone() throws CloneNotSupportedException {
+ if (!(this instanceof Cloneable)) {
+ throw new CloneNotSupportedException("Class " + getClass().getName() +
+ " doesn't implement Cloneable");
+ }
+
+ return internalClone();
+ }
+
+ /*
+ * Native helper method for cloning.
+ */
+ @FastNative
+ private native Object internalClone();
+ // END Android-changed: Use native local helper for clone()
+
+ /**
+ * Returns a string representation of the object. In general, the
+ * {@code toString} method returns a string that
+ * "textually represents" this object. The result should
+ * be a concise but informative representation that is easy for a
+ * person to read.
+ * It is recommended that all subclasses override this method.
+ * <p>
+ * The {@code toString} method for class {@code Object}
+ * returns a string consisting of the name of the class of which the
+ * object is an instance, the at-sign character `{@code @}', and
+ * the unsigned hexadecimal representation of the hash code of the
+ * object. In other words, this method returns a string equal to the
+ * value of:
+ * <blockquote>
+ * <pre>
+ * getClass().getName() + '@' + Integer.toHexString(hashCode())
+ * </pre></blockquote>
+ *
+ * @return a string representation of the object.
+ */
+ public String toString() {
+ return getClass().getName() + "@" + Integer.toHexString(hashCode());
+ }
+
+ /**
+ * Wakes up a single thread that is waiting on this object's
+ * monitor. If any threads are waiting on this object, one of them
+ * is chosen to be awakened. The choice is arbitrary and occurs at
+ * the discretion of the implementation. A thread waits on an object's
+ * monitor by calling one of the {@code wait} methods.
+ * <p>
+ * The awakened thread will not be able to proceed until the current
+ * thread relinquishes the lock on this object. The awakened thread will
+ * compete in the usual manner with any other threads that might be
+ * actively competing to synchronize on this object; for example, the
+ * awakened thread enjoys no reliable privilege or disadvantage in being
+ * the next thread to lock this object.
+ * <p>
+ * This method should only be called by a thread that is the owner
+ * of this object's monitor. A thread becomes the owner of the
+ * object's monitor in one of three ways:
+ * <ul>
+ * <li>By executing a synchronized instance method of that object.
+ * <li>By executing the body of a {@code synchronized} statement
+ * that synchronizes on the object.
+ * <li>For objects of type {@code Class,} by executing a
+ * synchronized static method of that class.
+ * </ul>
+ * <p>
+ * Only one thread at a time can own an object's monitor.
+ *
+ * @throws IllegalMonitorStateException if the current thread is not
+ * the owner of this object's monitor.
+ * @see java.lang.Object#notifyAll()
+ * @see java.lang.Object#wait()
+ */
+ @FastNative
+ public final native void notify();
+
+ /**
+ * Wakes up all threads that are waiting on this object's monitor. A
+ * thread waits on an object's monitor by calling one of the
+ * {@code wait} methods.
+ * <p>
+ * The awakened threads will not be able to proceed until the current
+ * thread relinquishes the lock on this object. The awakened threads
+ * will compete in the usual manner with any other threads that might
+ * be actively competing to synchronize on this object; for example,
+ * the awakened threads enjoy no reliable privilege or disadvantage in
+ * being the next thread to lock this object.
+ * <p>
+ * This method should only be called by a thread that is the owner
+ * of this object's monitor. See the {@code notify} method for a
+ * description of the ways in which a thread can become the owner of
+ * a monitor.
+ *
+ * @throws IllegalMonitorStateException if the current thread is not
+ * the owner of this object's monitor.
+ * @see java.lang.Object#notify()
+ * @see java.lang.Object#wait()
+ */
+ @FastNative
+ public final native void notifyAll();
+
+ /**
+ * Causes the current thread to wait until either another thread invokes the
+ * {@link java.lang.Object#notify()} method or the
+ * {@link java.lang.Object#notifyAll()} method for this object, or a
+ * specified amount of time has elapsed.
+ * <p>
+ * The current thread must own this object's monitor.
+ * <p>
+ * This method causes the current thread (call it <var>T</var>) to
+ * place itself in the wait set for this object and then to relinquish
+ * any and all synchronization claims on this object. Thread <var>T</var>
+ * becomes disabled for thread scheduling purposes and lies dormant
+ * until one of four things happens:
+ * <ul>
+ * <li>Some other thread invokes the {@code notify} method for this
+ * object and thread <var>T</var> happens to be arbitrarily chosen as
+ * the thread to be awakened.
+ * <li>Some other thread invokes the {@code notifyAll} method for this
+ * object.
+ * <li>Some other thread {@linkplain Thread#interrupt() interrupts}
+ * thread <var>T</var>.
+ * <li>The specified amount of real time has elapsed, more or less. If
+ * {@code timeout} is zero, however, then real time is not taken into
+ * consideration and the thread simply waits until notified.
+ * </ul>
+ * The thread <var>T</var> is then removed from the wait set for this
+ * object and re-enabled for thread scheduling. It then competes in the
+ * usual manner with other threads for the right to synchronize on the
+ * object; once it has gained control of the object, all its
+ * synchronization claims on the object are restored to the status quo
+ * ante - that is, to the situation as of the time that the {@code wait}
+ * method was invoked. Thread <var>T</var> then returns from the
+ * invocation of the {@code wait} method. Thus, on return from the
+ * {@code wait} method, the synchronization state of the object and of
+ * thread {@code T} is exactly as it was when the {@code wait} method
+ * was invoked.
+ * <p>
+ * A thread can also wake up without being notified, interrupted, or
+ * timing out, a so-called <i>spurious wakeup</i>. While this will rarely
+ * occur in practice, applications must guard against it by testing for
+ * the condition that should have caused the thread to be awakened, and
+ * continuing to wait if the condition is not satisfied. In other words,
+ * waits should always occur in loops, like this one:
+ * <pre>
+ * synchronized (obj) {
+ * while (<condition does not hold>)
+ * obj.wait(timeout);
+ * ... // Perform action appropriate to condition
+ * }
+ * </pre>
+ * (For more information on this topic, see Section 3.2.3 in Doug Lea's
+ * "Concurrent Programming in Java (Second Edition)" (Addison-Wesley,
+ * 2000), or Item 50 in Joshua Bloch's "Effective Java Programming
+ * Language Guide" (Addison-Wesley, 2001).
+ *
+ * <p>If the current thread is {@linkplain java.lang.Thread#interrupt()
+ * interrupted} by any thread before or while it is waiting, then an
+ * {@code InterruptedException} is thrown. This exception is not
+ * thrown until the lock status of this object has been restored as
+ * described above.
+ *
+ * <p>
+ * Note that the {@code wait} method, as it places the current thread
+ * into the wait set for this object, unlocks only this object; any
+ * other objects on which the current thread may be synchronized remain
+ * locked while the thread waits.
+ * <p>
+ * This method should only be called by a thread that is the owner
+ * of this object's monitor. See the {@code notify} method for a
+ * description of the ways in which a thread can become the owner of
+ * a monitor.
+ *
+ * @param timeout the maximum time to wait in milliseconds.
+ * @throws IllegalArgumentException if the value of timeout is
+ * negative.
+ * @throws IllegalMonitorStateException if the current thread is not
+ * the owner of the object's monitor.
+ * @throws InterruptedException if any thread interrupted the
+ * current thread before or while the current thread
+ * was waiting for a notification. The <i>interrupted
+ * status</i> of the current thread is cleared when
+ * this exception is thrown.
+ * @see java.lang.Object#notify()
+ * @see java.lang.Object#notifyAll()
+ */
+ // Android-changed: Implement wait(long) non-natively.
+ // public final native void wait(long timeout) throws InterruptedException;
+ public final void wait(long timeout) throws InterruptedException {
+ wait(timeout, 0);
+ }
+
+ /**
+ * Causes the current thread to wait until another thread invokes the
+ * {@link java.lang.Object#notify()} method or the
+ * {@link java.lang.Object#notifyAll()} method for this object, or
+ * some other thread interrupts the current thread, or a certain
+ * amount of real time has elapsed.
+ * <p>
+ * This method is similar to the {@code wait} method of one
+ * argument, but it allows finer control over the amount of time to
+ * wait for a notification before giving up. The amount of real time,
+ * measured in nanoseconds, is given by:
+ * <blockquote>
+ * <pre>
+ * 1000000*timeout+nanos</pre></blockquote>
+ * <p>
+ * In all other respects, this method does the same thing as the
+ * method {@link #wait(long)} of one argument. In particular,
+ * {@code wait(0, 0)} means the same thing as {@code wait(0)}.
+ * <p>
+ * The current thread must own this object's monitor. The thread
+ * releases ownership of this monitor and waits until either of the
+ * following two conditions has occurred:
+ * <ul>
+ * <li>Another thread notifies threads waiting on this object's monitor
+ * to wake up either through a call to the {@code notify} method
+ * or the {@code notifyAll} method.
+ * <li>The timeout period, specified by {@code timeout}
+ * milliseconds plus {@code nanos} nanoseconds arguments, has
+ * elapsed.
+ * </ul>
+ * <p>
+ * The thread then waits until it can re-obtain ownership of the
+ * monitor and resumes execution.
+ * <p>
+ * As in the one argument version, interrupts and spurious wakeups are
+ * possible, and this method should always be used in a loop:
+ * <pre>
+ * synchronized (obj) {
+ * while (<condition does not hold>)
+ * obj.wait(timeout, nanos);
+ * ... // Perform action appropriate to condition
+ * }
+ * </pre>
+ * This method should only be called by a thread that is the owner
+ * of this object's monitor. See the {@code notify} method for a
+ * description of the ways in which a thread can become the owner of
+ * a monitor.
+ *
+ * @param timeout the maximum time to wait in milliseconds.
+ * @param nanos additional time, in nanoseconds range
+ * 0-999999.
+ * @throws IllegalArgumentException if the value of timeout is
+ * negative or the value of nanos is
+ * not in the range 0-999999.
+ * @throws IllegalMonitorStateException if the current thread is not
+ * the owner of this object's monitor.
+ * @throws InterruptedException if any thread interrupted the
+ * current thread before or while the current thread
+ * was waiting for a notification. The <i>interrupted
+ * status</i> of the current thread is cleared when
+ * this exception is thrown.
+ */
+ // Android-changed: Implement wait(long, int) natively.
+ /*
+ public final void wait(long timeout, int nanos) throws InterruptedException {
+ if (timeout < 0) {
+ throw new IllegalArgumentException("timeout value is negative");
+ }
+
+ if (nanos < 0 || nanos > 999999) {
+ throw new IllegalArgumentException(
+ "nanosecond timeout value out of range");
+ }
+
+ if (nanos > 0) {
+ timeout++;
+ }
+
+ wait(timeout);
+ }
+ */
+ @FastNative
+ public final native void wait(long timeout, int nanos) throws InterruptedException;
+
+ /**
+ * Causes the current thread to wait until another thread invokes the
+ * {@link java.lang.Object#notify()} method or the
+ * {@link java.lang.Object#notifyAll()} method for this object.
+ * In other words, this method behaves exactly as if it simply
+ * performs the call {@code wait(0)}.
+ * <p>
+ * The current thread must own this object's monitor. The thread
+ * releases ownership of this monitor and waits until another thread
+ * notifies threads waiting on this object's monitor to wake up
+ * either through a call to the {@code notify} method or the
+ * {@code notifyAll} method. The thread then waits until it can
+ * re-obtain ownership of the monitor and resumes execution.
+ * <p>
+ * As in the one argument version, interrupts and spurious wakeups are
+ * possible, and this method should always be used in a loop:
+ * <pre>
+ * synchronized (obj) {
+ * while (<condition does not hold>)
+ * obj.wait();
+ * ... // Perform action appropriate to condition
+ * }
+ * </pre>
+ * This method should only be called by a thread that is the owner
+ * of this object's monitor. See the {@code notify} method for a
+ * description of the ways in which a thread can become the owner of
+ * a monitor.
+ *
+ * @throws IllegalMonitorStateException if the current thread is not
+ * the owner of the object's monitor.
+ * @throws InterruptedException if any thread interrupted the
+ * current thread before or while the current thread
+ * was waiting for a notification. The <i>interrupted
+ * status</i> of the current thread is cleared when
+ * this exception is thrown.
+ * @see java.lang.Object#notify()
+ * @see java.lang.Object#notifyAll()
+ */
+ public final void wait() throws InterruptedException {
+ wait(0);
+ }
+
+ /**
+ * Called by the garbage collector on an object when garbage collection
+ * determines that there are no more references to the object.
+ * A subclass overrides the {@code finalize} method to dispose of
+ * system resources or to perform other cleanup.
+ * <p>
+ * The general contract of {@code finalize} is that it is invoked
+ * if and when the Java™ virtual
+ * machine has determined that there is no longer any
+ * means by which this object can be accessed by any thread that has
+ * not yet died, except as a result of an action taken by the
+ * finalization of some other object or class which is ready to be
+ * finalized. The {@code finalize} method may take any action, including
+ * making this object available again to other threads; the usual purpose
+ * of {@code finalize}, however, is to perform cleanup actions before
+ * the object is irrevocably discarded. For example, the finalize method
+ * for an object that represents an input/output connection might perform
+ * explicit I/O transactions to break the connection before the object is
+ * permanently discarded.
+ * <p>
+ * The {@code finalize} method of class {@code Object} performs no
+ * special action; it simply returns normally. Subclasses of
+ * {@code Object} may override this definition.
+ * <p>
+ * The Java programming language does not guarantee which thread will
+ * invoke the {@code finalize} method for any given object. It is
+ * guaranteed, however, that the thread that invokes finalize will not
+ * be holding any user-visible synchronization locks when finalize is
+ * invoked. If an uncaught exception is thrown by the finalize method,
+ * the exception is ignored and finalization of that object terminates.
+ * <p>
+ * After the {@code finalize} method has been invoked for an object, no
+ * further action is taken until the Java virtual machine has again
+ * determined that there is no longer any means by which this object can
+ * be accessed by any thread that has not yet died, including possible
+ * actions by other objects or classes which are ready to be finalized,
+ * at which point the object may be discarded.
+ * <p>
+ * The {@code finalize} method is never invoked more than once by a Java
+ * virtual machine for any given object.
+ * <p>
+ * Any exception thrown by the {@code finalize} method causes
+ * the finalization of this object to be halted, but is otherwise
+ * ignored.
+ *
+ * @throws Throwable the {@code Exception} raised by this method
+ * @see java.lang.ref.WeakReference
+ * @see java.lang.ref.PhantomReference
+ * @jls 12.6 Finalization of Class Instances
+ */
+ protected void finalize() throws Throwable { }
+}
diff --git a/java/lang/OutOfMemoryError.java b/java/lang/OutOfMemoryError.java
new file mode 100644
index 0000000..0f9df4e
--- /dev/null
+++ b/java/lang/OutOfMemoryError.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 1994, 2011, 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;
+
+/**
+ * Thrown when the Java Virtual Machine cannot allocate an object
+ * because it is out of memory, and no more memory could be made
+ * available by the garbage collector.
+ *
+ * {@code OutOfMemoryError} objects may be constructed by the virtual
+ * machine as if {@linkplain Throwable#Throwable(String, Throwable,
+ * boolean, boolean) suppression were disabled and/or the stack trace was not
+ * writable}.
+ *
+ * @author unascribed
+ * @since JDK1.0
+ */
+public class OutOfMemoryError extends VirtualMachineError {
+ private static final long serialVersionUID = 8228564086184010517L;
+
+ /**
+ * Constructs an {@code OutOfMemoryError} with no detail message.
+ */
+ public OutOfMemoryError() {
+ super();
+ }
+
+ /**
+ * Constructs an {@code OutOfMemoryError} with the specified
+ * detail message.
+ *
+ * @param s the detail message.
+ */
+ public OutOfMemoryError(String s) {
+ super(s);
+ }
+}
diff --git a/java/lang/Override.java b/java/lang/Override.java
new file mode 100644
index 0000000..bf77344
--- /dev/null
+++ b/java/lang/Override.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2003, 2013, 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;
+
+import java.lang.annotation.*;
+
+/**
+ * Indicates that a method declaration is intended to override a
+ * method declaration in a supertype. If a method is annotated with
+ * this annotation type compilers are required to generate an error
+ * message unless at least one of the following conditions hold:
+ *
+ * <ul><li>
+ * The method does override or implement a method declared in a
+ * supertype.
+ * </li><li>
+ * The method has a signature that is override-equivalent to that of
+ * any public method declared in {@linkplain Object}.
+ * </li></ul>
+ *
+ * @author Peter von der Ahé
+ * @author Joshua Bloch
+ * @jls 9.6.1.4 @Override
+ * @since 1.5
+ */
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.SOURCE)
+public @interface Override {
+}
diff --git a/java/lang/Package.java b/java/lang/Package.java
new file mode 100644
index 0000000..b6a37fd
--- /dev/null
+++ b/java/lang/Package.java
@@ -0,0 +1,657 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1997, 2013, 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;
+
+import java.lang.reflect.AnnotatedElement;
+import java.io.InputStream;
+import java.util.Enumeration;
+
+import java.util.StringTokenizer;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.net.URL;
+import java.net.MalformedURLException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import java.util.jar.JarInputStream;
+import java.util.jar.Manifest;
+import java.util.jar.Attributes;
+import java.util.jar.Attributes.Name;
+import java.util.jar.JarException;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Iterator;
+
+import sun.net.www.ParseUtil;
+import sun.reflect.CallerSensitive;
+import dalvik.system.VMRuntime;
+import sun.reflect.Reflection;
+
+import java.lang.annotation.Annotation;
+
+/**
+ * {@code Package} objects contain version information
+ * about the implementation and specification of a Java package.
+ * This versioning information is retrieved and made available
+ * by the {@link ClassLoader} instance that
+ * loaded the class(es). Typically, it is stored in the manifest that is
+ * distributed with the classes.
+ *
+ * <p>The set of classes that make up the package may implement a
+ * particular specification and if so the specification title, version number,
+ * and vendor strings identify that specification.
+ * An application can ask if the package is
+ * compatible with a particular version, see the {@link
+ * #isCompatibleWith isCompatibleWith}
+ * method for details.
+ *
+ * <p>Specification version numbers use a syntax that consists of nonnegative
+ * decimal integers separated by periods ".", for example "2.0" or
+ * "1.2.3.4.5.6.7". This allows an extensible number to be used to represent
+ * major, minor, micro, etc. versions. The version specification is described
+ * by the following formal grammar:
+ * <blockquote>
+ * <dl>
+ * <dt><i>SpecificationVersion:</i>
+ * <dd><i>Digits RefinedVersion<sub>opt</sub></i>
+
+ * <dt><i>RefinedVersion:</i>
+ * <dd>{@code .} <i>Digits</i>
+ * <dd>{@code .} <i>Digits RefinedVersion</i>
+ *
+ * <dt><i>Digits:</i>
+ * <dd><i>Digit</i>
+ * <dd><i>Digits</i>
+ *
+ * <dt><i>Digit:</i>
+ * <dd>any character for which {@link Character#isDigit} returns {@code true},
+ * e.g. 0, 1, 2, ...
+ * </dl>
+ * </blockquote>
+ *
+ * <p>The implementation title, version, and vendor strings identify an
+ * implementation and are made available conveniently to enable accurate
+ * reporting of the packages involved when a problem occurs. The contents
+ * all three implementation strings are vendor specific. The
+ * implementation version strings have no specified syntax and should
+ * only be compared for equality with desired version identifiers.
+ *
+ * <p>Within each {@code ClassLoader} instance all classes from the same
+ * java package have the same Package object. The static methods allow a package
+ * to be found by name or the set of all packages known to the current class
+ * loader to be found.
+ *
+ * @see ClassLoader#definePackage
+ */
+public class Package implements java.lang.reflect.AnnotatedElement {
+ /**
+ * Return the name of this package.
+ *
+ * @return The fully-qualified name of this package as defined in section 6.5.3 of
+ * <cite>The Java™ Language Specification</cite>,
+ * for example, {@code java.lang}
+ */
+ public String getName() {
+ return pkgName;
+ }
+
+
+ /**
+ * Return the title of the specification that this package implements.
+ * @return the specification title, null is returned if it is not known.
+ */
+ public String getSpecificationTitle() {
+ return specTitle;
+ }
+
+ /**
+ * Returns the version number of the specification
+ * that this package implements.
+ * This version string must be a sequence of nonnegative decimal
+ * integers separated by "."'s and may have leading zeros.
+ * When version strings are compared the most significant
+ * numbers are compared.
+ * @return the specification version, null is returned if it is not known.
+ */
+ public String getSpecificationVersion() {
+ return specVersion;
+ }
+
+ /**
+ * Return the name of the organization, vendor,
+ * or company that owns and maintains the specification
+ * of the classes that implement this package.
+ * @return the specification vendor, null is returned if it is not known.
+ */
+ public String getSpecificationVendor() {
+ return specVendor;
+ }
+
+ /**
+ * Return the title of this package.
+ * @return the title of the implementation, null is returned if it is not known.
+ */
+ public String getImplementationTitle() {
+ return implTitle;
+ }
+
+ /**
+ * Return the version of this implementation. It consists of any string
+ * assigned by the vendor of this implementation and does
+ * not have any particular syntax specified or expected by the Java
+ * runtime. It may be compared for equality with other
+ * package version strings used for this implementation
+ * by this vendor for this package.
+ * @return the version of the implementation, null is returned if it is not known.
+ */
+ public String getImplementationVersion() {
+ return implVersion;
+ }
+
+ /**
+ * Returns the name of the organization,
+ * vendor or company that provided this implementation.
+ * @return the vendor that implemented this package..
+ */
+ public String getImplementationVendor() {
+ return implVendor;
+ }
+
+ /**
+ * Returns true if this package is sealed.
+ *
+ * @return true if the package is sealed, false otherwise
+ */
+ public boolean isSealed() {
+ return sealBase != null;
+ }
+
+ /**
+ * Returns true if this package is sealed with respect to the specified
+ * code source url.
+ *
+ * @param url the code source url
+ * @return true if this package is sealed with respect to url
+ */
+ public boolean isSealed(URL url) {
+ return url.equals(sealBase);
+ }
+
+ /**
+ * Compare this package's specification version with a
+ * desired version. It returns true if
+ * this packages specification version number is greater than or equal
+ * to the desired version number. <p>
+ *
+ * Version numbers are compared by sequentially comparing corresponding
+ * components of the desired and specification strings.
+ * Each component is converted as a decimal integer and the values
+ * compared.
+ * If the specification value is greater than the desired
+ * value true is returned. If the value is less false is returned.
+ * If the values are equal the period is skipped and the next pair of
+ * components is compared.
+ *
+ * @param desired the version string of the desired version.
+ * @return true if this package's version number is greater
+ * than or equal to the desired version number
+ *
+ * @exception NumberFormatException if the desired or current version
+ * is not of the correct dotted form.
+ */
+ public boolean isCompatibleWith(String desired)
+ throws NumberFormatException
+ {
+ if (specVersion == null || specVersion.length() < 1) {
+ throw new NumberFormatException("Empty version string");
+ }
+
+ String [] sa = specVersion.split("\\.", -1);
+ int [] si = new int[sa.length];
+ for (int i = 0; i < sa.length; i++) {
+ si[i] = Integer.parseInt(sa[i]);
+ if (si[i] < 0)
+ throw NumberFormatException.forInputString("" + si[i]);
+ }
+
+ String [] da = desired.split("\\.", -1);
+ int [] di = new int[da.length];
+ for (int i = 0; i < da.length; i++) {
+ di[i] = Integer.parseInt(da[i]);
+ if (di[i] < 0)
+ throw NumberFormatException.forInputString("" + di[i]);
+ }
+
+ int len = Math.max(di.length, si.length);
+ for (int i = 0; i < len; i++) {
+ int d = (i < di.length ? di[i] : 0);
+ int s = (i < si.length ? si[i] : 0);
+ if (s < d)
+ return false;
+ if (s > d)
+ return true;
+ }
+ return true;
+ }
+
+ /**
+ * Find a package by name in the callers {@code ClassLoader} instance.
+ * The callers {@code ClassLoader} instance is used to find the package
+ * instance corresponding to the named class. If the callers
+ * {@code ClassLoader} instance is null then the set of packages loaded
+ * by the system {@code ClassLoader} instance is searched to find the
+ * named package. <p>
+ *
+ * Packages have attributes for versions and specifications only if the class
+ * loader created the package instance with the appropriate attributes. Typically,
+ * those attributes are defined in the manifests that accompany the classes.
+ *
+ * @param name a package name, for example, java.lang.
+ * @return the package of the requested name. It may be null if no package
+ * information is available from the archive or codebase.
+ */
+ @CallerSensitive
+ public static Package getPackage(String name) {
+ ClassLoader l = ClassLoader.getClassLoader(Reflection.getCallerClass());
+ if (l != null) {
+ return l.getPackage(name);
+ } else {
+ return getSystemPackage(name);
+ }
+ }
+
+ /**
+ * Get all the packages currently known for the caller's {@code ClassLoader}
+ * instance. Those packages correspond to classes loaded via or accessible by
+ * name to that {@code ClassLoader} instance. If the caller's
+ * {@code ClassLoader} instance is the bootstrap {@code ClassLoader}
+ * instance, which may be represented by {@code null} in some implementations,
+ * only packages corresponding to classes loaded by the bootstrap
+ * {@code ClassLoader} instance will be returned.
+ *
+ * @return a new array of packages known to the callers {@code ClassLoader}
+ * instance. An zero length array is returned if none are known.
+ */
+ @CallerSensitive
+ public static Package[] getPackages() {
+ ClassLoader l = ClassLoader.getClassLoader(Reflection.getCallerClass());
+ if (l != null) {
+ return l.getPackages();
+ } else {
+ return getSystemPackages();
+ }
+ }
+
+ /**
+ * Get the package for the specified class.
+ * The class's class loader is used to find the package instance
+ * corresponding to the specified class. If the class loader
+ * is the bootstrap class loader, which may be represented by
+ * {@code null} in some implementations, then the set of packages
+ * loaded by the bootstrap class loader is searched to find the package.
+ * <p>
+ * Packages have attributes for versions and specifications only
+ * if the class loader created the package
+ * instance with the appropriate attributes. Typically those
+ * attributes are defined in the manifests that accompany
+ * the classes.
+ *
+ * @param c the class to get the package of.
+ * @return the package of the class. It may be null if no package
+ * information is available from the archive or codebase. */
+ static Package getPackage(Class<?> c) {
+ String name = c.getName();
+ int i = name.lastIndexOf('.');
+ if (i != -1) {
+ name = name.substring(0, i);
+ ClassLoader cl = c.getClassLoader();
+ if (cl != null) {
+ return cl.getPackage(name);
+ } else {
+ return getSystemPackage(name);
+ }
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Return the hash code computed from the package name.
+ * @return the hash code computed from the package name.
+ */
+ public int hashCode(){
+ return pkgName.hashCode();
+ }
+
+ /**
+ * Returns the string representation of this Package.
+ * Its value is the string "package " and the package name.
+ * If the package title is defined it is appended.
+ * If the package version is defined it is appended.
+ * @return the string representation of the package.
+ */
+ public String toString() {
+ // BEGIN Android-added: Backwards compatibility fix for target API <= 24.
+ // Several apps try to parse the output of toString(). This is a really
+ // bad idea - especially when there's a Package.getName() function as well as a
+ // Class.getName() function that can be used instead.
+ // Starting from the API level 25 the proper output is generated.
+ final int targetSdkVersion = VMRuntime.getRuntime().getTargetSdkVersion();
+ if (targetSdkVersion > 0 && targetSdkVersion <= 24) {
+ return "package " + pkgName;
+ }
+ // END Android-added: Backwards compatibility fix for target API <= 24.
+
+ String spec = specTitle;
+ String ver = specVersion;
+ if (spec != null && spec.length() > 0)
+ spec = ", " + spec;
+ else
+ spec = "";
+ if (ver != null && ver.length() > 0)
+ ver = ", version " + ver;
+ else
+ ver = "";
+ return "package " + pkgName + spec + ver;
+ }
+
+ private Class<?> getPackageInfo() {
+ if (packageInfo == null) {
+ try {
+ packageInfo = Class.forName(pkgName + ".package-info", false, loader);
+ } catch (ClassNotFoundException ex) {
+ // store a proxy for the package info that has no annotations
+ class PackageInfoProxy {}
+ packageInfo = PackageInfoProxy.class;
+ }
+ }
+ return packageInfo;
+ }
+
+ /**
+ * @throws NullPointerException {@inheritDoc}
+ * @since 1.5
+ */
+ public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {
+ return getPackageInfo().getAnnotation(annotationClass);
+ }
+
+ /**
+ * {@inheritDoc}
+ * @throws NullPointerException {@inheritDoc}
+ * @since 1.5
+ */
+ @Override
+ public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
+ return AnnotatedElement.super.isAnnotationPresent(annotationClass);
+ }
+
+ /**
+ * @throws NullPointerException {@inheritDoc}
+ * @since 1.8
+ */
+ @Override
+ public <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationClass) {
+ return getPackageInfo().getAnnotationsByType(annotationClass);
+ }
+
+ /**
+ * @since 1.5
+ */
+ public Annotation[] getAnnotations() {
+ return getPackageInfo().getAnnotations();
+ }
+
+ /**
+ * @throws NullPointerException {@inheritDoc}
+ * @since 1.8
+ */
+ @Override
+ public <A extends Annotation> A getDeclaredAnnotation(Class<A> annotationClass) {
+ return getPackageInfo().getDeclaredAnnotation(annotationClass);
+ }
+
+ /**
+ * @throws NullPointerException {@inheritDoc}
+ * @since 1.8
+ */
+ @Override
+ public <A extends Annotation> A[] getDeclaredAnnotationsByType(Class<A> annotationClass) {
+ return getPackageInfo().getDeclaredAnnotationsByType(annotationClass);
+ }
+
+ /**
+ * @since 1.5
+ */
+ public Annotation[] getDeclaredAnnotations() {
+ return getPackageInfo().getDeclaredAnnotations();
+ }
+
+ /**
+ * Construct a package instance with the specified version
+ * information.
+ * @param name the name of the package
+ * @param spectitle the title of the specification
+ * @param specversion the version of the specification
+ * @param specvendor the organization that maintains the specification
+ * @param impltitle the title of the implementation
+ * @param implversion the version of the implementation
+ * @param implvendor the organization that maintains the implementation
+ */
+ Package(String name,
+ String spectitle, String specversion, String specvendor,
+ String impltitle, String implversion, String implvendor,
+ URL sealbase, ClassLoader loader)
+ {
+ pkgName = name;
+ implTitle = impltitle;
+ implVersion = implversion;
+ implVendor = implvendor;
+ specTitle = spectitle;
+ specVersion = specversion;
+ specVendor = specvendor;
+ sealBase = sealbase;
+ this.loader = loader;
+ }
+
+ /*
+ * Construct a package using the attributes from the specified manifest.
+ *
+ * @param name the package name
+ * @param man the optional manifest for the package
+ * @param url the optional code source url for the package
+ */
+ private Package(String name, Manifest man, URL url, ClassLoader loader) {
+ String path = name.replace('.', '/').concat("/");
+ String sealed = null;
+ String specTitle= null;
+ String specVersion= null;
+ String specVendor= null;
+ String implTitle= null;
+ String implVersion= null;
+ String implVendor= null;
+ URL sealBase= null;
+ Attributes attr = man.getAttributes(path);
+ if (attr != null) {
+ specTitle = attr.getValue(Name.SPECIFICATION_TITLE);
+ specVersion = attr.getValue(Name.SPECIFICATION_VERSION);
+ specVendor = attr.getValue(Name.SPECIFICATION_VENDOR);
+ implTitle = attr.getValue(Name.IMPLEMENTATION_TITLE);
+ implVersion = attr.getValue(Name.IMPLEMENTATION_VERSION);
+ implVendor = attr.getValue(Name.IMPLEMENTATION_VENDOR);
+ sealed = attr.getValue(Name.SEALED);
+ }
+ attr = man.getMainAttributes();
+ if (attr != null) {
+ if (specTitle == null) {
+ specTitle = attr.getValue(Name.SPECIFICATION_TITLE);
+ }
+ if (specVersion == null) {
+ specVersion = attr.getValue(Name.SPECIFICATION_VERSION);
+ }
+ if (specVendor == null) {
+ specVendor = attr.getValue(Name.SPECIFICATION_VENDOR);
+ }
+ if (implTitle == null) {
+ implTitle = attr.getValue(Name.IMPLEMENTATION_TITLE);
+ }
+ if (implVersion == null) {
+ implVersion = attr.getValue(Name.IMPLEMENTATION_VERSION);
+ }
+ if (implVendor == null) {
+ implVendor = attr.getValue(Name.IMPLEMENTATION_VENDOR);
+ }
+ if (sealed == null) {
+ sealed = attr.getValue(Name.SEALED);
+ }
+ }
+ if ("true".equalsIgnoreCase(sealed)) {
+ sealBase = url;
+ }
+ pkgName = name;
+ this.specTitle = specTitle;
+ this.specVersion = specVersion;
+ this.specVendor = specVendor;
+ this.implTitle = implTitle;
+ this.implVersion = implVersion;
+ this.implVendor = implVendor;
+ this.sealBase = sealBase;
+ this.loader = loader;
+ }
+
+ /*
+ * Returns the loaded system package for the specified name.
+ */
+ static Package getSystemPackage(String name) {
+ synchronized (pkgs) {
+ Package pkg = pkgs.get(name);
+ if (pkg == null) {
+ name = name.replace('.', '/').concat("/");
+ String fn = getSystemPackage0(name);
+ if (fn != null) {
+ pkg = defineSystemPackage(name, fn);
+ }
+ }
+ return pkg;
+ }
+ }
+
+ /*
+ * Return an array of loaded system packages.
+ */
+ static Package[] getSystemPackages() {
+ // First, update the system package map with new package names
+ String[] names = getSystemPackages0();
+ synchronized (pkgs) {
+ for (int i = 0; i < names.length; i++) {
+ defineSystemPackage(names[i], getSystemPackage0(names[i]));
+ }
+ return pkgs.values().toArray(new Package[pkgs.size()]);
+ }
+ }
+
+ private static Package defineSystemPackage(final String iname,
+ final String fn)
+ {
+ return AccessController.doPrivileged(new PrivilegedAction<Package>() {
+ public Package run() {
+ String name = iname;
+ // Get the cached code source url for the file name
+ URL url = urls.get(fn);
+ if (url == null) {
+ // URL not found, so create one
+ File file = new File(fn);
+ try {
+ url = ParseUtil.fileToEncodedURL(file);
+ } catch (MalformedURLException e) {
+ }
+ if (url != null) {
+ urls.put(fn, url);
+ // If loading a JAR file, then also cache the manifest
+ if (file.isFile()) {
+ mans.put(fn, loadManifest(fn));
+ }
+ }
+ }
+ // Convert to "."-separated package name
+ name = name.substring(0, name.length() - 1).replace('/', '.');
+ Package pkg;
+ Manifest man = mans.get(fn);
+ if (man != null) {
+ pkg = new Package(name, man, url, null);
+ } else {
+ pkg = new Package(name, null, null, null,
+ null, null, null, null, null);
+ }
+ pkgs.put(name, pkg);
+ return pkg;
+ }
+ });
+ }
+
+ /*
+ * Returns the Manifest for the specified JAR file name.
+ */
+ private static Manifest loadManifest(String fn) {
+ try (FileInputStream fis = new FileInputStream(fn);
+ JarInputStream jis = new JarInputStream(fis, false))
+ {
+ return jis.getManifest();
+ } catch (IOException e) {
+ return null;
+ }
+ }
+
+ // The map of loaded system packages
+ private static Map<String, Package> pkgs = new HashMap<>(31);
+
+ // Maps each directory or zip file name to its corresponding url
+ private static Map<String, URL> urls = new HashMap<>(10);
+
+ // Maps each code source url for a jar file to its manifest
+ private static Map<String, Manifest> mans = new HashMap<>(10);
+
+ private static native String getSystemPackage0(String name);
+ private static native String[] getSystemPackages0();
+
+ /*
+ * Private storage for the package name and attributes.
+ */
+ private final String pkgName;
+ private final String specTitle;
+ private final String specVersion;
+ private final String specVendor;
+ private final String implTitle;
+ private final String implVersion;
+ private final String implVendor;
+ private final URL sealBase;
+ private transient final ClassLoader loader;
+ private transient Class<?> packageInfo;
+}
diff --git a/java/lang/Process.java b/java/lang/Process.java
new file mode 100644
index 0000000..4e94538
--- /dev/null
+++ b/java/lang/Process.java
@@ -0,0 +1,265 @@
+/*
+ * Copyright (c) 1995, 2012, 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;
+
+import java.io.*;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * The {@link ProcessBuilder#start()} and
+ * {@link Runtime#exec(String[],String[],File) Runtime.exec}
+ * methods create a native process and return an instance of a
+ * subclass of {@code Process} that can be used to control the process
+ * and obtain information about it. The class {@code Process}
+ * provides methods for performing input from the process, performing
+ * output to the process, waiting for the process to complete,
+ * checking the exit status of the process, and destroying (killing)
+ * the process.
+ *
+ * <p>The methods that create processes may not work well for special
+ * processes on certain native platforms, such as native windowing
+ * processes, daemon processes, Win16/DOS processes on Microsoft
+ * Windows, or shell scripts.
+ *
+ * <p>By default, the created subprocess does not have its own terminal
+ * or console. All its standard I/O (i.e. stdin, stdout, stderr)
+ * operations will be redirected to the parent process, where they can
+ * be accessed via the streams obtained using the methods
+ * {@link #getOutputStream()},
+ * {@link #getInputStream()}, and
+ * {@link #getErrorStream()}.
+ * The parent process uses these streams to feed input to and get output
+ * from the subprocess. Because some native platforms only provide
+ * limited buffer size for standard input and output streams, failure
+ * to promptly write the input stream or read the output stream of
+ * the subprocess may cause the subprocess to block, or even deadlock.
+ *
+ * <p>Where desired, <a href="ProcessBuilder.html#redirect-input">
+ * subprocess I/O can also be redirected</a>
+ * using methods of the {@link ProcessBuilder} class.
+ *
+ * <p>The subprocess is not killed when there are no more references to
+ * the {@code Process} object, but rather the subprocess
+ * continues executing asynchronously.
+ *
+ * <p>There is no requirement that a process represented by a {@code
+ * Process} object execute asynchronously or concurrently with respect
+ * to the Java process that owns the {@code Process} object.
+ *
+ * <p>As of 1.5, {@link ProcessBuilder#start()} is the preferred way
+ * to create a {@code Process}.
+ *
+ * @since JDK1.0
+ */
+public abstract class Process {
+ /**
+ * Returns the output stream connected to the normal input of the
+ * subprocess. Output to the stream is piped into the standard
+ * input of the process represented by this {@code Process} object.
+ *
+ * <p>If the standard input of the subprocess has been redirected using
+ * {@link ProcessBuilder#redirectInput(Redirect)
+ * ProcessBuilder.redirectInput}
+ * then this method will return a
+ * <a href="ProcessBuilder.html#redirect-input">null output stream</a>.
+ *
+ * <p>Implementation note: It is a good idea for the returned
+ * output stream to be buffered.
+ *
+ * @return the output stream connected to the normal input of the
+ * subprocess
+ */
+ public abstract OutputStream getOutputStream();
+
+ /**
+ * Returns the input stream connected to the normal output of the
+ * subprocess. The stream obtains data piped from the standard
+ * output of the process represented by this {@code Process} object.
+ *
+ * <p>If the standard output of the subprocess has been redirected using
+ * {@link ProcessBuilder#redirectOutput(Redirect)
+ * ProcessBuilder.redirectOutput}
+ * then this method will return a
+ * <a href="ProcessBuilder.html#redirect-output">null input stream</a>.
+ *
+ * <p>Otherwise, if the standard error of the subprocess has been
+ * redirected using
+ * {@link ProcessBuilder#redirectErrorStream(boolean)
+ * ProcessBuilder.redirectErrorStream}
+ * then the input stream returned by this method will receive the
+ * merged standard output and the standard error of the subprocess.
+ *
+ * <p>Implementation note: It is a good idea for the returned
+ * input stream to be buffered.
+ *
+ * @return the input stream connected to the normal output of the
+ * subprocess
+ */
+ public abstract InputStream getInputStream();
+
+ /**
+ * Returns the input stream connected to the error output of the
+ * subprocess. The stream obtains data piped from the error output
+ * of the process represented by this {@code Process} object.
+ *
+ * <p>If the standard error of the subprocess has been redirected using
+ * {@link ProcessBuilder#redirectError(Redirect)
+ * ProcessBuilder.redirectError} or
+ * {@link ProcessBuilder#redirectErrorStream(boolean)
+ * ProcessBuilder.redirectErrorStream}
+ * then this method will return a
+ * <a href="ProcessBuilder.html#redirect-output">null input stream</a>.
+ *
+ * <p>Implementation note: It is a good idea for the returned
+ * input stream to be buffered.
+ *
+ * @return the input stream connected to the error output of
+ * the subprocess
+ */
+ public abstract InputStream getErrorStream();
+
+ /**
+ * Causes the current thread to wait, if necessary, until the
+ * process represented by this {@code Process} object has
+ * terminated. This method returns immediately if the subprocess
+ * has already terminated. If the subprocess has not yet
+ * terminated, the calling thread will be blocked until the
+ * subprocess exits.
+ *
+ * @return the exit value of the subprocess represented by this
+ * {@code Process} object. By convention, the value
+ * {@code 0} indicates normal termination.
+ * @throws InterruptedException if the current thread is
+ * {@linkplain Thread#interrupt() interrupted} by another
+ * thread while it is waiting, then the wait is ended and
+ * an {@link InterruptedException} is thrown.
+ */
+ public abstract int waitFor() throws InterruptedException;
+
+ /**
+ * Causes the current thread to wait, if necessary, until the
+ * subprocess represented by this {@code Process} object has
+ * terminated, or the specified waiting time elapses.
+ *
+ * <p>If the subprocess has already terminated then this method returns
+ * immediately with the value {@code true}. If the process has not
+ * terminated and the timeout value is less than, or equal to, zero, then
+ * this method returns immediately with the value {@code false}.
+ *
+ * <p>The default implementation of this methods polls the {@code exitValue}
+ * to check if the process has terminated. Concrete implementations of this
+ * class are strongly encouraged to override this method with a more
+ * efficient implementation.
+ *
+ * @param timeout the maximum time to wait
+ * @param unit the time unit of the {@code timeout} argument
+ * @return {@code true} if the subprocess has exited and {@code false} if
+ * the waiting time elapsed before the subprocess has exited.
+ * @throws InterruptedException if the current thread is interrupted
+ * while waiting.
+ * @throws NullPointerException if unit is null
+ * @since 1.8
+ */
+ public boolean waitFor(long timeout, TimeUnit unit)
+ throws InterruptedException
+ {
+ long startTime = System.nanoTime();
+ long rem = unit.toNanos(timeout);
+
+ do {
+ try {
+ exitValue();
+ return true;
+ } catch(IllegalThreadStateException ex) {
+ if (rem > 0)
+ Thread.sleep(
+ Math.min(TimeUnit.NANOSECONDS.toMillis(rem) + 1, 100));
+ }
+ rem = unit.toNanos(timeout) - (System.nanoTime() - startTime);
+ } while (rem > 0);
+ return false;
+ }
+
+ /**
+ * Returns the exit value for the subprocess.
+ *
+ * @return the exit value of the subprocess represented by this
+ * {@code Process} object. By convention, the value
+ * {@code 0} indicates normal termination.
+ * @throws IllegalThreadStateException if the subprocess represented
+ * by this {@code Process} object has not yet terminated
+ */
+ public abstract int exitValue();
+
+ /**
+ * Kills the subprocess. Whether the subprocess represented by this
+ * {@code Process} object is forcibly terminated or not is
+ * implementation dependent.
+ */
+ public abstract void destroy();
+
+ /**
+ * Kills the subprocess. The subprocess represented by this
+ * {@code Process} object is forcibly terminated.
+ *
+ * <p>The default implementation of this method invokes {@link #destroy}
+ * and so may not forcibly terminate the process. Concrete implementations
+ * of this class are strongly encouraged to override this method with a
+ * compliant implementation. Invoking this method on {@code Process}
+ * objects returned by {@link ProcessBuilder#start} and
+ * {@link Runtime#exec} will forcibly terminate the process.
+ *
+ * <p>Note: The subprocess may not terminate immediately.
+ * i.e. {@code isAlive()} may return true for a brief period
+ * after {@code destroyForcibly()} is called. This method
+ * may be chained to {@code waitFor()} if needed.
+ *
+ * @return the {@code Process} object representing the
+ * subprocess to be forcibly destroyed.
+ * @since 1.8
+ */
+ public Process destroyForcibly() {
+ destroy();
+ return this;
+ }
+
+ /**
+ * Tests whether the subprocess represented by this {@code Process} is
+ * alive.
+ *
+ * @return {@code true} if the subprocess represented by this
+ * {@code Process} object has not yet terminated.
+ * @since 1.8
+ */
+ public boolean isAlive() {
+ try {
+ exitValue();
+ return false;
+ } catch(IllegalThreadStateException e) {
+ return true;
+ }
+ }
+}
diff --git a/java/lang/ProcessBuilder.java b/java/lang/ProcessBuilder.java
new file mode 100644
index 0000000..fc58abc
--- /dev/null
+++ b/java/lang/ProcessBuilder.java
@@ -0,0 +1,1055 @@
+/*
+ * Copyright (c) 2003, 2013, 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;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * This class is used to create operating system processes.
+ *
+ * <p>Each {@code ProcessBuilder} instance manages a collection
+ * of process attributes. The {@link #start()} method creates a new
+ * {@link Process} instance with those attributes. The {@link
+ * #start()} method can be invoked repeatedly from the same instance
+ * to create new subprocesses with identical or related attributes.
+ *
+ * <p>Each process builder manages these process attributes:
+ *
+ * <ul>
+ *
+ * <li>a <i>command</i>, a list of strings which signifies the
+ * external program file to be invoked and its arguments, if any.
+ * Which string lists represent a valid operating system command is
+ * system-dependent. For example, it is common for each conceptual
+ * argument to be an element in this list, but there are operating
+ * systems where programs are expected to tokenize command line
+ * strings themselves - on such a system a Java implementation might
+ * require commands to contain exactly two elements.
+ *
+ * <li>an <i>environment</i>, which is a system-dependent mapping from
+ * <i>variables</i> to <i>values</i>. The initial value is a copy of
+ * the environment of the current process (see {@link System#getenv()}).
+ *
+ * <li>a <i>working directory</i>. The default value is the current
+ * working directory of the current process, usually the directory
+ * named by the system property {@code user.dir}.
+ *
+ * <li><a name="redirect-input">a source of <i>standard input</i></a>.
+ * By default, the subprocess reads input from a pipe. Java code
+ * can access this pipe via the output stream returned by
+ * {@link Process#getOutputStream()}. However, standard input may
+ * be redirected to another source using
+ * {@link #redirectInput(Redirect) redirectInput}.
+ * In this case, {@link Process#getOutputStream()} will return a
+ * <i>null output stream</i>, for which:
+ *
+ * <ul>
+ * <li>the {@link OutputStream#write(int) write} methods always
+ * throw {@code IOException}
+ * <li>the {@link OutputStream#close() close} method does nothing
+ * </ul>
+ *
+ * <li><a name="redirect-output">a destination for <i>standard output</i>
+ * and <i>standard error</i></a>. By default, the subprocess writes standard
+ * output and standard error to pipes. Java code can access these pipes
+ * via the input streams returned by {@link Process#getInputStream()} and
+ * {@link Process#getErrorStream()}. However, standard output and
+ * standard error may be redirected to other destinations using
+ * {@link #redirectOutput(Redirect) redirectOutput} and
+ * {@link #redirectError(Redirect) redirectError}.
+ * In this case, {@link Process#getInputStream()} and/or
+ * {@link Process#getErrorStream()} will return a <i>null input
+ * stream</i>, for which:
+ *
+ * <ul>
+ * <li>the {@link InputStream#read() read} methods always return
+ * {@code -1}
+ * <li>the {@link InputStream#available() available} method always returns
+ * {@code 0}
+ * <li>the {@link InputStream#close() close} method does nothing
+ * </ul>
+ *
+ * <li>a <i>redirectErrorStream</i> property. Initially, this property
+ * is {@code false}, meaning that the standard output and error
+ * output of a subprocess are sent to two separate streams, which can
+ * be accessed using the {@link Process#getInputStream()} and {@link
+ * Process#getErrorStream()} methods.
+ *
+ * <p>If the value is set to {@code true}, then:
+ *
+ * <ul>
+ * <li>standard error is merged with the standard output and always sent
+ * to the same destination (this makes it easier to correlate error
+ * messages with the corresponding output)
+ * <li>the common destination of standard error and standard output can be
+ * redirected using
+ * {@link #redirectOutput(Redirect) redirectOutput}
+ * <li>any redirection set by the
+ * {@link #redirectError(Redirect) redirectError}
+ * method is ignored when creating a subprocess
+ * <li>the stream returned from {@link Process#getErrorStream()} will
+ * always be a <a href="#redirect-output">null input stream</a>
+ * </ul>
+ *
+ * </ul>
+ *
+ * <p>Modifying a process builder's attributes will affect processes
+ * subsequently started by that object's {@link #start()} method, but
+ * will never affect previously started processes or the Java process
+ * itself.
+ *
+ * <p>Most error checking is performed by the {@link #start()} method.
+ * It is possible to modify the state of an object so that {@link
+ * #start()} will fail. For example, setting the command attribute to
+ * an empty list will not throw an exception unless {@link #start()}
+ * is invoked.
+ *
+ * <p><strong>Note that this class is not synchronized.</strong>
+ * If multiple threads access a {@code ProcessBuilder} instance
+ * concurrently, and at least one of the threads modifies one of the
+ * attributes structurally, it <i>must</i> be synchronized externally.
+ *
+ * <p>Starting a new process which uses the default working directory
+ * and environment is easy:
+ *
+ * <pre> {@code
+ * Process p = new ProcessBuilder("myCommand", "myArg").start();
+ * }</pre>
+ *
+ * <p>Here is an example that starts a process with a modified working
+ * directory and environment, and redirects standard output and error
+ * to be appended to a log file:
+ *
+ * <pre> {@code
+ * ProcessBuilder pb =
+ * new ProcessBuilder("myCommand", "myArg1", "myArg2");
+ * Map<String, String> env = pb.environment();
+ * env.put("VAR1", "myValue");
+ * env.remove("OTHERVAR");
+ * env.put("VAR2", env.get("VAR1") + "suffix");
+ * pb.directory(new File("myDir"));
+ * File log = new File("log");
+ * pb.redirectErrorStream(true);
+ * pb.redirectOutput(Redirect.appendTo(log));
+ * Process p = pb.start();
+ * assert pb.redirectInput() == Redirect.PIPE;
+ * assert pb.redirectOutput().file() == log;
+ * assert p.getInputStream().read() == -1;
+ * }</pre>
+ *
+ * <p>To start a process with an explicit set of environment
+ * variables, first call {@link java.util.Map#clear() Map.clear()}
+ * before adding environment variables.
+ *
+ * @author Martin Buchholz
+ * @since 1.5
+ */
+
+public final class ProcessBuilder
+{
+ private List<String> command;
+ private File directory;
+ private Map<String,String> environment;
+ private boolean redirectErrorStream;
+ private Redirect[] redirects;
+
+ /**
+ * Constructs a process builder with the specified operating
+ * system program and arguments. This constructor does <i>not</i>
+ * make a copy of the {@code command} list. Subsequent
+ * updates to the list will be reflected in the state of the
+ * process builder. It is not checked whether
+ * {@code command} corresponds to a valid operating system
+ * command.
+ *
+ * @param command the list containing the program and its arguments
+ * @throws NullPointerException if the argument is null
+ */
+ public ProcessBuilder(List<String> command) {
+ if (command == null)
+ throw new NullPointerException();
+ this.command = command;
+ }
+
+ /**
+ * Constructs a process builder with the specified operating
+ * system program and arguments. This is a convenience
+ * constructor that sets the process builder's command to a string
+ * list containing the same strings as the {@code command}
+ * array, in the same order. It is not checked whether
+ * {@code command} corresponds to a valid operating system
+ * command.
+ *
+ * @param command a string array containing the program and its arguments
+ */
+ public ProcessBuilder(String... command) {
+ this.command = new ArrayList<>(command.length);
+ for (String arg : command)
+ this.command.add(arg);
+ }
+
+ /**
+ * Sets this process builder's operating system program and
+ * arguments. This method does <i>not</i> make a copy of the
+ * {@code command} list. Subsequent updates to the list will
+ * be reflected in the state of the process builder. It is not
+ * checked whether {@code command} corresponds to a valid
+ * operating system command.
+ *
+ * @param command the list containing the program and its arguments
+ * @return this process builder
+ *
+ * @throws NullPointerException if the argument is null
+ */
+ public ProcessBuilder command(List<String> command) {
+ if (command == null)
+ throw new NullPointerException();
+ this.command = command;
+ return this;
+ }
+
+ /**
+ * Sets this process builder's operating system program and
+ * arguments. This is a convenience method that sets the command
+ * to a string list containing the same strings as the
+ * {@code command} array, in the same order. It is not
+ * checked whether {@code command} corresponds to a valid
+ * operating system command.
+ *
+ * @param command a string array containing the program and its arguments
+ * @return this process builder
+ */
+ public ProcessBuilder command(String... command) {
+ this.command = new ArrayList<>(command.length);
+ for (String arg : command)
+ this.command.add(arg);
+ return this;
+ }
+
+ /**
+ * Returns this process builder's operating system program and
+ * arguments. The returned list is <i>not</i> a copy. Subsequent
+ * updates to the list will be reflected in the state of this
+ * process builder.
+ *
+ * @return this process builder's program and its arguments
+ */
+ public List<String> command() {
+ return command;
+ }
+
+ /**
+ * Returns a string map view of this process builder's environment.
+ *
+ * Whenever a process builder is created, the environment is
+ * initialized to a copy of the current process environment (see
+ * {@link System#getenv()}). Subprocesses subsequently started by
+ * this object's {@link #start()} method will use this map as
+ * their environment.
+ *
+ * <p>The returned object may be modified using ordinary {@link
+ * java.util.Map Map} operations. These modifications will be
+ * visible to subprocesses started via the {@link #start()}
+ * method. Two {@code ProcessBuilder} instances always
+ * contain independent process environments, so changes to the
+ * returned map will never be reflected in any other
+ * {@code ProcessBuilder} instance or the values returned by
+ * {@link System#getenv System.getenv}.
+ *
+ * <p>If the system does not support environment variables, an
+ * empty map is returned.
+ *
+ * <p>The returned map does not permit null keys or values.
+ * Attempting to insert or query the presence of a null key or
+ * value will throw a {@link NullPointerException}.
+ * Attempting to query the presence of a key or value which is not
+ * of type {@link String} will throw a {@link ClassCastException}.
+ *
+ * <p>The behavior of the returned map is system-dependent. A
+ * system may not allow modifications to environment variables or
+ * may forbid certain variable names or values. For this reason,
+ * attempts to modify the map may fail with
+ * {@link UnsupportedOperationException} or
+ * {@link IllegalArgumentException}
+ * if the modification is not permitted by the operating system.
+ *
+ * <p>Since the external format of environment variable names and
+ * values is system-dependent, there may not be a one-to-one
+ * mapping between them and Java's Unicode strings. Nevertheless,
+ * the map is implemented in such a way that environment variables
+ * which are not modified by Java code will have an unmodified
+ * native representation in the subprocess.
+ *
+ * <p>The returned map and its collection views may not obey the
+ * general contract of the {@link Object#equals} and
+ * {@link Object#hashCode} methods.
+ *
+ * <p>The returned map is typically case-sensitive on all platforms.
+ *
+ * <p>If a security manager exists, its
+ * {@link SecurityManager#checkPermission checkPermission} method
+ * is called with a
+ * {@link RuntimePermission}{@code ("getenv.*")} permission.
+ * This may result in a {@link SecurityException} being thrown.
+ *
+ * <p>When passing information to a Java subprocess,
+ * <a href=System.html#EnvironmentVSSystemProperties>system properties</a>
+ * are generally preferred over environment variables.
+ *
+ * @return this process builder's environment
+ *
+ * @throws SecurityException
+ * if a security manager exists and its
+ * {@link SecurityManager#checkPermission checkPermission}
+ * method doesn't allow access to the process environment
+ *
+ * @see Runtime#exec(String[],String[],java.io.File)
+ * @see System#getenv()
+ */
+ public Map<String,String> environment() {
+ SecurityManager security = System.getSecurityManager();
+ if (security != null)
+ security.checkPermission(new RuntimePermission("getenv.*"));
+
+ if (environment == null)
+ environment = ProcessEnvironment.environment();
+
+ assert environment != null;
+
+ return environment;
+ }
+
+ // Only for use by Runtime.exec(...envp...)
+ ProcessBuilder environment(String[] envp) {
+ assert environment == null;
+ if (envp != null) {
+ environment = ProcessEnvironment.emptyEnvironment(envp.length);
+ assert environment != null;
+
+ for (String envstring : envp) {
+ // Before 1.5, we blindly passed invalid envstrings
+ // to the child process.
+ // We would like to throw an exception, but do not,
+ // for compatibility with old broken code.
+
+ // Silently discard any trailing junk.
+ if (envstring.indexOf((int) '\u0000') != -1)
+ envstring = envstring.replaceFirst("\u0000.*", "");
+
+ int eqlsign =
+ envstring.indexOf('=', ProcessEnvironment.MIN_NAME_LENGTH);
+ // Silently ignore envstrings lacking the required `='.
+ if (eqlsign != -1)
+ environment.put(envstring.substring(0,eqlsign),
+ envstring.substring(eqlsign+1));
+ }
+ }
+ return this;
+ }
+
+ /**
+ * Returns this process builder's working directory.
+ *
+ * Subprocesses subsequently started by this object's {@link
+ * #start()} method will use this as their working directory.
+ * The returned value may be {@code null} -- this means to use
+ * the working directory of the current Java process, usually the
+ * directory named by the system property {@code user.dir},
+ * as the working directory of the child process.
+ *
+ * @return this process builder's working directory
+ */
+ public File directory() {
+ return directory;
+ }
+
+ /**
+ * Sets this process builder's working directory.
+ *
+ * Subprocesses subsequently started by this object's {@link
+ * #start()} method will use this as their working directory.
+ * The argument may be {@code null} -- this means to use the
+ * working directory of the current Java process, usually the
+ * directory named by the system property {@code user.dir},
+ * as the working directory of the child process.
+ *
+ * @param directory the new working directory
+ * @return this process builder
+ */
+ public ProcessBuilder directory(File directory) {
+ this.directory = directory;
+ return this;
+ }
+
+ // ---------------- I/O Redirection ----------------
+
+ /**
+ * Implements a <a href="#redirect-output">null input stream</a>.
+ */
+ static class NullInputStream extends InputStream {
+ static final NullInputStream INSTANCE = new NullInputStream();
+ private NullInputStream() {}
+ public int read() { return -1; }
+ public int available() { return 0; }
+ }
+
+ /**
+ * Implements a <a href="#redirect-input">null output stream</a>.
+ */
+ static class NullOutputStream extends OutputStream {
+ static final NullOutputStream INSTANCE = new NullOutputStream();
+ private NullOutputStream() {}
+ public void write(int b) throws IOException {
+ throw new IOException("Stream closed");
+ }
+ }
+
+ /**
+ * Represents a source of subprocess input or a destination of
+ * subprocess output.
+ *
+ * Each {@code Redirect} instance is one of the following:
+ *
+ * <ul>
+ * <li>the special value {@link #PIPE Redirect.PIPE}
+ * <li>the special value {@link #INHERIT Redirect.INHERIT}
+ * <li>a redirection to read from a file, created by an invocation of
+ * {@link Redirect#from Redirect.from(File)}
+ * <li>a redirection to write to a file, created by an invocation of
+ * {@link Redirect#to Redirect.to(File)}
+ * <li>a redirection to append to a file, created by an invocation of
+ * {@link Redirect#appendTo Redirect.appendTo(File)}
+ * </ul>
+ *
+ * <p>Each of the above categories has an associated unique
+ * {@link Type Type}.
+ *
+ * @since 1.7
+ */
+ public static abstract class Redirect {
+ /**
+ * The type of a {@link Redirect}.
+ */
+ public enum Type {
+ /**
+ * The type of {@link Redirect#PIPE Redirect.PIPE}.
+ */
+ PIPE,
+
+ /**
+ * The type of {@link Redirect#INHERIT Redirect.INHERIT}.
+ */
+ INHERIT,
+
+ /**
+ * The type of redirects returned from
+ * {@link Redirect#from Redirect.from(File)}.
+ */
+ READ,
+
+ /**
+ * The type of redirects returned from
+ * {@link Redirect#to Redirect.to(File)}.
+ */
+ WRITE,
+
+ /**
+ * The type of redirects returned from
+ * {@link Redirect#appendTo Redirect.appendTo(File)}.
+ */
+ APPEND
+ };
+
+ /**
+ * Returns the type of this {@code Redirect}.
+ * @return the type of this {@code Redirect}
+ */
+ public abstract Type type();
+
+ /**
+ * Indicates that subprocess I/O will be connected to the
+ * current Java process over a pipe.
+ *
+ * This is the default handling of subprocess standard I/O.
+ *
+ * <p>It will always be true that
+ * <pre> {@code
+ * Redirect.PIPE.file() == null &&
+ * Redirect.PIPE.type() == Redirect.Type.PIPE
+ * }</pre>
+ */
+ public static final Redirect PIPE = new Redirect() {
+ public Type type() { return Type.PIPE; }
+ public String toString() { return type().toString(); }};
+
+ /**
+ * Indicates that subprocess I/O source or destination will be the
+ * same as those of the current process. This is the normal
+ * behavior of most operating system command interpreters (shells).
+ *
+ * <p>It will always be true that
+ * <pre> {@code
+ * Redirect.INHERIT.file() == null &&
+ * Redirect.INHERIT.type() == Redirect.Type.INHERIT
+ * }</pre>
+ */
+ public static final Redirect INHERIT = new Redirect() {
+ public Type type() { return Type.INHERIT; }
+ public String toString() { return type().toString(); }};
+
+ /**
+ * Returns the {@link File} source or destination associated
+ * with this redirect, or {@code null} if there is no such file.
+ *
+ * @return the file associated with this redirect,
+ * or {@code null} if there is no such file
+ */
+ public File file() { return null; }
+
+ /**
+ * When redirected to a destination file, indicates if the output
+ * is to be written to the end of the file.
+ */
+ boolean append() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Returns a redirect to read from the specified file.
+ *
+ * <p>It will always be true that
+ * <pre> {@code
+ * Redirect.from(file).file() == file &&
+ * Redirect.from(file).type() == Redirect.Type.READ
+ * }</pre>
+ *
+ * @param file The {@code File} for the {@code Redirect}.
+ * @throws NullPointerException if the specified file is null
+ * @return a redirect to read from the specified file
+ */
+ public static Redirect from(final File file) {
+ if (file == null)
+ throw new NullPointerException();
+ return new Redirect() {
+ public Type type() { return Type.READ; }
+ public File file() { return file; }
+ public String toString() {
+ return "redirect to read from file \"" + file + "\"";
+ }
+ };
+ }
+
+ /**
+ * Returns a redirect to write to the specified file.
+ * If the specified file exists when the subprocess is started,
+ * its previous contents will be discarded.
+ *
+ * <p>It will always be true that
+ * <pre> {@code
+ * Redirect.to(file).file() == file &&
+ * Redirect.to(file).type() == Redirect.Type.WRITE
+ * }</pre>
+ *
+ * @param file The {@code File} for the {@code Redirect}.
+ * @throws NullPointerException if the specified file is null
+ * @return a redirect to write to the specified file
+ */
+ public static Redirect to(final File file) {
+ if (file == null)
+ throw new NullPointerException();
+ return new Redirect() {
+ public Type type() { return Type.WRITE; }
+ public File file() { return file; }
+ public String toString() {
+ return "redirect to write to file \"" + file + "\"";
+ }
+ boolean append() { return false; }
+ };
+ }
+
+ /**
+ * Returns a redirect to append to the specified file.
+ * Each write operation first advances the position to the
+ * end of the file and then writes the requested data.
+ * Whether the advancement of the position and the writing
+ * of the data are done in a single atomic operation is
+ * system-dependent and therefore unspecified.
+ *
+ * <p>It will always be true that
+ * <pre> {@code
+ * Redirect.appendTo(file).file() == file &&
+ * Redirect.appendTo(file).type() == Redirect.Type.APPEND
+ * }</pre>
+ *
+ * @param file The {@code File} for the {@code Redirect}.
+ * @throws NullPointerException if the specified file is null
+ * @return a redirect to append to the specified file
+ */
+ public static Redirect appendTo(final File file) {
+ if (file == null)
+ throw new NullPointerException();
+ return new Redirect() {
+ public Type type() { return Type.APPEND; }
+ public File file() { return file; }
+ public String toString() {
+ return "redirect to append to file \"" + file + "\"";
+ }
+ boolean append() { return true; }
+ };
+ }
+
+ /**
+ * Compares the specified object with this {@code Redirect} for
+ * equality. Returns {@code true} if and only if the two
+ * objects are identical or both objects are {@code Redirect}
+ * instances of the same type associated with non-null equal
+ * {@code File} instances.
+ */
+ public boolean equals(Object obj) {
+ if (obj == this)
+ return true;
+ if (! (obj instanceof Redirect))
+ return false;
+ Redirect r = (Redirect) obj;
+ if (r.type() != this.type())
+ return false;
+ assert this.file() != null;
+ return this.file().equals(r.file());
+ }
+
+ /**
+ * Returns a hash code value for this {@code Redirect}.
+ * @return a hash code value for this {@code Redirect}
+ */
+ public int hashCode() {
+ File file = file();
+ if (file == null)
+ return super.hashCode();
+ else
+ return file.hashCode();
+ }
+
+ /**
+ * No public constructors. Clients must use predefined
+ * static {@code Redirect} instances or factory methods.
+ */
+ private Redirect() {}
+ }
+
+ private Redirect[] redirects() {
+ if (redirects == null)
+ redirects = new Redirect[] {
+ Redirect.PIPE, Redirect.PIPE, Redirect.PIPE
+ };
+ return redirects;
+ }
+
+ /**
+ * Sets this process builder's standard input source.
+ *
+ * Subprocesses subsequently started by this object's {@link #start()}
+ * method obtain their standard input from this source.
+ *
+ * <p>If the source is {@link Redirect#PIPE Redirect.PIPE}
+ * (the initial value), then the standard input of a
+ * subprocess can be written to using the output stream
+ * returned by {@link Process#getOutputStream()}.
+ * If the source is set to any other value, then
+ * {@link Process#getOutputStream()} will return a
+ * <a href="#redirect-input">null output stream</a>.
+ *
+ * @param source the new standard input source
+ * @return this process builder
+ * @throws IllegalArgumentException
+ * if the redirect does not correspond to a valid source
+ * of data, that is, has type
+ * {@link Redirect.Type#WRITE WRITE} or
+ * {@link Redirect.Type#APPEND APPEND}
+ * @since 1.7
+ */
+ public ProcessBuilder redirectInput(Redirect source) {
+ if (source.type() == Redirect.Type.WRITE ||
+ source.type() == Redirect.Type.APPEND)
+ throw new IllegalArgumentException(
+ "Redirect invalid for reading: " + source);
+ redirects()[0] = source;
+ return this;
+ }
+
+ /**
+ * Sets this process builder's standard output destination.
+ *
+ * Subprocesses subsequently started by this object's {@link #start()}
+ * method send their standard output to this destination.
+ *
+ * <p>If the destination is {@link Redirect#PIPE Redirect.PIPE}
+ * (the initial value), then the standard output of a subprocess
+ * can be read using the input stream returned by {@link
+ * Process#getInputStream()}.
+ * If the destination is set to any other value, then
+ * {@link Process#getInputStream()} will return a
+ * <a href="#redirect-output">null input stream</a>.
+ *
+ * @param destination the new standard output destination
+ * @return this process builder
+ * @throws IllegalArgumentException
+ * if the redirect does not correspond to a valid
+ * destination of data, that is, has type
+ * {@link Redirect.Type#READ READ}
+ * @since 1.7
+ */
+ public ProcessBuilder redirectOutput(Redirect destination) {
+ if (destination.type() == Redirect.Type.READ)
+ throw new IllegalArgumentException(
+ "Redirect invalid for writing: " + destination);
+ redirects()[1] = destination;
+ return this;
+ }
+
+ /**
+ * Sets this process builder's standard error destination.
+ *
+ * Subprocesses subsequently started by this object's {@link #start()}
+ * method send their standard error to this destination.
+ *
+ * <p>If the destination is {@link Redirect#PIPE Redirect.PIPE}
+ * (the initial value), then the error output of a subprocess
+ * can be read using the input stream returned by {@link
+ * Process#getErrorStream()}.
+ * If the destination is set to any other value, then
+ * {@link Process#getErrorStream()} will return a
+ * <a href="#redirect-output">null input stream</a>.
+ *
+ * <p>If the {@link #redirectErrorStream redirectErrorStream}
+ * attribute has been set {@code true}, then the redirection set
+ * by this method has no effect.
+ *
+ * @param destination the new standard error destination
+ * @return this process builder
+ * @throws IllegalArgumentException
+ * if the redirect does not correspond to a valid
+ * destination of data, that is, has type
+ * {@link Redirect.Type#READ READ}
+ * @since 1.7
+ */
+ public ProcessBuilder redirectError(Redirect destination) {
+ if (destination.type() == Redirect.Type.READ)
+ throw new IllegalArgumentException(
+ "Redirect invalid for writing: " + destination);
+ redirects()[2] = destination;
+ return this;
+ }
+
+ /**
+ * Sets this process builder's standard input source to a file.
+ *
+ * <p>This is a convenience method. An invocation of the form
+ * {@code redirectInput(file)}
+ * behaves in exactly the same way as the invocation
+ * {@link #redirectInput(Redirect) redirectInput}
+ * {@code (Redirect.from(file))}.
+ *
+ * @param file the new standard input source
+ * @return this process builder
+ * @since 1.7
+ */
+ public ProcessBuilder redirectInput(File file) {
+ return redirectInput(Redirect.from(file));
+ }
+
+ /**
+ * Sets this process builder's standard output destination to a file.
+ *
+ * <p>This is a convenience method. An invocation of the form
+ * {@code redirectOutput(file)}
+ * behaves in exactly the same way as the invocation
+ * {@link #redirectOutput(Redirect) redirectOutput}
+ * {@code (Redirect.to(file))}.
+ *
+ * @param file the new standard output destination
+ * @return this process builder
+ * @since 1.7
+ */
+ public ProcessBuilder redirectOutput(File file) {
+ return redirectOutput(Redirect.to(file));
+ }
+
+ /**
+ * Sets this process builder's standard error destination to a file.
+ *
+ * <p>This is a convenience method. An invocation of the form
+ * {@code redirectError(file)}
+ * behaves in exactly the same way as the invocation
+ * {@link #redirectError(Redirect) redirectError}
+ * {@code (Redirect.to(file))}.
+ *
+ * @param file the new standard error destination
+ * @return this process builder
+ * @since 1.7
+ */
+ public ProcessBuilder redirectError(File file) {
+ return redirectError(Redirect.to(file));
+ }
+
+ /**
+ * Returns this process builder's standard input source.
+ *
+ * Subprocesses subsequently started by this object's {@link #start()}
+ * method obtain their standard input from this source.
+ * The initial value is {@link Redirect#PIPE Redirect.PIPE}.
+ *
+ * @return this process builder's standard input source
+ * @since 1.7
+ */
+ public Redirect redirectInput() {
+ return (redirects == null) ? Redirect.PIPE : redirects[0];
+ }
+
+ /**
+ * Returns this process builder's standard output destination.
+ *
+ * Subprocesses subsequently started by this object's {@link #start()}
+ * method redirect their standard output to this destination.
+ * The initial value is {@link Redirect#PIPE Redirect.PIPE}.
+ *
+ * @return this process builder's standard output destination
+ * @since 1.7
+ */
+ public Redirect redirectOutput() {
+ return (redirects == null) ? Redirect.PIPE : redirects[1];
+ }
+
+ /**
+ * Returns this process builder's standard error destination.
+ *
+ * Subprocesses subsequently started by this object's {@link #start()}
+ * method redirect their standard error to this destination.
+ * The initial value is {@link Redirect#PIPE Redirect.PIPE}.
+ *
+ * @return this process builder's standard error destination
+ * @since 1.7
+ */
+ public Redirect redirectError() {
+ return (redirects == null) ? Redirect.PIPE : redirects[2];
+ }
+
+ /**
+ * Sets the source and destination for subprocess standard I/O
+ * to be the same as those of the current Java process.
+ *
+ * <p>This is a convenience method. An invocation of the form
+ * <pre> {@code
+ * pb.inheritIO()
+ * }</pre>
+ * behaves in exactly the same way as the invocation
+ * <pre> {@code
+ * pb.redirectInput(Redirect.INHERIT)
+ * .redirectOutput(Redirect.INHERIT)
+ * .redirectError(Redirect.INHERIT)
+ * }</pre>
+ *
+ * This gives behavior equivalent to most operating system
+ * command interpreters, or the standard C library function
+ * {@code system()}.
+ *
+ * @return this process builder
+ * @since 1.7
+ */
+ public ProcessBuilder inheritIO() {
+ Arrays.fill(redirects(), Redirect.INHERIT);
+ return this;
+ }
+
+ /**
+ * Tells whether this process builder merges standard error and
+ * standard output.
+ *
+ * <p>If this property is {@code true}, then any error output
+ * generated by subprocesses subsequently started by this object's
+ * {@link #start()} method will be merged with the standard
+ * output, so that both can be read using the
+ * {@link Process#getInputStream()} method. This makes it easier
+ * to correlate error messages with the corresponding output.
+ * The initial value is {@code false}.
+ *
+ * @return this process builder's {@code redirectErrorStream} property
+ */
+ public boolean redirectErrorStream() {
+ return redirectErrorStream;
+ }
+
+ /**
+ * Sets this process builder's {@code redirectErrorStream} property.
+ *
+ * <p>If this property is {@code true}, then any error output
+ * generated by subprocesses subsequently started by this object's
+ * {@link #start()} method will be merged with the standard
+ * output, so that both can be read using the
+ * {@link Process#getInputStream()} method. This makes it easier
+ * to correlate error messages with the corresponding output.
+ * The initial value is {@code false}.
+ *
+ * @param redirectErrorStream the new property value
+ * @return this process builder
+ */
+ public ProcessBuilder redirectErrorStream(boolean redirectErrorStream) {
+ this.redirectErrorStream = redirectErrorStream;
+ return this;
+ }
+
+ /**
+ * Starts a new process using the attributes of this process builder.
+ *
+ * <p>The new process will
+ * invoke the command and arguments given by {@link #command()},
+ * in a working directory as given by {@link #directory()},
+ * with a process environment as given by {@link #environment()}.
+ *
+ * <p>This method checks that the command is a valid operating
+ * system command. Which commands are valid is system-dependent,
+ * but at the very least the command must be a non-empty list of
+ * non-null strings.
+ *
+ * <p>A minimal set of system dependent environment variables may
+ * be required to start a process on some operating systems.
+ * As a result, the subprocess may inherit additional environment variable
+ * settings beyond those in the process builder's {@link #environment()}.
+ *
+ * <p>If there is a security manager, its
+ * {@link SecurityManager#checkExec checkExec}
+ * method is called with the first component of this object's
+ * {@code command} array as its argument. This may result in
+ * a {@link SecurityException} being thrown.
+ *
+ * <p>Starting an operating system process is highly system-dependent.
+ * Among the many things that can go wrong are:
+ * <ul>
+ * <li>The operating system program file was not found.
+ * <li>Access to the program file was denied.
+ * <li>The working directory does not exist.
+ * </ul>
+ *
+ * <p>In such cases an exception will be thrown. The exact nature
+ * of the exception is system-dependent, but it will always be a
+ * subclass of {@link IOException}.
+ *
+ * <p>Subsequent modifications to this process builder will not
+ * affect the returned {@link Process}.
+ *
+ * @return a new {@link Process} object for managing the subprocess
+ *
+ * @throws NullPointerException
+ * if an element of the command list is null
+ *
+ * @throws IndexOutOfBoundsException
+ * if the command is an empty list (has size {@code 0})
+ *
+ * @throws SecurityException
+ * if a security manager exists and
+ * <ul>
+ *
+ * <li>its
+ * {@link SecurityManager#checkExec checkExec}
+ * method doesn't allow creation of the subprocess, or
+ *
+ * <li>the standard input to the subprocess was
+ * {@linkplain #redirectInput redirected from a file}
+ * and the security manager's
+ * {@link SecurityManager#checkRead checkRead} method
+ * denies read access to the file, or
+ *
+ * <li>the standard output or standard error of the
+ * subprocess was
+ * {@linkplain #redirectOutput redirected to a file}
+ * and the security manager's
+ * {@link SecurityManager#checkWrite checkWrite} method
+ * denies write access to the file
+ *
+ * </ul>
+ *
+ * @throws IOException if an I/O error occurs
+ *
+ * @see Runtime#exec(String[], String[], java.io.File)
+ */
+ public Process start() throws IOException {
+ // Must convert to array first -- a malicious user-supplied
+ // list might try to circumvent the security check.
+ String[] cmdarray = command.toArray(new String[command.size()]);
+ cmdarray = cmdarray.clone();
+
+ for (String arg : cmdarray)
+ if (arg == null)
+ throw new NullPointerException();
+ // Throws IndexOutOfBoundsException if command is empty
+ String prog = cmdarray[0];
+
+ SecurityManager security = System.getSecurityManager();
+ if (security != null)
+ security.checkExec(prog);
+
+ String dir = directory == null ? null : directory.toString();
+
+ for (int i = 1; i < cmdarray.length; i++) {
+ if (cmdarray[i].indexOf('\u0000') >= 0) {
+ throw new IOException("invalid null character in command");
+ }
+ }
+
+ try {
+ return ProcessImpl.start(cmdarray,
+ environment,
+ dir,
+ redirects,
+ redirectErrorStream);
+ } catch (IOException | IllegalArgumentException e) {
+ String exceptionInfo = ": " + e.getMessage();
+ Throwable cause = e;
+ if ((e instanceof IOException) && security != null) {
+ // Can not disclose the fail reason for read-protected files.
+ try {
+ security.checkRead(prog);
+ } catch (SecurityException se) {
+ exceptionInfo = "";
+ cause = se;
+ }
+ }
+ // It's much easier for us to create a high-quality error
+ // message than the low-level C code which found the problem.
+ throw new IOException(
+ "Cannot run program \"" + prog + "\""
+ + (dir == null ? "" : " (in directory \"" + dir + "\")")
+ + exceptionInfo,
+ cause);
+ }
+ }
+}
diff --git a/java/lang/ProcessEnvironment.java b/java/lang/ProcessEnvironment.java
new file mode 100644
index 0000000..08d260c
--- /dev/null
+++ b/java/lang/ProcessEnvironment.java
@@ -0,0 +1,440 @@
+/*
+ * Copyright (c) 2003, 2011, 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.
+ */
+
+/* We use APIs that access the standard Unix environ array, which
+ * is defined by UNIX98 to look like:
+ *
+ * char **environ;
+ *
+ * These are unsorted, case-sensitive, null-terminated arrays of bytes
+ * of the form FOO=BAR\000 which are usually encoded in the user's
+ * default encoding (file.encoding is an excellent choice for
+ * encoding/decoding these). However, even though the user cannot
+ * directly access the underlying byte representation, we take pains
+ * to pass on the child the exact byte representation we inherit from
+ * the parent process for any environment name or value not created by
+ * Javaland. So we keep track of all the byte representations.
+ *
+ * Internally, we define the types Variable and Value that exhibit
+ * String/byteArray duality. The internal representation of the
+ * environment then looks like a Map<Variable,Value>. But we don't
+ * expose this to the user -- we only provide a Map<String,String>
+ * view, although we could also provide a Map<byte[],byte[]> view.
+ *
+ * The non-private methods in this class are not for general use even
+ * within this package. Instead, they are the system-dependent parts
+ * of the system-independent method of the same name. Don't even
+ * think of using this class unless your method's name appears below.
+ *
+ * @author Martin Buchholz
+ * @since 1.5
+ */
+
+package java.lang;
+
+import java.io.*;
+import java.util.*;
+
+
+final class ProcessEnvironment
+{
+ private static final HashMap<Variable,Value> theEnvironment;
+ private static final Map<String,String> theUnmodifiableEnvironment;
+ static final int MIN_NAME_LENGTH = 0;
+
+ static {
+ // We cache the C environment. This means that subsequent calls
+ // to putenv/setenv from C will not be visible from Java code.
+ byte[][] environ = environ();
+ theEnvironment = new HashMap<>(environ.length/2 + 3);
+ // Read environment variables back to front,
+ // so that earlier variables override later ones.
+ for (int i = environ.length-1; i > 0; i-=2)
+ theEnvironment.put(Variable.valueOf(environ[i-1]),
+ Value.valueOf(environ[i]));
+
+ theUnmodifiableEnvironment
+ = Collections.unmodifiableMap
+ (new StringEnvironment(theEnvironment));
+ }
+
+ /* Only for use by System.getenv(String) */
+ static String getenv(String name) {
+ return theUnmodifiableEnvironment.get(name);
+ }
+
+ /* Only for use by System.getenv() */
+ static Map<String,String> getenv() {
+ return theUnmodifiableEnvironment;
+ }
+
+ /* Only for use by ProcessBuilder.environment() */
+ @SuppressWarnings("unchecked")
+ static Map<String,String> environment() {
+ return new StringEnvironment
+ ((Map<Variable,Value>)(theEnvironment.clone()));
+ }
+
+ /* Only for use by Runtime.exec(...String[]envp...) */
+ static Map<String,String> emptyEnvironment(int capacity) {
+ return new StringEnvironment(new HashMap<Variable,Value>(capacity));
+ }
+
+ private static native byte[][] environ();
+
+ // This class is not instantiable.
+ private ProcessEnvironment() {}
+
+ // Check that name is suitable for insertion into Environment map
+ private static void validateVariable(String name) {
+ if (name.indexOf('=') != -1 ||
+ name.indexOf('\u0000') != -1)
+ throw new IllegalArgumentException
+ ("Invalid environment variable name: \"" + name + "\"");
+ }
+
+ // Check that value is suitable for insertion into Environment map
+ private static void validateValue(String value) {
+ if (value.indexOf('\u0000') != -1)
+ throw new IllegalArgumentException
+ ("Invalid environment variable value: \"" + value + "\"");
+ }
+
+ // A class hiding the byteArray-String duality of
+ // text data on Unixoid operating systems.
+ private static abstract class ExternalData {
+ protected final String str;
+ protected final byte[] bytes;
+
+ protected ExternalData(String str, byte[] bytes) {
+ this.str = str;
+ this.bytes = bytes;
+ }
+
+ public byte[] getBytes() {
+ return bytes;
+ }
+
+ public String toString() {
+ return str;
+ }
+
+ public boolean equals(Object o) {
+ return o instanceof ExternalData
+ && arrayEquals(getBytes(), ((ExternalData) o).getBytes());
+ }
+
+ public int hashCode() {
+ return arrayHash(getBytes());
+ }
+ }
+
+ private static class Variable
+ extends ExternalData implements Comparable<Variable>
+ {
+ protected Variable(String str, byte[] bytes) {
+ super(str, bytes);
+ }
+
+ public static Variable valueOfQueryOnly(Object str) {
+ return valueOfQueryOnly((String) str);
+ }
+
+ public static Variable valueOfQueryOnly(String str) {
+ return new Variable(str, str.getBytes());
+ }
+
+ public static Variable valueOf(String str) {
+ validateVariable(str);
+ return valueOfQueryOnly(str);
+ }
+
+ public static Variable valueOf(byte[] bytes) {
+ return new Variable(new String(bytes), bytes);
+ }
+
+ public int compareTo(Variable variable) {
+ return arrayCompare(getBytes(), variable.getBytes());
+ }
+
+ public boolean equals(Object o) {
+ return o instanceof Variable && super.equals(o);
+ }
+ }
+
+ private static class Value
+ extends ExternalData implements Comparable<Value>
+ {
+ protected Value(String str, byte[] bytes) {
+ super(str, bytes);
+ }
+
+ public static Value valueOfQueryOnly(Object str) {
+ return valueOfQueryOnly((String) str);
+ }
+
+ public static Value valueOfQueryOnly(String str) {
+ return new Value(str, str.getBytes());
+ }
+
+ public static Value valueOf(String str) {
+ validateValue(str);
+ return valueOfQueryOnly(str);
+ }
+
+ public static Value valueOf(byte[] bytes) {
+ return new Value(new String(bytes), bytes);
+ }
+
+ public int compareTo(Value value) {
+ return arrayCompare(getBytes(), value.getBytes());
+ }
+
+ public boolean equals(Object o) {
+ return o instanceof Value && super.equals(o);
+ }
+ }
+
+ // This implements the String map view the user sees.
+ private static class StringEnvironment
+ extends AbstractMap<String,String>
+ {
+ private Map<Variable,Value> m;
+ private static String toString(Value v) {
+ return v == null ? null : v.toString();
+ }
+ public StringEnvironment(Map<Variable,Value> m) {this.m = m;}
+ public int size() {return m.size();}
+ public boolean isEmpty() {return m.isEmpty();}
+ public void clear() { m.clear();}
+ public boolean containsKey(Object key) {
+ return m.containsKey(Variable.valueOfQueryOnly(key));
+ }
+ public boolean containsValue(Object value) {
+ return m.containsValue(Value.valueOfQueryOnly(value));
+ }
+ public String get(Object key) {
+ return toString(m.get(Variable.valueOfQueryOnly(key)));
+ }
+ public String put(String key, String value) {
+ return toString(m.put(Variable.valueOf(key),
+ Value.valueOf(value)));
+ }
+ public String remove(Object key) {
+ return toString(m.remove(Variable.valueOfQueryOnly(key)));
+ }
+ public Set<String> keySet() {
+ return new StringKeySet(m.keySet());
+ }
+ public Set<Map.Entry<String,String>> entrySet() {
+ return new StringEntrySet(m.entrySet());
+ }
+ public Collection<String> values() {
+ return new StringValues(m.values());
+ }
+
+ // It is technically feasible to provide a byte-oriented view
+ // as follows:
+ // public Map<byte[],byte[]> asByteArrayMap() {
+ // return new ByteArrayEnvironment(m);
+ // }
+
+
+ // Convert to Unix style environ as a monolithic byte array
+ // inspired by the Windows Environment Block, except we work
+ // exclusively with bytes instead of chars, and we need only
+ // one trailing NUL on Unix.
+ // This keeps the JNI as simple and efficient as possible.
+ public byte[] toEnvironmentBlock(int[]envc) {
+ int count = m.size() * 2; // For added '=' and NUL
+ for (Map.Entry<Variable,Value> entry : m.entrySet()) {
+ count += entry.getKey().getBytes().length;
+ count += entry.getValue().getBytes().length;
+ }
+
+ byte[] block = new byte[count];
+
+ int i = 0;
+ for (Map.Entry<Variable,Value> entry : m.entrySet()) {
+ byte[] key = entry.getKey ().getBytes();
+ byte[] value = entry.getValue().getBytes();
+ System.arraycopy(key, 0, block, i, key.length);
+ i+=key.length;
+ block[i++] = (byte) '=';
+ System.arraycopy(value, 0, block, i, value.length);
+ i+=value.length + 1;
+ // No need to write NUL byte explicitly
+ //block[i++] = (byte) '\u0000';
+ }
+ envc[0] = m.size();
+ return block;
+ }
+ }
+
+ static byte[] toEnvironmentBlock(Map<String,String> map, int[]envc) {
+ return map == null ? null :
+ ((StringEnvironment)map).toEnvironmentBlock(envc);
+ }
+
+
+ private static class StringEntry
+ implements Map.Entry<String,String>
+ {
+ private final Map.Entry<Variable,Value> e;
+ public StringEntry(Map.Entry<Variable,Value> e) {this.e = e;}
+ public String getKey() {return e.getKey().toString();}
+ public String getValue() {return e.getValue().toString();}
+ public String setValue(String newValue) {
+ return e.setValue(Value.valueOf(newValue)).toString();
+ }
+ public String toString() {return getKey() + "=" + getValue();}
+ public boolean equals(Object o) {
+ return o instanceof StringEntry
+ && e.equals(((StringEntry)o).e);
+ }
+ public int hashCode() {return e.hashCode();}
+ }
+
+ private static class StringEntrySet
+ extends AbstractSet<Map.Entry<String,String>>
+ {
+ private final Set<Map.Entry<Variable,Value>> s;
+ public StringEntrySet(Set<Map.Entry<Variable,Value>> s) {this.s = s;}
+ public int size() {return s.size();}
+ public boolean isEmpty() {return s.isEmpty();}
+ public void clear() { s.clear();}
+ public Iterator<Map.Entry<String,String>> iterator() {
+ return new Iterator<Map.Entry<String,String>>() {
+ Iterator<Map.Entry<Variable,Value>> i = s.iterator();
+ public boolean hasNext() {return i.hasNext();}
+ public Map.Entry<String,String> next() {
+ return new StringEntry(i.next());
+ }
+ public void remove() {i.remove();}
+ };
+ }
+ private static Map.Entry<Variable,Value> vvEntry(final Object o) {
+ if (o instanceof StringEntry)
+ return ((StringEntry)o).e;
+ return new Map.Entry<Variable,Value>() {
+ public Variable getKey() {
+ return Variable.valueOfQueryOnly(((Map.Entry)o).getKey());
+ }
+ public Value getValue() {
+ return Value.valueOfQueryOnly(((Map.Entry)o).getValue());
+ }
+ public Value setValue(Value value) {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+ public boolean contains(Object o) { return s.contains(vvEntry(o)); }
+ public boolean remove(Object o) { return s.remove(vvEntry(o)); }
+ public boolean equals(Object o) {
+ return o instanceof StringEntrySet
+ && s.equals(((StringEntrySet) o).s);
+ }
+ public int hashCode() {return s.hashCode();}
+ }
+
+ private static class StringValues
+ extends AbstractCollection<String>
+ {
+ private final Collection<Value> c;
+ public StringValues(Collection<Value> c) {this.c = c;}
+ public int size() {return c.size();}
+ public boolean isEmpty() {return c.isEmpty();}
+ public void clear() { c.clear();}
+ public Iterator<String> iterator() {
+ return new Iterator<String>() {
+ Iterator<Value> i = c.iterator();
+ public boolean hasNext() {return i.hasNext();}
+ public String next() {return i.next().toString();}
+ public void remove() {i.remove();}
+ };
+ }
+ public boolean contains(Object o) {
+ return c.contains(Value.valueOfQueryOnly(o));
+ }
+ public boolean remove(Object o) {
+ return c.remove(Value.valueOfQueryOnly(o));
+ }
+ public boolean equals(Object o) {
+ return o instanceof StringValues
+ && c.equals(((StringValues)o).c);
+ }
+ public int hashCode() {return c.hashCode();}
+ }
+
+ private static class StringKeySet extends AbstractSet<String> {
+ private final Set<Variable> s;
+ public StringKeySet(Set<Variable> s) {this.s = s;}
+ public int size() {return s.size();}
+ public boolean isEmpty() {return s.isEmpty();}
+ public void clear() { s.clear();}
+ public Iterator<String> iterator() {
+ return new Iterator<String>() {
+ Iterator<Variable> i = s.iterator();
+ public boolean hasNext() {return i.hasNext();}
+ public String next() {return i.next().toString();}
+ public void remove() { i.remove();}
+ };
+ }
+ public boolean contains(Object o) {
+ return s.contains(Variable.valueOfQueryOnly(o));
+ }
+ public boolean remove(Object o) {
+ return s.remove(Variable.valueOfQueryOnly(o));
+ }
+ }
+
+ // Replace with general purpose method someday
+ private static int arrayCompare(byte[]x, byte[] y) {
+ int min = x.length < y.length ? x.length : y.length;
+ for (int i = 0; i < min; i++)
+ if (x[i] != y[i])
+ return x[i] - y[i];
+ return x.length - y.length;
+ }
+
+ // Replace with general purpose method someday
+ private static boolean arrayEquals(byte[] x, byte[] y) {
+ if (x.length != y.length)
+ return false;
+ for (int i = 0; i < x.length; i++)
+ if (x[i] != y[i])
+ return false;
+ return true;
+ }
+
+ // Replace with general purpose method someday
+ private static int arrayHash(byte[] x) {
+ int hash = 0;
+ for (int i = 0; i < x.length; i++)
+ hash = 31 * hash + x[i];
+ return hash;
+ }
+
+}
diff --git a/java/lang/ProcessImpl.java b/java/lang/ProcessImpl.java
new file mode 100644
index 0000000..39ea145
--- /dev/null
+++ b/java/lang/ProcessImpl.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2003, 2010, 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;
+
+import java.io.IOException;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.lang.ProcessBuilder.Redirect;
+import java.lang.ProcessBuilder.Redirect;
+
+/**
+ * This class is for the exclusive use of ProcessBuilder.start() to
+ * create new processes.
+ *
+ * @author Martin Buchholz
+ * @since 1.5
+ */
+final class ProcessImpl {
+ // Android-changed: Use FileDescriptor.getInt$() instead of fdAccess.get(...).
+ // private static final sun.misc.JavaIOFileDescriptorAccess fdAccess
+ // = sun.misc.SharedSecrets.getJavaIOFileDescriptorAccess();
+
+ private ProcessImpl() {} // Not instantiable
+
+ private static byte[] toCString(String s) {
+ if (s == null)
+ return null;
+ byte[] bytes = s.getBytes();
+ byte[] result = new byte[bytes.length + 1];
+ System.arraycopy(bytes, 0,
+ result, 0,
+ bytes.length);
+ result[result.length-1] = (byte)0;
+ return result;
+ }
+
+ // Only for use by ProcessBuilder.start()
+ static Process start(String[] cmdarray,
+ java.util.Map<String,String> environment,
+ String dir,
+ ProcessBuilder.Redirect[] redirects,
+ boolean redirectErrorStream)
+ throws IOException
+ {
+ assert cmdarray != null && cmdarray.length > 0;
+
+ // Convert arguments to a contiguous block; it's easier to do
+ // memory management in Java than in C.
+ byte[][] args = new byte[cmdarray.length-1][];
+ int size = args.length; // For added NUL bytes
+ for (int i = 0; i < args.length; i++) {
+ args[i] = cmdarray[i+1].getBytes();
+ size += args[i].length;
+ }
+ byte[] argBlock = new byte[size];
+ int i = 0;
+ for (byte[] arg : args) {
+ System.arraycopy(arg, 0, argBlock, i, arg.length);
+ i += arg.length + 1;
+ // No need to write NUL bytes explicitly
+ }
+
+ int[] envc = new int[1];
+ byte[] envBlock = ProcessEnvironment.toEnvironmentBlock(environment, envc);
+
+ int[] std_fds;
+
+ FileInputStream f0 = null;
+ FileOutputStream f1 = null;
+ FileOutputStream f2 = null;
+
+ try {
+ if (redirects == null) {
+ std_fds = new int[] { -1, -1, -1 };
+ } else {
+ std_fds = new int[3];
+
+ if (redirects[0] == Redirect.PIPE)
+ std_fds[0] = -1;
+ else if (redirects[0] == Redirect.INHERIT)
+ std_fds[0] = 0;
+ else {
+ f0 = new FileInputStream(redirects[0].file());
+ // Android-changed: Use FileDescriptor.getInt$() instead of fdAccess.get(...).
+ // std_fds[0] = fdAccess.get(f0.getFD());
+ std_fds[0] = f0.getFD().getInt$();
+ }
+
+ if (redirects[1] == Redirect.PIPE)
+ std_fds[1] = -1;
+ else if (redirects[1] == Redirect.INHERIT)
+ std_fds[1] = 1;
+ else {
+ f1 = new FileOutputStream(redirects[1].file(),
+ redirects[1].append());
+ // Android-changed: Use FileDescriptor.getInt$() instead of fdAccess.get(...).
+ // std_fds[1] = fdAccess.get(f1.getFD());
+ std_fds[1] = f1.getFD().getInt$();
+ }
+
+ if (redirects[2] == Redirect.PIPE)
+ std_fds[2] = -1;
+ else if (redirects[2] == Redirect.INHERIT)
+ std_fds[2] = 2;
+ else {
+ f2 = new FileOutputStream(redirects[2].file(),
+ redirects[2].append());
+ // Android-changed: Use FileDescriptor.getInt$() instead of fdAccess.get(...).
+ // std_fds[2] = fdAccess.get(f2.getFD());
+ std_fds[2] = f2.getFD().getInt$();
+ }
+ }
+
+ return new UNIXProcess
+ (toCString(cmdarray[0]),
+ argBlock, args.length,
+ envBlock, envc[0],
+ toCString(dir),
+ std_fds,
+ redirectErrorStream);
+ } finally {
+ // In theory, close() can throw IOException
+ // (although it is rather unlikely to happen here)
+ try { if (f0 != null) f0.close(); }
+ finally {
+ try { if (f1 != null) f1.close(); }
+ finally { if (f2 != null) f2.close(); }
+ }
+ }
+ }
+}
diff --git a/java/lang/Readable.java b/java/lang/Readable.java
new file mode 100644
index 0000000..c7a3d1a
--- /dev/null
+++ b/java/lang/Readable.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2003, 2013, 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;
+
+import java.io.IOException;
+
+/**
+ * A <tt>Readable</tt> is a source of characters. Characters from
+ * a <tt>Readable</tt> are made available to callers of the read
+ * method via a {@link java.nio.CharBuffer CharBuffer}.
+ *
+ * @since 1.5
+ */
+public interface Readable {
+
+ /**
+ * Attempts to read characters into the specified character buffer.
+ * The buffer is used as a repository of characters as-is: the only
+ * changes made are the results of a put operation. No flipping or
+ * rewinding of the buffer is performed.
+ *
+ * @param cb the buffer to read characters into
+ * @return The number of {@code char} values added to the buffer,
+ * or -1 if this source of characters is at its end
+ * @throws IOException if an I/O error occurs
+ * @throws NullPointerException if cb is null
+ * @throws java.nio.ReadOnlyBufferException if cb is a read only buffer
+ */
+ public int read(java.nio.CharBuffer cb) throws IOException;
+}
diff --git a/java/lang/ReflectiveOperationException.java b/java/lang/ReflectiveOperationException.java
new file mode 100644
index 0000000..a140478
--- /dev/null
+++ b/java/lang/ReflectiveOperationException.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2009, 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;
+
+/**
+ * Common superclass of exceptions thrown by reflective operations in
+ * core reflection.
+ *
+ * @see LinkageError
+ * @since 1.7
+ */
+public class ReflectiveOperationException extends Exception {
+ static final long serialVersionUID = 123456789L;
+
+ /**
+ * Constructs a new exception with {@code null} as its detail
+ * message. The cause is not initialized, and may subsequently be
+ * initialized by a call to {@link #initCause}.
+ */
+ public ReflectiveOperationException() {
+ super();
+ }
+
+ /**
+ * Constructs a new exception with the specified detail message.
+ * The cause is not initialized, and may subsequently be
+ * initialized by a call to {@link #initCause}.
+ *
+ * @param message the detail message. The detail message is saved for
+ * later retrieval by the {@link #getMessage()} method.
+ */
+ public ReflectiveOperationException(String message) {
+ super(message);
+ }
+
+ /**
+ * Constructs a new exception with the specified detail message
+ * and cause.
+ *
+ * <p>Note that the detail message associated with
+ * {@code cause} is <em>not</em> automatically incorporated in
+ * this exception's detail message.
+ *
+ * @param message the detail message (which is saved for later retrieval
+ * by the {@link #getMessage()} method).
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link #getCause()} method). (A {@code null} value is
+ * permitted, and indicates that the cause is nonexistent or
+ * unknown.)
+ */
+ public ReflectiveOperationException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * Constructs a new exception with the specified cause and a detail
+ * message of {@code (cause==null ? null : cause.toString())} (which
+ * typically contains the class and detail message of {@code cause}).
+ *
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link #getCause()} method). (A {@code null} value is
+ * permitted, and indicates that the cause is nonexistent or
+ * unknown.)
+ */
+ public ReflectiveOperationException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/java/lang/Runnable.java b/java/lang/Runnable.java
new file mode 100644
index 0000000..b9f1df7
--- /dev/null
+++ b/java/lang/Runnable.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 1994, 2013, 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;
+
+/**
+ * The <code>Runnable</code> interface should be implemented by any
+ * class whose instances are intended to be executed by a thread. The
+ * class must define a method of no arguments called <code>run</code>.
+ * <p>
+ * This interface is designed to provide a common protocol for objects that
+ * wish to execute code while they are active. For example,
+ * <code>Runnable</code> is implemented by class <code>Thread</code>.
+ * Being active simply means that a thread has been started and has not
+ * yet been stopped.
+ * <p>
+ * In addition, <code>Runnable</code> provides the means for a class to be
+ * active while not subclassing <code>Thread</code>. A class that implements
+ * <code>Runnable</code> can run without subclassing <code>Thread</code>
+ * by instantiating a <code>Thread</code> instance and passing itself in
+ * as the target. In most cases, the <code>Runnable</code> interface should
+ * be used if you are only planning to override the <code>run()</code>
+ * method and no other <code>Thread</code> methods.
+ * This is important because classes should not be subclassed
+ * unless the programmer intends on modifying or enhancing the fundamental
+ * behavior of the class.
+ *
+ * @author Arthur van Hoff
+ * @see java.lang.Thread
+ * @see java.util.concurrent.Callable
+ * @since JDK1.0
+ */
+@FunctionalInterface
+public interface Runnable {
+ /**
+ * When an object implementing interface <code>Runnable</code> is used
+ * to create a thread, starting the thread causes the object's
+ * <code>run</code> method to be called in that separately executing
+ * thread.
+ * <p>
+ * The general contract of the method <code>run</code> is that it may
+ * take any action whatsoever.
+ *
+ * @see java.lang.Thread#run()
+ */
+ public abstract void run();
+}
diff --git a/java/lang/Runtime.java b/java/lang/Runtime.java
new file mode 100644
index 0000000..f5c52e7
--- /dev/null
+++ b/java/lang/Runtime.java
@@ -0,0 +1,1191 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1995, 2013, 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;
+
+import dalvik.annotation.optimization.FastNative;
+import java.io.*;
+import java.util.StringTokenizer;
+
+import dalvik.system.BlockGuard;
+import sun.reflect.CallerSensitive;
+import java.lang.ref.FinalizerReference;
+import java.util.ArrayList;
+import java.util.List;
+import dalvik.system.DelegateLastClassLoader;
+import dalvik.system.PathClassLoader;
+import dalvik.system.VMDebug;
+import dalvik.system.VMRuntime;
+import sun.reflect.Reflection;
+
+import libcore.io.IoUtils;
+import libcore.io.Libcore;
+import libcore.util.EmptyArray;
+import static android.system.OsConstants._SC_NPROCESSORS_CONF;
+
+/**
+ * Every Java application has a single instance of class
+ * <code>Runtime</code> that allows the application to interface with
+ * the environment in which the application is running. The current
+ * runtime can be obtained from the <code>getRuntime</code> method.
+ * <p>
+ * An application cannot create its own instance of this class.
+ *
+ * @author unascribed
+ * @see java.lang.Runtime#getRuntime()
+ * @since JDK1.0
+ */
+
+public class Runtime {
+ private static Runtime currentRuntime = new Runtime();
+
+ /**
+ * Holds the list of threads to run when the VM terminates
+ */
+ private List<Thread> shutdownHooks = new ArrayList<Thread>();
+
+ /**
+ * Reflects whether finalization should be run for all objects
+ * when the VM terminates.
+ */
+ private static boolean finalizeOnExit;
+
+ /**
+ * Reflects whether we are already shutting down the VM.
+ */
+ private boolean shuttingDown;
+
+ /**
+ * Reflects whether we are tracing method calls.
+ */
+ private boolean tracingMethods;
+
+ private static native void nativeExit(int code);
+
+ /**
+ * Returns the runtime object associated with the current Java application.
+ * Most of the methods of class <code>Runtime</code> are instance
+ * methods and must be invoked with respect to the current runtime object.
+ *
+ * @return the <code>Runtime</code> object associated with the current
+ * Java application.
+ */
+ public static Runtime getRuntime() {
+ return currentRuntime;
+ }
+
+ /** Don't let anyone else instantiate this class */
+ private Runtime() {}
+
+ /**
+ * Terminates the currently running Java virtual machine by initiating its
+ * shutdown sequence. This method never returns normally. The argument
+ * serves as a status code; by convention, a nonzero status code indicates
+ * abnormal termination.
+ *
+ * <p> The virtual machine's shutdown sequence consists of two phases. In
+ * the first phase all registered {@link #addShutdownHook shutdown hooks},
+ * if any, are started in some unspecified order and allowed to run
+ * concurrently until they finish. In the second phase all uninvoked
+ * finalizers are run if {@link #runFinalizersOnExit finalization-on-exit}
+ * has been enabled. Once this is done the virtual machine {@link #halt
+ * halts}.
+ *
+ * <p> If this method is invoked after the virtual machine has begun its
+ * shutdown sequence then if shutdown hooks are being run this method will
+ * block indefinitely. If shutdown hooks have already been run and on-exit
+ * finalization has been enabled then this method halts the virtual machine
+ * with the given status code if the status is nonzero; otherwise, it
+ * blocks indefinitely.
+ *
+ * <p> The <tt>{@link System#exit(int) System.exit}</tt> method is the
+ * conventional and convenient means of invoking this method. <p>
+ *
+ * @param status
+ * Termination status. By convention, a nonzero status code
+ * indicates abnormal termination.
+ *
+ * @throws SecurityException
+ * If a security manager is present and its <tt>{@link
+ * SecurityManager#checkExit checkExit}</tt> method does not permit
+ * exiting with the specified status
+ *
+ * @see java.lang.SecurityException
+ * @see java.lang.SecurityManager#checkExit(int)
+ * @see #addShutdownHook
+ * @see #removeShutdownHook
+ * @see #runFinalizersOnExit
+ * @see #halt(int)
+ */
+ public void exit(int status) {
+ // Make sure we don't try this several times
+ synchronized(this) {
+ if (!shuttingDown) {
+ shuttingDown = true;
+
+ Thread[] hooks;
+ synchronized (shutdownHooks) {
+ // create a copy of the hooks
+ hooks = new Thread[shutdownHooks.size()];
+ shutdownHooks.toArray(hooks);
+ }
+
+ // Start all shutdown hooks concurrently
+ for (Thread hook : hooks) {
+ hook.start();
+ }
+
+ // Wait for all shutdown hooks to finish
+ for (Thread hook : hooks) {
+ try {
+ hook.join();
+ } catch (InterruptedException ex) {
+ // Ignore, since we are at VM shutdown.
+ }
+ }
+
+ // Ensure finalization on exit, if requested
+ if (finalizeOnExit) {
+ runFinalization();
+ }
+
+ // Get out of here finally...
+ nativeExit(status);
+ }
+ }
+ }
+
+ /**
+ * Registers a new virtual-machine shutdown hook.
+ *
+ * <p> The Java virtual machine <i>shuts down</i> in response to two kinds
+ * of events:
+ *
+ * <ul>
+ *
+ * <li> The program <i>exits</i> normally, when the last non-daemon
+ * thread exits or when the <tt>{@link #exit exit}</tt> (equivalently,
+ * {@link System#exit(int) System.exit}) method is invoked, or
+ *
+ * <li> The virtual machine is <i>terminated</i> in response to a
+ * user interrupt, such as typing <tt>^C</tt>, or a system-wide event,
+ * such as user logoff or system shutdown.
+ *
+ * </ul>
+ *
+ * <p> A <i>shutdown hook</i> is simply an initialized but unstarted
+ * thread. When the virtual machine begins its shutdown sequence it will
+ * start all registered shutdown hooks in some unspecified order and let
+ * them run concurrently. When all the hooks have finished it will then
+ * run all uninvoked finalizers if finalization-on-exit has been enabled.
+ * Finally, the virtual machine will halt. Note that daemon threads will
+ * continue to run during the shutdown sequence, as will non-daemon threads
+ * if shutdown was initiated by invoking the <tt>{@link #exit exit}</tt>
+ * method.
+ *
+ * <p> Once the shutdown sequence has begun it can be stopped only by
+ * invoking the <tt>{@link #halt halt}</tt> method, which forcibly
+ * terminates the virtual machine.
+ *
+ * <p> Once the shutdown sequence has begun it is impossible to register a
+ * new shutdown hook or de-register a previously-registered hook.
+ * Attempting either of these operations will cause an
+ * <tt>{@link IllegalStateException}</tt> to be thrown.
+ *
+ * <p> Shutdown hooks run at a delicate time in the life cycle of a virtual
+ * machine and should therefore be coded defensively. They should, in
+ * particular, be written to be thread-safe and to avoid deadlocks insofar
+ * as possible. They should also not rely blindly upon services that may
+ * have registered their own shutdown hooks and therefore may themselves in
+ * the process of shutting down. Attempts to use other thread-based
+ * services such as the AWT event-dispatch thread, for example, may lead to
+ * deadlocks.
+ *
+ * <p> Shutdown hooks should also finish their work quickly. When a
+ * program invokes <tt>{@link #exit exit}</tt> the expectation is
+ * that the virtual machine will promptly shut down and exit. When the
+ * virtual machine is terminated due to user logoff or system shutdown the
+ * underlying operating system may only allow a fixed amount of time in
+ * which to shut down and exit. It is therefore inadvisable to attempt any
+ * user interaction or to perform a long-running computation in a shutdown
+ * hook.
+ *
+ * <p> Uncaught exceptions are handled in shutdown hooks just as in any
+ * other thread, by invoking the <tt>{@link ThreadGroup#uncaughtException
+ * uncaughtException}</tt> method of the thread's <tt>{@link
+ * ThreadGroup}</tt> object. The default implementation of this method
+ * prints the exception's stack trace to <tt>{@link System#err}</tt> and
+ * terminates the thread; it does not cause the virtual machine to exit or
+ * halt.
+ *
+ * <p> In rare circumstances the virtual machine may <i>abort</i>, that is,
+ * stop running without shutting down cleanly. This occurs when the
+ * virtual machine is terminated externally, for example with the
+ * <tt>SIGKILL</tt> signal on Unix or the <tt>TerminateProcess</tt> call on
+ * Microsoft Windows. The virtual machine may also abort if a native
+ * method goes awry by, for example, corrupting internal data structures or
+ * attempting to access nonexistent memory. If the virtual machine aborts
+ * then no guarantee can be made about whether or not any shutdown hooks
+ * will be run. <p>
+ *
+ * @param hook
+ * An initialized but unstarted <tt>{@link Thread}</tt> object
+ *
+ * @throws IllegalArgumentException
+ * If the specified hook has already been registered,
+ * or if it can be determined that the hook is already running or
+ * has already been run
+ *
+ * @throws IllegalStateException
+ * If the virtual machine is already in the process
+ * of shutting down
+ *
+ * @throws SecurityException
+ * If a security manager is present and it denies
+ * <tt>{@link RuntimePermission}("shutdownHooks")</tt>
+ *
+ * @see #removeShutdownHook
+ * @see #halt(int)
+ * @see #exit(int)
+ * @since 1.3
+ */
+ public void addShutdownHook(Thread hook) {
+ // Sanity checks
+ if (hook == null) {
+ throw new NullPointerException("hook == null");
+ }
+
+ if (shuttingDown) {
+ throw new IllegalStateException("VM already shutting down");
+ }
+
+ if (hook.started) {
+ throw new IllegalArgumentException("Hook has already been started");
+ }
+
+ synchronized (shutdownHooks) {
+ if (shutdownHooks.contains(hook)) {
+ throw new IllegalArgumentException("Hook already registered.");
+ }
+
+ shutdownHooks.add(hook);
+ }
+ }
+
+ /**
+ * De-registers a previously-registered virtual-machine shutdown hook. <p>
+ *
+ * @param hook the hook to remove
+ * @return <tt>true</tt> if the specified hook had previously been
+ * registered and was successfully de-registered, <tt>false</tt>
+ * otherwise.
+ *
+ * @throws IllegalStateException
+ * If the virtual machine is already in the process of shutting
+ * down
+ *
+ * @throws SecurityException
+ * If a security manager is present and it denies
+ * <tt>{@link RuntimePermission}("shutdownHooks")</tt>
+ *
+ * @see #addShutdownHook
+ * @see #exit(int)
+ * @since 1.3
+ */
+ public boolean removeShutdownHook(Thread hook) {
+ // Sanity checks
+ if (hook == null) {
+ throw new NullPointerException("hook == null");
+ }
+
+ if (shuttingDown) {
+ throw new IllegalStateException("VM already shutting down");
+ }
+
+ synchronized (shutdownHooks) {
+ return shutdownHooks.remove(hook);
+ }
+ }
+
+ /**
+ * Forcibly terminates the currently running Java virtual machine. This
+ * method never returns normally.
+ *
+ * <p> This method should be used with extreme caution. Unlike the
+ * <tt>{@link #exit exit}</tt> method, this method does not cause shutdown
+ * hooks to be started and does not run uninvoked finalizers if
+ * finalization-on-exit has been enabled. If the shutdown sequence has
+ * already been initiated then this method does not wait for any running
+ * shutdown hooks or finalizers to finish their work. <p>
+ *
+ * @param status
+ * Termination status. By convention, a nonzero status code
+ * indicates abnormal termination. If the <tt>{@link Runtime#exit
+ * exit}</tt> (equivalently, <tt>{@link System#exit(int)
+ * System.exit}</tt>) method has already been invoked then this
+ * status code will override the status code passed to that method.
+ *
+ * @throws SecurityException
+ * If a security manager is present and its <tt>{@link
+ * SecurityManager#checkExit checkExit}</tt> method does not permit
+ * an exit with the specified status
+ *
+ * @see #exit
+ * @see #addShutdownHook
+ * @see #removeShutdownHook
+ * @since 1.3
+ */
+ public void halt(int status) {
+ nativeExit(status);
+ }
+
+ /**
+ * Enable or disable finalization on exit; doing so specifies that the
+ * finalizers of all objects that have finalizers that have not yet been
+ * automatically invoked are to be run before the Java runtime exits.
+ * By default, finalization on exit is disabled.
+ *
+ * <p>If there is a security manager,
+ * its <code>checkExit</code> method is first called
+ * with 0 as its argument to ensure the exit is allowed.
+ * This could result in a SecurityException.
+ *
+ * @param value true to enable finalization on exit, false to disable
+ * @deprecated This method is inherently unsafe. It may result in
+ * finalizers being called on live objects while other threads are
+ * concurrently manipulating those objects, resulting in erratic
+ * behavior or deadlock.
+ *
+ * @throws SecurityException
+ * if a security manager exists and its <code>checkExit</code>
+ * method doesn't allow the exit.
+ *
+ * @see java.lang.Runtime#exit(int)
+ * @see java.lang.Runtime#gc()
+ * @see java.lang.SecurityManager#checkExit(int)
+ * @since JDK1.1
+ */
+ @Deprecated
+ public static void runFinalizersOnExit(boolean value) {
+ finalizeOnExit = value;
+ }
+
+ /**
+ * Executes the specified string command in a separate process.
+ *
+ * <p>This is a convenience method. An invocation of the form
+ * <tt>exec(command)</tt>
+ * behaves in exactly the same way as the invocation
+ * <tt>{@link #exec(String, String[], File) exec}(command, null, null)</tt>.
+ *
+ * @param command a specified system command.
+ *
+ * @return A new {@link Process} object for managing the subprocess
+ *
+ * @throws SecurityException
+ * If a security manager exists and its
+ * {@link SecurityManager#checkExec checkExec}
+ * method doesn't allow creation of the subprocess
+ *
+ * @throws IOException
+ * If an I/O error occurs
+ *
+ * @throws NullPointerException
+ * If <code>command</code> is <code>null</code>
+ *
+ * @throws IllegalArgumentException
+ * If <code>command</code> is empty
+ *
+ * @see #exec(String[], String[], File)
+ * @see ProcessBuilder
+ */
+ public Process exec(String command) throws IOException {
+ return exec(command, null, null);
+ }
+
+ /**
+ * Executes the specified string command in a separate process with the
+ * specified environment.
+ *
+ * <p>This is a convenience method. An invocation of the form
+ * <tt>exec(command, envp)</tt>
+ * behaves in exactly the same way as the invocation
+ * <tt>{@link #exec(String, String[], File) exec}(command, envp, null)</tt>.
+ *
+ * @param command a specified system command.
+ *
+ * @param envp array of strings, each element of which
+ * has environment variable settings in the format
+ * <i>name</i>=<i>value</i>, or
+ * <tt>null</tt> if the subprocess should inherit
+ * the environment of the current process.
+ *
+ * @return A new {@link Process} object for managing the subprocess
+ *
+ * @throws SecurityException
+ * If a security manager exists and its
+ * {@link SecurityManager#checkExec checkExec}
+ * method doesn't allow creation of the subprocess
+ *
+ * @throws IOException
+ * If an I/O error occurs
+ *
+ * @throws NullPointerException
+ * If <code>command</code> is <code>null</code>,
+ * or one of the elements of <code>envp</code> is <code>null</code>
+ *
+ * @throws IllegalArgumentException
+ * If <code>command</code> is empty
+ *
+ * @see #exec(String[], String[], File)
+ * @see ProcessBuilder
+ */
+ public Process exec(String command, String[] envp) throws IOException {
+ return exec(command, envp, null);
+ }
+
+ /**
+ * Executes the specified string command in a separate process with the
+ * specified environment and working directory.
+ *
+ * <p>This is a convenience method. An invocation of the form
+ * <tt>exec(command, envp, dir)</tt>
+ * behaves in exactly the same way as the invocation
+ * <tt>{@link #exec(String[], String[], File) exec}(cmdarray, envp, dir)</tt>,
+ * where <code>cmdarray</code> is an array of all the tokens in
+ * <code>command</code>.
+ *
+ * <p>More precisely, the <code>command</code> string is broken
+ * into tokens using a {@link StringTokenizer} created by the call
+ * <code>new {@link StringTokenizer}(command)</code> with no
+ * further modification of the character categories. The tokens
+ * produced by the tokenizer are then placed in the new string
+ * array <code>cmdarray</code>, in the same order.
+ *
+ * @param command a specified system command.
+ *
+ * @param envp array of strings, each element of which
+ * has environment variable settings in the format
+ * <i>name</i>=<i>value</i>, or
+ * <tt>null</tt> if the subprocess should inherit
+ * the environment of the current process.
+ *
+ * @param dir the working directory of the subprocess, or
+ * <tt>null</tt> if the subprocess should inherit
+ * the working directory of the current process.
+ *
+ * @return A new {@link Process} object for managing the subprocess
+ *
+ * @throws SecurityException
+ * If a security manager exists and its
+ * {@link SecurityManager#checkExec checkExec}
+ * method doesn't allow creation of the subprocess
+ *
+ * @throws IOException
+ * If an I/O error occurs
+ *
+ * @throws NullPointerException
+ * If <code>command</code> is <code>null</code>,
+ * or one of the elements of <code>envp</code> is <code>null</code>
+ *
+ * @throws IllegalArgumentException
+ * If <code>command</code> is empty
+ *
+ * @see ProcessBuilder
+ * @since 1.3
+ */
+ public Process exec(String command, String[] envp, File dir)
+ throws IOException {
+ if (command.length() == 0)
+ throw new IllegalArgumentException("Empty command");
+
+ StringTokenizer st = new StringTokenizer(command);
+ String[] cmdarray = new String[st.countTokens()];
+ for (int i = 0; st.hasMoreTokens(); i++)
+ cmdarray[i] = st.nextToken();
+ return exec(cmdarray, envp, dir);
+ }
+
+ /**
+ * Executes the specified command and arguments in a separate process.
+ *
+ * <p>This is a convenience method. An invocation of the form
+ * <tt>exec(cmdarray)</tt>
+ * behaves in exactly the same way as the invocation
+ * <tt>{@link #exec(String[], String[], File) exec}(cmdarray, null, null)</tt>.
+ *
+ * @param cmdarray array containing the command to call and
+ * its arguments.
+ *
+ * @return A new {@link Process} object for managing the subprocess
+ *
+ * @throws SecurityException
+ * If a security manager exists and its
+ * {@link SecurityManager#checkExec checkExec}
+ * method doesn't allow creation of the subprocess
+ *
+ * @throws IOException
+ * If an I/O error occurs
+ *
+ * @throws NullPointerException
+ * If <code>cmdarray</code> is <code>null</code>,
+ * or one of the elements of <code>cmdarray</code> is <code>null</code>
+ *
+ * @throws IndexOutOfBoundsException
+ * If <code>cmdarray</code> is an empty array
+ * (has length <code>0</code>)
+ *
+ * @see ProcessBuilder
+ */
+ public Process exec(String cmdarray[]) throws IOException {
+ return exec(cmdarray, null, null);
+ }
+
+ /**
+ * Executes the specified command and arguments in a separate process
+ * with the specified environment.
+ *
+ * <p>This is a convenience method. An invocation of the form
+ * <tt>exec(cmdarray, envp)</tt>
+ * behaves in exactly the same way as the invocation
+ * <tt>{@link #exec(String[], String[], File) exec}(cmdarray, envp, null)</tt>.
+ *
+ * @param cmdarray array containing the command to call and
+ * its arguments.
+ *
+ * @param envp array of strings, each element of which
+ * has environment variable settings in the format
+ * <i>name</i>=<i>value</i>, or
+ * <tt>null</tt> if the subprocess should inherit
+ * the environment of the current process.
+ *
+ * @return A new {@link Process} object for managing the subprocess
+ *
+ * @throws SecurityException
+ * If a security manager exists and its
+ * {@link SecurityManager#checkExec checkExec}
+ * method doesn't allow creation of the subprocess
+ *
+ * @throws IOException
+ * If an I/O error occurs
+ *
+ * @throws NullPointerException
+ * If <code>cmdarray</code> is <code>null</code>,
+ * or one of the elements of <code>cmdarray</code> is <code>null</code>,
+ * or one of the elements of <code>envp</code> is <code>null</code>
+ *
+ * @throws IndexOutOfBoundsException
+ * If <code>cmdarray</code> is an empty array
+ * (has length <code>0</code>)
+ *
+ * @see ProcessBuilder
+ */
+ public Process exec(String[] cmdarray, String[] envp) throws IOException {
+ return exec(cmdarray, envp, null);
+ }
+
+
+ /**
+ * Executes the specified command and arguments in a separate process with
+ * the specified environment and working directory.
+ *
+ * <p>Given an array of strings <code>cmdarray</code>, representing the
+ * tokens of a command line, and an array of strings <code>envp</code>,
+ * representing "environment" variable settings, this method creates
+ * a new process in which to execute the specified command.
+ *
+ * <p>This method checks that <code>cmdarray</code> is a valid operating
+ * system command. Which commands are valid is system-dependent,
+ * but at the very least the command must be a non-empty list of
+ * non-null strings.
+ *
+ * <p>If <tt>envp</tt> is <tt>null</tt>, the subprocess inherits the
+ * environment settings of the current process.
+ *
+ * <p>A minimal set of system dependent environment variables may
+ * be required to start a process on some operating systems.
+ * As a result, the subprocess may inherit additional environment variable
+ * settings beyond those in the specified environment.
+ *
+ * <p>{@link ProcessBuilder#start()} is now the preferred way to
+ * start a process with a modified environment.
+ *
+ * <p>The working directory of the new subprocess is specified by <tt>dir</tt>.
+ * If <tt>dir</tt> is <tt>null</tt>, the subprocess inherits the
+ * current working directory of the current process.
+ *
+ * <p>If a security manager exists, its
+ * {@link SecurityManager#checkExec checkExec}
+ * method is invoked with the first component of the array
+ * <code>cmdarray</code> as its argument. This may result in a
+ * {@link SecurityException} being thrown.
+ *
+ * <p>Starting an operating system process is highly system-dependent.
+ * Among the many things that can go wrong are:
+ * <ul>
+ * <li>The operating system program file was not found.
+ * <li>Access to the program file was denied.
+ * <li>The working directory does not exist.
+ * </ul>
+ *
+ * <p>In such cases an exception will be thrown. The exact nature
+ * of the exception is system-dependent, but it will always be a
+ * subclass of {@link IOException}.
+ *
+ *
+ * @param cmdarray array containing the command to call and
+ * its arguments.
+ *
+ * @param envp array of strings, each element of which
+ * has environment variable settings in the format
+ * <i>name</i>=<i>value</i>, or
+ * <tt>null</tt> if the subprocess should inherit
+ * the environment of the current process.
+ *
+ * @param dir the working directory of the subprocess, or
+ * <tt>null</tt> if the subprocess should inherit
+ * the working directory of the current process.
+ *
+ * @return A new {@link Process} object for managing the subprocess
+ *
+ * @throws SecurityException
+ * If a security manager exists and its
+ * {@link SecurityManager#checkExec checkExec}
+ * method doesn't allow creation of the subprocess
+ *
+ * @throws IOException
+ * If an I/O error occurs
+ *
+ * @throws NullPointerException
+ * If <code>cmdarray</code> is <code>null</code>,
+ * or one of the elements of <code>cmdarray</code> is <code>null</code>,
+ * or one of the elements of <code>envp</code> is <code>null</code>
+ *
+ * @throws IndexOutOfBoundsException
+ * If <code>cmdarray</code> is an empty array
+ * (has length <code>0</code>)
+ *
+ * @see ProcessBuilder
+ * @since 1.3
+ */
+ public Process exec(String[] cmdarray, String[] envp, File dir)
+ throws IOException {
+ return new ProcessBuilder(cmdarray)
+ .environment(envp)
+ .directory(dir)
+ .start();
+ }
+
+ /**
+ * Returns the number of processors available to the Java virtual machine.
+ *
+ * <p> This value may change during a particular invocation of the virtual
+ * machine. Applications that are sensitive to the number of available
+ * processors should therefore occasionally poll this property and adjust
+ * their resource usage appropriately. </p>
+ *
+ * @return the maximum number of processors available to the virtual
+ * machine; never smaller than one
+ * @since 1.4
+ */
+ public int availableProcessors() {
+ return (int) Libcore.os.sysconf(_SC_NPROCESSORS_CONF);
+ }
+
+ /**
+ * Returns the amount of free memory in the Java Virtual Machine.
+ * Calling the
+ * <code>gc</code> method may result in increasing the value returned
+ * by <code>freeMemory.</code>
+ *
+ * @return an approximation to the total amount of memory currently
+ * available for future allocated objects, measured in bytes.
+ */
+ @FastNative
+ public native long freeMemory();
+
+ /**
+ * Returns the total amount of memory in the Java virtual machine.
+ * The value returned by this method may vary over time, depending on
+ * the host environment.
+ * <p>
+ * Note that the amount of memory required to hold an object of any
+ * given type may be implementation-dependent.
+ *
+ * @return the total amount of memory currently available for current
+ * and future objects, measured in bytes.
+ */
+ @FastNative
+ public native long totalMemory();
+
+ /**
+ * Returns the maximum amount of memory that the Java virtual machine will
+ * attempt to use. If there is no inherent limit then the value {@link
+ * java.lang.Long#MAX_VALUE} will be returned.
+ *
+ * @return the maximum amount of memory that the virtual machine will
+ * attempt to use, measured in bytes
+ * @since 1.4
+ */
+ @FastNative
+ public native long maxMemory();
+
+ /**
+ * Runs the garbage collector.
+ * Calling this method suggests that the Java virtual machine expend
+ * effort toward recycling unused objects in order to make the memory
+ * they currently occupy available for quick reuse. When control
+ * returns from the method call, the virtual machine has made
+ * its best effort to recycle all discarded objects.
+ * <p>
+ * The name <code>gc</code> stands for "garbage
+ * collector". The virtual machine performs this recycling
+ * process automatically as needed, in a separate thread, even if the
+ * <code>gc</code> method is not invoked explicitly.
+ * <p>
+ * The method {@link System#gc()} is the conventional and convenient
+ * means of invoking this method.
+ */
+ // Android-changed: Added BlockGuard check to gc()
+ // public native void gc();
+ public void gc() {
+ BlockGuard.getThreadPolicy().onExplicitGc();
+ nativeGc();
+ }
+
+ private native void nativeGc();
+
+ /* Wormhole for calling java.lang.ref.Finalizer.runFinalization */
+ private static native void runFinalization0();
+
+ /**
+ * Runs the finalization methods of any objects pending finalization.
+ * Calling this method suggests that the Java virtual machine expend
+ * effort toward running the <code>finalize</code> methods of objects
+ * that have been found to be discarded but whose <code>finalize</code>
+ * methods have not yet been run. When control returns from the
+ * method call, the virtual machine has made a best effort to
+ * complete all outstanding finalizations.
+ * <p>
+ * The virtual machine performs the finalization process
+ * automatically as needed, in a separate thread, if the
+ * <code>runFinalization</code> method is not invoked explicitly.
+ * <p>
+ * The method {@link System#runFinalization()} is the conventional
+ * and convenient means of invoking this method.
+ *
+ * @see java.lang.Object#finalize()
+ */
+ public void runFinalization() {
+ VMRuntime.runFinalization(0);
+ }
+
+ /**
+ * Enables/Disables tracing of instructions.
+ * If the <code>boolean</code> argument is <code>true</code>, this
+ * method suggests that the Java virtual machine emit debugging
+ * information for each instruction in the virtual machine as it
+ * is executed. The format of this information, and the file or other
+ * output stream to which it is emitted, depends on the host environment.
+ * The virtual machine may ignore this request if it does not support
+ * this feature. The destination of the trace output is system
+ * dependent.
+ * <p>
+ * If the <code>boolean</code> argument is <code>false</code>, this
+ * method causes the virtual machine to stop performing the
+ * detailed instruction trace it is performing.
+ *
+ * @param on <code>true</code> to enable instruction tracing;
+ * <code>false</code> to disable this feature.
+ */
+ public void traceInstructions(boolean on) {
+ }
+
+ /**
+ * Enables/Disables tracing of method calls.
+ * If the <code>boolean</code> argument is <code>true</code>, this
+ * method suggests that the Java virtual machine emit debugging
+ * information for each method in the virtual machine as it is
+ * called. The format of this information, and the file or other output
+ * stream to which it is emitted, depends on the host environment. The
+ * virtual machine may ignore this request if it does not support
+ * this feature.
+ * <p>
+ * Calling this method with argument false suggests that the
+ * virtual machine cease emitting per-call debugging information.
+ * <p>
+ * Calling this method on Android Lollipop or later (API level >= 21)
+ * with {@code true} argument will cause it to throw an
+ * {@code UnsupportedOperationException}.
+ *
+ * @param on <code>true</code> to enable instruction tracing;
+ * <code>false</code> to disable this feature.
+ */
+ public void traceMethodCalls(boolean on) {
+ if (on != tracingMethods) {
+ if (on) {
+ VMDebug.startMethodTracing();
+ } else {
+ VMDebug.stopMethodTracing();
+ }
+ tracingMethods = on;
+ }
+ }
+
+ /**
+ * Loads the native library specified by the filename argument. The filename
+ * argument must be an absolute path name.
+ * (for example
+ * <code>Runtime.getRuntime().load("/home/avh/lib/libX11.so");</code>).
+ *
+ * If the filename argument, when stripped of any platform-specific library
+ * prefix, path, and file extension, indicates a library whose name is,
+ * for example, L, and a native library called L is statically linked
+ * with the VM, then the JNI_OnLoad_L function exported by the library
+ * is invoked rather than attempting to load a dynamic library.
+ * A filename matching the argument does not have to exist in the file
+ * system. See the JNI Specification for more details.
+ *
+ * Otherwise, the filename argument is mapped to a native library image in
+ * an implementation-dependent manner.
+ * <p>
+ * First, if there is a security manager, its <code>checkLink</code>
+ * method is called with the <code>filename</code> as its argument.
+ * This may result in a security exception.
+ * <p>
+ * This is similar to the method {@link #loadLibrary(String)}, but it
+ * accepts a general file name as an argument rather than just a library
+ * name, allowing any file of native code to be loaded.
+ * <p>
+ * The method {@link System#load(String)} is the conventional and
+ * convenient means of invoking this method.
+ *
+ * @param filename the file to load.
+ * @exception SecurityException if a security manager exists and its
+ * <code>checkLink</code> method doesn't allow
+ * loading of the specified dynamic library
+ * @exception UnsatisfiedLinkError if either the filename is not an
+ * absolute path name, the native library is not statically
+ * linked with the VM, or the library cannot be mapped to
+ * a native library image by the host system.
+ * @exception NullPointerException if <code>filename</code> is
+ * <code>null</code>
+ * @see java.lang.Runtime#getRuntime()
+ * @see java.lang.SecurityException
+ * @see java.lang.SecurityManager#checkLink(java.lang.String)
+ */
+ @CallerSensitive
+ public void load(String filename) {
+ load0(Reflection.getCallerClass(), filename);
+ }
+
+ /** Check target sdk, if it's higher than N, we throw an UnsupportedOperationException */
+ private void checkTargetSdkVersionForLoad(String methodName) {
+ final int targetSdkVersion = VMRuntime.getRuntime().getTargetSdkVersion();
+ if (targetSdkVersion > 24) {
+ throw new UnsupportedOperationException(methodName + " is not supported on SDK " +
+ targetSdkVersion);
+ }
+ }
+
+ // Fixes b/25859957 regression. Depending on private methods is bad, mkay.
+ void load(String absolutePath, ClassLoader loader) {
+ checkTargetSdkVersionForLoad("java.lang.Runtime#load(String, ClassLoader)");
+
+ java.lang.System.logE("java.lang.Runtime#load(String, ClassLoader)" +
+ " is private and will be removed in a future Android release");
+ if (absolutePath == null) {
+ throw new NullPointerException("absolutePath == null");
+ }
+ String error = nativeLoad(absolutePath, loader);
+ if (error != null) {
+ throw new UnsatisfiedLinkError(error);
+ }
+ }
+
+ synchronized void load0(Class<?> fromClass, String filename) {
+ if (!(new File(filename).isAbsolute())) {
+ throw new UnsatisfiedLinkError(
+ "Expecting an absolute path of the library: " + filename);
+ }
+ if (filename == null) {
+ throw new NullPointerException("filename == null");
+ }
+ String error = nativeLoad(filename, fromClass.getClassLoader());
+ if (error != null) {
+ throw new UnsatisfiedLinkError(error);
+ }
+ }
+
+ /**
+ * Loads the native library specified by the <code>libname</code>
+ * argument. The <code>libname</code> argument must not contain any platform
+ * specific prefix, file extension or path. If a native library
+ * called <code>libname</code> is statically linked with the VM, then the
+ * JNI_OnLoad_<code>libname</code> function exported by the library is invoked.
+ * See the JNI Specification for more details.
+ *
+ * Otherwise, the libname argument is loaded from a system library
+ * location and mapped to a native library image in an implementation-
+ * dependent manner.
+ * <p>
+ * First, if there is a security manager, its <code>checkLink</code>
+ * method is called with the <code>libname</code> as its argument.
+ * This may result in a security exception.
+ * <p>
+ * The method {@link System#loadLibrary(String)} is the conventional
+ * and convenient means of invoking this method. If native
+ * methods are to be used in the implementation of a class, a standard
+ * strategy is to put the native code in a library file (call it
+ * <code>LibFile</code>) and then to put a static initializer:
+ * <blockquote><pre>
+ * static { System.loadLibrary("LibFile"); }
+ * </pre></blockquote>
+ * within the class declaration. When the class is loaded and
+ * initialized, the necessary native code implementation for the native
+ * methods will then be loaded as well.
+ * <p>
+ * If this method is called more than once with the same library
+ * name, the second and subsequent calls are ignored.
+ *
+ * @param libname the name of the library.
+ * @exception SecurityException if a security manager exists and its
+ * <code>checkLink</code> method doesn't allow
+ * loading of the specified dynamic library
+ * @exception UnsatisfiedLinkError if either the libname argument
+ * contains a file path, the native library is not statically
+ * linked with the VM, or the library cannot be mapped to a
+ * native library image by the host system.
+ * @exception NullPointerException if <code>libname</code> is
+ * <code>null</code>
+ * @see java.lang.SecurityException
+ * @see java.lang.SecurityManager#checkLink(java.lang.String)
+ */
+ @CallerSensitive
+ public void loadLibrary(String libname) {
+ loadLibrary0(Reflection.getCallerClass(), libname);
+ }
+
+ // BEGIN Android-changed: Different implementation of loadLibrary0(Class, String).
+ /*
+ synchronized void loadLibrary0(Class<?> fromClass, String libname) {
+ SecurityManager security = System.getSecurityManager();
+ if (security != null) {
+ security.checkLink(libname);
+ }
+ if (libname.indexOf((int)File.separatorChar) != -1) {
+ throw new UnsatisfiedLinkError(
+ "Directory separator should not appear in library name: " + libname);
+ }
+ ClassLoader.loadLibrary(fromClass, libname, false);
+ }
+ */
+ void loadLibrary0(Class<?> fromClass, String libname) {
+ ClassLoader classLoader = ClassLoader.getClassLoader(fromClass);
+ loadLibrary0(classLoader, fromClass, libname);
+ }
+
+ /**
+ * Temporarily preserved for backward compatibility. Applications call this
+ * method using reflection.
+ *
+ * **** THIS METHOD WILL BE REMOVED IN A FUTURE ANDROID VERSION ****
+ *
+ * http://b/26217329
+ *
+ * @hide
+ */
+ public void loadLibrary(String libname, ClassLoader classLoader) {
+ checkTargetSdkVersionForLoad("java.lang.Runtime#loadLibrary(String, ClassLoader)");
+ java.lang.System.logE("java.lang.Runtime#loadLibrary(String, ClassLoader)" +
+ " is private and will be removed in a future Android release");
+ // Pass null for callerClass, we don't know it at this point. Passing null preserved
+ // the behavior when we used to not pass the class.
+ loadLibrary0(classLoader, null, libname);
+ }
+
+ // This overload exists for @UnsupportedAppUsage
+ void loadLibrary0(ClassLoader loader, String libname) {
+ // Pass null for callerClass, we don't know it at this point. Passing null preserved
+ // the behavior when we used to not pass the class.
+ loadLibrary0(loader, null, libname);
+ }
+
+ /**
+ * Loads the shared library {@code libname} in the context of {@code loader} and
+ * {@code callerClass}.
+ *
+ * @param loader the class loader that initiated the loading. Used by the
+ * underlying linker to determine linker namespace. A {@code null}
+ * value represents the boot class loader.
+ * @param fromClass the class that initiated the loading. Used when loader is
+ * {@code null} and ignored in all other cases. When used, it
+ * determines the linker namespace from the class's .dex location.
+ * {@code null} indicates the default namespace for the boot
+ * class loader.
+ * @param libname the name of the library.
+ */
+ private synchronized void loadLibrary0(ClassLoader loader, Class<?> callerClass, String libname) {
+ if (libname.indexOf((int)File.separatorChar) != -1) {
+ throw new UnsatisfiedLinkError(
+ "Directory separator should not appear in library name: " + libname);
+ }
+ String libraryName = libname;
+ // Android-note: BootClassLoader doesn't implement findLibrary(). http://b/111850480
+ // Android's class.getClassLoader() can return BootClassLoader where the RI would
+ // have returned null; therefore we treat BootClassLoader the same as null here.
+ if (loader != null && !(loader instanceof BootClassLoader)) {
+ String filename = loader.findLibrary(libraryName);
+ if (filename == null &&
+ (loader.getClass() == PathClassLoader.class ||
+ loader.getClass() == DelegateLastClassLoader.class)) {
+ // Don't give up even if we failed to find the library in the native lib paths.
+ // The underlying dynamic linker might be able to find the lib in one of the linker
+ // namespaces associated with the current linker namespace. In order to give the
+ // dynamic linker a chance, proceed to load the library with its soname, which
+ // is the fileName.
+ // Note that we do this only for PathClassLoader and DelegateLastClassLoader to
+ // minimize the scope of this behavioral change as much as possible, which might
+ // cause problem like b/143649498. These two class loaders are the only
+ // platform-provided class loaders that can load apps. See the classLoader attribute
+ // of the application tag in app manifest.
+ filename = System.mapLibraryName(libraryName);
+ }
+ if (filename == null) {
+ // It's not necessarily true that the ClassLoader used
+ // System.mapLibraryName, but the default setup does, and it's
+ // misleading to say we didn't find "libMyLibrary.so" when we
+ // actually searched for "liblibMyLibrary.so.so".
+ throw new UnsatisfiedLinkError(loader + " couldn't find \"" +
+ System.mapLibraryName(libraryName) + "\"");
+ }
+ String error = nativeLoad(filename, loader);
+ if (error != null) {
+ throw new UnsatisfiedLinkError(error);
+ }
+ return;
+ }
+
+ // We know some apps use mLibPaths directly, potentially assuming it's not null.
+ // Initialize it here to make sure apps see a non-null value.
+ getLibPaths();
+ String filename = System.mapLibraryName(libraryName);
+ String error = nativeLoad(filename, loader, callerClass);
+ if (error != null) {
+ throw new UnsatisfiedLinkError(error);
+ }
+ }
+
+ private volatile String[] mLibPaths = null;
+
+ private String[] getLibPaths() {
+ if (mLibPaths == null) {
+ synchronized(this) {
+ if (mLibPaths == null) {
+ mLibPaths = initLibPaths();
+ }
+ }
+ }
+ return mLibPaths;
+ }
+
+ private static String[] initLibPaths() {
+ String javaLibraryPath = System.getProperty("java.library.path");
+ if (javaLibraryPath == null) {
+ return EmptyArray.STRING;
+ }
+ String[] paths = javaLibraryPath.split(":");
+ // Add a '/' to the end of each directory so we don't have to do it every time.
+ for (int i = 0; i < paths.length; ++i) {
+ if (!paths[i].endsWith("/")) {
+ paths[i] += "/";
+ }
+ }
+ return paths;
+ }
+
+ private static String nativeLoad(String filename, ClassLoader loader) {
+ return nativeLoad(filename, loader, null);
+ }
+
+ private static native String nativeLoad(String filename, ClassLoader loader, Class<?> caller);
+ // END Android-changed: Different implementation of loadLibrary0(Class, String).
+
+ /**
+ * Creates a localized version of an input stream. This method takes
+ * an <code>InputStream</code> and returns an <code>InputStream</code>
+ * equivalent to the argument in all respects except that it is
+ * localized: as characters in the local character set are read from
+ * the stream, they are automatically converted from the local
+ * character set to Unicode.
+ * <p>
+ * If the argument is already a localized stream, it may be returned
+ * as the result.
+ *
+ * @param in InputStream to localize
+ * @return a localized input stream
+ * @see java.io.InputStream
+ * @see java.io.BufferedReader#BufferedReader(java.io.Reader)
+ * @see java.io.InputStreamReader#InputStreamReader(java.io.InputStream)
+ * @deprecated As of JDK 1.1, the preferred way to translate a byte
+ * stream in the local encoding into a character stream in Unicode is via
+ * the <code>InputStreamReader</code> and <code>BufferedReader</code>
+ * classes.
+ */
+ @Deprecated
+ public InputStream getLocalizedInputStream(InputStream in) {
+ return in;
+ }
+
+ /**
+ * Creates a localized version of an output stream. This method
+ * takes an <code>OutputStream</code> and returns an
+ * <code>OutputStream</code> equivalent to the argument in all respects
+ * except that it is localized: as Unicode characters are written to
+ * the stream, they are automatically converted to the local
+ * character set.
+ * <p>
+ * If the argument is already a localized stream, it may be returned
+ * as the result.
+ *
+ * @deprecated As of JDK 1.1, the preferred way to translate a
+ * Unicode character stream into a byte stream in the local encoding is via
+ * the <code>OutputStreamWriter</code>, <code>BufferedWriter</code>, and
+ * <code>PrintWriter</code> classes.
+ *
+ * @param out OutputStream to localize
+ * @return a localized output stream
+ * @see java.io.OutputStream
+ * @see java.io.BufferedWriter#BufferedWriter(java.io.Writer)
+ * @see java.io.OutputStreamWriter#OutputStreamWriter(java.io.OutputStream)
+ * @see java.io.PrintWriter#PrintWriter(java.io.OutputStream)
+ */
+ @Deprecated
+ public OutputStream getLocalizedOutputStream(OutputStream out) {
+ return out;
+ }
+
+}
diff --git a/java/lang/RuntimeException.java b/java/lang/RuntimeException.java
new file mode 100644
index 0000000..c9731e8
--- /dev/null
+++ b/java/lang/RuntimeException.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 1995, 2011, 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;
+
+/**
+ * {@code RuntimeException} is the superclass of those
+ * exceptions that can be thrown during the normal operation of the
+ * Java Virtual Machine.
+ *
+ * <p>{@code RuntimeException} and its subclasses are <em>unchecked
+ * exceptions</em>. Unchecked exceptions do <em>not</em> need to be
+ * declared in a method or constructor's {@code throws} clause if they
+ * can be thrown by the execution of the method or constructor and
+ * propagate outside the method or constructor boundary.
+ *
+ * @author Frank Yellin
+ * @jls 11.2 Compile-Time Checking of Exceptions
+ * @since JDK1.0
+ */
+public class RuntimeException extends Exception {
+ static final long serialVersionUID = -7034897190745766939L;
+
+ /** Constructs a new runtime exception with {@code null} as its
+ * detail message. The cause is not initialized, and may subsequently be
+ * initialized by a call to {@link #initCause}.
+ */
+ public RuntimeException() {
+ super();
+ }
+
+ /** Constructs a new runtime exception with the specified detail message.
+ * The cause is not initialized, and may subsequently be initialized by a
+ * call to {@link #initCause}.
+ *
+ * @param message the detail message. The detail message is saved for
+ * later retrieval by the {@link #getMessage()} method.
+ */
+ public RuntimeException(String message) {
+ super(message);
+ }
+
+ /**
+ * Constructs a new runtime exception with the specified detail message and
+ * cause. <p>Note that the detail message associated with
+ * {@code cause} is <i>not</i> automatically incorporated in
+ * this runtime exception's detail message.
+ *
+ * @param message the detail message (which is saved for later retrieval
+ * by the {@link #getMessage()} method).
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link #getCause()} method). (A <tt>null</tt> value is
+ * permitted, and indicates that the cause is nonexistent or
+ * unknown.)
+ * @since 1.4
+ */
+ public RuntimeException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /** Constructs a new runtime exception with the specified cause and a
+ * detail message of <tt>(cause==null ? null : cause.toString())</tt>
+ * (which typically contains the class and detail message of
+ * <tt>cause</tt>). This constructor is useful for runtime exceptions
+ * that are little more than wrappers for other throwables.
+ *
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link #getCause()} method). (A <tt>null</tt> value is
+ * permitted, and indicates that the cause is nonexistent or
+ * unknown.)
+ * @since 1.4
+ */
+ public RuntimeException(Throwable cause) {
+ super(cause);
+ }
+
+ /**
+ * Constructs a new runtime exception with the specified detail
+ * message, cause, suppression enabled or disabled, and writable
+ * stack trace enabled or disabled.
+ *
+ * @param message the detail message.
+ * @param cause the cause. (A {@code null} value is permitted,
+ * and indicates that the cause is nonexistent or unknown.)
+ * @param enableSuppression whether or not suppression is enabled
+ * or disabled
+ * @param writableStackTrace whether or not the stack trace should
+ * be writable
+ *
+ * @since 1.7
+ */
+ protected RuntimeException(String message, Throwable cause,
+ boolean enableSuppression,
+ boolean writableStackTrace) {
+ super(message, cause, enableSuppression, writableStackTrace);
+ }
+}
diff --git a/java/lang/RuntimePermission.java b/java/lang/RuntimePermission.java
new file mode 100644
index 0000000..2d05ba1
--- /dev/null
+++ b/java/lang/RuntimePermission.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 1997, 2013, 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;
+
+import java.security.*;
+
+// Android-changed: Stubbed the implementation. Android doesn't support SecurityManager.
+// See comments in java.lang.SecurityManager for details.
+/**
+ * Legacy security code; do not use.
+ */
+
+public final class RuntimePermission extends BasicPermission {
+
+ private static final long serialVersionUID = 7399184964622342223L;
+
+ public RuntimePermission(String name)
+ {
+ super(name);
+ }
+
+ public RuntimePermission(String name, String actions)
+ {
+ super(name, actions);
+ }
+}
diff --git a/java/lang/SafeVarargs.java b/java/lang/SafeVarargs.java
new file mode 100644
index 0000000..6fcd48e
--- /dev/null
+++ b/java/lang/SafeVarargs.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2010, 2013, 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;
+
+import java.lang.annotation.*;
+
+/**
+ * A programmer assertion that the body of the annotated method or
+ * constructor does not perform potentially unsafe operations on its
+ * varargs parameter. Applying this annotation to a method or
+ * constructor suppresses unchecked warnings about a
+ * <i>non-reifiable</i> variable arity (vararg) type and suppresses
+ * unchecked warnings about parameterized array creation at call
+ * sites.
+ *
+ * <p> In addition to the usage restrictions imposed by its {@link
+ * Target @Target} meta-annotation, compilers are required to implement
+ * additional usage restrictions on this annotation type; it is a
+ * compile-time error if a method or constructor declaration is
+ * annotated with a {@code @SafeVarargs} annotation, and either:
+ * <ul>
+ * <li> the declaration is a fixed arity method or constructor
+ *
+ * <li> the declaration is a variable arity method that is neither
+ * {@code static} nor {@code final}.
+ *
+ * </ul>
+ *
+ * <p> Compilers are encouraged to issue warnings when this annotation
+ * type is applied to a method or constructor declaration where:
+ *
+ * <ul>
+ *
+ * <li> The variable arity parameter has a reifiable element type,
+ * which includes primitive types, {@code Object}, and {@code String}.
+ * (The unchecked warnings this annotation type suppresses already do
+ * not occur for a reifiable element type.)
+ *
+ * <li> The body of the method or constructor declaration performs
+ * potentially unsafe operations, such as an assignment to an element
+ * of the variable arity parameter's array that generates an unchecked
+ * warning. Some unsafe operations do not trigger an unchecked
+ * warning. For example, the aliasing in
+ *
+ * <blockquote><pre>
+ * @SafeVarargs // Not actually safe!
+ * static void m(List<String>... stringLists) {
+ * Object[] array = stringLists;
+ * List<Integer> tmpList = Arrays.asList(42);
+ * array[0] = tmpList; // Semantically invalid, but compiles without warnings
+ * String s = stringLists[0].get(0); // Oh no, ClassCastException at runtime!
+ * }
+ * </pre></blockquote>
+ *
+ * leads to a {@code ClassCastException} at runtime.
+ *
+ * <p>Future versions of the platform may mandate compiler errors for
+ * such unsafe operations.
+ *
+ * </ul>
+ *
+ * @since 1.7
+ * @jls 4.7 Reifiable Types
+ * @jls 8.4.1 Formal Parameters
+ * @jls 9.6.3.7 @SafeVarargs
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.CONSTRUCTOR, ElementType.METHOD})
+public @interface SafeVarargs {}
diff --git a/java/lang/SecurityException.java b/java/lang/SecurityException.java
new file mode 100644
index 0000000..7e07178
--- /dev/null
+++ b/java/lang/SecurityException.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 1995, 2003, 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;
+
+/**
+ * Thrown by the security manager to indicate a security violation.
+ *
+ * @author unascribed
+ * @see java.lang.SecurityManager
+ * @since JDK1.0
+ */
+public class SecurityException extends RuntimeException {
+
+ private static final long serialVersionUID = 6878364983674394167L;
+
+ /**
+ * Constructs a <code>SecurityException</code> with no detail message.
+ */
+ public SecurityException() {
+ super();
+ }
+
+ /**
+ * Constructs a <code>SecurityException</code> with the specified
+ * detail message.
+ *
+ * @param s the detail message.
+ */
+ public SecurityException(String s) {
+ super(s);
+ }
+
+ /**
+ * Creates a <code>SecurityException</code> with the specified
+ * detail message and cause.
+ *
+ * @param message the detail message (which is saved for later retrieval
+ * by the {@link #getMessage()} method).
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link #getCause()} method). (A <tt>null</tt> value is permitted,
+ * and indicates that the cause is nonexistent or unknown.)
+ * @since 1.5
+ */
+ public SecurityException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * Creates a <code>SecurityException</code> with the specified cause
+ * and a detail message of <tt>(cause==null ? null : cause.toString())</tt>
+ * (which typically contains the class and detail message of
+ * <tt>cause</tt>).
+ *
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link #getCause()} method). (A <tt>null</tt> value is permitted,
+ * and indicates that the cause is nonexistent or unknown.)
+ * @since 1.5
+ */
+ public SecurityException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/java/lang/SecurityManager.java b/java/lang/SecurityManager.java
new file mode 100644
index 0000000..b7053e0
--- /dev/null
+++ b/java/lang/SecurityManager.java
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1995, 2006, 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;
+
+import java.security.*;
+import java.io.FileDescriptor;
+import java.net.InetAddress;
+
+// Android-changed: Stubbed the implementation. Android doesn't support SecurityManager.
+// SecurityManager can only check access by Java code, so it can be bypassed by using
+// native code. Applications should rely on Android permissions, process separation,
+// other other methods for security purposes.
+/**
+ * Legacy security code; do not use.
+ *
+ * <p>Security managers do <i>not</i> provide a secure environment for
+ * executing untrusted code and are unsupported on Android. Untrusted code
+ * cannot be safely isolated within a single VM on Android. Application
+ * developers can assume that there's no SecurityManager installed,
+ * i.e. {@link java.lang.System#getSecurityManager()} will return null.
+ */
+public
+class SecurityManager {
+
+ /**
+ * @deprecated Use {@link #checkPermission} instead.
+ */
+ @Deprecated
+ protected boolean inCheck;
+
+ /**
+ * @deprecated Use {@link #checkPermission} instead.
+ */
+ @Deprecated
+ public boolean getInCheck() {
+ return inCheck;
+ }
+
+ public SecurityManager() {
+
+ }
+
+ protected Class[] getClassContext() {
+ return null;
+ }
+
+ /**
+ * @deprecated Use {@link #checkPermission} instead.
+ */
+ @Deprecated
+ protected ClassLoader currentClassLoader()
+ {
+ return null;
+ }
+
+ /**
+ * @deprecated Use {@link #checkPermission} instead.
+ */
+ @Deprecated
+ protected Class<?> currentLoadedClass() {
+ return null;
+ }
+
+ /**
+ * @deprecated Use {@link #checkPermission} instead.
+ */
+ @Deprecated
+ protected int classDepth(String name) {
+ return -1;
+ }
+
+ /**
+ * @deprecated Use {@link #checkPermission} instead.
+ */
+ @Deprecated
+ protected int classLoaderDepth()
+ {
+ return -1;
+ }
+
+ /**
+ * @deprecated Use {@link #checkPermission} instead.
+ */
+ @Deprecated
+ protected boolean inClass(String name) {
+ return false;
+ }
+
+ /**
+ * @deprecated Use {@link #checkPermission} instead.
+ */
+ @Deprecated
+ protected boolean inClassLoader() {
+ return false;
+ }
+
+ public Object getSecurityContext() {
+ return null;
+ }
+
+ public void checkPermission(Permission perm) {
+
+ }
+
+ public void checkPermission(Permission perm, Object context) {
+
+ }
+
+ public void checkCreateClassLoader() {
+
+ }
+
+ public void checkAccess(Thread t) { }
+
+ public void checkAccess(ThreadGroup g) { }
+
+ public void checkExit(int status) { }
+
+ public void checkExec(String cmd) { }
+
+ public void checkLink(String lib) { }
+
+ public void checkRead(FileDescriptor fd) { }
+
+ public void checkRead(String file) { }
+
+ public void checkRead(String file, Object context) { }
+
+ public void checkWrite(FileDescriptor fd) { }
+
+ public void checkWrite(String file) { }
+
+ public void checkDelete(String file) { }
+
+ public void checkConnect(String host, int port) { }
+
+ public void checkConnect(String host, int port, Object context) { }
+
+ public void checkListen(int port) { }
+
+ public void checkAccept(String host, int port) { }
+
+ public void checkMulticast(InetAddress maddr) { }
+
+ /**
+ * @deprecated use {@link #checkMulticast(java.net.InetAddress)} instead.
+ */
+ @Deprecated
+ public void checkMulticast(InetAddress maddr, byte ttl) { }
+
+ public void checkPropertiesAccess() { }
+
+ public void checkPropertyAccess(String key) { }
+
+ public boolean checkTopLevelWindow(Object window) {
+ return true;
+ }
+
+ public void checkPrintJobAccess() { }
+
+ public void checkSystemClipboardAccess() { }
+
+ public void checkAwtEventQueueAccess() { }
+
+ public void checkPackageAccess(String pkg) { }
+
+ public void checkPackageDefinition(String pkg) { }
+
+ public void checkSetFactory() { }
+
+ public void checkMemberAccess(Class<?> clazz, int which) { }
+
+ public void checkSecurityAccess(String target) { }
+
+ /**
+ * Returns the current thread's thread group.
+ */
+ public ThreadGroup getThreadGroup() {
+ return Thread.currentThread().getThreadGroup();
+ }
+
+}
diff --git a/java/lang/Short.java b/java/lang/Short.java
new file mode 100644
index 0000000..9fb3913
--- /dev/null
+++ b/java/lang/Short.java
@@ -0,0 +1,537 @@
+/*
+ * Copyright (c) 1996, 2013, 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;
+
+/**
+ * The {@code Short} class wraps a value of primitive type {@code
+ * short} in an object. An object of type {@code Short} contains a
+ * single field whose type is {@code short}.
+ *
+ * <p>In addition, this class provides several methods for converting
+ * a {@code short} to a {@code String} and a {@code String} to a
+ * {@code short}, as well as other constants and methods useful when
+ * dealing with a {@code short}.
+ *
+ * @author Nakul Saraiya
+ * @author Joseph D. Darcy
+ * @see java.lang.Number
+ * @since JDK1.1
+ */
+public final class Short extends Number implements Comparable<Short> {
+
+ /**
+ * A constant holding the minimum value a {@code short} can
+ * have, -2<sup>15</sup>.
+ */
+ public static final short MIN_VALUE = -32768;
+
+ /**
+ * A constant holding the maximum value a {@code short} can
+ * have, 2<sup>15</sup>-1.
+ */
+ public static final short MAX_VALUE = 32767;
+
+ /**
+ * The {@code Class} instance representing the primitive type
+ * {@code short}.
+ */
+ @SuppressWarnings("unchecked")
+ public static final Class<Short> TYPE = (Class<Short>) Class.getPrimitiveClass("short");
+
+ /**
+ * Returns a new {@code String} object representing the
+ * specified {@code short}. The radix is assumed to be 10.
+ *
+ * @param s the {@code short} to be converted
+ * @return the string representation of the specified {@code short}
+ * @see java.lang.Integer#toString(int)
+ */
+ public static String toString(short s) {
+ return Integer.toString((int)s, 10);
+ }
+
+ /**
+ * Parses the string argument as a signed {@code short} in the
+ * radix specified by the second argument. The characters in the
+ * string must all be digits, of the specified radix (as
+ * determined by whether {@link java.lang.Character#digit(char,
+ * int)} returns a nonnegative value) except that the first
+ * character may be an ASCII minus sign {@code '-'}
+ * ({@code '\u005Cu002D'}) to indicate a negative value or an
+ * ASCII plus sign {@code '+'} ({@code '\u005Cu002B'}) to
+ * indicate a positive value. The resulting {@code short} value
+ * is returned.
+ *
+ * <p>An exception of type {@code NumberFormatException} is
+ * thrown if any of the following situations occurs:
+ * <ul>
+ * <li> The first argument is {@code null} or is a string of
+ * length zero.
+ *
+ * <li> The radix is either smaller than {@link
+ * java.lang.Character#MIN_RADIX} or larger than {@link
+ * java.lang.Character#MAX_RADIX}.
+ *
+ * <li> Any character of the string is not a digit of the
+ * specified radix, except that the first character may be a minus
+ * sign {@code '-'} ({@code '\u005Cu002D'}) or plus sign
+ * {@code '+'} ({@code '\u005Cu002B'}) provided that the
+ * string is longer than length 1.
+ *
+ * <li> The value represented by the string is not a value of type
+ * {@code short}.
+ * </ul>
+ *
+ * @param s the {@code String} containing the
+ * {@code short} representation to be parsed
+ * @param radix the radix to be used while parsing {@code s}
+ * @return the {@code short} represented by the string
+ * argument in the specified radix.
+ * @throws NumberFormatException If the {@code String}
+ * does not contain a parsable {@code short}.
+ */
+ public static short parseShort(String s, int radix)
+ throws NumberFormatException {
+ int i = Integer.parseInt(s, radix);
+ if (i < MIN_VALUE || i > MAX_VALUE)
+ throw new NumberFormatException(
+ "Value out of range. Value:\"" + s + "\" Radix:" + radix);
+ return (short)i;
+ }
+
+ /**
+ * Parses the string argument as a signed decimal {@code
+ * short}. The characters in the string must all be decimal
+ * digits, except that the first character may be an ASCII minus
+ * sign {@code '-'} ({@code '\u005Cu002D'}) to indicate a
+ * negative value or an ASCII plus sign {@code '+'}
+ * ({@code '\u005Cu002B'}) to indicate a positive value. The
+ * resulting {@code short} value is returned, exactly as if the
+ * argument and the radix 10 were given as arguments to the {@link
+ * #parseShort(java.lang.String, int)} method.
+ *
+ * @param s a {@code String} containing the {@code short}
+ * representation to be parsed
+ * @return the {@code short} value represented by the
+ * argument in decimal.
+ * @throws NumberFormatException If the string does not
+ * contain a parsable {@code short}.
+ */
+ public static short parseShort(String s) throws NumberFormatException {
+ return parseShort(s, 10);
+ }
+
+ /**
+ * Returns a {@code Short} object holding the value
+ * extracted from the specified {@code String} when parsed
+ * with the radix given by the second argument. The first argument
+ * is interpreted as representing a signed {@code short} in
+ * the radix specified by the second argument, exactly as if the
+ * argument were given to the {@link #parseShort(java.lang.String,
+ * int)} method. The result is a {@code Short} object that
+ * represents the {@code short} value specified by the string.
+ *
+ * <p>In other words, this method returns a {@code Short} object
+ * equal to the value of:
+ *
+ * <blockquote>
+ * {@code new Short(Short.parseShort(s, radix))}
+ * </blockquote>
+ *
+ * @param s the string to be parsed
+ * @param radix the radix to be used in interpreting {@code s}
+ * @return a {@code Short} object holding the value
+ * represented by the string argument in the
+ * specified radix.
+ * @throws NumberFormatException If the {@code String} does
+ * not contain a parsable {@code short}.
+ */
+ public static Short valueOf(String s, int radix)
+ throws NumberFormatException {
+ return valueOf(parseShort(s, radix));
+ }
+
+ /**
+ * Returns a {@code Short} object holding the
+ * value given by the specified {@code String}. The argument
+ * is interpreted as representing a signed decimal
+ * {@code short}, exactly as if the argument were given to
+ * the {@link #parseShort(java.lang.String)} method. The result is
+ * a {@code Short} object that represents the
+ * {@code short} value specified by the string.
+ *
+ * <p>In other words, this method returns a {@code Short} object
+ * equal to the value of:
+ *
+ * <blockquote>
+ * {@code new Short(Short.parseShort(s))}
+ * </blockquote>
+ *
+ * @param s the string to be parsed
+ * @return a {@code Short} object holding the value
+ * represented by the string argument
+ * @throws NumberFormatException If the {@code String} does
+ * not contain a parsable {@code short}.
+ */
+ public static Short valueOf(String s) throws NumberFormatException {
+ return valueOf(s, 10);
+ }
+
+ private static class ShortCache {
+ private ShortCache(){}
+
+ static final Short cache[] = new Short[-(-128) + 127 + 1];
+
+ static {
+ for(int i = 0; i < cache.length; i++)
+ cache[i] = new Short((short)(i - 128));
+ }
+ }
+
+ /**
+ * Returns a {@code Short} instance representing the specified
+ * {@code short} value.
+ * If a new {@code Short} instance is not required, this method
+ * should generally be used in preference to the constructor
+ * {@link #Short(short)}, as this method is likely to yield
+ * significantly better space and time performance by caching
+ * frequently requested values.
+ *
+ * This method will always cache values in the range -128 to 127,
+ * inclusive, and may cache other values outside of this range.
+ *
+ * @param s a short value.
+ * @return a {@code Short} instance representing {@code s}.
+ * @since 1.5
+ */
+ public static Short valueOf(short s) {
+ final int offset = 128;
+ int sAsInt = s;
+ if (sAsInt >= -128 && sAsInt <= 127) { // must cache
+ return ShortCache.cache[sAsInt + offset];
+ }
+ return new Short(s);
+ }
+
+ /**
+ * Decodes a {@code String} into a {@code Short}.
+ * Accepts decimal, hexadecimal, and octal numbers given by
+ * the following grammar:
+ *
+ * <blockquote>
+ * <dl>
+ * <dt><i>DecodableString:</i>
+ * <dd><i>Sign<sub>opt</sub> DecimalNumeral</i>
+ * <dd><i>Sign<sub>opt</sub></i> {@code 0x} <i>HexDigits</i>
+ * <dd><i>Sign<sub>opt</sub></i> {@code 0X} <i>HexDigits</i>
+ * <dd><i>Sign<sub>opt</sub></i> {@code #} <i>HexDigits</i>
+ * <dd><i>Sign<sub>opt</sub></i> {@code 0} <i>OctalDigits</i>
+ *
+ * <dt><i>Sign:</i>
+ * <dd>{@code -}
+ * <dd>{@code +}
+ * </dl>
+ * </blockquote>
+ *
+ * <i>DecimalNumeral</i>, <i>HexDigits</i>, and <i>OctalDigits</i>
+ * are as defined in section 3.10.1 of
+ * <cite>The Java™ Language Specification</cite>,
+ * except that underscores are not accepted between digits.
+ *
+ * <p>The sequence of characters following an optional
+ * sign and/or radix specifier ("{@code 0x}", "{@code 0X}",
+ * "{@code #}", or leading zero) is parsed as by the {@code
+ * Short.parseShort} method with the indicated radix (10, 16, or
+ * 8). This sequence of characters must represent a positive
+ * value or a {@link NumberFormatException} will be thrown. The
+ * result is negated if first character of the specified {@code
+ * String} is the minus sign. No whitespace characters are
+ * permitted in the {@code String}.
+ *
+ * @param nm the {@code String} to decode.
+ * @return a {@code Short} object holding the {@code short}
+ * value represented by {@code nm}
+ * @throws NumberFormatException if the {@code String} does not
+ * contain a parsable {@code short}.
+ * @see java.lang.Short#parseShort(java.lang.String, int)
+ */
+ public static Short decode(String nm) throws NumberFormatException {
+ int i = Integer.decode(nm);
+ if (i < MIN_VALUE || i > MAX_VALUE)
+ throw new NumberFormatException(
+ "Value " + i + " out of range from input " + nm);
+ return valueOf((short)i);
+ }
+
+ /**
+ * The value of the {@code Short}.
+ *
+ * @serial
+ */
+ private final short value;
+
+ /**
+ * Constructs a newly allocated {@code Short} object that
+ * represents the specified {@code short} value.
+ *
+ * @param value the value to be represented by the
+ * {@code Short}.
+ */
+ public Short(short value) {
+ this.value = value;
+ }
+
+ /**
+ * Constructs a newly allocated {@code Short} object that
+ * represents the {@code short} value indicated by the
+ * {@code String} parameter. The string is converted to a
+ * {@code short} value in exactly the manner used by the
+ * {@code parseShort} method for radix 10.
+ *
+ * @param s the {@code String} to be converted to a
+ * {@code Short}
+ * @throws NumberFormatException If the {@code String}
+ * does not contain a parsable {@code short}.
+ * @see java.lang.Short#parseShort(java.lang.String, int)
+ */
+ public Short(String s) throws NumberFormatException {
+ this.value = parseShort(s, 10);
+ }
+
+ /**
+ * Returns the value of this {@code Short} as a {@code byte} after
+ * a narrowing primitive conversion.
+ * @jls 5.1.3 Narrowing Primitive Conversions
+ */
+ public byte byteValue() {
+ return (byte)value;
+ }
+
+ /**
+ * Returns the value of this {@code Short} as a
+ * {@code short}.
+ */
+ public short shortValue() {
+ return value;
+ }
+
+ /**
+ * Returns the value of this {@code Short} as an {@code int} after
+ * a widening primitive conversion.
+ * @jls 5.1.2 Widening Primitive Conversions
+ */
+ public int intValue() {
+ return (int)value;
+ }
+
+ /**
+ * Returns the value of this {@code Short} as a {@code long} after
+ * a widening primitive conversion.
+ * @jls 5.1.2 Widening Primitive Conversions
+ */
+ public long longValue() {
+ return (long)value;
+ }
+
+ /**
+ * Returns the value of this {@code Short} as a {@code float}
+ * after a widening primitive conversion.
+ * @jls 5.1.2 Widening Primitive Conversions
+ */
+ public float floatValue() {
+ return (float)value;
+ }
+
+ /**
+ * Returns the value of this {@code Short} as a {@code double}
+ * after a widening primitive conversion.
+ * @jls 5.1.2 Widening Primitive Conversions
+ */
+ public double doubleValue() {
+ return (double)value;
+ }
+
+ /**
+ * Returns a {@code String} object representing this
+ * {@code Short}'s value. The value is converted to signed
+ * decimal representation and returned as a string, exactly as if
+ * the {@code short} value were given as an argument to the
+ * {@link java.lang.Short#toString(short)} method.
+ *
+ * @return a string representation of the value of this object in
+ * base 10.
+ */
+ public String toString() {
+ return Integer.toString((int)value);
+ }
+
+ /**
+ * Returns a hash code for this {@code Short}; equal to the result
+ * of invoking {@code intValue()}.
+ *
+ * @return a hash code value for this {@code Short}
+ */
+ @Override
+ public int hashCode() {
+ return Short.hashCode(value);
+ }
+
+ /**
+ * Returns a hash code for a {@code short} value; compatible with
+ * {@code Short.hashCode()}.
+ *
+ * @param value the value to hash
+ * @return a hash code value for a {@code short} value.
+ * @since 1.8
+ */
+ public static int hashCode(short value) {
+ return (int)value;
+ }
+
+ /**
+ * Compares this object to the specified object. The result is
+ * {@code true} if and only if the argument is not
+ * {@code null} and is a {@code Short} object that
+ * contains the same {@code short} value as this object.
+ *
+ * @param obj the object to compare with
+ * @return {@code true} if the objects are the same;
+ * {@code false} otherwise.
+ */
+ public boolean equals(Object obj) {
+ if (obj instanceof Short) {
+ return value == ((Short)obj).shortValue();
+ }
+ return false;
+ }
+
+ /**
+ * Compares two {@code Short} objects numerically.
+ *
+ * @param anotherShort the {@code Short} to be compared.
+ * @return the value {@code 0} if this {@code Short} is
+ * equal to the argument {@code Short}; a value less than
+ * {@code 0} if this {@code Short} is numerically less
+ * than the argument {@code Short}; and a value greater than
+ * {@code 0} if this {@code Short} is numerically
+ * greater than the argument {@code Short} (signed
+ * comparison).
+ * @since 1.2
+ */
+ public int compareTo(Short anotherShort) {
+ return compare(this.value, anotherShort.value);
+ }
+
+ /**
+ * Compares two {@code short} values numerically.
+ * The value returned is identical to what would be returned by:
+ * <pre>
+ * Short.valueOf(x).compareTo(Short.valueOf(y))
+ * </pre>
+ *
+ * @param x the first {@code short} to compare
+ * @param y the second {@code short} to compare
+ * @return the value {@code 0} if {@code x == y};
+ * a value less than {@code 0} if {@code x < y}; and
+ * a value greater than {@code 0} if {@code x > y}
+ * @since 1.7
+ */
+ public static int compare(short x, short y) {
+ return x - y;
+ }
+
+ /**
+ * The number of bits used to represent a {@code short} value in two's
+ * complement binary form.
+ * @since 1.5
+ */
+ public static final int SIZE = 16;
+
+ /**
+ * The number of bytes used to represent a {@code short} value in two's
+ * complement binary form.
+ *
+ * @since 1.8
+ */
+ public static final int BYTES = SIZE / Byte.SIZE;
+
+ /**
+ * Returns the value obtained by reversing the order of the bytes in the
+ * two's complement representation of the specified {@code short} value.
+ *
+ * @param i the value whose bytes are to be reversed
+ * @return the value obtained by reversing (or, equivalently, swapping)
+ * the bytes in the specified {@code short} value.
+ * @since 1.5
+ */
+ public static short reverseBytes(short i) {
+ return (short) (((i & 0xFF00) >> 8) | (i << 8));
+ }
+
+
+ /**
+ * Converts the argument to an {@code int} by an unsigned
+ * conversion. In an unsigned conversion to an {@code int}, the
+ * high-order 16 bits of the {@code int} are zero and the
+ * low-order 16 bits are equal to the bits of the {@code short} argument.
+ *
+ * Consequently, zero and positive {@code short} values are mapped
+ * to a numerically equal {@code int} value and negative {@code
+ * short} values are mapped to an {@code int} value equal to the
+ * input plus 2<sup>16</sup>.
+ *
+ * @param x the value to convert to an unsigned {@code int}
+ * @return the argument converted to {@code int} by an unsigned
+ * conversion
+ * @since 1.8
+ */
+ public static int toUnsignedInt(short x) {
+ return ((int) x) & 0xffff;
+ }
+
+ /**
+ * Converts the argument to a {@code long} by an unsigned
+ * conversion. In an unsigned conversion to a {@code long}, the
+ * high-order 48 bits of the {@code long} are zero and the
+ * low-order 16 bits are equal to the bits of the {@code short} argument.
+ *
+ * Consequently, zero and positive {@code short} values are mapped
+ * to a numerically equal {@code long} value and negative {@code
+ * short} values are mapped to a {@code long} value equal to the
+ * input plus 2<sup>16</sup>.
+ *
+ * @param x the value to convert to an unsigned {@code long}
+ * @return the argument converted to {@code long} by an unsigned
+ * conversion
+ * @since 1.8
+ */
+ public static long toUnsignedLong(short x) {
+ return ((long) x) & 0xffffL;
+ }
+
+ /** use serialVersionUID from JDK 1.1. for interoperability */
+ private static final long serialVersionUID = 7515723908773894738L;
+}
diff --git a/java/lang/StackOverflowError.java b/java/lang/StackOverflowError.java
new file mode 100644
index 0000000..73fd8c1
--- /dev/null
+++ b/java/lang/StackOverflowError.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 1994, 2008, 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;
+
+/**
+ * Thrown when a stack overflow occurs because an application
+ * recurses too deeply.
+ *
+ * @author unascribed
+ * @since JDK1.0
+ */
+public
+class StackOverflowError extends VirtualMachineError {
+ private static final long serialVersionUID = 8609175038441759607L;
+
+ /**
+ * Constructs a <code>StackOverflowError</code> with no detail message.
+ */
+ public StackOverflowError() {
+ super();
+ }
+
+ /**
+ * Constructs a <code>StackOverflowError</code> with the specified
+ * detail message.
+ *
+ * @param s the detail message.
+ */
+ public StackOverflowError(String s) {
+ super(s);
+ }
+}
diff --git a/java/lang/StackTraceElement.java b/java/lang/StackTraceElement.java
new file mode 100644
index 0000000..e3dad88
--- /dev/null
+++ b/java/lang/StackTraceElement.java
@@ -0,0 +1,252 @@
+/*
+ * Copyright (c) 2000, 2013, 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;
+
+import java.util.Objects;
+
+/**
+ * An element in a stack trace, as returned by {@link
+ * Throwable#getStackTrace()}. Each element represents a single stack frame.
+ * All stack frames except for the one at the top of the stack represent
+ * a method invocation. The frame at the top of the stack represents the
+ * execution point at which the stack trace was generated. Typically,
+ * this is the point at which the throwable corresponding to the stack trace
+ * was created.
+ *
+ * @since 1.4
+ * @author Josh Bloch
+ */
+public final class StackTraceElement implements java.io.Serializable {
+ // Normally initialized by VM (public constructor added in 1.5)
+ private String declaringClass;
+ private String methodName;
+ private String fileName;
+ private int lineNumber;
+
+ /**
+ * Creates a stack trace element representing the specified execution
+ * point.
+ *
+ * @param declaringClass the fully qualified name of the class containing
+ * the execution point represented by the stack trace element
+ * @param methodName the name of the method containing the execution point
+ * represented by the stack trace element
+ * @param fileName the name of the file containing the execution point
+ * represented by the stack trace element, or {@code null} if
+ * this information is unavailable
+ * @param lineNumber the line number of the source line containing the
+ * execution point represented by this stack trace element, or
+ * a negative number if this information is unavailable. A value
+ * of -2 indicates that the method containing the execution point
+ * is a native method
+ * @throws NullPointerException if {@code declaringClass} or
+ * {@code methodName} is null
+ * @since 1.5
+ */
+ public StackTraceElement(String declaringClass, String methodName,
+ String fileName, int lineNumber) {
+ this.declaringClass = Objects.requireNonNull(declaringClass, "Declaring class is null");
+ this.methodName = Objects.requireNonNull(methodName, "Method name is null");
+ this.fileName = fileName;
+ this.lineNumber = lineNumber;
+ }
+
+ /**
+ * Returns the name of the source file containing the execution point
+ * represented by this stack trace element. Generally, this corresponds
+ * to the {@code SourceFile} attribute of the relevant {@code class}
+ * file (as per <i>The Java Virtual Machine Specification</i>, Section
+ * 4.7.7). In some systems, the name may refer to some source code unit
+ * other than a file, such as an entry in source repository.
+ *
+ * @return the name of the file containing the execution point
+ * represented by this stack trace element, or {@code null} if
+ * this information is unavailable.
+ */
+ public String getFileName() {
+ return fileName;
+ }
+
+ /**
+ * Returns the line number of the source line containing the execution
+ * point represented by this stack trace element. Generally, this is
+ * derived from the {@code LineNumberTable} attribute of the relevant
+ * {@code class} file (as per <i>The Java Virtual Machine
+ * Specification</i>, Section 4.7.8).
+ *
+ * @return the line number of the source line containing the execution
+ * point represented by this stack trace element, or a negative
+ * number if this information is unavailable.
+ */
+ public int getLineNumber() {
+ return lineNumber;
+ }
+
+ /**
+ * Returns the fully qualified name of the class containing the
+ * execution point represented by this stack trace element.
+ *
+ * @return the fully qualified name of the {@code Class} containing
+ * the execution point represented by this stack trace element.
+ */
+ public String getClassName() {
+ return declaringClass;
+ }
+
+ /**
+ * Returns the name of the method containing the execution point
+ * represented by this stack trace element. If the execution point is
+ * contained in an instance or class initializer, this method will return
+ * the appropriate <i>special method name</i>, {@code <init>} or
+ * {@code <clinit>}, as per Section 3.9 of <i>The Java Virtual
+ * Machine Specification</i>.
+ *
+ * @return the name of the method containing the execution point
+ * represented by this stack trace element.
+ */
+ public String getMethodName() {
+ return methodName;
+ }
+
+ /**
+ * Returns true if the method containing the execution point
+ * represented by this stack trace element is a native method.
+ *
+ * @return {@code true} if the method containing the execution point
+ * represented by this stack trace element is a native method.
+ */
+ public boolean isNativeMethod() {
+ return lineNumber == -2;
+ }
+
+ /**
+ * Returns a string representation of this stack trace element. The
+ * format of this string depends on the implementation, but the following
+ * examples may be regarded as typical:
+ * <ul>
+ * <li>
+ * {@code "MyClass.mash(MyClass.java:9)"} - Here, {@code "MyClass"}
+ * is the <i>fully-qualified name</i> of the class containing the
+ * execution point represented by this stack trace element,
+ * {@code "mash"} is the name of the method containing the execution
+ * point, {@code "MyClass.java"} is the source file containing the
+ * execution point, and {@code "9"} is the line number of the source
+ * line containing the execution point.
+ * <li>
+ * {@code "MyClass.mash(MyClass.java)"} - As above, but the line
+ * number is unavailable.
+ * <li>
+ * {@code "MyClass.mash(Unknown Source)"} - As above, but neither
+ * the file name nor the line number are available.
+ * <li>
+ * {@code "MyClass.mash(Native Method)"} - As above, but neither
+ * the file name nor the line number are available, and the method
+ * containing the execution point is known to be a native method.
+ * </ul>
+ * @see Throwable#printStackTrace()
+ */
+ public String toString() {
+ // BEGIN Android-changed: Fall back Unknown Source:<dex_pc> for unknown lineNumber.
+ // http://b/30183883
+ // The only behavior change is that "Unknown Source" is followed by a number
+ // (the value of the dex program counter, dex_pc), which never occurs on the
+ // RI. This value isn't a line number, but can be useful for debugging and
+ // avoids the need to ship line number information along with the dex code to
+ // get an accurate stack trace.
+ // Formatting it in this way might be more digestible to automated tools that
+ // are not specifically written to expect this behavior.
+ /*
+ return getClassName() + "." + methodName +
+ (isNativeMethod() ? "(Native Method)" :
+ (fileName != null && lineNumber >= 0 ?
+ "(" + fileName + ":" + lineNumber + ")" :
+ (fileName != null ? "("+fileName+")" : "(Unknown Source)")));
+ */
+ StringBuilder result = new StringBuilder();
+ result.append(getClassName()).append(".").append(methodName);
+ if (isNativeMethod()) {
+ result.append("(Native Method)");
+ } else if (fileName != null) {
+ if (lineNumber >= 0) {
+ result.append("(").append(fileName).append(":").append(lineNumber).append(")");
+ } else {
+ result.append("(").append(fileName).append(")");
+ }
+ } else {
+ if (lineNumber >= 0) {
+ // The line number is actually the dex pc.
+ result.append("(Unknown Source:").append(lineNumber).append(")");
+ } else {
+ result.append("(Unknown Source)");
+ }
+ }
+ return result.toString();
+ // END Android-changed: Fall back Unknown Source:<dex_pc> for unknown lineNumber.
+ }
+
+ /**
+ * Returns true if the specified object is another
+ * {@code StackTraceElement} instance representing the same execution
+ * point as this instance. Two stack trace elements {@code a} and
+ * {@code b} are equal if and only if:
+ * <pre>{@code
+ * equals(a.getFileName(), b.getFileName()) &&
+ * a.getLineNumber() == b.getLineNumber()) &&
+ * equals(a.getClassName(), b.getClassName()) &&
+ * equals(a.getMethodName(), b.getMethodName())
+ * }</pre>
+ * where {@code equals} has the semantics of {@link
+ * java.util.Objects#equals(Object, Object) Objects.equals}.
+ *
+ * @param obj the object to be compared with this stack trace element.
+ * @return true if the specified object is another
+ * {@code StackTraceElement} instance representing the same
+ * execution point as this instance.
+ */
+ public boolean equals(Object obj) {
+ if (obj==this)
+ return true;
+ if (!(obj instanceof StackTraceElement))
+ return false;
+ StackTraceElement e = (StackTraceElement)obj;
+ return e.declaringClass.equals(declaringClass) &&
+ e.lineNumber == lineNumber &&
+ Objects.equals(methodName, e.methodName) &&
+ Objects.equals(fileName, e.fileName);
+ }
+
+ /**
+ * Returns a hash code value for this stack trace element.
+ */
+ public int hashCode() {
+ int result = 31*declaringClass.hashCode() + methodName.hashCode();
+ result = 31*result + Objects.hashCode(fileName);
+ result = 31*result + lineNumber;
+ return result;
+ }
+
+ private static final long serialVersionUID = 6992337162326171013L;
+}
diff --git a/java/lang/StrictMath.java b/java/lang/StrictMath.java
new file mode 100644
index 0000000..ae4af2b
--- /dev/null
+++ b/java/lang/StrictMath.java
@@ -0,0 +1,1710 @@
+/*
+ * Copyright (c) 1999, 2013, 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;
+import java.util.Random;
+import sun.misc.DoubleConsts;
+
+/**
+ * The class {@code StrictMath} contains methods for performing basic
+ * numeric operations such as the elementary exponential, logarithm,
+ * square root, and trigonometric functions.
+ *
+ * <p>To help ensure portability of Java programs, the definitions of
+ * some of the numeric functions in this package require that they
+ * produce the same results as certain published algorithms. These
+ * algorithms are available from the well-known network library
+ * {@code netlib} as the package "Freely Distributable Math
+ * Library," <a
+ * href="ftp://ftp.netlib.org/fdlibm.tar">{@code fdlibm}</a>. These
+ * algorithms, which are written in the C programming language, are
+ * then to be understood as executed with all floating-point
+ * operations following the rules of Java floating-point arithmetic.
+ *
+ * <p>The Java math library is defined with respect to
+ * {@code fdlibm} version 5.3. Where {@code fdlibm} provides
+ * more than one definition for a function (such as
+ * {@code acos}), use the "IEEE 754 core function" version
+ * (residing in a file whose name begins with the letter
+ * {@code e}). The methods which require {@code fdlibm}
+ * semantics are {@code sin}, {@code cos}, {@code tan},
+ * {@code asin}, {@code acos}, {@code atan},
+ * {@code exp}, {@code log}, {@code log10},
+ * {@code cbrt}, {@code atan2}, {@code pow},
+ * {@code sinh}, {@code cosh}, {@code tanh},
+ * {@code hypot}, {@code expm1}, and {@code log1p}.
+ *
+ * <p>
+ * The platform uses signed two's complement integer arithmetic with
+ * int and long primitive types. The developer should choose
+ * the primitive type to ensure that arithmetic operations consistently
+ * produce correct results, which in some cases means the operations
+ * will not overflow the range of values of the computation.
+ * The best practice is to choose the primitive type and algorithm to avoid
+ * overflow. In cases where the size is {@code int} or {@code long} and
+ * overflow errors need to be detected, the methods {@code addExact},
+ * {@code subtractExact}, {@code multiplyExact}, and {@code toIntExact}
+ * throw an {@code ArithmeticException} when the results overflow.
+ * For other arithmetic operations such as divide, absolute value,
+ * increment, decrement, and negation overflow occurs only with
+ * a specific minimum or maximum value and should be checked against
+ * the minimum or maximum as appropriate.
+ *
+ * @author unascribed
+ * @author Joseph D. Darcy
+ * @since 1.3
+ */
+
+public final class StrictMath {
+
+ /**
+ * Don't let anyone instantiate this class.
+ */
+ private StrictMath() {}
+
+ /**
+ * The {@code double} value that is closer than any other to
+ * <i>e</i>, the base of the natural logarithms.
+ */
+ public static final double E = 2.7182818284590452354;
+
+ /**
+ * The {@code double} value that is closer than any other to
+ * <i>pi</i>, the ratio of the circumference of a circle to its
+ * diameter.
+ */
+ public static final double PI = 3.14159265358979323846;
+
+ /**
+ * Returns the trigonometric sine of an angle. Special cases:
+ * <ul><li>If the argument is NaN or an infinity, then the
+ * result is NaN.
+ * <li>If the argument is zero, then the result is a zero with the
+ * same sign as the argument.</ul>
+ *
+ * @param a an angle, in radians.
+ * @return the sine of the argument.
+ */
+ public static native double sin(double a);
+
+ /**
+ * Returns the trigonometric cosine of an angle. Special cases:
+ * <ul><li>If the argument is NaN or an infinity, then the
+ * result is NaN.</ul>
+ *
+ * @param a an angle, in radians.
+ * @return the cosine of the argument.
+ */
+ public static native double cos(double a);
+
+ /**
+ * Returns the trigonometric tangent of an angle. Special cases:
+ * <ul><li>If the argument is NaN or an infinity, then the result
+ * is NaN.
+ * <li>If the argument is zero, then the result is a zero with the
+ * same sign as the argument.</ul>
+ *
+ * @param a an angle, in radians.
+ * @return the tangent of the argument.
+ */
+ public static native double tan(double a);
+
+ /**
+ * Returns the arc sine of a value; the returned angle is in the
+ * range -<i>pi</i>/2 through <i>pi</i>/2. Special cases:
+ * <ul><li>If the argument is NaN or its absolute value is greater
+ * than 1, then the result is NaN.
+ * <li>If the argument is zero, then the result is a zero with the
+ * same sign as the argument.</ul>
+ *
+ * @param a the value whose arc sine is to be returned.
+ * @return the arc sine of the argument.
+ */
+ public static native double asin(double a);
+
+ /**
+ * Returns the arc cosine of a value; the returned angle is in the
+ * range 0.0 through <i>pi</i>. Special case:
+ * <ul><li>If the argument is NaN or its absolute value is greater
+ * than 1, then the result is NaN.</ul>
+ *
+ * @param a the value whose arc cosine is to be returned.
+ * @return the arc cosine of the argument.
+ */
+ public static native double acos(double a);
+
+ /**
+ * Returns the arc tangent of a value; the returned angle is in the
+ * range -<i>pi</i>/2 through <i>pi</i>/2. Special cases:
+ * <ul><li>If the argument is NaN, then the result is NaN.
+ * <li>If the argument is zero, then the result is a zero with the
+ * same sign as the argument.</ul>
+ *
+ * @param a the value whose arc tangent is to be returned.
+ * @return the arc tangent of the argument.
+ */
+ public static native double atan(double a);
+
+ /**
+ * Converts an angle measured in degrees to an approximately
+ * equivalent angle measured in radians. The conversion from
+ * degrees to radians is generally inexact.
+ *
+ * @param angdeg an angle, in degrees
+ * @return the measurement of the angle {@code angdeg}
+ * in radians.
+ */
+ public static strictfp double toRadians(double angdeg) {
+ // Do not delegate to Math.toRadians(angdeg) because
+ // this method has the strictfp modifier.
+ return angdeg / 180.0 * PI;
+ }
+
+ /**
+ * Converts an angle measured in radians to an approximately
+ * equivalent angle measured in degrees. The conversion from
+ * radians to degrees is generally inexact; users should
+ * <i>not</i> expect {@code cos(toRadians(90.0))} to exactly
+ * equal {@code 0.0}.
+ *
+ * @param angrad an angle, in radians
+ * @return the measurement of the angle {@code angrad}
+ * in degrees.
+ */
+ public static strictfp double toDegrees(double angrad) {
+ // Do not delegate to Math.toDegrees(angrad) because
+ // this method has the strictfp modifier.
+ return angrad * 180.0 / PI;
+ }
+
+ /**
+ * Returns Euler's number <i>e</i> raised to the power of a
+ * {@code double} value. Special cases:
+ * <ul><li>If the argument is NaN, the result is NaN.
+ * <li>If the argument is positive infinity, then the result is
+ * positive infinity.
+ * <li>If the argument is negative infinity, then the result is
+ * positive zero.</ul>
+ *
+ * @param a the exponent to raise <i>e</i> to.
+ * @return the value <i>e</i><sup>{@code a}</sup>,
+ * where <i>e</i> is the base of the natural logarithms.
+ */
+ public static native double exp(double a);
+
+ /**
+ * Returns the natural logarithm (base <i>e</i>) of a {@code double}
+ * value. Special cases:
+ * <ul><li>If the argument is NaN or less than zero, then the result
+ * is NaN.
+ * <li>If the argument is positive infinity, then the result is
+ * positive infinity.
+ * <li>If the argument is positive zero or negative zero, then the
+ * result is negative infinity.</ul>
+ *
+ * @param a a value
+ * @return the value ln {@code a}, the natural logarithm of
+ * {@code a}.
+ */
+ public static native double log(double a);
+
+
+ /**
+ * Returns the base 10 logarithm of a {@code double} value.
+ * Special cases:
+ *
+ * <ul><li>If the argument is NaN or less than zero, then the result
+ * is NaN.
+ * <li>If the argument is positive infinity, then the result is
+ * positive infinity.
+ * <li>If the argument is positive zero or negative zero, then the
+ * result is negative infinity.
+ * <li> If the argument is equal to 10<sup><i>n</i></sup> for
+ * integer <i>n</i>, then the result is <i>n</i>.
+ * </ul>
+ *
+ * @param a a value
+ * @return the base 10 logarithm of {@code a}.
+ * @since 1.5
+ */
+ public static native double log10(double a);
+
+ /**
+ * Returns the correctly rounded positive square root of a
+ * {@code double} value.
+ * Special cases:
+ * <ul><li>If the argument is NaN or less than zero, then the result
+ * is NaN.
+ * <li>If the argument is positive infinity, then the result is positive
+ * infinity.
+ * <li>If the argument is positive zero or negative zero, then the
+ * result is the same as the argument.</ul>
+ * Otherwise, the result is the {@code double} value closest to
+ * the true mathematical square root of the argument value.
+ *
+ * @param a a value.
+ * @return the positive square root of {@code a}.
+ */
+ public static native double sqrt(double a);
+
+ /**
+ * Returns the cube root of a {@code double} value. For
+ * positive finite {@code x}, {@code cbrt(-x) ==
+ * -cbrt(x)}; that is, the cube root of a negative value is
+ * the negative of the cube root of that value's magnitude.
+ * Special cases:
+ *
+ * <ul>
+ *
+ * <li>If the argument is NaN, then the result is NaN.
+ *
+ * <li>If the argument is infinite, then the result is an infinity
+ * with the same sign as the argument.
+ *
+ * <li>If the argument is zero, then the result is a zero with the
+ * same sign as the argument.
+ *
+ * </ul>
+ *
+ * @param a a value.
+ * @return the cube root of {@code a}.
+ * @since 1.5
+ */
+ public static native double cbrt(double a);
+
+ /**
+ * Computes the remainder operation on two arguments as prescribed
+ * by the IEEE 754 standard.
+ * The remainder value is mathematically equal to
+ * <code>f1 - f2</code> × <i>n</i>,
+ * where <i>n</i> is the mathematical integer closest to the exact
+ * mathematical value of the quotient {@code f1/f2}, and if two
+ * mathematical integers are equally close to {@code f1/f2},
+ * then <i>n</i> is the integer that is even. If the remainder is
+ * zero, its sign is the same as the sign of the first argument.
+ * Special cases:
+ * <ul><li>If either argument is NaN, or the first argument is infinite,
+ * or the second argument is positive zero or negative zero, then the
+ * result is NaN.
+ * <li>If the first argument is finite and the second argument is
+ * infinite, then the result is the same as the first argument.</ul>
+ *
+ * @param f1 the dividend.
+ * @param f2 the divisor.
+ * @return the remainder when {@code f1} is divided by
+ * {@code f2}.
+ */
+ public static native double IEEEremainder(double f1, double f2);
+
+ /**
+ * Returns the smallest (closest to negative infinity)
+ * {@code double} value that is greater than or equal to the
+ * argument and is equal to a mathematical integer. Special cases:
+ * <ul><li>If the argument value is already equal to a
+ * mathematical integer, then the result is the same as the
+ * argument. <li>If the argument is NaN or an infinity or
+ * positive zero or negative zero, then the result is the same as
+ * the argument. <li>If the argument value is less than zero but
+ * greater than -1.0, then the result is negative zero.</ul> Note
+ * that the value of {@code StrictMath.ceil(x)} is exactly the
+ * value of {@code -StrictMath.floor(-x)}.
+ *
+ * @param a a value.
+ * @return the smallest (closest to negative infinity)
+ * floating-point value that is greater than or equal to
+ * the argument and is equal to a mathematical integer.
+ */
+ public static double ceil(double a) {
+ return floorOrCeil(a, -0.0, 1.0, 1.0);
+ }
+
+ /**
+ * Returns the largest (closest to positive infinity)
+ * {@code double} value that is less than or equal to the
+ * argument and is equal to a mathematical integer. Special cases:
+ * <ul><li>If the argument value is already equal to a
+ * mathematical integer, then the result is the same as the
+ * argument. <li>If the argument is NaN or an infinity or
+ * positive zero or negative zero, then the result is the same as
+ * the argument.</ul>
+ *
+ * @param a a value.
+ * @return the largest (closest to positive infinity)
+ * floating-point value that less than or equal to the argument
+ * and is equal to a mathematical integer.
+ */
+ public static double floor(double a) {
+ return floorOrCeil(a, -1.0, 0.0, -1.0);
+ }
+
+ /**
+ * Internal method to share logic between floor and ceil.
+ *
+ * @param a the value to be floored or ceiled
+ * @param negativeBoundary result for values in (-1, 0)
+ * @param positiveBoundary result for values in (0, 1)
+ * @param increment value to add when the argument is non-integral
+ */
+ private static double floorOrCeil(double a,
+ double negativeBoundary,
+ double positiveBoundary,
+ double sign) {
+ int exponent = Math.getExponent(a);
+
+ if (exponent < 0) {
+ /*
+ * Absolute value of argument is less than 1.
+ * floorOrceil(-0.0) => -0.0
+ * floorOrceil(+0.0) => +0.0
+ */
+ return ((a == 0.0) ? a :
+ ( (a < 0.0) ? negativeBoundary : positiveBoundary) );
+ } else if (exponent >= 52) {
+ /*
+ * Infinity, NaN, or a value so large it must be integral.
+ */
+ return a;
+ }
+ // Else the argument is either an integral value already XOR it
+ // has to be rounded to one.
+ assert exponent >= 0 && exponent <= 51;
+
+ long doppel = Double.doubleToRawLongBits(a);
+ long mask = DoubleConsts.SIGNIF_BIT_MASK >> exponent;
+
+ if ( (mask & doppel) == 0L )
+ return a; // integral value
+ else {
+ double result = Double.longBitsToDouble(doppel & (~mask));
+ if (sign*a > 0.0)
+ result = result + sign;
+ return result;
+ }
+ }
+
+ /**
+ * Returns the {@code double} value that is closest in value
+ * to the argument and is equal to a mathematical integer. If two
+ * {@code double} values that are mathematical integers are
+ * equally close to the value of the argument, the result is the
+ * integer value that is even. Special cases:
+ * <ul><li>If the argument value is already equal to a mathematical
+ * integer, then the result is the same as the argument.
+ * <li>If the argument is NaN or an infinity or positive zero or negative
+ * zero, then the result is the same as the argument.</ul>
+ *
+ * @param a a value.
+ * @return the closest floating-point value to {@code a} that is
+ * equal to a mathematical integer.
+ * @author Joseph D. Darcy
+ */
+ public static double rint(double a) {
+ /*
+ * If the absolute value of a is not less than 2^52, it
+ * is either a finite integer (the double format does not have
+ * enough significand bits for a number that large to have any
+ * fractional portion), an infinity, or a NaN. In any of
+ * these cases, rint of the argument is the argument.
+ *
+ * Otherwise, the sum (twoToThe52 + a ) will properly round
+ * away any fractional portion of a since ulp(twoToThe52) ==
+ * 1.0; subtracting out twoToThe52 from this sum will then be
+ * exact and leave the rounded integer portion of a.
+ *
+ * This method does *not* need to be declared strictfp to get
+ * fully reproducible results. Whether or not a method is
+ * declared strictfp can only make a difference in the
+ * returned result if some operation would overflow or
+ * underflow with strictfp semantics. The operation
+ * (twoToThe52 + a ) cannot overflow since large values of a
+ * are screened out; the add cannot underflow since twoToThe52
+ * is too large. The subtraction ((twoToThe52 + a ) -
+ * twoToThe52) will be exact as discussed above and thus
+ * cannot overflow or meaningfully underflow. Finally, the
+ * last multiply in the return statement is by plus or minus
+ * 1.0, which is exact too.
+ */
+ double twoToThe52 = (double)(1L << 52); // 2^52
+ double sign = Math.copySign(1.0, a); // preserve sign info
+ a = Math.abs(a);
+
+ if (a < twoToThe52) { // E_min <= ilogb(a) <= 51
+ a = ((twoToThe52 + a ) - twoToThe52);
+ }
+
+ return sign * a; // restore original sign
+ }
+
+ /**
+ * Returns the angle <i>theta</i> from the conversion of rectangular
+ * coordinates ({@code x}, {@code y}) to polar
+ * coordinates (r, <i>theta</i>).
+ * This method computes the phase <i>theta</i> by computing an arc tangent
+ * of {@code y/x} in the range of -<i>pi</i> to <i>pi</i>. Special
+ * cases:
+ * <ul><li>If either argument is NaN, then the result is NaN.
+ * <li>If the first argument is positive zero and the second argument
+ * is positive, or the first argument is positive and finite and the
+ * second argument is positive infinity, then the result is positive
+ * zero.
+ * <li>If the first argument is negative zero and the second argument
+ * is positive, or the first argument is negative and finite and the
+ * second argument is positive infinity, then the result is negative zero.
+ * <li>If the first argument is positive zero and the second argument
+ * is negative, or the first argument is positive and finite and the
+ * second argument is negative infinity, then the result is the
+ * {@code double} value closest to <i>pi</i>.
+ * <li>If the first argument is negative zero and the second argument
+ * is negative, or the first argument is negative and finite and the
+ * second argument is negative infinity, then the result is the
+ * {@code double} value closest to -<i>pi</i>.
+ * <li>If the first argument is positive and the second argument is
+ * positive zero or negative zero, or the first argument is positive
+ * infinity and the second argument is finite, then the result is the
+ * {@code double} value closest to <i>pi</i>/2.
+ * <li>If the first argument is negative and the second argument is
+ * positive zero or negative zero, or the first argument is negative
+ * infinity and the second argument is finite, then the result is the
+ * {@code double} value closest to -<i>pi</i>/2.
+ * <li>If both arguments are positive infinity, then the result is the
+ * {@code double} value closest to <i>pi</i>/4.
+ * <li>If the first argument is positive infinity and the second argument
+ * is negative infinity, then the result is the {@code double}
+ * value closest to 3*<i>pi</i>/4.
+ * <li>If the first argument is negative infinity and the second argument
+ * is positive infinity, then the result is the {@code double} value
+ * closest to -<i>pi</i>/4.
+ * <li>If both arguments are negative infinity, then the result is the
+ * {@code double} value closest to -3*<i>pi</i>/4.</ul>
+ *
+ * @param y the ordinate coordinate
+ * @param x the abscissa coordinate
+ * @return the <i>theta</i> component of the point
+ * (<i>r</i>, <i>theta</i>)
+ * in polar coordinates that corresponds to the point
+ * (<i>x</i>, <i>y</i>) in Cartesian coordinates.
+ */
+ public static native double atan2(double y, double x);
+
+
+ /**
+ * Returns the value of the first argument raised to the power of the
+ * second argument. Special cases:
+ *
+ * <ul><li>If the second argument is positive or negative zero, then the
+ * result is 1.0.
+ * <li>If the second argument is 1.0, then the result is the same as the
+ * first argument.
+ * <li>If the second argument is NaN, then the result is NaN.
+ * <li>If the first argument is NaN and the second argument is nonzero,
+ * then the result is NaN.
+ *
+ * <li>If
+ * <ul>
+ * <li>the absolute value of the first argument is greater than 1
+ * and the second argument is positive infinity, or
+ * <li>the absolute value of the first argument is less than 1 and
+ * the second argument is negative infinity,
+ * </ul>
+ * then the result is positive infinity.
+ *
+ * <li>If
+ * <ul>
+ * <li>the absolute value of the first argument is greater than 1 and
+ * the second argument is negative infinity, or
+ * <li>the absolute value of the
+ * first argument is less than 1 and the second argument is positive
+ * infinity,
+ * </ul>
+ * then the result is positive zero.
+ *
+ * <li>If the absolute value of the first argument equals 1 and the
+ * second argument is infinite, then the result is NaN.
+ *
+ * <li>If
+ * <ul>
+ * <li>the first argument is positive zero and the second argument
+ * is greater than zero, or
+ * <li>the first argument is positive infinity and the second
+ * argument is less than zero,
+ * </ul>
+ * then the result is positive zero.
+ *
+ * <li>If
+ * <ul>
+ * <li>the first argument is positive zero and the second argument
+ * is less than zero, or
+ * <li>the first argument is positive infinity and the second
+ * argument is greater than zero,
+ * </ul>
+ * then the result is positive infinity.
+ *
+ * <li>If
+ * <ul>
+ * <li>the first argument is negative zero and the second argument
+ * is greater than zero but not a finite odd integer, or
+ * <li>the first argument is negative infinity and the second
+ * argument is less than zero but not a finite odd integer,
+ * </ul>
+ * then the result is positive zero.
+ *
+ * <li>If
+ * <ul>
+ * <li>the first argument is negative zero and the second argument
+ * is a positive finite odd integer, or
+ * <li>the first argument is negative infinity and the second
+ * argument is a negative finite odd integer,
+ * </ul>
+ * then the result is negative zero.
+ *
+ * <li>If
+ * <ul>
+ * <li>the first argument is negative zero and the second argument
+ * is less than zero but not a finite odd integer, or
+ * <li>the first argument is negative infinity and the second
+ * argument is greater than zero but not a finite odd integer,
+ * </ul>
+ * then the result is positive infinity.
+ *
+ * <li>If
+ * <ul>
+ * <li>the first argument is negative zero and the second argument
+ * is a negative finite odd integer, or
+ * <li>the first argument is negative infinity and the second
+ * argument is a positive finite odd integer,
+ * </ul>
+ * then the result is negative infinity.
+ *
+ * <li>If the first argument is finite and less than zero
+ * <ul>
+ * <li> if the second argument is a finite even integer, the
+ * result is equal to the result of raising the absolute value of
+ * the first argument to the power of the second argument
+ *
+ * <li>if the second argument is a finite odd integer, the result
+ * is equal to the negative of the result of raising the absolute
+ * value of the first argument to the power of the second
+ * argument
+ *
+ * <li>if the second argument is finite and not an integer, then
+ * the result is NaN.
+ * </ul>
+ *
+ * <li>If both arguments are integers, then the result is exactly equal
+ * to the mathematical result of raising the first argument to the power
+ * of the second argument if that result can in fact be represented
+ * exactly as a {@code double} value.</ul>
+ *
+ * <p>(In the foregoing descriptions, a floating-point value is
+ * considered to be an integer if and only if it is finite and a
+ * fixed point of the method {@link #ceil ceil} or,
+ * equivalently, a fixed point of the method {@link #floor
+ * floor}. A value is a fixed point of a one-argument
+ * method if and only if the result of applying the method to the
+ * value is equal to the value.)
+ *
+ * @param a base.
+ * @param b the exponent.
+ * @return the value {@code a}<sup>{@code b}</sup>.
+ */
+ public static native double pow(double a, double b);
+
+ /**
+ * Returns the closest {@code int} to the argument, with ties
+ * rounding to positive infinity.
+ *
+ * <p>Special cases:
+ * <ul><li>If the argument is NaN, the result is 0.
+ * <li>If the argument is negative infinity or any value less than or
+ * equal to the value of {@code Integer.MIN_VALUE}, the result is
+ * equal to the value of {@code Integer.MIN_VALUE}.
+ * <li>If the argument is positive infinity or any value greater than or
+ * equal to the value of {@code Integer.MAX_VALUE}, the result is
+ * equal to the value of {@code Integer.MAX_VALUE}.</ul>
+ *
+ * @param a a floating-point value to be rounded to an integer.
+ * @return the value of the argument rounded to the nearest
+ * {@code int} value.
+ * @see java.lang.Integer#MAX_VALUE
+ * @see java.lang.Integer#MIN_VALUE
+ */
+ public static int round(float a) {
+ return Math.round(a);
+ }
+
+ /**
+ * Returns the closest {@code long} to the argument, with ties
+ * rounding to positive infinity.
+ *
+ * <p>Special cases:
+ * <ul><li>If the argument is NaN, the result is 0.
+ * <li>If the argument is negative infinity or any value less than or
+ * equal to the value of {@code Long.MIN_VALUE}, the result is
+ * equal to the value of {@code Long.MIN_VALUE}.
+ * <li>If the argument is positive infinity or any value greater than or
+ * equal to the value of {@code Long.MAX_VALUE}, the result is
+ * equal to the value of {@code Long.MAX_VALUE}.</ul>
+ *
+ * @param a a floating-point value to be rounded to a
+ * {@code long}.
+ * @return the value of the argument rounded to the nearest
+ * {@code long} value.
+ * @see java.lang.Long#MAX_VALUE
+ * @see java.lang.Long#MIN_VALUE
+ */
+ public static long round(double a) {
+ return Math.round(a);
+ }
+
+ private static final class RandomNumberGeneratorHolder {
+ static final Random randomNumberGenerator = new Random();
+ }
+
+ /**
+ * Returns a {@code double} value with a positive sign, greater
+ * than or equal to {@code 0.0} and less than {@code 1.0}.
+ * Returned values are chosen pseudorandomly with (approximately)
+ * uniform distribution from that range.
+ *
+ * <p>When this method is first called, it creates a single new
+ * pseudorandom-number generator, exactly as if by the expression
+ *
+ * <blockquote>{@code new java.util.Random()}</blockquote>
+ *
+ * This new pseudorandom-number generator is used thereafter for
+ * all calls to this method and is used nowhere else.
+ *
+ * <p>This method is properly synchronized to allow correct use by
+ * more than one thread. However, if many threads need to generate
+ * pseudorandom numbers at a great rate, it may reduce contention
+ * for each thread to have its own pseudorandom-number generator.
+ *
+ * @return a pseudorandom {@code double} greater than or equal
+ * to {@code 0.0} and less than {@code 1.0}.
+ * @see Random#nextDouble()
+ */
+ public static double random() {
+ return RandomNumberGeneratorHolder.randomNumberGenerator.nextDouble();
+ }
+
+ /**
+ * Returns the sum of its arguments,
+ * throwing an exception if the result overflows an {@code int}.
+ *
+ * @param x the first value
+ * @param y the second value
+ * @return the result
+ * @throws ArithmeticException if the result overflows an int
+ * @see Math#addExact(int,int)
+ * @since 1.8
+ */
+ public static int addExact(int x, int y) {
+ return Math.addExact(x, y);
+ }
+
+ /**
+ * Returns the sum of its arguments,
+ * throwing an exception if the result overflows a {@code long}.
+ *
+ * @param x the first value
+ * @param y the second value
+ * @return the result
+ * @throws ArithmeticException if the result overflows a long
+ * @see Math#addExact(long,long)
+ * @since 1.8
+ */
+ public static long addExact(long x, long y) {
+ return Math.addExact(x, y);
+ }
+
+ /**
+ * Returns the difference of the arguments,
+ * throwing an exception if the result overflows an {@code int}.
+ *
+ * @param x the first value
+ * @param y the second value to subtract from the first
+ * @return the result
+ * @throws ArithmeticException if the result overflows an int
+ * @see Math#subtractExact(int,int)
+ * @since 1.8
+ */
+ public static int subtractExact(int x, int y) {
+ return Math.subtractExact(x, y);
+ }
+
+ /**
+ * Returns the difference of the arguments,
+ * throwing an exception if the result overflows a {@code long}.
+ *
+ * @param x the first value
+ * @param y the second value to subtract from the first
+ * @return the result
+ * @throws ArithmeticException if the result overflows a long
+ * @see Math#subtractExact(long,long)
+ * @since 1.8
+ */
+ public static long subtractExact(long x, long y) {
+ return Math.subtractExact(x, y);
+ }
+
+ /**
+ * Returns the product of the arguments,
+ * throwing an exception if the result overflows an {@code int}.
+ *
+ * @param x the first value
+ * @param y the second value
+ * @return the result
+ * @throws ArithmeticException if the result overflows an int
+ * @see Math#multiplyExact(int,int)
+ * @since 1.8
+ */
+ public static int multiplyExact(int x, int y) {
+ return Math.multiplyExact(x, y);
+ }
+
+ /**
+ * Returns the product of the arguments,
+ * throwing an exception if the result overflows a {@code long}.
+ *
+ * @param x the first value
+ * @param y the second value
+ * @return the result
+ * @throws ArithmeticException if the result overflows a long
+ * @see Math#multiplyExact(long,long)
+ * @since 1.8
+ */
+ public static long multiplyExact(long x, long y) {
+ return Math.multiplyExact(x, y);
+ }
+
+ /**
+ * Returns the value of the {@code long} argument;
+ * throwing an exception if the value overflows an {@code int}.
+ *
+ * @param value the long value
+ * @return the argument as an int
+ * @throws ArithmeticException if the {@code argument} overflows an int
+ * @see Math#toIntExact(long)
+ * @since 1.8
+ */
+ public static int toIntExact(long value) {
+ return Math.toIntExact(value);
+ }
+
+ /**
+ * Returns the largest (closest to positive infinity)
+ * {@code int} value that is less than or equal to the algebraic quotient.
+ * There is one special case, if the dividend is the
+ * {@linkplain Integer#MIN_VALUE Integer.MIN_VALUE} and the divisor is {@code -1},
+ * then integer overflow occurs and
+ * the result is equal to the {@code Integer.MIN_VALUE}.
+ * <p>
+ * See {@link Math#floorDiv(int, int) Math.floorDiv} for examples and
+ * a comparison to the integer division {@code /} operator.
+ *
+ * @param x the dividend
+ * @param y the divisor
+ * @return the largest (closest to positive infinity)
+ * {@code int} value that is less than or equal to the algebraic quotient.
+ * @throws ArithmeticException if the divisor {@code y} is zero
+ * @see Math#floorDiv(int, int)
+ * @see Math#floor(double)
+ * @since 1.8
+ */
+ public static int floorDiv(int x, int y) {
+ return Math.floorDiv(x, y);
+ }
+
+ /**
+ * Returns the largest (closest to positive infinity)
+ * {@code long} value that is less than or equal to the algebraic quotient.
+ * There is one special case, if the dividend is the
+ * {@linkplain Long#MIN_VALUE Long.MIN_VALUE} and the divisor is {@code -1},
+ * then integer overflow occurs and
+ * the result is equal to the {@code Long.MIN_VALUE}.
+ * <p>
+ * See {@link Math#floorDiv(int, int) Math.floorDiv} for examples and
+ * a comparison to the integer division {@code /} operator.
+ *
+ * @param x the dividend
+ * @param y the divisor
+ * @return the largest (closest to positive infinity)
+ * {@code long} value that is less than or equal to the algebraic quotient.
+ * @throws ArithmeticException if the divisor {@code y} is zero
+ * @see Math#floorDiv(long, long)
+ * @see Math#floor(double)
+ * @since 1.8
+ */
+ public static long floorDiv(long x, long y) {
+ return Math.floorDiv(x, y);
+ }
+
+ /**
+ * Returns the floor modulus of the {@code int} arguments.
+ * <p>
+ * The floor modulus is {@code x - (floorDiv(x, y) * y)},
+ * has the same sign as the divisor {@code y}, and
+ * is in the range of {@code -abs(y) < r < +abs(y)}.
+ * <p>
+ * The relationship between {@code floorDiv} and {@code floorMod} is such that:
+ * <ul>
+ * <li>{@code floorDiv(x, y) * y + floorMod(x, y) == x}
+ * </ul>
+ * <p>
+ * See {@link Math#floorMod(int, int) Math.floorMod} for examples and
+ * a comparison to the {@code %} operator.
+ *
+ * @param x the dividend
+ * @param y the divisor
+ * @return the floor modulus {@code x - (floorDiv(x, y) * y)}
+ * @throws ArithmeticException if the divisor {@code y} is zero
+ * @see Math#floorMod(int, int)
+ * @see StrictMath#floorDiv(int, int)
+ * @since 1.8
+ */
+ public static int floorMod(int x, int y) {
+ return Math.floorMod(x , y);
+ }
+ /**
+ * Returns the floor modulus of the {@code long} arguments.
+ * <p>
+ * The floor modulus is {@code x - (floorDiv(x, y) * y)},
+ * has the same sign as the divisor {@code y}, and
+ * is in the range of {@code -abs(y) < r < +abs(y)}.
+ * <p>
+ * The relationship between {@code floorDiv} and {@code floorMod} is such that:
+ * <ul>
+ * <li>{@code floorDiv(x, y) * y + floorMod(x, y) == x}
+ * </ul>
+ * <p>
+ * See {@link Math#floorMod(int, int) Math.floorMod} for examples and
+ * a comparison to the {@code %} operator.
+ *
+ * @param x the dividend
+ * @param y the divisor
+ * @return the floor modulus {@code x - (floorDiv(x, y) * y)}
+ * @throws ArithmeticException if the divisor {@code y} is zero
+ * @see Math#floorMod(long, long)
+ * @see StrictMath#floorDiv(long, long)
+ * @since 1.8
+ */
+ public static long floorMod(long x, long y) {
+ return Math.floorMod(x, y);
+ }
+
+ /**
+ * Returns the absolute value of an {@code int} value.
+ * If the argument is not negative, the argument is returned.
+ * If the argument is negative, the negation of the argument is returned.
+ *
+ * <p>Note that if the argument is equal to the value of
+ * {@link Integer#MIN_VALUE}, the most negative representable
+ * {@code int} value, the result is that same value, which is
+ * negative.
+ *
+ * @param a the argument whose absolute value is to be determined.
+ * @return the absolute value of the argument.
+ */
+ public static int abs(int a) {
+ return Math.abs(a);
+ }
+
+ /**
+ * Returns the absolute value of a {@code long} value.
+ * If the argument is not negative, the argument is returned.
+ * If the argument is negative, the negation of the argument is returned.
+ *
+ * <p>Note that if the argument is equal to the value of
+ * {@link Long#MIN_VALUE}, the most negative representable
+ * {@code long} value, the result is that same value, which
+ * is negative.
+ *
+ * @param a the argument whose absolute value is to be determined.
+ * @return the absolute value of the argument.
+ */
+ public static long abs(long a) {
+ return Math.abs(a);
+ }
+
+ /**
+ * Returns the absolute value of a {@code float} value.
+ * If the argument is not negative, the argument is returned.
+ * If the argument is negative, the negation of the argument is returned.
+ * Special cases:
+ * <ul><li>If the argument is positive zero or negative zero, the
+ * result is positive zero.
+ * <li>If the argument is infinite, the result is positive infinity.
+ * <li>If the argument is NaN, the result is NaN.</ul>
+ * In other words, the result is the same as the value of the expression:
+ * <p>{@code Float.intBitsToFloat(0x7fffffff & Float.floatToIntBits(a))}
+ *
+ * @param a the argument whose absolute value is to be determined
+ * @return the absolute value of the argument.
+ */
+ public static float abs(float a) {
+ return Math.abs(a);
+ }
+
+ /**
+ * Returns the absolute value of a {@code double} value.
+ * If the argument is not negative, the argument is returned.
+ * If the argument is negative, the negation of the argument is returned.
+ * Special cases:
+ * <ul><li>If the argument is positive zero or negative zero, the result
+ * is positive zero.
+ * <li>If the argument is infinite, the result is positive infinity.
+ * <li>If the argument is NaN, the result is NaN.</ul>
+ * In other words, the result is the same as the value of the expression:
+ * <p>{@code Double.longBitsToDouble((Double.doubleToLongBits(a)<<1)>>>1)}
+ *
+ * @param a the argument whose absolute value is to be determined
+ * @return the absolute value of the argument.
+ */
+ public static double abs(double a) {
+ return Math.abs(a);
+ }
+
+ /**
+ * Returns the greater of two {@code int} values. That is, the
+ * result is the argument closer to the value of
+ * {@link Integer#MAX_VALUE}. If the arguments have the same value,
+ * the result is that same value.
+ *
+ * @param a an argument.
+ * @param b another argument.
+ * @return the larger of {@code a} and {@code b}.
+ */
+ public static int max(int a, int b) {
+ return Math.max(a, b);
+ }
+
+ /**
+ * Returns the greater of two {@code long} values. That is, the
+ * result is the argument closer to the value of
+ * {@link Long#MAX_VALUE}. If the arguments have the same value,
+ * the result is that same value.
+ *
+ * @param a an argument.
+ * @param b another argument.
+ * @return the larger of {@code a} and {@code b}.
+ */
+ public static long max(long a, long b) {
+ return Math.max(a, b);
+ }
+
+ /**
+ * Returns the greater of two {@code float} values. That is,
+ * the result is the argument closer to positive infinity. If the
+ * arguments have the same value, the result is that same
+ * value. If either value is NaN, then the result is NaN. Unlike
+ * the numerical comparison operators, this method considers
+ * negative zero to be strictly smaller than positive zero. If one
+ * argument is positive zero and the other negative zero, the
+ * result is positive zero.
+ *
+ * @param a an argument.
+ * @param b another argument.
+ * @return the larger of {@code a} and {@code b}.
+ */
+ public static float max(float a, float b) {
+ return Math.max(a, b);
+ }
+
+ /**
+ * Returns the greater of two {@code double} values. That
+ * is, the result is the argument closer to positive infinity. If
+ * the arguments have the same value, the result is that same
+ * value. If either value is NaN, then the result is NaN. Unlike
+ * the numerical comparison operators, this method considers
+ * negative zero to be strictly smaller than positive zero. If one
+ * argument is positive zero and the other negative zero, the
+ * result is positive zero.
+ *
+ * @param a an argument.
+ * @param b another argument.
+ * @return the larger of {@code a} and {@code b}.
+ */
+ public static double max(double a, double b) {
+ return Math.max(a, b);
+ }
+
+ /**
+ * Returns the smaller of two {@code int} values. That is,
+ * the result the argument closer to the value of
+ * {@link Integer#MIN_VALUE}. If the arguments have the same
+ * value, the result is that same value.
+ *
+ * @param a an argument.
+ * @param b another argument.
+ * @return the smaller of {@code a} and {@code b}.
+ */
+ public static int min(int a, int b) {
+ return Math.min(a, b);
+ }
+
+ /**
+ * Returns the smaller of two {@code long} values. That is,
+ * the result is the argument closer to the value of
+ * {@link Long#MIN_VALUE}. If the arguments have the same
+ * value, the result is that same value.
+ *
+ * @param a an argument.
+ * @param b another argument.
+ * @return the smaller of {@code a} and {@code b}.
+ */
+ public static long min(long a, long b) {
+ return Math.min(a, b);
+ }
+
+ /**
+ * Returns the smaller of two {@code float} values. That is,
+ * the result is the value closer to negative infinity. If the
+ * arguments have the same value, the result is that same
+ * value. If either value is NaN, then the result is NaN. Unlike
+ * the numerical comparison operators, this method considers
+ * negative zero to be strictly smaller than positive zero. If
+ * one argument is positive zero and the other is negative zero,
+ * the result is negative zero.
+ *
+ * @param a an argument.
+ * @param b another argument.
+ * @return the smaller of {@code a} and {@code b.}
+ */
+ public static float min(float a, float b) {
+ return Math.min(a, b);
+ }
+
+ /**
+ * Returns the smaller of two {@code double} values. That
+ * is, the result is the value closer to negative infinity. If the
+ * arguments have the same value, the result is that same
+ * value. If either value is NaN, then the result is NaN. Unlike
+ * the numerical comparison operators, this method considers
+ * negative zero to be strictly smaller than positive zero. If one
+ * argument is positive zero and the other is negative zero, the
+ * result is negative zero.
+ *
+ * @param a an argument.
+ * @param b another argument.
+ * @return the smaller of {@code a} and {@code b}.
+ */
+ public static double min(double a, double b) {
+ return Math.min(a, b);
+ }
+
+ /**
+ * Returns the size of an ulp of the argument. An ulp, unit in
+ * the last place, of a {@code double} value is the positive
+ * distance between this floating-point value and the {@code
+ * double} value next larger in magnitude. Note that for non-NaN
+ * <i>x</i>, <code>ulp(-<i>x</i>) == ulp(<i>x</i>)</code>.
+ *
+ * <p>Special Cases:
+ * <ul>
+ * <li> If the argument is NaN, then the result is NaN.
+ * <li> If the argument is positive or negative infinity, then the
+ * result is positive infinity.
+ * <li> If the argument is positive or negative zero, then the result is
+ * {@code Double.MIN_VALUE}.
+ * <li> If the argument is ±{@code Double.MAX_VALUE}, then
+ * the result is equal to 2<sup>971</sup>.
+ * </ul>
+ *
+ * @param d the floating-point value whose ulp is to be returned
+ * @return the size of an ulp of the argument
+ * @author Joseph D. Darcy
+ * @since 1.5
+ */
+ public static double ulp(double d) {
+ return Math.ulp(d);
+ }
+
+ /**
+ * Returns the size of an ulp of the argument. An ulp, unit in
+ * the last place, of a {@code float} value is the positive
+ * distance between this floating-point value and the {@code
+ * float} value next larger in magnitude. Note that for non-NaN
+ * <i>x</i>, <code>ulp(-<i>x</i>) == ulp(<i>x</i>)</code>.
+ *
+ * <p>Special Cases:
+ * <ul>
+ * <li> If the argument is NaN, then the result is NaN.
+ * <li> If the argument is positive or negative infinity, then the
+ * result is positive infinity.
+ * <li> If the argument is positive or negative zero, then the result is
+ * {@code Float.MIN_VALUE}.
+ * <li> If the argument is ±{@code Float.MAX_VALUE}, then
+ * the result is equal to 2<sup>104</sup>.
+ * </ul>
+ *
+ * @param f the floating-point value whose ulp is to be returned
+ * @return the size of an ulp of the argument
+ * @author Joseph D. Darcy
+ * @since 1.5
+ */
+ public static float ulp(float f) {
+ return Math.ulp(f);
+ }
+
+ /**
+ * Returns the signum function of the argument; zero if the argument
+ * is zero, 1.0 if the argument is greater than zero, -1.0 if the
+ * argument is less than zero.
+ *
+ * <p>Special Cases:
+ * <ul>
+ * <li> If the argument is NaN, then the result is NaN.
+ * <li> If the argument is positive zero or negative zero, then the
+ * result is the same as the argument.
+ * </ul>
+ *
+ * @param d the floating-point value whose signum is to be returned
+ * @return the signum function of the argument
+ * @author Joseph D. Darcy
+ * @since 1.5
+ */
+ public static double signum(double d) {
+ return Math.signum(d);
+ }
+
+ /**
+ * Returns the signum function of the argument; zero if the argument
+ * is zero, 1.0f if the argument is greater than zero, -1.0f if the
+ * argument is less than zero.
+ *
+ * <p>Special Cases:
+ * <ul>
+ * <li> If the argument is NaN, then the result is NaN.
+ * <li> If the argument is positive zero or negative zero, then the
+ * result is the same as the argument.
+ * </ul>
+ *
+ * @param f the floating-point value whose signum is to be returned
+ * @return the signum function of the argument
+ * @author Joseph D. Darcy
+ * @since 1.5
+ */
+ public static float signum(float f) {
+ return Math.signum(f);
+ }
+
+ /**
+ * Returns the hyperbolic sine of a {@code double} value.
+ * The hyperbolic sine of <i>x</i> is defined to be
+ * (<i>e<sup>x</sup> - e<sup>-x</sup></i>)/2
+ * where <i>e</i> is {@linkplain Math#E Euler's number}.
+ *
+ * <p>Special cases:
+ * <ul>
+ *
+ * <li>If the argument is NaN, then the result is NaN.
+ *
+ * <li>If the argument is infinite, then the result is an infinity
+ * with the same sign as the argument.
+ *
+ * <li>If the argument is zero, then the result is a zero with the
+ * same sign as the argument.
+ *
+ * </ul>
+ *
+ * @param x The number whose hyperbolic sine is to be returned.
+ * @return The hyperbolic sine of {@code x}.
+ * @since 1.5
+ */
+ public static native double sinh(double x);
+
+ /**
+ * Returns the hyperbolic cosine of a {@code double} value.
+ * The hyperbolic cosine of <i>x</i> is defined to be
+ * (<i>e<sup>x</sup> + e<sup>-x</sup></i>)/2
+ * where <i>e</i> is {@linkplain Math#E Euler's number}.
+ *
+ * <p>Special cases:
+ * <ul>
+ *
+ * <li>If the argument is NaN, then the result is NaN.
+ *
+ * <li>If the argument is infinite, then the result is positive
+ * infinity.
+ *
+ * <li>If the argument is zero, then the result is {@code 1.0}.
+ *
+ * </ul>
+ *
+ * @param x The number whose hyperbolic cosine is to be returned.
+ * @return The hyperbolic cosine of {@code x}.
+ * @since 1.5
+ */
+ public static native double cosh(double x);
+
+ /**
+ * Returns the hyperbolic tangent of a {@code double} value.
+ * The hyperbolic tangent of <i>x</i> is defined to be
+ * (<i>e<sup>x</sup> - e<sup>-x</sup></i>)/(<i>e<sup>x</sup> + e<sup>-x</sup></i>),
+ * in other words, {@linkplain Math#sinh
+ * sinh(<i>x</i>)}/{@linkplain Math#cosh cosh(<i>x</i>)}. Note
+ * that the absolute value of the exact tanh is always less than
+ * 1.
+ *
+ * <p>Special cases:
+ * <ul>
+ *
+ * <li>If the argument is NaN, then the result is NaN.
+ *
+ * <li>If the argument is zero, then the result is a zero with the
+ * same sign as the argument.
+ *
+ * <li>If the argument is positive infinity, then the result is
+ * {@code +1.0}.
+ *
+ * <li>If the argument is negative infinity, then the result is
+ * {@code -1.0}.
+ *
+ * </ul>
+ *
+ * @param x The number whose hyperbolic tangent is to be returned.
+ * @return The hyperbolic tangent of {@code x}.
+ * @since 1.5
+ */
+ public static native double tanh(double x);
+
+ /**
+ * Returns sqrt(<i>x</i><sup>2</sup> +<i>y</i><sup>2</sup>)
+ * without intermediate overflow or underflow.
+ *
+ * <p>Special cases:
+ * <ul>
+ *
+ * <li> If either argument is infinite, then the result
+ * is positive infinity.
+ *
+ * <li> If either argument is NaN and neither argument is infinite,
+ * then the result is NaN.
+ *
+ * </ul>
+ *
+ * @param x a value
+ * @param y a value
+ * @return sqrt(<i>x</i><sup>2</sup> +<i>y</i><sup>2</sup>)
+ * without intermediate overflow or underflow
+ * @since 1.5
+ */
+ public static native double hypot(double x, double y);
+
+ /**
+ * Returns <i>e</i><sup>x</sup> -1. Note that for values of
+ * <i>x</i> near 0, the exact sum of
+ * {@code expm1(x)} + 1 is much closer to the true
+ * result of <i>e</i><sup>x</sup> than {@code exp(x)}.
+ *
+ * <p>Special cases:
+ * <ul>
+ * <li>If the argument is NaN, the result is NaN.
+ *
+ * <li>If the argument is positive infinity, then the result is
+ * positive infinity.
+ *
+ * <li>If the argument is negative infinity, then the result is
+ * -1.0.
+ *
+ * <li>If the argument is zero, then the result is a zero with the
+ * same sign as the argument.
+ *
+ * </ul>
+ *
+ * @param x the exponent to raise <i>e</i> to in the computation of
+ * <i>e</i><sup>{@code x}</sup> -1.
+ * @return the value <i>e</i><sup>{@code x}</sup> - 1.
+ * @since 1.5
+ */
+ public static native double expm1(double x);
+
+ /**
+ * Returns the natural logarithm of the sum of the argument and 1.
+ * Note that for small values {@code x}, the result of
+ * {@code log1p(x)} is much closer to the true result of ln(1
+ * + {@code x}) than the floating-point evaluation of
+ * {@code log(1.0+x)}.
+ *
+ * <p>Special cases:
+ * <ul>
+ *
+ * <li>If the argument is NaN or less than -1, then the result is
+ * NaN.
+ *
+ * <li>If the argument is positive infinity, then the result is
+ * positive infinity.
+ *
+ * <li>If the argument is negative one, then the result is
+ * negative infinity.
+ *
+ * <li>If the argument is zero, then the result is a zero with the
+ * same sign as the argument.
+ *
+ * </ul>
+ *
+ * @param x a value
+ * @return the value ln({@code x} + 1), the natural
+ * log of {@code x} + 1
+ * @since 1.5
+ */
+ public static native double log1p(double x);
+
+ /**
+ * Returns the first floating-point argument with the sign of the
+ * second floating-point argument. For this method, a NaN
+ * {@code sign} argument is always treated as if it were
+ * positive.
+ *
+ * @param magnitude the parameter providing the magnitude of the result
+ * @param sign the parameter providing the sign of the result
+ * @return a value with the magnitude of {@code magnitude}
+ * and the sign of {@code sign}.
+ * @since 1.6
+ */
+ public static double copySign(double magnitude, double sign) {
+ return Math.copySign(magnitude, (Double.isNaN(sign)?1.0d:sign));
+ }
+
+ /**
+ * Returns the first floating-point argument with the sign of the
+ * second floating-point argument. For this method, a NaN
+ * {@code sign} argument is always treated as if it were
+ * positive.
+ *
+ * @param magnitude the parameter providing the magnitude of the result
+ * @param sign the parameter providing the sign of the result
+ * @return a value with the magnitude of {@code magnitude}
+ * and the sign of {@code sign}.
+ * @since 1.6
+ */
+ public static float copySign(float magnitude, float sign) {
+ return Math.copySign(magnitude, (Float.isNaN(sign)?1.0f:sign));
+ }
+ /**
+ * Returns the unbiased exponent used in the representation of a
+ * {@code float}. Special cases:
+ *
+ * <ul>
+ * <li>If the argument is NaN or infinite, then the result is
+ * {@link Float#MAX_EXPONENT} + 1.
+ * <li>If the argument is zero or subnormal, then the result is
+ * {@link Float#MIN_EXPONENT} -1.
+ * </ul>
+ * @param f a {@code float} value
+ * @return the unbiased exponent of the argument
+ * @since 1.6
+ */
+ public static int getExponent(float f) {
+ return Math.getExponent(f);
+ }
+
+ /**
+ * Returns the unbiased exponent used in the representation of a
+ * {@code double}. Special cases:
+ *
+ * <ul>
+ * <li>If the argument is NaN or infinite, then the result is
+ * {@link Double#MAX_EXPONENT} + 1.
+ * <li>If the argument is zero or subnormal, then the result is
+ * {@link Double#MIN_EXPONENT} -1.
+ * </ul>
+ * @param d a {@code double} value
+ * @return the unbiased exponent of the argument
+ * @since 1.6
+ */
+ public static int getExponent(double d) {
+ return Math.getExponent(d);
+ }
+
+ /**
+ * Returns the floating-point number adjacent to the first
+ * argument in the direction of the second argument. If both
+ * arguments compare as equal the second argument is returned.
+ *
+ * <p>Special cases:
+ * <ul>
+ * <li> If either argument is a NaN, then NaN is returned.
+ *
+ * <li> If both arguments are signed zeros, {@code direction}
+ * is returned unchanged (as implied by the requirement of
+ * returning the second argument if the arguments compare as
+ * equal).
+ *
+ * <li> If {@code start} is
+ * ±{@link Double#MIN_VALUE} and {@code direction}
+ * has a value such that the result should have a smaller
+ * magnitude, then a zero with the same sign as {@code start}
+ * is returned.
+ *
+ * <li> If {@code start} is infinite and
+ * {@code direction} has a value such that the result should
+ * have a smaller magnitude, {@link Double#MAX_VALUE} with the
+ * same sign as {@code start} is returned.
+ *
+ * <li> If {@code start} is equal to ±
+ * {@link Double#MAX_VALUE} and {@code direction} has a
+ * value such that the result should have a larger magnitude, an
+ * infinity with same sign as {@code start} is returned.
+ * </ul>
+ *
+ * @param start starting floating-point value
+ * @param direction value indicating which of
+ * {@code start}'s neighbors or {@code start} should
+ * be returned
+ * @return The floating-point number adjacent to {@code start} in the
+ * direction of {@code direction}.
+ * @since 1.6
+ */
+ public static double nextAfter(double start, double direction) {
+ return Math.nextAfter(start, direction);
+ }
+
+ /**
+ * Returns the floating-point number adjacent to the first
+ * argument in the direction of the second argument. If both
+ * arguments compare as equal a value equivalent to the second argument
+ * is returned.
+ *
+ * <p>Special cases:
+ * <ul>
+ * <li> If either argument is a NaN, then NaN is returned.
+ *
+ * <li> If both arguments are signed zeros, a value equivalent
+ * to {@code direction} is returned.
+ *
+ * <li> If {@code start} is
+ * ±{@link Float#MIN_VALUE} and {@code direction}
+ * has a value such that the result should have a smaller
+ * magnitude, then a zero with the same sign as {@code start}
+ * is returned.
+ *
+ * <li> If {@code start} is infinite and
+ * {@code direction} has a value such that the result should
+ * have a smaller magnitude, {@link Float#MAX_VALUE} with the
+ * same sign as {@code start} is returned.
+ *
+ * <li> If {@code start} is equal to ±
+ * {@link Float#MAX_VALUE} and {@code direction} has a
+ * value such that the result should have a larger magnitude, an
+ * infinity with same sign as {@code start} is returned.
+ * </ul>
+ *
+ * @param start starting floating-point value
+ * @param direction value indicating which of
+ * {@code start}'s neighbors or {@code start} should
+ * be returned
+ * @return The floating-point number adjacent to {@code start} in the
+ * direction of {@code direction}.
+ * @since 1.6
+ */
+ public static float nextAfter(float start, double direction) {
+ return Math.nextAfter(start, direction);
+ }
+
+ /**
+ * Returns the floating-point value adjacent to {@code d} in
+ * the direction of positive infinity. This method is
+ * semantically equivalent to {@code nextAfter(d,
+ * Double.POSITIVE_INFINITY)}; however, a {@code nextUp}
+ * implementation may run faster than its equivalent
+ * {@code nextAfter} call.
+ *
+ * <p>Special Cases:
+ * <ul>
+ * <li> If the argument is NaN, the result is NaN.
+ *
+ * <li> If the argument is positive infinity, the result is
+ * positive infinity.
+ *
+ * <li> If the argument is zero, the result is
+ * {@link Double#MIN_VALUE}
+ *
+ * </ul>
+ *
+ * @param d starting floating-point value
+ * @return The adjacent floating-point value closer to positive
+ * infinity.
+ * @since 1.6
+ */
+ public static double nextUp(double d) {
+ return Math.nextUp(d);
+ }
+
+ /**
+ * Returns the floating-point value adjacent to {@code f} in
+ * the direction of positive infinity. This method is
+ * semantically equivalent to {@code nextAfter(f,
+ * Float.POSITIVE_INFINITY)}; however, a {@code nextUp}
+ * implementation may run faster than its equivalent
+ * {@code nextAfter} call.
+ *
+ * <p>Special Cases:
+ * <ul>
+ * <li> If the argument is NaN, the result is NaN.
+ *
+ * <li> If the argument is positive infinity, the result is
+ * positive infinity.
+ *
+ * <li> If the argument is zero, the result is
+ * {@link Float#MIN_VALUE}
+ *
+ * </ul>
+ *
+ * @param f starting floating-point value
+ * @return The adjacent floating-point value closer to positive
+ * infinity.
+ * @since 1.6
+ */
+ public static float nextUp(float f) {
+ return Math.nextUp(f);
+ }
+
+ /**
+ * Returns the floating-point value adjacent to {@code d} in
+ * the direction of negative infinity. This method is
+ * semantically equivalent to {@code nextAfter(d,
+ * Double.NEGATIVE_INFINITY)}; however, a
+ * {@code nextDown} implementation may run faster than its
+ * equivalent {@code nextAfter} call.
+ *
+ * <p>Special Cases:
+ * <ul>
+ * <li> If the argument is NaN, the result is NaN.
+ *
+ * <li> If the argument is negative infinity, the result is
+ * negative infinity.
+ *
+ * <li> If the argument is zero, the result is
+ * {@code -Double.MIN_VALUE}
+ *
+ * </ul>
+ *
+ * @param d starting floating-point value
+ * @return The adjacent floating-point value closer to negative
+ * infinity.
+ * @since 1.8
+ */
+ public static double nextDown(double d) {
+ return Math.nextDown(d);
+ }
+
+ /**
+ * Returns the floating-point value adjacent to {@code f} in
+ * the direction of negative infinity. This method is
+ * semantically equivalent to {@code nextAfter(f,
+ * Float.NEGATIVE_INFINITY)}; however, a
+ * {@code nextDown} implementation may run faster than its
+ * equivalent {@code nextAfter} call.
+ *
+ * <p>Special Cases:
+ * <ul>
+ * <li> If the argument is NaN, the result is NaN.
+ *
+ * <li> If the argument is negative infinity, the result is
+ * negative infinity.
+ *
+ * <li> If the argument is zero, the result is
+ * {@code -Float.MIN_VALUE}
+ *
+ * </ul>
+ *
+ * @param f starting floating-point value
+ * @return The adjacent floating-point value closer to negative
+ * infinity.
+ * @since 1.8
+ */
+ public static float nextDown(float f) {
+ return Math.nextDown(f);
+ }
+
+ /**
+ * Returns {@code d} ×
+ * 2<sup>{@code scaleFactor}</sup> rounded as if performed
+ * by a single correctly rounded floating-point multiply to a
+ * member of the double value set. See the Java
+ * Language Specification for a discussion of floating-point
+ * value sets. If the exponent of the result is between {@link
+ * Double#MIN_EXPONENT} and {@link Double#MAX_EXPONENT}, the
+ * answer is calculated exactly. If the exponent of the result
+ * would be larger than {@code Double.MAX_EXPONENT}, an
+ * infinity is returned. Note that if the result is subnormal,
+ * precision may be lost; that is, when {@code scalb(x, n)}
+ * is subnormal, {@code scalb(scalb(x, n), -n)} may not equal
+ * <i>x</i>. When the result is non-NaN, the result has the same
+ * sign as {@code d}.
+ *
+ * <p>Special cases:
+ * <ul>
+ * <li> If the first argument is NaN, NaN is returned.
+ * <li> If the first argument is infinite, then an infinity of the
+ * same sign is returned.
+ * <li> If the first argument is zero, then a zero of the same
+ * sign is returned.
+ * </ul>
+ *
+ * @param d number to be scaled by a power of two.
+ * @param scaleFactor power of 2 used to scale {@code d}
+ * @return {@code d} × 2<sup>{@code scaleFactor}</sup>
+ * @since 1.6
+ */
+ public static double scalb(double d, int scaleFactor) {
+ return Math.scalb(d, scaleFactor);
+ }
+
+ /**
+ * Returns {@code f} ×
+ * 2<sup>{@code scaleFactor}</sup> rounded as if performed
+ * by a single correctly rounded floating-point multiply to a
+ * member of the float value set. See the Java
+ * Language Specification for a discussion of floating-point
+ * value sets. If the exponent of the result is between {@link
+ * Float#MIN_EXPONENT} and {@link Float#MAX_EXPONENT}, the
+ * answer is calculated exactly. If the exponent of the result
+ * would be larger than {@code Float.MAX_EXPONENT}, an
+ * infinity is returned. Note that if the result is subnormal,
+ * precision may be lost; that is, when {@code scalb(x, n)}
+ * is subnormal, {@code scalb(scalb(x, n), -n)} may not equal
+ * <i>x</i>. When the result is non-NaN, the result has the same
+ * sign as {@code f}.
+ *
+ * <p>Special cases:
+ * <ul>
+ * <li> If the first argument is NaN, NaN is returned.
+ * <li> If the first argument is infinite, then an infinity of the
+ * same sign is returned.
+ * <li> If the first argument is zero, then a zero of the same
+ * sign is returned.
+ * </ul>
+ *
+ * @param f number to be scaled by a power of two.
+ * @param scaleFactor power of 2 used to scale {@code f}
+ * @return {@code f} × 2<sup>{@code scaleFactor}</sup>
+ * @since 1.6
+ */
+ public static float scalb(float f, int scaleFactor) {
+ return Math.scalb(f, scaleFactor);
+ }
+}
diff --git a/java/lang/String.annotated.java b/java/lang/String.annotated.java
new file mode 100644
index 0000000..a8cf1de
--- /dev/null
+++ b/java/lang/String.annotated.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 2013, 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;
+
+import java.nio.charset.Charset;
+import java.io.UnsupportedEncodingException;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+import java.util.StringJoiner;
+import java.util.Locale;
+import java.util.Formatter;
+import java.util.Comparator;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class String implements java.io.Serializable, java.lang.Comparable<java.lang.String>, java.lang.CharSequence {
+
+public String() { throw new RuntimeException("Stub!"); }
+
+public String(@libcore.util.NonNull java.lang.String original) { throw new RuntimeException("Stub!"); }
+
+public String(char[] value) { throw new RuntimeException("Stub!"); }
+
+public String(char[] value, int offset, int count) { throw new RuntimeException("Stub!"); }
+
+public String(int[] codePoints, int offset, int count) { throw new RuntimeException("Stub!"); }
+
+@Deprecated public String(byte[] ascii, int hibyte, int offset, int count) { throw new RuntimeException("Stub!"); }
+
+@Deprecated public String(byte[] ascii, int hibyte) { throw new RuntimeException("Stub!"); }
+
+public String(byte[] bytes, int offset, int length, @libcore.util.NonNull java.lang.String charsetName) throws java.io.UnsupportedEncodingException { throw new RuntimeException("Stub!"); }
+
+public String(byte[] bytes, int offset, int length, @libcore.util.NonNull java.nio.charset.Charset charset) { throw new RuntimeException("Stub!"); }
+
+public String(byte[] bytes, @libcore.util.NonNull java.lang.String charsetName) throws java.io.UnsupportedEncodingException { throw new RuntimeException("Stub!"); }
+
+public String(byte[] bytes, @libcore.util.NonNull java.nio.charset.Charset charset) { throw new RuntimeException("Stub!"); }
+
+public String(byte[] bytes, int offset, int length) { throw new RuntimeException("Stub!"); }
+
+public String(byte[] bytes) { throw new RuntimeException("Stub!"); }
+
+public String(@libcore.util.NonNull java.lang.StringBuffer buffer) { throw new RuntimeException("Stub!"); }
+
+public String(@libcore.util.NonNull java.lang.StringBuilder builder) { throw new RuntimeException("Stub!"); }
+
+public int length() { throw new RuntimeException("Stub!"); }
+
+public boolean isEmpty() { throw new RuntimeException("Stub!"); }
+
+public native char charAt(int index);
+
+public int codePointAt(int index) { throw new RuntimeException("Stub!"); }
+
+public int codePointBefore(int index) { throw new RuntimeException("Stub!"); }
+
+public int codePointCount(int beginIndex, int endIndex) { throw new RuntimeException("Stub!"); }
+
+public int offsetByCodePoints(int index, int codePointOffset) { throw new RuntimeException("Stub!"); }
+
+public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) { throw new RuntimeException("Stub!"); }
+
+@Deprecated public void getBytes(int srcBegin, int srcEnd, byte[] dst, int dstBegin) { throw new RuntimeException("Stub!"); }
+
+public byte[] getBytes(@libcore.util.NonNull java.lang.String charsetName) throws java.io.UnsupportedEncodingException { throw new RuntimeException("Stub!"); }
+
+public byte[] getBytes(@libcore.util.NonNull java.nio.charset.Charset charset) { throw new RuntimeException("Stub!"); }
+
+public byte[] getBytes() { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable java.lang.Object anObject) { throw new RuntimeException("Stub!"); }
+
+public boolean contentEquals(@libcore.util.NonNull java.lang.StringBuffer sb) { throw new RuntimeException("Stub!"); }
+
+public boolean contentEquals(@libcore.util.NonNull java.lang.CharSequence cs) { throw new RuntimeException("Stub!"); }
+
+public boolean equalsIgnoreCase(@libcore.util.Nullable java.lang.String anotherString) { throw new RuntimeException("Stub!"); }
+
+public native int compareTo(@libcore.util.NonNull java.lang.String anotherString);
+
+public int compareToIgnoreCase(@libcore.util.NonNull java.lang.String str) { throw new RuntimeException("Stub!"); }
+
+public boolean regionMatches(int toffset, @libcore.util.NonNull java.lang.String other, int ooffset, int len) { throw new RuntimeException("Stub!"); }
+
+public boolean regionMatches(boolean ignoreCase, int toffset, @libcore.util.NonNull java.lang.String other, int ooffset, int len) { throw new RuntimeException("Stub!"); }
+
+public boolean startsWith(@libcore.util.NonNull java.lang.String prefix, int toffset) { throw new RuntimeException("Stub!"); }
+
+public boolean startsWith(@libcore.util.NonNull java.lang.String prefix) { throw new RuntimeException("Stub!"); }
+
+public boolean endsWith(@libcore.util.NonNull java.lang.String suffix) { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public int indexOf(int ch) { throw new RuntimeException("Stub!"); }
+
+public int indexOf(int ch, int fromIndex) { throw new RuntimeException("Stub!"); }
+
+public int lastIndexOf(int ch) { throw new RuntimeException("Stub!"); }
+
+public int lastIndexOf(int ch, int fromIndex) { throw new RuntimeException("Stub!"); }
+
+public int indexOf(@libcore.util.NonNull java.lang.String str) { throw new RuntimeException("Stub!"); }
+
+public int indexOf(@libcore.util.NonNull java.lang.String str, int fromIndex) { throw new RuntimeException("Stub!"); }
+
+public int lastIndexOf(@libcore.util.NonNull java.lang.String str) { throw new RuntimeException("Stub!"); }
+
+public int lastIndexOf(@libcore.util.NonNull java.lang.String str, int fromIndex) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String substring(int beginIndex) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String substring(int beginIndex, int endIndex) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.CharSequence subSequence(int beginIndex, int endIndex) { throw new RuntimeException("Stub!"); }
+
[email protected] public native java.lang.String concat(@libcore.util.NonNull java.lang.String str);
+
[email protected] public java.lang.String replace(char oldChar, char newChar) { throw new RuntimeException("Stub!"); }
+
+public boolean matches(@libcore.util.NonNull java.lang.String regex) { throw new RuntimeException("Stub!"); }
+
+public boolean contains(@libcore.util.NonNull java.lang.CharSequence s) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String replaceFirst(@libcore.util.NonNull java.lang.String regex, @libcore.util.NonNull java.lang.String replacement) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String replaceAll(@libcore.util.NonNull java.lang.String regex, @libcore.util.NonNull java.lang.String replacement) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String replace(@libcore.util.NonNull java.lang.CharSequence target, @libcore.util.NonNull java.lang.CharSequence replacement) { throw new RuntimeException("Stub!"); }
+
+public [email protected] String @libcore.util.NonNull [] split(@libcore.util.NonNull java.lang.String regex, int limit) { throw new RuntimeException("Stub!"); }
+
+public [email protected] String @libcore.util.NonNull [] split(@libcore.util.NonNull java.lang.String regex) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String join(@libcore.util.NonNull java.lang.CharSequence delimiter, [email protected] CharSequence @libcore.util.Nullable ... elements) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String join(@libcore.util.NonNull java.lang.CharSequence delimiter, @libcore.util.NonNull java.lang.Iterable<? extends @libcore.util.Nullable java.lang.CharSequence> elements) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String toLowerCase(@libcore.util.NonNull java.util.Locale locale) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String toLowerCase() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String toUpperCase(@libcore.util.NonNull java.util.Locale locale) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String toUpperCase() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String trim() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public native char[] toCharArray();
+
[email protected] public static java.lang.String format(@libcore.util.NonNull java.lang.String format, [email protected] Object @libcore.util.NonNull ... args) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String format(@libcore.util.NonNull java.util.Locale l, @libcore.util.NonNull java.lang.String format, [email protected] Object @libcore.util.NonNull ... args) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String valueOf(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String valueOf(char[] data) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String valueOf(char[] data, int offset, int count) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String copyValueOf(char[] data, int offset, int count) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String copyValueOf(char[] data) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String valueOf(boolean b) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String valueOf(char c) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String valueOf(int i) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String valueOf(long l) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String valueOf(float f) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.String valueOf(double d) { throw new RuntimeException("Stub!"); }
+
[email protected] public native java.lang.String intern();
+
+public static final java.util.Comparator<java.lang.String> CASE_INSENSITIVE_ORDER;
+static { CASE_INSENSITIVE_ORDER = null; }
+}
diff --git a/java/lang/String.java b/java/lang/String.java
new file mode 100644
index 0000000..2ba7b1f
--- /dev/null
+++ b/java/lang/String.java
@@ -0,0 +1,3104 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 2013, 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;
+
+import dalvik.annotation.optimization.FastNative;
+import java.io.ObjectStreamField;
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
+import java.nio.ByteBuffer;
+import java.util.Comparator;
+import java.util.Formatter;
+import java.util.Locale;
+import java.util.Objects;
+import java.util.StringJoiner;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+
+import libcore.util.CharsetUtils;
+
+/**
+ * The {@code String} class represents character strings. All
+ * string literals in Java programs, such as {@code "abc"}, are
+ * implemented as instances of this class.
+ * <p>
+ * Strings are constant; their values cannot be changed after they
+ * are created. String buffers support mutable strings.
+ * Because String objects are immutable they can be shared. For example:
+ * <blockquote><pre>
+ * String str = "abc";
+ * </pre></blockquote><p>
+ * is equivalent to:
+ * <blockquote><pre>
+ * char data[] = {'a', 'b', 'c'};
+ * String str = new String(data);
+ * </pre></blockquote><p>
+ * Here are some more examples of how strings can be used:
+ * <blockquote><pre>
+ * System.out.println("abc");
+ * String cde = "cde";
+ * System.out.println("abc" + cde);
+ * String c = "abc".substring(2,3);
+ * String d = cde.substring(1, 2);
+ * </pre></blockquote>
+ * <p>
+ * The class {@code String} includes methods for examining
+ * individual characters of the sequence, for comparing strings, for
+ * searching strings, for extracting substrings, and for creating a
+ * copy of a string with all characters translated to uppercase or to
+ * lowercase. Case mapping is based on the Unicode Standard version
+ * specified by the {@link java.lang.Character Character} class.
+ * <p>
+ * The Java language provides special support for the string
+ * concatenation operator ( + ), and for conversion of
+ * other objects to strings. String concatenation is implemented
+ * through the {@code StringBuilder}(or {@code StringBuffer})
+ * class and its {@code append} method.
+ * String conversions are implemented through the method
+ * {@code toString}, defined by {@code Object} and
+ * inherited by all classes in Java. For additional information on
+ * string concatenation and conversion, see Gosling, Joy, and Steele,
+ * <i>The Java Language Specification</i>.
+ *
+ * <p> Unless otherwise noted, passing a <tt>null</tt> argument to a constructor
+ * or method in this class will cause a {@link NullPointerException} to be
+ * thrown.
+ *
+ * <p>A {@code String} represents a string in the UTF-16 format
+ * in which <em>supplementary characters</em> are represented by <em>surrogate
+ * pairs</em> (see the section <a href="Character.html#unicode">Unicode
+ * Character Representations</a> in the {@code Character} class for
+ * more information).
+ * Index values refer to {@code char} code units, so a supplementary
+ * character uses two positions in a {@code String}.
+ * <p>The {@code String} class provides methods for dealing with
+ * Unicode code points (i.e., characters), in addition to those for
+ * dealing with Unicode code units (i.e., {@code char} values).
+ *
+ * @author Lee Boynton
+ * @author Arthur van Hoff
+ * @author Martin Buchholz
+ * @author Ulf Zibis
+ * @see java.lang.Object#toString()
+ * @see java.lang.StringBuffer
+ * @see java.lang.StringBuilder
+ * @see java.nio.charset.Charset
+ * @since JDK1.0
+ */
+
+public final class String
+ implements java.io.Serializable, Comparable<String>, CharSequence {
+
+ // BEGIN Android-changed: The character data is managed by the runtime.
+ // We only keep track of the length here and compression here. This has several consequences
+ // throughout this class:
+ // - References to value[i] are replaced by charAt(i).
+ // - References to value.length are replaced by calls to length().
+ // - Sometimes the result of length() is assigned to a local variable to avoid repeated calls.
+ // - We skip several attempts at optimization where the values field was assigned to a local
+ // variable to avoid the getfield opcode.
+ // These changes are not all marked individually.
+ //
+ // private final char value[];
+ //
+ // If STRING_COMPRESSION_ENABLED, count stores the length shifted one bit to the left with the
+ // lowest bit used to indicate whether or not the bytes are compressed (see GetFlaggedCount in
+ // the native code).
+ private final int count;
+ // END Android-changed: The character data is managed by the runtime.
+
+ // Android-changed: We make use of new StringIndexOutOfBoundsException constructor signatures.
+ // These improve some error messages. These changes are not all marked individually.
+
+ /** Cache the hash code for the string */
+ private int hash; // Default to 0
+
+ /** use serialVersionUID from JDK 1.0.2 for interoperability */
+ private static final long serialVersionUID = -6849794470754667710L;
+
+ /**
+ * Class String is special cased within the Serialization Stream Protocol.
+ *
+ * A String instance is written into an ObjectOutputStream according to
+ * <a href="{@docRoot}/../platform/serialization/spec/output.html">
+ * Object Serialization Specification, Section 6.2, "Stream Elements"</a>
+ */
+ private static final ObjectStreamField[] serialPersistentFields =
+ new ObjectStreamField[0];
+
+ /**
+ * Initializes a newly created {@code String} object so that it represents
+ * an empty character sequence. Note that use of this constructor is
+ * unnecessary since Strings are immutable.
+ */
+ public String() {
+ // Android-changed: Constructor unsupported as all calls are intercepted by the runtime.
+ throw new UnsupportedOperationException("Use StringFactory instead.");
+ }
+
+ /**
+ * Initializes a newly created {@code String} object so that it represents
+ * the same sequence of characters as the argument; in other words, the
+ * newly created string is a copy of the argument string. Unless an
+ * explicit copy of {@code original} is needed, use of this constructor is
+ * unnecessary since Strings are immutable.
+ *
+ * @param original
+ * A {@code String}
+ */
+ public String(String original) {
+ // Android-changed: Constructor unsupported as all calls are intercepted by the runtime.
+ throw new UnsupportedOperationException("Use StringFactory instead.");
+ }
+
+ /**
+ * Allocates a new {@code String} so that it represents the sequence of
+ * characters currently contained in the character array argument. The
+ * contents of the character array are copied; subsequent modification of
+ * the character array does not affect the newly created string.
+ *
+ * @param value
+ * The initial value of the string
+ */
+ public String(char value[]) {
+ // Android-changed: Constructor unsupported as all calls are intercepted by the runtime.
+ throw new UnsupportedOperationException("Use StringFactory instead.");
+ }
+
+ /**
+ * Allocates a new {@code String} that contains characters from a subarray
+ * of the character array argument. The {@code offset} argument is the
+ * index of the first character of the subarray and the {@code count}
+ * argument specifies the length of the subarray. The contents of the
+ * subarray are copied; subsequent modification of the character array does
+ * not affect the newly created string.
+ *
+ * @param value
+ * Array that is the source of characters
+ *
+ * @param offset
+ * The initial offset
+ *
+ * @param count
+ * The length
+ *
+ * @throws IndexOutOfBoundsException
+ * If the {@code offset} and {@code count} arguments index
+ * characters outside the bounds of the {@code value} array
+ */
+ public String(char value[], int offset, int count) {
+ // Android-changed: Constructor unsupported as all calls are intercepted by the runtime.
+ throw new UnsupportedOperationException("Use StringFactory instead.");
+ }
+
+ /**
+ * Allocates a new {@code String} that contains characters from a subarray
+ * of the <a href="Character.html#unicode">Unicode code point</a> array
+ * argument. The {@code offset} argument is the index of the first code
+ * point of the subarray and the {@code count} argument specifies the
+ * length of the subarray. The contents of the subarray are converted to
+ * {@code char}s; subsequent modification of the {@code int} array does not
+ * affect the newly created string.
+ *
+ * @param codePoints
+ * Array that is the source of Unicode code points
+ *
+ * @param offset
+ * The initial offset
+ *
+ * @param count
+ * The length
+ *
+ * @throws IllegalArgumentException
+ * If any invalid Unicode code point is found in {@code
+ * codePoints}
+ *
+ * @throws IndexOutOfBoundsException
+ * If the {@code offset} and {@code count} arguments index
+ * characters outside the bounds of the {@code codePoints} array
+ *
+ * @since 1.5
+ */
+ public String(int[] codePoints, int offset, int count) {
+ // Android-changed: Constructor unsupported as all calls are intercepted by the runtime.
+ throw new UnsupportedOperationException("Use StringFactory instead.");
+ }
+
+ /**
+ * Allocates a new {@code String} constructed from a subarray of an array
+ * of 8-bit integer values.
+ *
+ * <p> The {@code offset} argument is the index of the first byte of the
+ * subarray, and the {@code count} argument specifies the length of the
+ * subarray.
+ *
+ * <p> Each {@code byte} in the subarray is converted to a {@code char} as
+ * specified in the method above.
+ *
+ * @deprecated This method does not properly convert bytes into characters.
+ * As of JDK 1.1, the preferred way to do this is via the
+ * {@code String} constructors that take a {@link
+ * java.nio.charset.Charset}, charset name, or that use the platform's
+ * default charset.
+ *
+ * @param ascii
+ * The bytes to be converted to characters
+ *
+ * @param hibyte
+ * The top 8 bits of each 16-bit Unicode code unit
+ *
+ * @param offset
+ * The initial offset
+ * @param count
+ * The length
+ *
+ * @throws IndexOutOfBoundsException
+ * If the {@code offset} or {@code count} argument is invalid
+ *
+ * @see #String(byte[], int)
+ * @see #String(byte[], int, int, java.lang.String)
+ * @see #String(byte[], int, int, java.nio.charset.Charset)
+ * @see #String(byte[], int, int)
+ * @see #String(byte[], java.lang.String)
+ * @see #String(byte[], java.nio.charset.Charset)
+ * @see #String(byte[])
+ */
+ @Deprecated
+ public String(byte ascii[], int hibyte, int offset, int count) {
+ // Android-changed: Constructor unsupported as all calls are intercepted by the runtime.
+ throw new UnsupportedOperationException("Use StringFactory instead.");
+ }
+
+ /**
+ * Allocates a new {@code String} containing characters constructed from
+ * an array of 8-bit integer values. Each character <i>c</i>in the
+ * resulting string is constructed from the corresponding component
+ * <i>b</i> in the byte array such that:
+ *
+ * <blockquote><pre>
+ * <b><i>c</i></b> == (char)(((hibyte & 0xff) << 8)
+ * | (<b><i>b</i></b> & 0xff))
+ * </pre></blockquote>
+ *
+ * @deprecated This method does not properly convert bytes into
+ * characters. As of JDK 1.1, the preferred way to do this is via the
+ * {@code String} constructors that take a {@link
+ * java.nio.charset.Charset}, charset name, or that use the platform's
+ * default charset.
+ *
+ * @param ascii
+ * The bytes to be converted to characters
+ *
+ * @param hibyte
+ * The top 8 bits of each 16-bit Unicode code unit
+ *
+ * @see #String(byte[], int, int, java.lang.String)
+ * @see #String(byte[], int, int, java.nio.charset.Charset)
+ * @see #String(byte[], int, int)
+ * @see #String(byte[], java.lang.String)
+ * @see #String(byte[], java.nio.charset.Charset)
+ * @see #String(byte[])
+ */
+ @Deprecated
+ public String(byte ascii[], int hibyte) {
+ // Android-changed: Constructor unsupported as all calls are intercepted by the runtime.
+ throw new UnsupportedOperationException("Use StringFactory instead.");
+ }
+
+ /**
+ * Constructs a new {@code String} by decoding the specified subarray of
+ * bytes using the specified charset. The length of the new {@code String}
+ * is a function of the charset, and hence may not be equal to the length
+ * of the subarray.
+ *
+ * <p> The behavior of this constructor when the given bytes are not valid
+ * in the given charset is unspecified. The {@link
+ * java.nio.charset.CharsetDecoder} class should be used when more control
+ * over the decoding process is required.
+ *
+ * @param bytes
+ * The bytes to be decoded into characters
+ *
+ * @param offset
+ * The index of the first byte to decode
+ *
+ * @param length
+ * The number of bytes to decode
+
+ * @param charsetName
+ * The name of a supported {@linkplain java.nio.charset.Charset
+ * charset}
+ *
+ * @throws UnsupportedEncodingException
+ * If the named charset is not supported
+ *
+ * @throws IndexOutOfBoundsException
+ * If the {@code offset} and {@code length} arguments index
+ * characters outside the bounds of the {@code bytes} array
+ *
+ * @since JDK1.1
+ */
+ public String(byte bytes[], int offset, int length, String charsetName)
+ throws UnsupportedEncodingException {
+ // Android-changed: Constructor unsupported as all calls are intercepted by the runtime.
+ throw new UnsupportedOperationException("Use StringFactory instead.");
+ }
+
+ /**
+ * Constructs a new {@code String} by decoding the specified subarray of
+ * bytes using the specified {@linkplain java.nio.charset.Charset charset}.
+ * The length of the new {@code String} is a function of the charset, and
+ * hence may not be equal to the length of the subarray.
+ *
+ * <p> This method always replaces malformed-input and unmappable-character
+ * sequences with this charset's default replacement string. The {@link
+ * java.nio.charset.CharsetDecoder} class should be used when more control
+ * over the decoding process is required.
+ *
+ * @param bytes
+ * The bytes to be decoded into characters
+ *
+ * @param offset
+ * The index of the first byte to decode
+ *
+ * @param length
+ * The number of bytes to decode
+ *
+ * @param charset
+ * The {@linkplain java.nio.charset.Charset charset} to be used to
+ * decode the {@code bytes}
+ *
+ * @throws IndexOutOfBoundsException
+ * If the {@code offset} and {@code length} arguments index
+ * characters outside the bounds of the {@code bytes} array
+ *
+ * @since 1.6
+ */
+ public String(byte bytes[], int offset, int length, Charset charset) {
+ // Android-changed: Constructor unsupported as all calls are intercepted by the runtime.
+ throw new UnsupportedOperationException("Use StringFactory instead.");
+ }
+
+ /**
+ * Constructs a new {@code String} by decoding the specified array of bytes
+ * using the specified {@linkplain java.nio.charset.Charset charset}. The
+ * length of the new {@code String} is a function of the charset, and hence
+ * may not be equal to the length of the byte array.
+ *
+ * <p> The behavior of this constructor when the given bytes are not valid
+ * in the given charset is unspecified. The {@link
+ * java.nio.charset.CharsetDecoder} class should be used when more control
+ * over the decoding process is required.
+ *
+ * @param bytes
+ * The bytes to be decoded into characters
+ *
+ * @param charsetName
+ * The name of a supported {@linkplain java.nio.charset.Charset
+ * charset}
+ *
+ * @throws UnsupportedEncodingException
+ * If the named charset is not supported
+ *
+ * @since JDK1.1
+ */
+ public String(byte bytes[], String charsetName)
+ throws UnsupportedEncodingException {
+ // Android-changed: Constructor unsupported as all calls are intercepted by the runtime.
+ throw new UnsupportedOperationException("Use StringFactory instead.");
+ }
+
+ /**
+ * Constructs a new {@code String} by decoding the specified array of
+ * bytes using the specified {@linkplain java.nio.charset.Charset charset}.
+ * The length of the new {@code String} is a function of the charset, and
+ * hence may not be equal to the length of the byte array.
+ *
+ * <p> This method always replaces malformed-input and unmappable-character
+ * sequences with this charset's default replacement string. The {@link
+ * java.nio.charset.CharsetDecoder} class should be used when more control
+ * over the decoding process is required.
+ *
+ * @param bytes
+ * The bytes to be decoded into characters
+ *
+ * @param charset
+ * The {@linkplain java.nio.charset.Charset charset} to be used to
+ * decode the {@code bytes}
+ *
+ * @since 1.6
+ */
+ public String(byte bytes[], Charset charset) {
+ // Android-changed: Constructor unsupported as all calls are intercepted by the runtime.
+ throw new UnsupportedOperationException("Use StringFactory instead.");
+ }
+
+ /**
+ * Constructs a new {@code String} by decoding the specified subarray of
+ * bytes using the platform's default charset. The length of the new
+ * {@code String} is a function of the charset, and hence may not be equal
+ * to the length of the subarray.
+ *
+ * <p> The behavior of this constructor when the given bytes are not valid
+ * in the default charset is unspecified. The {@link
+ * java.nio.charset.CharsetDecoder} class should be used when more control
+ * over the decoding process is required.
+ *
+ * @param bytes
+ * The bytes to be decoded into characters
+ *
+ * @param offset
+ * The index of the first byte to decode
+ *
+ * @param length
+ * The number of bytes to decode
+ *
+ * @throws IndexOutOfBoundsException
+ * If the {@code offset} and the {@code length} arguments index
+ * characters outside the bounds of the {@code bytes} array
+ *
+ * @since JDK1.1
+ */
+ public String(byte bytes[], int offset, int length) {
+ // Android-changed: Constructor unsupported as all calls are intercepted by the runtime.
+ throw new UnsupportedOperationException("Use StringFactory instead.");
+ }
+
+ /**
+ * Constructs a new {@code String} by decoding the specified array of bytes
+ * using the platform's default charset. The length of the new {@code
+ * String} is a function of the charset, and hence may not be equal to the
+ * length of the byte array.
+ *
+ * <p> The behavior of this constructor when the given bytes are not valid
+ * in the default charset is unspecified. The {@link
+ * java.nio.charset.CharsetDecoder} class should be used when more control
+ * over the decoding process is required.
+ *
+ * @param bytes
+ * The bytes to be decoded into characters
+ *
+ * @since JDK1.1
+ */
+ public String(byte bytes[]) {
+ // Android-changed: Constructor unsupported as all calls are intercepted by the runtime.
+ throw new UnsupportedOperationException("Use StringFactory instead.");
+ }
+
+ /**
+ * Allocates a new string that contains the sequence of characters
+ * currently contained in the string buffer argument. The contents of the
+ * string buffer are copied; subsequent modification of the string buffer
+ * does not affect the newly created string.
+ *
+ * @param buffer
+ * A {@code StringBuffer}
+ */
+ public String(StringBuffer buffer) {
+ // Android-changed: Constructor unsupported as all calls are intercepted by the runtime.
+ throw new UnsupportedOperationException("Use StringFactory instead.");
+ }
+
+ /**
+ * Allocates a new string that contains the sequence of characters
+ * currently contained in the string builder argument. The contents of the
+ * string builder are copied; subsequent modification of the string builder
+ * does not affect the newly created string.
+ *
+ * <p> This constructor is provided to ease migration to {@code
+ * StringBuilder}. Obtaining a string from a string builder via the {@code
+ * toString} method is likely to run faster and is generally preferred.
+ *
+ * @param builder
+ * A {@code StringBuilder}
+ *
+ * @since 1.5
+ */
+ public String(StringBuilder builder) {
+ // Android-changed: Constructor unsupported as all calls are intercepted by the runtime.
+ throw new UnsupportedOperationException("Use StringFactory instead.");
+ }
+
+ // Android-removed: Unused package-private constructor String(char[] value, boolean share).
+
+ // BEGIN Android-added: Constructor for internal use.
+ // Not implemented in java as all calls are intercepted by the runtime.
+ /**
+ * Package private constructor
+ *
+ * @deprecated Use {@link #String(char[],int,int)} instead.
+ */
+ @Deprecated
+ String(int offset, int count, char[] value) {
+ throw new UnsupportedOperationException("Use StringFactory instead.");
+ }
+ // END Android-added: Constructor for internal use.
+
+ /**
+ * Returns the length of this string.
+ * The length is equal to the number of <a href="Character.html#unicode">Unicode
+ * code units</a> in the string.
+ *
+ * @return the length of the sequence of characters represented by this
+ * object.
+ */
+ public int length() {
+ // BEGIN Android-changed: Get length from count field rather than value array (see above).
+ // return value.length;
+ final boolean STRING_COMPRESSION_ENABLED = true;
+ if (STRING_COMPRESSION_ENABLED) {
+ // For the compression purposes (save the characters as 8-bit if all characters
+ // are ASCII), the least significant bit of "count" is used as the compression flag.
+ return (count >>> 1);
+ } else {
+ return count;
+ }
+ // END Android-changed: Get length from count field rather than value array (see above).
+ }
+
+ /**
+ * Returns {@code true} if, and only if, {@link #length()} is {@code 0}.
+ *
+ * @return {@code true} if {@link #length()} is {@code 0}, otherwise
+ * {@code false}
+ *
+ * @since 1.6
+ */
+ public boolean isEmpty() {
+ // Android-changed: Get length from count field rather than value array (see above).
+ // Empty string has {@code count == 0} with or without string compression enabled.
+ // return value.length == 0;
+ return count == 0;
+ }
+
+ /**
+ * Returns the {@code char} value at the
+ * specified index. An index ranges from {@code 0} to
+ * {@code length() - 1}. The first {@code char} value of the sequence
+ * is at index {@code 0}, the next at index {@code 1},
+ * and so on, as for array indexing.
+ *
+ * <p>If the {@code char} value specified by the index is a
+ * <a href="Character.html#unicode">surrogate</a>, the surrogate
+ * value is returned.
+ *
+ * @param index the index of the {@code char} value.
+ * @return the {@code char} value at the specified index of this string.
+ * The first {@code char} value is at index {@code 0}.
+ * @exception IndexOutOfBoundsException if the {@code index}
+ * argument is negative or not less than the length of this
+ * string.
+ */
+ // BEGIN Android-changed: Replace with implementation in runtime to access chars (see above).
+ @FastNative
+ public native char charAt(int index);
+ // END Android-changed: Replace with implementation in runtime to access chars (see above).
+
+ /**
+ * Returns the character (Unicode code point) at the specified
+ * index. The index refers to {@code char} values
+ * (Unicode code units) and ranges from {@code 0} to
+ * {@link #length()}{@code - 1}.
+ *
+ * <p> If the {@code char} value specified at the given index
+ * is in the high-surrogate range, the following index is less
+ * than the length of this {@code String}, and the
+ * {@code char} value at the following index is in the
+ * low-surrogate range, then the supplementary code point
+ * corresponding to this surrogate pair is returned. Otherwise,
+ * the {@code char} value at the given index is returned.
+ *
+ * @param index the index to the {@code char} values
+ * @return the code point value of the character at the
+ * {@code index}
+ * @exception IndexOutOfBoundsException if the {@code index}
+ * argument is negative or not less than the length of this
+ * string.
+ * @since 1.5
+ */
+ public int codePointAt(int index) {
+ if ((index < 0) || (index >= length())) {
+ throw new StringIndexOutOfBoundsException(index);
+ }
+ // Android-changed: Skip codePointAtImpl optimization that needs access to java chars.
+ return Character.codePointAt(this, index);
+ }
+
+ /**
+ * Returns the character (Unicode code point) before the specified
+ * index. The index refers to {@code char} values
+ * (Unicode code units) and ranges from {@code 1} to {@link
+ * CharSequence#length() length}.
+ *
+ * <p> If the {@code char} value at {@code (index - 1)}
+ * is in the low-surrogate range, {@code (index - 2)} is not
+ * negative, and the {@code char} value at {@code (index -
+ * 2)} is in the high-surrogate range, then the
+ * supplementary code point value of the surrogate pair is
+ * returned. If the {@code char} value at {@code index -
+ * 1} is an unpaired low-surrogate or a high-surrogate, the
+ * surrogate value is returned.
+ *
+ * @param index the index following the code point that should be returned
+ * @return the Unicode code point value before the given index.
+ * @exception IndexOutOfBoundsException if the {@code index}
+ * argument is less than 1 or greater than the length
+ * of this string.
+ * @since 1.5
+ */
+ public int codePointBefore(int index) {
+ int i = index - 1;
+ if ((i < 0) || (i >= length())) {
+ throw new StringIndexOutOfBoundsException(index);
+ }
+ // Android-changed: Skip codePointBeforeImpl optimization that needs access to java chars.
+ return Character.codePointBefore(this, index);
+ }
+
+ /**
+ * Returns the number of Unicode code points in the specified text
+ * range of this {@code String}. The text range begins at the
+ * specified {@code beginIndex} and extends to the
+ * {@code char} at index {@code endIndex - 1}. Thus the
+ * length (in {@code char}s) of the text range is
+ * {@code endIndex-beginIndex}. Unpaired surrogates within
+ * the text range count as one code point each.
+ *
+ * @param beginIndex the index to the first {@code char} of
+ * the text range.
+ * @param endIndex the index after the last {@code char} of
+ * the text range.
+ * @return the number of Unicode code points in the specified text
+ * range
+ * @exception IndexOutOfBoundsException if the
+ * {@code beginIndex} is negative, or {@code endIndex}
+ * is larger than the length of this {@code String}, or
+ * {@code beginIndex} is larger than {@code endIndex}.
+ * @since 1.5
+ */
+ public int codePointCount(int beginIndex, int endIndex) {
+ if (beginIndex < 0 || endIndex > length() || beginIndex > endIndex) {
+ throw new IndexOutOfBoundsException();
+ }
+ // Android-changed: Skip codePointCountImpl optimization that needs access to java chars.
+ return Character.codePointCount(this, beginIndex, endIndex);
+ }
+
+ /**
+ * Returns the index within this {@code String} that is
+ * offset from the given {@code index} by
+ * {@code codePointOffset} code points. Unpaired surrogates
+ * within the text range given by {@code index} and
+ * {@code codePointOffset} count as one code point each.
+ *
+ * @param index the index to be offset
+ * @param codePointOffset the offset in code points
+ * @return the index within this {@code String}
+ * @exception IndexOutOfBoundsException if {@code index}
+ * is negative or larger then the length of this
+ * {@code String}, or if {@code codePointOffset} is positive
+ * and the substring starting with {@code index} has fewer
+ * than {@code codePointOffset} code points,
+ * or if {@code codePointOffset} is negative and the substring
+ * before {@code index} has fewer than the absolute value
+ * of {@code codePointOffset} code points.
+ * @since 1.5
+ */
+ public int offsetByCodePoints(int index, int codePointOffset) {
+ if (index < 0 || index > length()) {
+ throw new IndexOutOfBoundsException();
+ }
+ // Android-changed: Skip offsetByCodePointsImpl optimization that needs access to java chars
+ return Character.offsetByCodePoints(this, index, codePointOffset);
+ }
+
+ /**
+ * Copy characters from this string into dst starting at dstBegin.
+ * This method doesn't perform any range checking.
+ */
+ void getChars(char dst[], int dstBegin) {
+ // Android-changed: Replace arraycopy with native call since chars are managed by runtime.
+ getCharsNoCheck(0, length(), dst, dstBegin);
+ }
+
+ /**
+ * Copies characters from this string into the destination character
+ * array.
+ * <p>
+ * The first character to be copied is at index {@code srcBegin};
+ * the last character to be copied is at index {@code srcEnd-1}
+ * (thus the total number of characters to be copied is
+ * {@code srcEnd-srcBegin}). The characters are copied into the
+ * subarray of {@code dst} starting at index {@code dstBegin}
+ * and ending at index:
+ * <blockquote><pre>
+ * dstBegin + (srcEnd-srcBegin) - 1
+ * </pre></blockquote>
+ *
+ * @param srcBegin index of the first character in the string
+ * to copy.
+ * @param srcEnd index after the last character in the string
+ * to copy.
+ * @param dst the destination array.
+ * @param dstBegin the start offset in the destination array.
+ * @exception IndexOutOfBoundsException If any of the following
+ * is true:
+ * <ul><li>{@code srcBegin} is negative.
+ * <li>{@code srcBegin} is greater than {@code srcEnd}
+ * <li>{@code srcEnd} is greater than the length of this
+ * string
+ * <li>{@code dstBegin} is negative
+ * <li>{@code dstBegin+(srcEnd-srcBegin)} is larger than
+ * {@code dst.length}</ul>
+ */
+ public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
+ // BEGIN Android-changed: Implement in terms of length() and native getCharsNoCheck method.
+ if (dst == null) {
+ throw new NullPointerException("dst == null");
+ }
+
+ if (srcBegin < 0) {
+ throw new StringIndexOutOfBoundsException(this, srcBegin);
+ }
+ if (srcEnd > length()) {
+ throw new StringIndexOutOfBoundsException(this, srcEnd);
+ }
+
+ int n = srcEnd - srcBegin;
+ if (srcEnd < srcBegin) {
+ throw new StringIndexOutOfBoundsException(this, srcBegin, n);
+ }
+
+ if (dstBegin < 0) {
+ throw new ArrayIndexOutOfBoundsException("dstBegin < 0. dstBegin=" + dstBegin);
+ }
+ // dstBegin can be equal to dst.length, but only in the case where zero chars are to be
+ // copied.
+ if (dstBegin > dst.length) {
+ throw new ArrayIndexOutOfBoundsException(
+ "dstBegin > dst.length. dstBegin=" + dstBegin + ", dst.length=" + dst.length);
+ }
+ if (n > dst.length - dstBegin) {
+ throw new ArrayIndexOutOfBoundsException(
+ "n > dst.length - dstBegin. n=" + n + ", dst.length=" + dst.length
+ + "dstBegin=" + dstBegin);
+ }
+
+ getCharsNoCheck(srcBegin, srcEnd, dst, dstBegin);
+ // END Android-changed: Implement in terms of length() and native getCharsNoCheck method.
+ }
+
+ // BEGIN Android-added: Native method to access char storage managed by runtime.
+ /**
+ * getChars without bounds checks, for use by other classes
+ * within the java.lang package only. The caller is responsible for
+ * ensuring that start >= 0 && start <= end && end <= count.
+ */
+ @FastNative
+ native void getCharsNoCheck(int start, int end, char[] buffer, int index);
+ // END Android-added: Native method to access char storage managed by runtime.
+
+ /**
+ * Copies characters from this string into the destination byte array. Each
+ * byte receives the 8 low-order bits of the corresponding character. The
+ * eight high-order bits of each character are not copied and do not
+ * participate in the transfer in any way.
+ *
+ * <p> The first character to be copied is at index {@code srcBegin}; the
+ * last character to be copied is at index {@code srcEnd-1}. The total
+ * number of characters to be copied is {@code srcEnd-srcBegin}. The
+ * characters, converted to bytes, are copied into the subarray of {@code
+ * dst} starting at index {@code dstBegin} and ending at index:
+ *
+ * <blockquote><pre>
+ * dstBegin + (srcEnd-srcBegin) - 1
+ * </pre></blockquote>
+ *
+ * @deprecated This method does not properly convert characters into
+ * bytes. As of JDK 1.1, the preferred way to do this is via the
+ * {@link #getBytes()} method, which uses the platform's default charset.
+ *
+ * @param srcBegin
+ * Index of the first character in the string to copy
+ *
+ * @param srcEnd
+ * Index after the last character in the string to copy
+ *
+ * @param dst
+ * The destination array
+ *
+ * @param dstBegin
+ * The start offset in the destination array
+ *
+ * @throws IndexOutOfBoundsException
+ * If any of the following is true:
+ * <ul>
+ * <li> {@code srcBegin} is negative
+ * <li> {@code srcBegin} is greater than {@code srcEnd}
+ * <li> {@code srcEnd} is greater than the length of this String
+ * <li> {@code dstBegin} is negative
+ * <li> {@code dstBegin+(srcEnd-srcBegin)} is larger than {@code
+ * dst.length}
+ * </ul>
+ */
+ @Deprecated
+ public void getBytes(int srcBegin, int srcEnd, byte dst[], int dstBegin) {
+ if (srcBegin < 0) {
+ throw new StringIndexOutOfBoundsException(this, srcBegin);
+ }
+ if (srcEnd > length()) {
+ throw new StringIndexOutOfBoundsException(this, srcEnd);
+ }
+ if (srcBegin > srcEnd) {
+ throw new StringIndexOutOfBoundsException(this, srcEnd - srcBegin);
+ }
+
+ int j = dstBegin;
+ int n = srcEnd;
+ int i = srcBegin;
+
+ while (i < n) {
+ dst[j++] = (byte)charAt(i++);
+ }
+ }
+
+ /**
+ * Encodes this {@code String} into a sequence of bytes using the named
+ * charset, storing the result into a new byte array.
+ *
+ * <p> The behavior of this method when this string cannot be encoded in
+ * the given charset is unspecified. The {@link
+ * java.nio.charset.CharsetEncoder} class should be used when more control
+ * over the encoding process is required.
+ *
+ * @param charsetName
+ * The name of a supported {@linkplain java.nio.charset.Charset
+ * charset}
+ *
+ * @return The resultant byte array
+ *
+ * @throws UnsupportedEncodingException
+ * If the named charset is not supported
+ *
+ * @since JDK1.1
+ */
+ public byte[] getBytes(String charsetName)
+ throws UnsupportedEncodingException {
+ if (charsetName == null) throw new NullPointerException();
+ // Android-changed: Skip StringCoding optimization that needs access to java chars.
+ // return StringCoding.encode(charsetName, value, 0, value.length);
+ return getBytes(Charset.forNameUEE(charsetName));
+ }
+
+ /**
+ * Encodes this {@code String} into a sequence of bytes using the given
+ * {@linkplain java.nio.charset.Charset charset}, storing the result into a
+ * new byte array.
+ *
+ * <p> This method always replaces malformed-input and unmappable-character
+ * sequences with this charset's default replacement byte array. The
+ * {@link java.nio.charset.CharsetEncoder} class should be used when more
+ * control over the encoding process is required.
+ *
+ * @param charset
+ * The {@linkplain java.nio.charset.Charset} to be used to encode
+ * the {@code String}
+ *
+ * @return The resultant byte array
+ *
+ * @since 1.6
+ */
+ public byte[] getBytes(Charset charset) {
+ // BEGIN Android-changed: Skip StringCoding optimization that needs access to java chars.
+ // if (charset == null) throw new NullPointerException();
+ // return StringCoding.encode(charset, value, 0, value.length);
+ if (charset == null) {
+ throw new NullPointerException("charset == null");
+ }
+
+ final int len = length();
+ final String name = charset.name();
+ if ("UTF-8".equals(name)) {
+ return CharsetUtils.toUtf8Bytes(this, 0, len);
+ } else if ("ISO-8859-1".equals(name)) {
+ return CharsetUtils.toIsoLatin1Bytes(this, 0, len);
+ } else if ("US-ASCII".equals(name)) {
+ return CharsetUtils.toAsciiBytes(this, 0, len);
+ } else if ("UTF-16BE".equals(name)) {
+ return CharsetUtils.toBigEndianUtf16Bytes(this, 0, len);
+ }
+
+ ByteBuffer buffer = charset.encode(this);
+ byte[] bytes = new byte[buffer.limit()];
+ buffer.get(bytes);
+ return bytes;
+ // END Android-changed: Skip StringCoding optimization that needs access to java chars.
+ }
+
+ /**
+ * Encodes this {@code String} into a sequence of bytes using the
+ * platform's default charset, storing the result into a new byte array.
+ *
+ * <p> The behavior of this method when this string cannot be encoded in
+ * the default charset is unspecified. The {@link
+ * java.nio.charset.CharsetEncoder} class should be used when more control
+ * over the encoding process is required.
+ *
+ * @return The resultant byte array
+ *
+ * @since JDK1.1
+ */
+ public byte[] getBytes() {
+ // Android-changed: Skip StringCoding optimization that needs access to java chars.
+ // return StringCoding.encode(value, 0, value.length);
+ return getBytes(Charset.defaultCharset());
+ }
+
+ /**
+ * Compares this string to the specified object. The result is {@code
+ * true} if and only if the argument is not {@code null} and is a {@code
+ * String} object that represents the same sequence of characters as this
+ * object.
+ *
+ * @param anObject
+ * The object to compare this {@code String} against
+ *
+ * @return {@code true} if the given object represents a {@code String}
+ * equivalent to this string, {@code false} otherwise
+ *
+ * @see #compareTo(String)
+ * @see #equalsIgnoreCase(String)
+ */
+ public boolean equals(Object anObject) {
+ if (this == anObject) {
+ return true;
+ }
+ if (anObject instanceof String) {
+ String anotherString = (String)anObject;
+ int n = length();
+ if (n == anotherString.length()) {
+ int i = 0;
+ while (n-- != 0) {
+ if (charAt(i) != anotherString.charAt(i))
+ return false;
+ i++;
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Compares this string to the specified {@code StringBuffer}. The result
+ * is {@code true} if and only if this {@code String} represents the same
+ * sequence of characters as the specified {@code StringBuffer}. This method
+ * synchronizes on the {@code StringBuffer}.
+ *
+ * @param sb
+ * The {@code StringBuffer} to compare this {@code String} against
+ *
+ * @return {@code true} if this {@code String} represents the same
+ * sequence of characters as the specified {@code StringBuffer},
+ * {@code false} otherwise
+ *
+ * @since 1.4
+ */
+ public boolean contentEquals(StringBuffer sb) {
+ return contentEquals((CharSequence)sb);
+ }
+
+ private boolean nonSyncContentEquals(AbstractStringBuilder sb) {
+ char v2[] = sb.getValue();
+ int n = length();
+ if (n != sb.length()) {
+ return false;
+ }
+ for (int i = 0; i < n; i++) {
+ if (charAt(i) != v2[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Compares this string to the specified {@code CharSequence}. The
+ * result is {@code true} if and only if this {@code String} represents the
+ * same sequence of char values as the specified sequence. Note that if the
+ * {@code CharSequence} is a {@code StringBuffer} then the method
+ * synchronizes on it.
+ *
+ * @param cs
+ * The sequence to compare this {@code String} against
+ *
+ * @return {@code true} if this {@code String} represents the same
+ * sequence of char values as the specified sequence, {@code
+ * false} otherwise
+ *
+ * @since 1.5
+ */
+ public boolean contentEquals(CharSequence cs) {
+ // Argument is a StringBuffer, StringBuilder
+ if (cs instanceof AbstractStringBuilder) {
+ if (cs instanceof StringBuffer) {
+ synchronized(cs) {
+ return nonSyncContentEquals((AbstractStringBuilder)cs);
+ }
+ } else {
+ return nonSyncContentEquals((AbstractStringBuilder)cs);
+ }
+ }
+ // Argument is a String
+ if (cs instanceof String) {
+ return equals(cs);
+ }
+ // Argument is a generic CharSequence
+ int n = length();
+ if (n != cs.length()) {
+ return false;
+ }
+ for (int i = 0; i < n; i++) {
+ if (charAt(i) != cs.charAt(i)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Compares this {@code String} to another {@code String}, ignoring case
+ * considerations. Two strings are considered equal ignoring case if they
+ * are of the same length and corresponding characters in the two strings
+ * are equal ignoring case.
+ *
+ * <p> Two characters {@code c1} and {@code c2} are considered the same
+ * ignoring case if at least one of the following is true:
+ * <ul>
+ * <li> The two characters are the same (as compared by the
+ * {@code ==} operator)
+ * <li> Applying the method {@link
+ * java.lang.Character#toUpperCase(char)} to each character
+ * produces the same result
+ * <li> Applying the method {@link
+ * java.lang.Character#toLowerCase(char)} to each character
+ * produces the same result
+ * </ul>
+ *
+ * @param anotherString
+ * The {@code String} to compare this {@code String} against
+ *
+ * @return {@code true} if the argument is not {@code null} and it
+ * represents an equivalent {@code String} ignoring case; {@code
+ * false} otherwise
+ *
+ * @see #equals(Object)
+ */
+ public boolean equalsIgnoreCase(String anotherString) {
+ final int len = length();
+ return (this == anotherString) ? true
+ : (anotherString != null)
+ && (anotherString.length() == len)
+ && regionMatches(true, 0, anotherString, 0, len);
+ }
+
+ /**
+ * Compares two strings lexicographically.
+ * The comparison is based on the Unicode value of each character in
+ * the strings. The character sequence represented by this
+ * {@code String} object is compared lexicographically to the
+ * character sequence represented by the argument string. The result is
+ * a negative integer if this {@code String} object
+ * lexicographically precedes the argument string. The result is a
+ * positive integer if this {@code String} object lexicographically
+ * follows the argument string. The result is zero if the strings
+ * are equal; {@code compareTo} returns {@code 0} exactly when
+ * the {@link #equals(Object)} method would return {@code true}.
+ * <p>
+ * This is the definition of lexicographic ordering. If two strings are
+ * different, then either they have different characters at some index
+ * that is a valid index for both strings, or their lengths are different,
+ * or both. If they have different characters at one or more index
+ * positions, let <i>k</i> be the smallest such index; then the string
+ * whose character at position <i>k</i> has the smaller value, as
+ * determined by using the < operator, lexicographically precedes the
+ * other string. In this case, {@code compareTo} returns the
+ * difference of the two character values at position {@code k} in
+ * the two string -- that is, the value:
+ * <blockquote><pre>
+ * this.charAt(k)-anotherString.charAt(k)
+ * </pre></blockquote>
+ * If there is no index position at which they differ, then the shorter
+ * string lexicographically precedes the longer string. In this case,
+ * {@code compareTo} returns the difference of the lengths of the
+ * strings -- that is, the value:
+ * <blockquote><pre>
+ * this.length()-anotherString.length()
+ * </pre></blockquote>
+ *
+ * @param anotherString the {@code String} to be compared.
+ * @return the value {@code 0} if the argument string is equal to
+ * this string; a value less than {@code 0} if this string
+ * is lexicographically less than the string argument; and a
+ * value greater than {@code 0} if this string is
+ * lexicographically greater than the string argument.
+ */
+ // BEGIN Android-changed: Replace with implementation in runtime to access chars (see above).
+ @FastNative
+ public native int compareTo(String anotherString);
+ // END Android-changed: Replace with implementation in runtime to access chars (see above).
+
+ /**
+ * A Comparator that orders {@code String} objects as by
+ * {@code compareToIgnoreCase}. This comparator is serializable.
+ * <p>
+ * Note that this Comparator does <em>not</em> take locale into account,
+ * and will result in an unsatisfactory ordering for certain locales.
+ * The java.text package provides <em>Collators</em> to allow
+ * locale-sensitive ordering.
+ *
+ * @see java.text.Collator#compare(String, String)
+ * @since 1.2
+ */
+ public static final Comparator<String> CASE_INSENSITIVE_ORDER
+ = new CaseInsensitiveComparator();
+ private static class CaseInsensitiveComparator
+ implements Comparator<String>, java.io.Serializable {
+ // use serialVersionUID from JDK 1.2.2 for interoperability
+ private static final long serialVersionUID = 8575799808933029326L;
+
+ public int compare(String s1, String s2) {
+ int n1 = s1.length();
+ int n2 = s2.length();
+ int min = Math.min(n1, n2);
+ for (int i = 0; i < min; i++) {
+ char c1 = s1.charAt(i);
+ char c2 = s2.charAt(i);
+ if (c1 != c2) {
+ c1 = Character.toUpperCase(c1);
+ c2 = Character.toUpperCase(c2);
+ if (c1 != c2) {
+ c1 = Character.toLowerCase(c1);
+ c2 = Character.toLowerCase(c2);
+ if (c1 != c2) {
+ // No overflow because of numeric promotion
+ return c1 - c2;
+ }
+ }
+ }
+ }
+ return n1 - n2;
+ }
+
+ /** Replaces the de-serialized object. */
+ private Object readResolve() { return CASE_INSENSITIVE_ORDER; }
+ }
+
+ /**
+ * Compares two strings lexicographically, ignoring case
+ * differences. This method returns an integer whose sign is that of
+ * calling {@code compareTo} with normalized versions of the strings
+ * where case differences have been eliminated by calling
+ * {@code Character.toLowerCase(Character.toUpperCase(character))} on
+ * each character.
+ * <p>
+ * Note that this method does <em>not</em> take locale into account,
+ * and will result in an unsatisfactory ordering for certain locales.
+ * The java.text package provides <em>collators</em> to allow
+ * locale-sensitive ordering.
+ *
+ * @param str the {@code String} to be compared.
+ * @return a negative integer, zero, or a positive integer as the
+ * specified String is greater than, equal to, or less
+ * than this String, ignoring case considerations.
+ * @see java.text.Collator#compare(String, String)
+ * @since 1.2
+ */
+ public int compareToIgnoreCase(String str) {
+ return CASE_INSENSITIVE_ORDER.compare(this, str);
+ }
+
+ /**
+ * Tests if two string regions are equal.
+ * <p>
+ * A substring of this {@code String} object is compared to a substring
+ * of the argument other. The result is true if these substrings
+ * represent identical character sequences. The substring of this
+ * {@code String} object to be compared begins at index {@code toffset}
+ * and has length {@code len}. The substring of other to be compared
+ * begins at index {@code ooffset} and has length {@code len}. The
+ * result is {@code false} if and only if at least one of the following
+ * is true:
+ * <ul><li>{@code toffset} is negative.
+ * <li>{@code ooffset} is negative.
+ * <li>{@code toffset+len} is greater than the length of this
+ * {@code String} object.
+ * <li>{@code ooffset+len} is greater than the length of the other
+ * argument.
+ * <li>There is some nonnegative integer <i>k</i> less than {@code len}
+ * such that:
+ * {@code this.charAt(toffset + }<i>k</i>{@code ) != other.charAt(ooffset + }
+ * <i>k</i>{@code )}
+ * </ul>
+ *
+ * @param toffset the starting offset of the subregion in this string.
+ * @param other the string argument.
+ * @param ooffset the starting offset of the subregion in the string
+ * argument.
+ * @param len the number of characters to compare.
+ * @return {@code true} if the specified subregion of this string
+ * exactly matches the specified subregion of the string argument;
+ * {@code false} otherwise.
+ */
+ public boolean regionMatches(int toffset, String other, int ooffset,
+ int len) {
+ int to = toffset;
+ int po = ooffset;
+ // Note: toffset, ooffset, or len might be near -1>>>1.
+ if ((ooffset < 0) || (toffset < 0)
+ || (toffset > (long)length() - len)
+ || (ooffset > (long)other.length() - len)) {
+ return false;
+ }
+ while (len-- > 0) {
+ if (charAt(to++) != other.charAt(po++)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Tests if two string regions are equal.
+ * <p>
+ * A substring of this {@code String} object is compared to a substring
+ * of the argument {@code other}. The result is {@code true} if these
+ * substrings represent character sequences that are the same, ignoring
+ * case if and only if {@code ignoreCase} is true. The substring of
+ * this {@code String} object to be compared begins at index
+ * {@code toffset} and has length {@code len}. The substring of
+ * {@code other} to be compared begins at index {@code ooffset} and
+ * has length {@code len}. The result is {@code false} if and only if
+ * at least one of the following is true:
+ * <ul><li>{@code toffset} is negative.
+ * <li>{@code ooffset} is negative.
+ * <li>{@code toffset+len} is greater than the length of this
+ * {@code String} object.
+ * <li>{@code ooffset+len} is greater than the length of the other
+ * argument.
+ * <li>{@code ignoreCase} is {@code false} and there is some nonnegative
+ * integer <i>k</i> less than {@code len} such that:
+ * <blockquote><pre>
+ * this.charAt(toffset+k) != other.charAt(ooffset+k)
+ * </pre></blockquote>
+ * <li>{@code ignoreCase} is {@code true} and there is some nonnegative
+ * integer <i>k</i> less than {@code len} such that:
+ * <blockquote><pre>
+ * Character.toLowerCase(this.charAt(toffset+k)) !=
+ Character.toLowerCase(other.charAt(ooffset+k))
+ * </pre></blockquote>
+ * and:
+ * <blockquote><pre>
+ * Character.toUpperCase(this.charAt(toffset+k)) !=
+ * Character.toUpperCase(other.charAt(ooffset+k))
+ * </pre></blockquote>
+ * </ul>
+ *
+ * @param ignoreCase if {@code true}, ignore case when comparing
+ * characters.
+ * @param toffset the starting offset of the subregion in this
+ * string.
+ * @param other the string argument.
+ * @param ooffset the starting offset of the subregion in the string
+ * argument.
+ * @param len the number of characters to compare.
+ * @return {@code true} if the specified subregion of this string
+ * matches the specified subregion of the string argument;
+ * {@code false} otherwise. Whether the matching is exact
+ * or case insensitive depends on the {@code ignoreCase}
+ * argument.
+ */
+ public boolean regionMatches(boolean ignoreCase, int toffset,
+ String other, int ooffset, int len) {
+ int to = toffset;
+ int po = ooffset;
+ // Note: toffset, ooffset, or len might be near -1>>>1.
+ if ((ooffset < 0) || (toffset < 0)
+ || (toffset > (long)length() - len)
+ || (ooffset > (long)other.length() - len)) {
+ return false;
+ }
+ while (len-- > 0) {
+ char c1 = charAt(to++);
+ char c2 = other.charAt(po++);
+ if (c1 == c2) {
+ continue;
+ }
+ if (ignoreCase) {
+ // If characters don't match but case may be ignored,
+ // try converting both characters to uppercase.
+ // If the results match, then the comparison scan should
+ // continue.
+ char u1 = Character.toUpperCase(c1);
+ char u2 = Character.toUpperCase(c2);
+ if (u1 == u2) {
+ continue;
+ }
+ // Unfortunately, conversion to uppercase does not work properly
+ // for the Georgian alphabet, which has strange rules about case
+ // conversion. So we need to make one last check before
+ // exiting.
+ if (Character.toLowerCase(u1) == Character.toLowerCase(u2)) {
+ continue;
+ }
+ }
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Tests if the substring of this string beginning at the
+ * specified index starts with the specified prefix.
+ *
+ * @param prefix the prefix.
+ * @param toffset where to begin looking in this string.
+ * @return {@code true} if the character sequence represented by the
+ * argument is a prefix of the substring of this object starting
+ * at index {@code toffset}; {@code false} otherwise.
+ * The result is {@code false} if {@code toffset} is
+ * negative or greater than the length of this
+ * {@code String} object; otherwise the result is the same
+ * as the result of the expression
+ * <pre>
+ * this.substring(toffset).startsWith(prefix)
+ * </pre>
+ */
+ public boolean startsWith(String prefix, int toffset) {
+ int to = toffset;
+ int po = 0;
+ int pc = prefix.length();
+ // Note: toffset might be near -1>>>1.
+ if ((toffset < 0) || (toffset > length() - pc)) {
+ return false;
+ }
+ while (--pc >= 0) {
+ if (charAt(to++) != prefix.charAt(po++)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Tests if this string starts with the specified prefix.
+ *
+ * @param prefix the prefix.
+ * @return {@code true} if the character sequence represented by the
+ * argument is a prefix of the character sequence represented by
+ * this string; {@code false} otherwise.
+ * Note also that {@code true} will be returned if the
+ * argument is an empty string or is equal to this
+ * {@code String} object as determined by the
+ * {@link #equals(Object)} method.
+ * @since 1. 0
+ */
+ public boolean startsWith(String prefix) {
+ return startsWith(prefix, 0);
+ }
+
+ /**
+ * Tests if this string ends with the specified suffix.
+ *
+ * @param suffix the suffix.
+ * @return {@code true} if the character sequence represented by the
+ * argument is a suffix of the character sequence represented by
+ * this object; {@code false} otherwise. Note that the
+ * result will be {@code true} if the argument is the
+ * empty string or is equal to this {@code String} object
+ * as determined by the {@link #equals(Object)} method.
+ */
+ public boolean endsWith(String suffix) {
+ return startsWith(suffix, length() - suffix.length());
+ }
+
+ /**
+ * Returns a hash code for this string. The hash code for a
+ * {@code String} object is computed as
+ * <blockquote><pre>
+ * s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
+ * </pre></blockquote>
+ * using {@code int} arithmetic, where {@code s[i]} is the
+ * <i>i</i>th character of the string, {@code n} is the length of
+ * the string, and {@code ^} indicates exponentiation.
+ * (The hash value of the empty string is zero.)
+ *
+ * @return a hash code value for this object.
+ */
+ public int hashCode() {
+ int h = hash;
+ final int len = length();
+ if (h == 0 && len > 0) {
+ for (int i = 0; i < len; i++) {
+ h = 31 * h + charAt(i);
+ }
+ hash = h;
+ }
+ return h;
+ }
+
+ /**
+ * Returns the index within this string of the first occurrence of
+ * the specified character. If a character with value
+ * {@code ch} occurs in the character sequence represented by
+ * this {@code String} object, then the index (in Unicode
+ * code units) of the first such occurrence is returned. For
+ * values of {@code ch} in the range from 0 to 0xFFFF
+ * (inclusive), this is the smallest value <i>k</i> such that:
+ * <blockquote><pre>
+ * this.charAt(<i>k</i>) == ch
+ * </pre></blockquote>
+ * is true. For other values of {@code ch}, it is the
+ * smallest value <i>k</i> such that:
+ * <blockquote><pre>
+ * this.codePointAt(<i>k</i>) == ch
+ * </pre></blockquote>
+ * is true. In either case, if no such character occurs in this
+ * string, then {@code -1} is returned.
+ *
+ * @param ch a character (Unicode code point).
+ * @return the index of the first occurrence of the character in the
+ * character sequence represented by this object, or
+ * {@code -1} if the character does not occur.
+ */
+ public int indexOf(int ch) {
+ return indexOf(ch, 0);
+ }
+
+ /**
+ * Returns the index within this string of the first occurrence of the
+ * specified character, starting the search at the specified index.
+ * <p>
+ * If a character with value {@code ch} occurs in the
+ * character sequence represented by this {@code String}
+ * object at an index no smaller than {@code fromIndex}, then
+ * the index of the first such occurrence is returned. For values
+ * of {@code ch} in the range from 0 to 0xFFFF (inclusive),
+ * this is the smallest value <i>k</i> such that:
+ * <blockquote><pre>
+ * (this.charAt(<i>k</i>) == ch) {@code &&} (<i>k</i> >= fromIndex)
+ * </pre></blockquote>
+ * is true. For other values of {@code ch}, it is the
+ * smallest value <i>k</i> such that:
+ * <blockquote><pre>
+ * (this.codePointAt(<i>k</i>) == ch) {@code &&} (<i>k</i> >= fromIndex)
+ * </pre></blockquote>
+ * is true. In either case, if no such character occurs in this
+ * string at or after position {@code fromIndex}, then
+ * {@code -1} is returned.
+ *
+ * <p>
+ * There is no restriction on the value of {@code fromIndex}. If it
+ * is negative, it has the same effect as if it were zero: this entire
+ * string may be searched. If it is greater than the length of this
+ * string, it has the same effect as if it were equal to the length of
+ * this string: {@code -1} is returned.
+ *
+ * <p>All indices are specified in {@code char} values
+ * (Unicode code units).
+ *
+ * @param ch a character (Unicode code point).
+ * @param fromIndex the index to start the search from.
+ * @return the index of the first occurrence of the character in the
+ * character sequence represented by this object that is greater
+ * than or equal to {@code fromIndex}, or {@code -1}
+ * if the character does not occur.
+ */
+ public int indexOf(int ch, int fromIndex) {
+ final int max = length();
+ if (fromIndex < 0) {
+ fromIndex = 0;
+ } else if (fromIndex >= max) {
+ // Note: fromIndex might be near -1>>>1.
+ return -1;
+ }
+
+ if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
+ // handle most cases here (ch is a BMP code point or a
+ // negative value (invalid code point))
+ for (int i = fromIndex; i < max; i++) {
+ if (charAt(i) == ch) {
+ return i;
+ }
+ }
+ return -1;
+ } else {
+ return indexOfSupplementary(ch, fromIndex);
+ }
+ }
+
+ /**
+ * Handles (rare) calls of indexOf with a supplementary character.
+ */
+ private int indexOfSupplementary(int ch, int fromIndex) {
+ if (Character.isValidCodePoint(ch)) {
+ final char hi = Character.highSurrogate(ch);
+ final char lo = Character.lowSurrogate(ch);
+ final int max = length() - 1;
+ for (int i = fromIndex; i < max; i++) {
+ if (charAt(i) == hi && charAt(i + 1) == lo) {
+ return i;
+ }
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Returns the index within this string of the last occurrence of
+ * the specified character. For values of {@code ch} in the
+ * range from 0 to 0xFFFF (inclusive), the index (in Unicode code
+ * units) returned is the largest value <i>k</i> such that:
+ * <blockquote><pre>
+ * this.charAt(<i>k</i>) == ch
+ * </pre></blockquote>
+ * is true. For other values of {@code ch}, it is the
+ * largest value <i>k</i> such that:
+ * <blockquote><pre>
+ * this.codePointAt(<i>k</i>) == ch
+ * </pre></blockquote>
+ * is true. In either case, if no such character occurs in this
+ * string, then {@code -1} is returned. The
+ * {@code String} is searched backwards starting at the last
+ * character.
+ *
+ * @param ch a character (Unicode code point).
+ * @return the index of the last occurrence of the character in the
+ * character sequence represented by this object, or
+ * {@code -1} if the character does not occur.
+ */
+ public int lastIndexOf(int ch) {
+ return lastIndexOf(ch, length() - 1);
+ }
+
+ /**
+ * Returns the index within this string of the last occurrence of
+ * the specified character, searching backward starting at the
+ * specified index. For values of {@code ch} in the range
+ * from 0 to 0xFFFF (inclusive), the index returned is the largest
+ * value <i>k</i> such that:
+ * <blockquote><pre>
+ * (this.charAt(<i>k</i>) == ch) {@code &&} (<i>k</i> <= fromIndex)
+ * </pre></blockquote>
+ * is true. For other values of {@code ch}, it is the
+ * largest value <i>k</i> such that:
+ * <blockquote><pre>
+ * (this.codePointAt(<i>k</i>) == ch) {@code &&} (<i>k</i> <= fromIndex)
+ * </pre></blockquote>
+ * is true. In either case, if no such character occurs in this
+ * string at or before position {@code fromIndex}, then
+ * {@code -1} is returned.
+ *
+ * <p>All indices are specified in {@code char} values
+ * (Unicode code units).
+ *
+ * @param ch a character (Unicode code point).
+ * @param fromIndex the index to start the search from. There is no
+ * restriction on the value of {@code fromIndex}. If it is
+ * greater than or equal to the length of this string, it has
+ * the same effect as if it were equal to one less than the
+ * length of this string: this entire string may be searched.
+ * If it is negative, it has the same effect as if it were -1:
+ * -1 is returned.
+ * @return the index of the last occurrence of the character in the
+ * character sequence represented by this object that is less
+ * than or equal to {@code fromIndex}, or {@code -1}
+ * if the character does not occur before that point.
+ */
+ public int lastIndexOf(int ch, int fromIndex) {
+ if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
+ // handle most cases here (ch is a BMP code point or a
+ // negative value (invalid code point))
+ int i = Math.min(fromIndex, length() - 1);
+ for (; i >= 0; i--) {
+ if (charAt(i) == ch) {
+ return i;
+ }
+ }
+ return -1;
+ } else {
+ return lastIndexOfSupplementary(ch, fromIndex);
+ }
+ }
+
+ /**
+ * Handles (rare) calls of lastIndexOf with a supplementary character.
+ */
+ private int lastIndexOfSupplementary(int ch, int fromIndex) {
+ if (Character.isValidCodePoint(ch)) {
+ char hi = Character.highSurrogate(ch);
+ char lo = Character.lowSurrogate(ch);
+ int i = Math.min(fromIndex, length() - 2);
+ for (; i >= 0; i--) {
+ if (charAt(i) == hi && charAt(i + 1) == lo) {
+ return i;
+ }
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Returns the index within this string of the first occurrence of the
+ * specified substring.
+ *
+ * <p>The returned index is the smallest value <i>k</i> for which:
+ * <blockquote><pre>
+ * this.startsWith(str, <i>k</i>)
+ * </pre></blockquote>
+ * If no such value of <i>k</i> exists, then {@code -1} is returned.
+ *
+ * @param str the substring to search for.
+ * @return the index of the first occurrence of the specified substring,
+ * or {@code -1} if there is no such occurrence.
+ */
+ public int indexOf(String str) {
+ return indexOf(str, 0);
+ }
+
+ /**
+ * Returns the index within this string of the first occurrence of the
+ * specified substring, starting at the specified index.
+ *
+ * <p>The returned index is the smallest value <i>k</i> for which:
+ * <blockquote><pre>
+ * <i>k</i> >= fromIndex {@code &&} this.startsWith(str, <i>k</i>)
+ * </pre></blockquote>
+ * If no such value of <i>k</i> exists, then {@code -1} is returned.
+ *
+ * @param str the substring to search for.
+ * @param fromIndex the index from which to start the search.
+ * @return the index of the first occurrence of the specified substring,
+ * starting at the specified index,
+ * or {@code -1} if there is no such occurrence.
+ */
+ public int indexOf(String str, int fromIndex) {
+ // Android-changed: Delegate to the static indexOf method below.
+ return indexOf(this, str, fromIndex);
+ }
+
+ // BEGIN Android-added: Private static indexOf method that takes String parameters.
+ // The use of length(), charAt(), etc. makes it more efficient for compressed strings.
+ /**
+ * The source is the string being searched, and the target is the string being searched for.
+ *
+ * @param source the characters being searched.
+ * @param target the characters being searched for.
+ * @param fromIndex the index to begin searching from.
+ */
+ private static int indexOf(String source, String target, int fromIndex) {
+ final int sourceLength = source.length();
+ final int targetLength = target.length();
+ if (fromIndex >= sourceLength) {
+ return (targetLength == 0 ? sourceLength : -1);
+ }
+ if (fromIndex < 0) {
+ fromIndex = 0;
+ }
+ if (targetLength == 0) {
+ return fromIndex;
+ }
+
+ char first = target.charAt(0);
+ int max = (sourceLength - targetLength);
+
+ for (int i = fromIndex; i <= max; i++) {
+ /* Look for first character. */
+ if (source.charAt(i)!= first) {
+ while (++i <= max && source.charAt(i) != first);
+ }
+
+ /* Found first character, now look at the rest of v2 */
+ if (i <= max) {
+ int j = i + 1;
+ int end = j + targetLength - 1;
+ for (int k = 1; j < end && source.charAt(j)
+ == target.charAt(k); j++, k++);
+
+ if (j == end) {
+ /* Found whole string. */
+ return i;
+ }
+ }
+ }
+ return -1;
+ }
+ // END Android-added: Private static indexOf method that takes String parameters.
+
+ /**
+ * Code shared by String and AbstractStringBuilder to do searches. The
+ * source is the character array being searched, and the target
+ * is the string being searched for.
+ *
+ * @param source the characters being searched.
+ * @param sourceOffset offset of the source string.
+ * @param sourceCount count of the source string.
+ * @param target the characters being searched for.
+ * @param fromIndex the index to begin searching from.
+ */
+ static int indexOf(char[] source, int sourceOffset, int sourceCount,
+ String target, int fromIndex) {
+ return indexOf(source, sourceOffset, sourceCount,
+ target.toCharArray(), 0, target.length(),
+ fromIndex);
+ }
+
+ /**
+ * Code shared by String and StringBuffer to do searches. The
+ * source is the character array being searched, and the target
+ * is the string being searched for.
+ *
+ * @param source the characters being searched.
+ * @param sourceOffset offset of the source string.
+ * @param sourceCount count of the source string.
+ * @param target the characters being searched for.
+ * @param targetOffset offset of the target string.
+ * @param targetCount count of the target string.
+ * @param fromIndex the index to begin searching from.
+ */
+ static int indexOf(char[] source, int sourceOffset, int sourceCount,
+ char[] target, int targetOffset, int targetCount,
+ int fromIndex) {
+ if (fromIndex >= sourceCount) {
+ return (targetCount == 0 ? sourceCount : -1);
+ }
+ if (fromIndex < 0) {
+ fromIndex = 0;
+ }
+ if (targetCount == 0) {
+ return fromIndex;
+ }
+
+ char first = target[targetOffset];
+ int max = sourceOffset + (sourceCount - targetCount);
+
+ for (int i = sourceOffset + fromIndex; i <= max; i++) {
+ /* Look for first character. */
+ if (source[i] != first) {
+ while (++i <= max && source[i] != first);
+ }
+
+ /* Found first character, now look at the rest of v2 */
+ if (i <= max) {
+ int j = i + 1;
+ int end = j + targetCount - 1;
+ for (int k = targetOffset + 1; j < end && source[j]
+ == target[k]; j++, k++);
+
+ if (j == end) {
+ /* Found whole string. */
+ return i - sourceOffset;
+ }
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Returns the index within this string of the last occurrence of the
+ * specified substring. The last occurrence of the empty string ""
+ * is considered to occur at the index value {@code this.length()}.
+ *
+ * <p>The returned index is the largest value <i>k</i> for which:
+ * <blockquote><pre>
+ * this.startsWith(str, <i>k</i>)
+ * </pre></blockquote>
+ * If no such value of <i>k</i> exists, then {@code -1} is returned.
+ *
+ * @param str the substring to search for.
+ * @return the index of the last occurrence of the specified substring,
+ * or {@code -1} if there is no such occurrence.
+ */
+ public int lastIndexOf(String str) {
+ return lastIndexOf(str, length());
+ }
+
+ /**
+ * Returns the index within this string of the last occurrence of the
+ * specified substring, searching backward starting at the specified index.
+ *
+ * <p>The returned index is the largest value <i>k</i> for which:
+ * <blockquote><pre>
+ * <i>k</i> {@code <=} fromIndex {@code &&} this.startsWith(str, <i>k</i>)
+ * </pre></blockquote>
+ * If no such value of <i>k</i> exists, then {@code -1} is returned.
+ *
+ * @param str the substring to search for.
+ * @param fromIndex the index to start the search from.
+ * @return the index of the last occurrence of the specified substring,
+ * searching backward from the specified index,
+ * or {@code -1} if there is no such occurrence.
+ */
+ public int lastIndexOf(String str, int fromIndex) {
+ // Android-changed: Change parameters to static lastIndexOf to match new signature below.
+ return lastIndexOf(this, str, fromIndex);
+ }
+
+ // BEGIN Android-added: Private static lastIndexOf method that takes String parameters.
+ // The use of length(), charAt(), etc. makes it more efficient for compressed strings.
+ /**
+ * The source is the string being searched, and the target is the string being searched for.
+ *
+ * @param source the characters being searched.
+ * @param target the characters being searched for.
+ * @param fromIndex the index to begin searching from.
+ */
+ private static int lastIndexOf(String source, String target, int fromIndex) {
+ /*
+ * Check arguments; return immediately where possible. For
+ * consistency, don't check for null str.
+ */
+ final int sourceLength = source.length();
+ final int targetLength = target.length();
+ int rightIndex = sourceLength - targetLength;
+ if (fromIndex < 0) {
+ return -1;
+ }
+ if (fromIndex > rightIndex) {
+ fromIndex = rightIndex;
+ }
+ /* Empty string always matches. */
+ if (targetLength == 0) {
+ return fromIndex;
+ }
+
+ int strLastIndex = targetLength - 1;
+ char strLastChar = target.charAt(strLastIndex);
+ int min = targetLength - 1;
+ int i = min + fromIndex;
+
+ startSearchForLastChar:
+ while (true) {
+ while (i >= min && source.charAt(i) != strLastChar) {
+ i--;
+ }
+ if (i < min) {
+ return -1;
+ }
+ int j = i - 1;
+ int start = j - (targetLength - 1);
+ int k = strLastIndex - 1;
+
+ while (j > start) {
+ if (source.charAt(j--) != target.charAt(k--)) {
+ i--;
+ continue startSearchForLastChar;
+ }
+ }
+ return start + 1;
+ }
+ }
+ // END Android-added: Private static lastIndexOf method that takes String parameters.
+
+ /**
+ * Code shared by String and AbstractStringBuilder to do searches. The
+ * source is the character array being searched, and the target
+ * is the string being searched for.
+ *
+ * @param source the characters being searched.
+ * @param sourceOffset offset of the source string.
+ * @param sourceCount count of the source string.
+ * @param target the characters being searched for.
+ * @param fromIndex the index to begin searching from.
+ */
+ static int lastIndexOf(char[] source, int sourceOffset, int sourceCount,
+ String target, int fromIndex) {
+ return lastIndexOf(source, sourceOffset, sourceCount,
+ target.toCharArray(), 0, target.length(),
+ fromIndex);
+ }
+
+ /**
+ * Code shared by String and StringBuffer to do searches. The
+ * source is the character array being searched, and the target
+ * is the string being searched for.
+ *
+ * @param source the characters being searched.
+ * @param sourceOffset offset of the source string.
+ * @param sourceCount count of the source string.
+ * @param target the characters being searched for.
+ * @param targetOffset offset of the target string.
+ * @param targetCount count of the target string.
+ * @param fromIndex the index to begin searching from.
+ */
+ static int lastIndexOf(char[] source, int sourceOffset, int sourceCount,
+ char[] target, int targetOffset, int targetCount,
+ int fromIndex) {
+ /*
+ * Check arguments; return immediately where possible. For
+ * consistency, don't check for null str.
+ */
+ int rightIndex = sourceCount - targetCount;
+ if (fromIndex < 0) {
+ return -1;
+ }
+ if (fromIndex > rightIndex) {
+ fromIndex = rightIndex;
+ }
+ /* Empty string always matches. */
+ if (targetCount == 0) {
+ return fromIndex;
+ }
+
+ int strLastIndex = targetOffset + targetCount - 1;
+ char strLastChar = target[strLastIndex];
+ int min = sourceOffset + targetCount - 1;
+ int i = min + fromIndex;
+
+ startSearchForLastChar:
+ while (true) {
+ while (i >= min && source[i] != strLastChar) {
+ i--;
+ }
+ if (i < min) {
+ return -1;
+ }
+ int j = i - 1;
+ int start = j - (targetCount - 1);
+ int k = strLastIndex - 1;
+
+ while (j > start) {
+ if (source[j--] != target[k--]) {
+ i--;
+ continue startSearchForLastChar;
+ }
+ }
+ return start - sourceOffset + 1;
+ }
+ }
+
+ /**
+ * Returns a string that is a substring of this string. The
+ * substring begins with the character at the specified index and
+ * extends to the end of this string. <p>
+ * Examples:
+ * <blockquote><pre>
+ * "unhappy".substring(2) returns "happy"
+ * "Harbison".substring(3) returns "bison"
+ * "emptiness".substring(9) returns "" (an empty string)
+ * </pre></blockquote>
+ *
+ * @param beginIndex the beginning index, inclusive.
+ * @return the specified substring.
+ * @exception IndexOutOfBoundsException if
+ * {@code beginIndex} is negative or larger than the
+ * length of this {@code String} object.
+ */
+ public String substring(int beginIndex) {
+ if (beginIndex < 0) {
+ throw new StringIndexOutOfBoundsException(this, beginIndex);
+ }
+ int subLen = length() - beginIndex;
+ if (subLen < 0) {
+ throw new StringIndexOutOfBoundsException(this, beginIndex);
+ }
+ // Android-changed: Use native fastSubstring instead of String constructor.
+ return (beginIndex == 0) ? this : fastSubstring(beginIndex, subLen);
+ }
+
+ /**
+ * Returns a string that is a substring of this string. The
+ * substring begins at the specified {@code beginIndex} and
+ * extends to the character at index {@code endIndex - 1}.
+ * Thus the length of the substring is {@code endIndex-beginIndex}.
+ * <p>
+ * Examples:
+ * <blockquote><pre>
+ * "hamburger".substring(4, 8) returns "urge"
+ * "smiles".substring(1, 5) returns "mile"
+ * </pre></blockquote>
+ *
+ * @param beginIndex the beginning index, inclusive.
+ * @param endIndex the ending index, exclusive.
+ * @return the specified substring.
+ * @exception IndexOutOfBoundsException if the
+ * {@code beginIndex} is negative, or
+ * {@code endIndex} is larger than the length of
+ * this {@code String} object, or
+ * {@code beginIndex} is larger than
+ * {@code endIndex}.
+ */
+ public String substring(int beginIndex, int endIndex) {
+ if (beginIndex < 0) {
+ throw new StringIndexOutOfBoundsException(this, beginIndex);
+ }
+ if (endIndex > length()) {
+ throw new StringIndexOutOfBoundsException(this, endIndex);
+ }
+ int subLen = endIndex - beginIndex;
+ if (subLen < 0) {
+ throw new StringIndexOutOfBoundsException(subLen);
+ }
+
+ // Android-changed: Use native fastSubstring instead of String constructor.
+ return ((beginIndex == 0) && (endIndex == length())) ? this
+ : fastSubstring(beginIndex, subLen);
+ }
+
+ // BEGIN Android-added: Native method to access char storage managed by runtime.
+ @FastNative
+ private native String fastSubstring(int start, int length);
+ // END Android-added: Native method to access char storage managed by runtime.
+
+ /**
+ * Returns a character sequence that is a subsequence of this sequence.
+ *
+ * <p> An invocation of this method of the form
+ *
+ * <blockquote><pre>
+ * str.subSequence(begin, end)</pre></blockquote>
+ *
+ * behaves in exactly the same way as the invocation
+ *
+ * <blockquote><pre>
+ * str.substring(begin, end)</pre></blockquote>
+ *
+ * @apiNote
+ * This method is defined so that the {@code String} class can implement
+ * the {@link CharSequence} interface.
+ *
+ * @param beginIndex the begin index, inclusive.
+ * @param endIndex the end index, exclusive.
+ * @return the specified subsequence.
+ *
+ * @throws IndexOutOfBoundsException
+ * if {@code beginIndex} or {@code endIndex} is negative,
+ * if {@code endIndex} is greater than {@code length()},
+ * or if {@code beginIndex} is greater than {@code endIndex}
+ *
+ * @since 1.4
+ * @spec JSR-51
+ */
+ public CharSequence subSequence(int beginIndex, int endIndex) {
+ return this.substring(beginIndex, endIndex);
+ }
+
+ /**
+ * Concatenates the specified string to the end of this string.
+ * <p>
+ * If the length of the argument string is {@code 0}, then this
+ * {@code String} object is returned. Otherwise, a
+ * {@code String} object is returned that represents a character
+ * sequence that is the concatenation of the character sequence
+ * represented by this {@code String} object and the character
+ * sequence represented by the argument string.<p>
+ * Examples:
+ * <blockquote><pre>
+ * "cares".concat("s") returns "caress"
+ * "to".concat("get").concat("her") returns "together"
+ * </pre></blockquote>
+ *
+ * @param str the {@code String} that is concatenated to the end
+ * of this {@code String}.
+ * @return a string that represents the concatenation of this object's
+ * characters followed by the string argument's characters.
+ */
+ // BEGIN Android-changed: Replace with implementation in runtime to access chars (see above).
+ @FastNative
+ public native String concat(String str);
+ // END Android-changed: Replace with implementation in runtime to access chars (see above).
+
+ /**
+ * Returns a string resulting from replacing all occurrences of
+ * {@code oldChar} in this string with {@code newChar}.
+ * <p>
+ * If the character {@code oldChar} does not occur in the
+ * character sequence represented by this {@code String} object,
+ * then a reference to this {@code String} object is returned.
+ * Otherwise, a {@code String} object is returned that
+ * represents a character sequence identical to the character sequence
+ * represented by this {@code String} object, except that every
+ * occurrence of {@code oldChar} is replaced by an occurrence
+ * of {@code newChar}.
+ * <p>
+ * Examples:
+ * <blockquote><pre>
+ * "mesquite in your cellar".replace('e', 'o')
+ * returns "mosquito in your collar"
+ * "the war of baronets".replace('r', 'y')
+ * returns "the way of bayonets"
+ * "sparring with a purple porpoise".replace('p', 't')
+ * returns "starring with a turtle tortoise"
+ * "JonL".replace('q', 'x') returns "JonL" (no change)
+ * </pre></blockquote>
+ *
+ * @param oldChar the old character.
+ * @param newChar the new character.
+ * @return a string derived from this string by replacing every
+ * occurrence of {@code oldChar} with {@code newChar}.
+ */
+ public String replace(char oldChar, char newChar) {
+ // BEGIN Android-changed: Replace with implementation using native doReplace method.
+ if (oldChar != newChar) {
+ final int len = length();
+ for (int i = 0; i < len; ++i) {
+ if (charAt(i) == oldChar) {
+ return doReplace(oldChar, newChar);
+ }
+ }
+ }
+ // END Android-changed: Replace with implementation using native doReplace method.
+ return this;
+ }
+
+ // BEGIN Android-added: Native method to access char storage managed by runtime.
+ // Implementation of replace(char oldChar, char newChar) called when we found a match.
+ @FastNative
+ private native String doReplace(char oldChar, char newChar);
+ // END Android-added: Native method to access char storage managed by runtime.
+
+ /**
+ * Tells whether or not this string matches the given <a
+ * href="../util/regex/Pattern.html#sum">regular expression</a>.
+ *
+ * <p> An invocation of this method of the form
+ * <i>str</i>{@code .matches(}<i>regex</i>{@code )} yields exactly the
+ * same result as the expression
+ *
+ * <blockquote>
+ * {@link java.util.regex.Pattern}.{@link java.util.regex.Pattern#matches(String,CharSequence)
+ * matches(<i>regex</i>, <i>str</i>)}
+ * </blockquote>
+ *
+ * @param regex
+ * the regular expression to which this string is to be matched
+ *
+ * @return {@code true} if, and only if, this string matches the
+ * given regular expression
+ *
+ * @throws PatternSyntaxException
+ * if the regular expression's syntax is invalid
+ *
+ * @see java.util.regex.Pattern
+ *
+ * @since 1.4
+ * @spec JSR-51
+ */
+ public boolean matches(String regex) {
+ return Pattern.matches(regex, this);
+ }
+
+ /**
+ * Returns true if and only if this string contains the specified
+ * sequence of char values.
+ *
+ * @param s the sequence to search for
+ * @return true if this string contains {@code s}, false otherwise
+ * @since 1.5
+ */
+ public boolean contains(CharSequence s) {
+ return indexOf(s.toString()) > -1;
+ }
+
+ /**
+ * Replaces the first substring of this string that matches the given <a
+ * href="../util/regex/Pattern.html#sum">regular expression</a> with the
+ * given replacement.
+ *
+ * <p> An invocation of this method of the form
+ * <i>str</i>{@code .replaceFirst(}<i>regex</i>{@code ,} <i>repl</i>{@code )}
+ * yields exactly the same result as the expression
+ *
+ * <blockquote>
+ * <code>
+ * {@link java.util.regex.Pattern}.{@link
+ * java.util.regex.Pattern#compile compile}(<i>regex</i>).{@link
+ * java.util.regex.Pattern#matcher(java.lang.CharSequence) matcher}(<i>str</i>).{@link
+ * java.util.regex.Matcher#replaceFirst replaceFirst}(<i>repl</i>)
+ * </code>
+ * </blockquote>
+ *
+ *<p>
+ * Note that backslashes ({@code \}) and dollar signs ({@code $}) in the
+ * replacement string may cause the results to be different than if it were
+ * being treated as a literal replacement string; see
+ * {@link java.util.regex.Matcher#replaceFirst}.
+ * Use {@link java.util.regex.Matcher#quoteReplacement} to suppress the special
+ * meaning of these characters, if desired.
+ *
+ * @param regex
+ * the regular expression to which this string is to be matched
+ * @param replacement
+ * the string to be substituted for the first match
+ *
+ * @return The resulting {@code String}
+ *
+ * @throws PatternSyntaxException
+ * if the regular expression's syntax is invalid
+ *
+ * @see java.util.regex.Pattern
+ *
+ * @since 1.4
+ * @spec JSR-51
+ */
+ public String replaceFirst(String regex, String replacement) {
+ return Pattern.compile(regex).matcher(this).replaceFirst(replacement);
+ }
+
+ /**
+ * Replaces each substring of this string that matches the given <a
+ * href="../util/regex/Pattern.html#sum">regular expression</a> with the
+ * given replacement.
+ *
+ * <p> An invocation of this method of the form
+ * <i>str</i>{@code .replaceAll(}<i>regex</i>{@code ,} <i>repl</i>{@code )}
+ * yields exactly the same result as the expression
+ *
+ * <blockquote>
+ * <code>
+ * {@link java.util.regex.Pattern}.{@link
+ * java.util.regex.Pattern#compile compile}(<i>regex</i>).{@link
+ * java.util.regex.Pattern#matcher(java.lang.CharSequence) matcher}(<i>str</i>).{@link
+ * java.util.regex.Matcher#replaceAll replaceAll}(<i>repl</i>)
+ * </code>
+ * </blockquote>
+ *
+ *<p>
+ * Note that backslashes ({@code \}) and dollar signs ({@code $}) in the
+ * replacement string may cause the results to be different than if it were
+ * being treated as a literal replacement string; see
+ * {@link java.util.regex.Matcher#replaceAll Matcher.replaceAll}.
+ * Use {@link java.util.regex.Matcher#quoteReplacement} to suppress the special
+ * meaning of these characters, if desired.
+ *
+ * @param regex
+ * the regular expression to which this string is to be matched
+ * @param replacement
+ * the string to be substituted for each match
+ *
+ * @return The resulting {@code String}
+ *
+ * @throws PatternSyntaxException
+ * if the regular expression's syntax is invalid
+ *
+ * @see java.util.regex.Pattern
+ *
+ * @since 1.4
+ * @spec JSR-51
+ */
+ public String replaceAll(String regex, String replacement) {
+ return Pattern.compile(regex).matcher(this).replaceAll(replacement);
+ }
+
+ /**
+ * Replaces each substring of this string that matches the literal target
+ * sequence with the specified literal replacement sequence. The
+ * replacement proceeds from the beginning of the string to the end, for
+ * example, replacing "aa" with "b" in the string "aaa" will result in
+ * "ba" rather than "ab".
+ *
+ * @param target The sequence of char values to be replaced
+ * @param replacement The replacement sequence of char values
+ * @return The resulting string
+ * @since 1.5
+ */
+ public String replace(CharSequence target, CharSequence replacement) {
+ // BEGIN Android-changed: Replace regex-based implementation with a bespoke one.
+ if (target == null) {
+ throw new NullPointerException("target == null");
+ }
+
+ if (replacement == null) {
+ throw new NullPointerException("replacement == null");
+ }
+
+ String replacementStr = replacement.toString();
+ String targetStr = target.toString();
+
+ // Special case when target == "". This is a pretty nonsensical transformation and nobody
+ // should be hitting this.
+ //
+ // See commit 870b23b3febc85 and http://code.google.com/p/android/issues/detail?id=8807
+ // An empty target is inserted at the start of the string, the end of the string and
+ // between all characters.
+ final int len = length();
+ if (targetStr.isEmpty()) {
+ // Note that overallocates by |replacement.size()| if |this| is the empty string, but
+ // that should be a rare case within an already nonsensical case.
+ StringBuilder sb = new StringBuilder(replacementStr.length() * (len + 2) + len);
+ sb.append(replacementStr);
+ for (int i = 0; i < len; ++i) {
+ sb.append(charAt(i));
+ sb.append(replacementStr);
+ }
+
+ return sb.toString();
+ }
+
+ // This is the "regular" case.
+ int lastMatch = 0;
+ StringBuilder sb = null;
+ for (;;) {
+ int currentMatch = indexOf(this, targetStr, lastMatch);
+ if (currentMatch == -1) {
+ break;
+ }
+
+ if (sb == null) {
+ sb = new StringBuilder(len);
+ }
+
+ sb.append(this, lastMatch, currentMatch);
+ sb.append(replacementStr);
+ lastMatch = currentMatch + targetStr.length();
+ }
+
+ if (sb != null) {
+ sb.append(this, lastMatch, len);
+ return sb.toString();
+ } else {
+ return this;
+ }
+ // END Android-changed: Replace regex-based implementation with a bespoke one.
+ }
+
+ /**
+ * Splits this string around matches of the given
+ * <a href="../util/regex/Pattern.html#sum">regular expression</a>.
+ *
+ * <p> The array returned by this method contains each substring of this
+ * string that is terminated by another substring that matches the given
+ * expression or is terminated by the end of the string. The substrings in
+ * the array are in the order in which they occur in this string. If the
+ * expression does not match any part of the input then the resulting array
+ * has just one element, namely this string.
+ *
+ * <p> When there is a positive-width match at the beginning of this
+ * string then an empty leading substring is included at the beginning
+ * of the resulting array. A zero-width match at the beginning however
+ * never produces such empty leading substring.
+ *
+ * <p> The {@code limit} parameter controls the number of times the
+ * pattern is applied and therefore affects the length of the resulting
+ * array. If the limit <i>n</i> is greater than zero then the pattern
+ * will be applied at most <i>n</i> - 1 times, the array's
+ * length will be no greater than <i>n</i>, and the array's last entry
+ * will contain all input beyond the last matched delimiter. If <i>n</i>
+ * is non-positive then the pattern will be applied as many times as
+ * possible and the array can have any length. If <i>n</i> is zero then
+ * the pattern will be applied as many times as possible, the array can
+ * have any length, and trailing empty strings will be discarded.
+ *
+ * <p> The string {@code "boo:and:foo"}, for example, yields the
+ * following results with these parameters:
+ *
+ * <blockquote><table cellpadding=1 cellspacing=0 summary="Split example showing regex, limit, and result">
+ * <tr>
+ * <th>Regex</th>
+ * <th>Limit</th>
+ * <th>Result</th>
+ * </tr>
+ * <tr><td align=center>:</td>
+ * <td align=center>2</td>
+ * <td>{@code { "boo", "and:foo" }}</td></tr>
+ * <tr><td align=center>:</td>
+ * <td align=center>5</td>
+ * <td>{@code { "boo", "and", "foo" }}</td></tr>
+ * <tr><td align=center>:</td>
+ * <td align=center>-2</td>
+ * <td>{@code { "boo", "and", "foo" }}</td></tr>
+ * <tr><td align=center>o</td>
+ * <td align=center>5</td>
+ * <td>{@code { "b", "", ":and:f", "", "" }}</td></tr>
+ * <tr><td align=center>o</td>
+ * <td align=center>-2</td>
+ * <td>{@code { "b", "", ":and:f", "", "" }}</td></tr>
+ * <tr><td align=center>o</td>
+ * <td align=center>0</td>
+ * <td>{@code { "b", "", ":and:f" }}</td></tr>
+ * </table></blockquote>
+ *
+ * <p> An invocation of this method of the form
+ * <i>str.</i>{@code split(}<i>regex</i>{@code ,} <i>n</i>{@code )}
+ * yields the same result as the expression
+ *
+ * <blockquote>
+ * <code>
+ * {@link java.util.regex.Pattern}.{@link
+ * java.util.regex.Pattern#compile compile}(<i>regex</i>).{@link
+ * java.util.regex.Pattern#split(java.lang.CharSequence,int) split}(<i>str</i>, <i>n</i>)
+ * </code>
+ * </blockquote>
+ *
+ *
+ * @param regex
+ * the delimiting regular expression
+ *
+ * @param limit
+ * the result threshold, as described above
+ *
+ * @return the array of strings computed by splitting this string
+ * around matches of the given regular expression
+ *
+ * @throws PatternSyntaxException
+ * if the regular expression's syntax is invalid
+ *
+ * @see java.util.regex.Pattern
+ *
+ * @since 1.4
+ * @spec JSR-51
+ */
+ public String[] split(String regex, int limit) {
+ // BEGIN Android-changed: Replace custom fast-path with use of new Pattern.fastSplit method.
+ // Try fast splitting without allocating Pattern object
+ String[] fast = Pattern.fastSplit(regex, this, limit);
+ if (fast != null) {
+ return fast;
+ }
+ // END Android-changed: Replace custom fast-path with use of new Pattern.fastSplit method.
+ return Pattern.compile(regex).split(this, limit);
+ }
+
+ /**
+ * Splits this string around matches of the given <a
+ * href="../util/regex/Pattern.html#sum">regular expression</a>.
+ *
+ * <p> This method works as if by invoking the two-argument {@link
+ * #split(String, int) split} method with the given expression and a limit
+ * argument of zero. Trailing empty strings are therefore not included in
+ * the resulting array.
+ *
+ * <p> The string {@code "boo:and:foo"}, for example, yields the following
+ * results with these expressions:
+ *
+ * <blockquote><table cellpadding=1 cellspacing=0 summary="Split examples showing regex and result">
+ * <tr>
+ * <th>Regex</th>
+ * <th>Result</th>
+ * </tr>
+ * <tr><td align=center>:</td>
+ * <td>{@code { "boo", "and", "foo" }}</td></tr>
+ * <tr><td align=center>o</td>
+ * <td>{@code { "b", "", ":and:f" }}</td></tr>
+ * </table></blockquote>
+ *
+ *
+ * @param regex
+ * the delimiting regular expression
+ *
+ * @return the array of strings computed by splitting this string
+ * around matches of the given regular expression
+ *
+ * @throws PatternSyntaxException
+ * if the regular expression's syntax is invalid
+ *
+ * @see java.util.regex.Pattern
+ *
+ * @since 1.4
+ * @spec JSR-51
+ */
+ public String[] split(String regex) {
+ return split(regex, 0);
+ }
+
+ /**
+ * Returns a new String composed of copies of the
+ * {@code CharSequence elements} joined together with a copy of
+ * the specified {@code delimiter}.
+ *
+ * <blockquote>For example,
+ * <pre>{@code
+ * String message = String.join("-", "Java", "is", "cool");
+ * // message returned is: "Java-is-cool"
+ * }</pre></blockquote>
+ *
+ * Note that if an element is null, then {@code "null"} is added.
+ *
+ * @param delimiter the delimiter that separates each element
+ * @param elements the elements to join together.
+ *
+ * @return a new {@code String} that is composed of the {@code elements}
+ * separated by the {@code delimiter}
+ *
+ * @throws NullPointerException If {@code delimiter} or {@code elements}
+ * is {@code null}
+ *
+ * @see java.util.StringJoiner
+ * @since 1.8
+ */
+ public static String join(CharSequence delimiter, CharSequence... elements) {
+ Objects.requireNonNull(delimiter);
+ Objects.requireNonNull(elements);
+ // Number of elements not likely worth Arrays.stream overhead.
+ StringJoiner joiner = new StringJoiner(delimiter);
+ for (CharSequence cs: elements) {
+ joiner.add(cs);
+ }
+ return joiner.toString();
+ }
+
+ /**
+ * Returns a new {@code String} composed of copies of the
+ * {@code CharSequence elements} joined together with a copy of the
+ * specified {@code delimiter}.
+ *
+ * <blockquote>For example,
+ * <pre>{@code
+ * List<String> strings = new LinkedList<>();
+ * strings.add("Java");strings.add("is");
+ * strings.add("cool");
+ * String message = String.join(" ", strings);
+ * //message returned is: "Java is cool"
+ *
+ * Set<String> strings = new LinkedHashSet<>();
+ * strings.add("Java"); strings.add("is");
+ * strings.add("very"); strings.add("cool");
+ * String message = String.join("-", strings);
+ * //message returned is: "Java-is-very-cool"
+ * }</pre></blockquote>
+ *
+ * Note that if an individual element is {@code null}, then {@code "null"} is added.
+ *
+ * @param delimiter a sequence of characters that is used to separate each
+ * of the {@code elements} in the resulting {@code String}
+ * @param elements an {@code Iterable} that will have its {@code elements}
+ * joined together.
+ *
+ * @return a new {@code String} that is composed from the {@code elements}
+ * argument
+ *
+ * @throws NullPointerException If {@code delimiter} or {@code elements}
+ * is {@code null}
+ *
+ * @see #join(CharSequence,CharSequence...)
+ * @see java.util.StringJoiner
+ * @since 1.8
+ */
+ public static String join(CharSequence delimiter,
+ Iterable<? extends CharSequence> elements) {
+ Objects.requireNonNull(delimiter);
+ Objects.requireNonNull(elements);
+ StringJoiner joiner = new StringJoiner(delimiter);
+ for (CharSequence cs: elements) {
+ joiner.add(cs);
+ }
+ return joiner.toString();
+ }
+
+ /**
+ * Converts all of the characters in this {@code String} to lower
+ * case using the rules of the given {@code Locale}. Case mapping is based
+ * on the Unicode Standard version specified by the {@link java.lang.Character Character}
+ * class. Since case mappings are not always 1:1 char mappings, the resulting
+ * {@code String} may be a different length than the original {@code String}.
+ * <p>
+ * Examples of lowercase mappings are in the following table:
+ * <table border="1" summary="Lowercase mapping examples showing language code of locale, upper case, lower case, and description">
+ * <tr>
+ * <th>Language Code of Locale</th>
+ * <th>Upper Case</th>
+ * <th>Lower Case</th>
+ * <th>Description</th>
+ * </tr>
+ * <tr>
+ * <td>tr (Turkish)</td>
+ * <td>\u0130</td>
+ * <td>\u0069</td>
+ * <td>capital letter I with dot above -> small letter i</td>
+ * </tr>
+ * <tr>
+ * <td>tr (Turkish)</td>
+ * <td>\u0049</td>
+ * <td>\u0131</td>
+ * <td>capital letter I -> small letter dotless i </td>
+ * </tr>
+ * <tr>
+ * <td>(all)</td>
+ * <td>French Fries</td>
+ * <td>french fries</td>
+ * <td>lowercased all chars in String</td>
+ * </tr>
+ * <tr>
+ * <td>(all)</td>
+ * <td><img src="doc-files/capiota.gif" alt="capiota"><img src="doc-files/capchi.gif" alt="capchi">
+ * <img src="doc-files/captheta.gif" alt="captheta"><img src="doc-files/capupsil.gif" alt="capupsil">
+ * <img src="doc-files/capsigma.gif" alt="capsigma"></td>
+ * <td><img src="doc-files/iota.gif" alt="iota"><img src="doc-files/chi.gif" alt="chi">
+ * <img src="doc-files/theta.gif" alt="theta"><img src="doc-files/upsilon.gif" alt="upsilon">
+ * <img src="doc-files/sigma1.gif" alt="sigma"></td>
+ * <td>lowercased all chars in String</td>
+ * </tr>
+ * </table>
+ *
+ * @param locale use the case transformation rules for this locale
+ * @return the {@code String}, converted to lowercase.
+ * @see java.lang.String#toLowerCase()
+ * @see java.lang.String#toUpperCase()
+ * @see java.lang.String#toUpperCase(Locale)
+ * @since 1.1
+ */
+ public String toLowerCase(Locale locale) {
+ // Android-changed: Replace custom code with call to new CaseMapper class.
+ return CaseMapper.toLowerCase(locale, this);
+ }
+
+ /**
+ * Converts all of the characters in this {@code String} to lower
+ * case using the rules of the default locale. This is equivalent to calling
+ * {@code toLowerCase(Locale.getDefault())}.
+ * <p>
+ * <b>Note:</b> This method is locale sensitive, and may produce unexpected
+ * results if used for strings that are intended to be interpreted locale
+ * independently.
+ * Examples are programming language identifiers, protocol keys, and HTML
+ * tags.
+ * For instance, {@code "TITLE".toLowerCase()} in a Turkish locale
+ * returns {@code "t\u005Cu0131tle"}, where '\u005Cu0131' is the
+ * LATIN SMALL LETTER DOTLESS I character.
+ * To obtain correct results for locale insensitive strings, use
+ * {@code toLowerCase(Locale.ROOT)}.
+ * <p>
+ * @return the {@code String}, converted to lowercase.
+ * @see java.lang.String#toLowerCase(Locale)
+ */
+ public String toLowerCase() {
+ return toLowerCase(Locale.getDefault());
+ }
+
+ /**
+ * Converts all of the characters in this {@code String} to upper
+ * case using the rules of the given {@code Locale}. Case mapping is based
+ * on the Unicode Standard version specified by the {@link java.lang.Character Character}
+ * class. Since case mappings are not always 1:1 char mappings, the resulting
+ * {@code String} may be a different length than the original {@code String}.
+ * <p>
+ * Examples of locale-sensitive and 1:M case mappings are in the following table.
+ *
+ * <table border="1" summary="Examples of locale-sensitive and 1:M case mappings. Shows Language code of locale, lower case, upper case, and description.">
+ * <tr>
+ * <th>Language Code of Locale</th>
+ * <th>Lower Case</th>
+ * <th>Upper Case</th>
+ * <th>Description</th>
+ * </tr>
+ * <tr>
+ * <td>tr (Turkish)</td>
+ * <td>\u0069</td>
+ * <td>\u0130</td>
+ * <td>small letter i -> capital letter I with dot above</td>
+ * </tr>
+ * <tr>
+ * <td>tr (Turkish)</td>
+ * <td>\u0131</td>
+ * <td>\u0049</td>
+ * <td>small letter dotless i -> capital letter I</td>
+ * </tr>
+ * <tr>
+ * <td>(all)</td>
+ * <td>\u00df</td>
+ * <td>\u0053 \u0053</td>
+ * <td>small letter sharp s -> two letters: SS</td>
+ * </tr>
+ * <tr>
+ * <td>(all)</td>
+ * <td>Fahrvergnügen</td>
+ * <td>FAHRVERGNÜGEN</td>
+ * <td></td>
+ * </tr>
+ * </table>
+ * @param locale use the case transformation rules for this locale
+ * @return the {@code String}, converted to uppercase.
+ * @see java.lang.String#toUpperCase()
+ * @see java.lang.String#toLowerCase()
+ * @see java.lang.String#toLowerCase(Locale)
+ * @since 1.1
+ */
+ public String toUpperCase(Locale locale) {
+ // Android-changed: Replace custom code with call to new CaseMapper class.
+ return CaseMapper.toUpperCase(locale, this, length());
+ }
+
+ /**
+ * Converts all of the characters in this {@code String} to upper
+ * case using the rules of the default locale. This method is equivalent to
+ * {@code toUpperCase(Locale.getDefault())}.
+ * <p>
+ * <b>Note:</b> This method is locale sensitive, and may produce unexpected
+ * results if used for strings that are intended to be interpreted locale
+ * independently.
+ * Examples are programming language identifiers, protocol keys, and HTML
+ * tags.
+ * For instance, {@code "title".toUpperCase()} in a Turkish locale
+ * returns {@code "T\u005Cu0130TLE"}, where '\u005Cu0130' is the
+ * LATIN CAPITAL LETTER I WITH DOT ABOVE character.
+ * To obtain correct results for locale insensitive strings, use
+ * {@code toUpperCase(Locale.ROOT)}.
+ * <p>
+ * @return the {@code String}, converted to uppercase.
+ * @see java.lang.String#toUpperCase(Locale)
+ */
+ public String toUpperCase() {
+ return toUpperCase(Locale.getDefault());
+ }
+
+ /**
+ * Returns a string whose value is this string, with any leading and trailing
+ * whitespace removed.
+ * <p>
+ * If this {@code String} object represents an empty character
+ * sequence, or the first and last characters of character sequence
+ * represented by this {@code String} object both have codes
+ * greater than {@code '\u005Cu0020'} (the space character), then a
+ * reference to this {@code String} object is returned.
+ * <p>
+ * Otherwise, if there is no character with a code greater than
+ * {@code '\u005Cu0020'} in the string, then a
+ * {@code String} object representing an empty string is
+ * returned.
+ * <p>
+ * Otherwise, let <i>k</i> be the index of the first character in the
+ * string whose code is greater than {@code '\u005Cu0020'}, and let
+ * <i>m</i> be the index of the last character in the string whose code
+ * is greater than {@code '\u005Cu0020'}. A {@code String}
+ * object is returned, representing the substring of this string that
+ * begins with the character at index <i>k</i> and ends with the
+ * character at index <i>m</i>-that is, the result of
+ * {@code this.substring(k, m + 1)}.
+ * <p>
+ * This method may be used to trim whitespace (as defined above) from
+ * the beginning and end of a string.
+ *
+ * @return A string whose value is this string, with any leading and trailing white
+ * space removed, or this string if it has no leading or
+ * trailing white space.
+ */
+ public String trim() {
+ int len = length();
+ int st = 0;
+
+ while ((st < len) && (charAt(st) <= ' ')) {
+ st++;
+ }
+ while ((st < len) && (charAt(len - 1) <= ' ')) {
+ len--;
+ }
+ return ((st > 0) || (len < length())) ? substring(st, len) : this;
+ }
+
+ /**
+ * This object (which is already a string!) is itself returned.
+ *
+ * @return the string itself.
+ */
+ public String toString() {
+ return this;
+ }
+
+ /**
+ * Converts this string to a new character array.
+ *
+ * @return a newly allocated character array whose length is the length
+ * of this string and whose contents are initialized to contain
+ * the character sequence represented by this string.
+ */
+ // BEGIN Android-changed: Replace with implementation in runtime to access chars (see above).
+ @FastNative
+ public native char[] toCharArray();
+ // END Android-changed: Replace with implementation in runtime to access chars (see above).
+
+
+ /**
+ * Returns a formatted string using the specified format string and
+ * arguments.
+ *
+ * <p> The locale always used is the one returned by {@link
+ * java.util.Locale#getDefault() Locale.getDefault()}.
+ *
+ * @param format
+ * A <a href="../util/Formatter.html#syntax">format string</a>
+ *
+ * @param args
+ * Arguments referenced by the format specifiers in the format
+ * string. If there are more arguments than format specifiers, the
+ * extra arguments are ignored. The number of arguments is
+ * variable and may be zero. The maximum number of arguments is
+ * limited by the maximum dimension of a Java array as defined by
+ * <cite>The Java™ Virtual Machine Specification</cite>.
+ * The behaviour on a
+ * {@code null} argument depends on the <a
+ * href="../util/Formatter.html#syntax">conversion</a>.
+ *
+ * @throws java.util.IllegalFormatException
+ * If a format string contains an illegal syntax, a format
+ * specifier that is incompatible with the given arguments,
+ * insufficient arguments given the format string, or other
+ * illegal conditions. For specification of all possible
+ * formatting errors, see the <a
+ * href="../util/Formatter.html#detail">Details</a> section of the
+ * formatter class specification.
+ *
+ * @return A formatted string
+ *
+ * @see java.util.Formatter
+ * @since 1.5
+ */
+ public static String format(String format, Object... args) {
+ return new Formatter().format(format, args).toString();
+ }
+
+ /**
+ * Returns a formatted string using the specified locale, format string,
+ * and arguments.
+ *
+ * @param l
+ * The {@linkplain java.util.Locale locale} to apply during
+ * formatting. If {@code l} is {@code null} then no localization
+ * is applied.
+ *
+ * @param format
+ * A <a href="../util/Formatter.html#syntax">format string</a>
+ *
+ * @param args
+ * Arguments referenced by the format specifiers in the format
+ * string. If there are more arguments than format specifiers, the
+ * extra arguments are ignored. The number of arguments is
+ * variable and may be zero. The maximum number of arguments is
+ * limited by the maximum dimension of a Java array as defined by
+ * <cite>The Java™ Virtual Machine Specification</cite>.
+ * The behaviour on a
+ * {@code null} argument depends on the
+ * <a href="../util/Formatter.html#syntax">conversion</a>.
+ *
+ * @throws java.util.IllegalFormatException
+ * If a format string contains an illegal syntax, a format
+ * specifier that is incompatible with the given arguments,
+ * insufficient arguments given the format string, or other
+ * illegal conditions. For specification of all possible
+ * formatting errors, see the <a
+ * href="../util/Formatter.html#detail">Details</a> section of the
+ * formatter class specification
+ *
+ * @return A formatted string
+ *
+ * @see java.util.Formatter
+ * @since 1.5
+ */
+ public static String format(Locale l, String format, Object... args) {
+ return new Formatter(l).format(format, args).toString();
+ }
+
+ /**
+ * Returns the string representation of the {@code Object} argument.
+ *
+ * @param obj an {@code Object}.
+ * @return if the argument is {@code null}, then a string equal to
+ * {@code "null"}; otherwise, the value of
+ * {@code obj.toString()} is returned.
+ * @see java.lang.Object#toString()
+ */
+ public static String valueOf(Object obj) {
+ return (obj == null) ? "null" : obj.toString();
+ }
+
+ /**
+ * Returns the string representation of the {@code char} array
+ * argument. The contents of the character array are copied; subsequent
+ * modification of the character array does not affect the returned
+ * string.
+ *
+ * @param data the character array.
+ * @return a {@code String} that contains the characters of the
+ * character array.
+ */
+ public static String valueOf(char data[]) {
+ return new String(data);
+ }
+
+ /**
+ * Returns the string representation of a specific subarray of the
+ * {@code char} array argument.
+ * <p>
+ * The {@code offset} argument is the index of the first
+ * character of the subarray. The {@code count} argument
+ * specifies the length of the subarray. The contents of the subarray
+ * are copied; subsequent modification of the character array does not
+ * affect the returned string.
+ *
+ * @param data the character array.
+ * @param offset initial offset of the subarray.
+ * @param count length of the subarray.
+ * @return a {@code String} that contains the characters of the
+ * specified subarray of the character array.
+ * @exception IndexOutOfBoundsException if {@code offset} is
+ * negative, or {@code count} is negative, or
+ * {@code offset+count} is larger than
+ * {@code data.length}.
+ */
+ public static String valueOf(char data[], int offset, int count) {
+ return new String(data, offset, count);
+ }
+
+ /**
+ * Equivalent to {@link #valueOf(char[], int, int)}.
+ *
+ * @param data the character array.
+ * @param offset initial offset of the subarray.
+ * @param count length of the subarray.
+ * @return a {@code String} that contains the characters of the
+ * specified subarray of the character array.
+ * @exception IndexOutOfBoundsException if {@code offset} is
+ * negative, or {@code count} is negative, or
+ * {@code offset+count} is larger than
+ * {@code data.length}.
+ */
+ public static String copyValueOf(char data[], int offset, int count) {
+ return new String(data, offset, count);
+ }
+
+ /**
+ * Equivalent to {@link #valueOf(char[])}.
+ *
+ * @param data the character array.
+ * @return a {@code String} that contains the characters of the
+ * character array.
+ */
+ public static String copyValueOf(char data[]) {
+ return new String(data);
+ }
+
+ /**
+ * Returns the string representation of the {@code boolean} argument.
+ *
+ * @param b a {@code boolean}.
+ * @return if the argument is {@code true}, a string equal to
+ * {@code "true"} is returned; otherwise, a string equal to
+ * {@code "false"} is returned.
+ */
+ public static String valueOf(boolean b) {
+ return b ? "true" : "false";
+ }
+
+ /**
+ * Returns the string representation of the {@code char}
+ * argument.
+ *
+ * @param c a {@code char}.
+ * @return a string of length {@code 1} containing
+ * as its single character the argument {@code c}.
+ */
+ public static String valueOf(char c) {
+ // Android-changed: Replace constructor call with call to StringFactory class.
+ // There is currently no String(char[], boolean) on Android to call. http://b/79902155
+ // char data[] = {c};
+ // return new String(data, true);
+ return StringFactory.newStringFromChars(0, 1, new char[] { c });
+ }
+
+ /**
+ * Returns the string representation of the {@code int} argument.
+ * <p>
+ * The representation is exactly the one returned by the
+ * {@code Integer.toString} method of one argument.
+ *
+ * @param i an {@code int}.
+ * @return a string representation of the {@code int} argument.
+ * @see java.lang.Integer#toString(int, int)
+ */
+ public static String valueOf(int i) {
+ return Integer.toString(i);
+ }
+
+ /**
+ * Returns the string representation of the {@code long} argument.
+ * <p>
+ * The representation is exactly the one returned by the
+ * {@code Long.toString} method of one argument.
+ *
+ * @param l a {@code long}.
+ * @return a string representation of the {@code long} argument.
+ * @see java.lang.Long#toString(long)
+ */
+ public static String valueOf(long l) {
+ return Long.toString(l);
+ }
+
+ /**
+ * Returns the string representation of the {@code float} argument.
+ * <p>
+ * The representation is exactly the one returned by the
+ * {@code Float.toString} method of one argument.
+ *
+ * @param f a {@code float}.
+ * @return a string representation of the {@code float} argument.
+ * @see java.lang.Float#toString(float)
+ */
+ public static String valueOf(float f) {
+ return Float.toString(f);
+ }
+
+ /**
+ * Returns the string representation of the {@code double} argument.
+ * <p>
+ * The representation is exactly the one returned by the
+ * {@code Double.toString} method of one argument.
+ *
+ * @param d a {@code double}.
+ * @return a string representation of the {@code double} argument.
+ * @see java.lang.Double#toString(double)
+ */
+ public static String valueOf(double d) {
+ return Double.toString(d);
+ }
+
+ /**
+ * Returns a canonical representation for the string object.
+ * <p>
+ * A pool of strings, initially empty, is maintained privately by the
+ * class {@code String}.
+ * <p>
+ * When the intern method is invoked, if the pool already contains a
+ * string equal to this {@code String} object as determined by
+ * the {@link #equals(Object)} method, then the string from the pool is
+ * returned. Otherwise, this {@code String} object is added to the
+ * pool and a reference to this {@code String} object is returned.
+ * <p>
+ * It follows that for any two strings {@code s} and {@code t},
+ * {@code s.intern() == t.intern()} is {@code true}
+ * if and only if {@code s.equals(t)} is {@code true}.
+ * <p>
+ * All literal strings and string-valued constant expressions are
+ * interned. String literals are defined in section 3.10.5 of the
+ * <cite>The Java™ Language Specification</cite>.
+ *
+ * @return a string that has the same contents as this string, but is
+ * guaranteed to be from a pool of unique strings.
+ */
+ // BEGIN Android-changed: Annotate native method as @FastNative.
+ @FastNative
+ // END Android-changed: Annotate native method as @FastNative.
+ public native String intern();
+}
diff --git a/java/lang/StringBuffer.annotated.java b/java/lang/StringBuffer.annotated.java
new file mode 100644
index 0000000..4baff67
--- /dev/null
+++ b/java/lang/StringBuffer.annotated.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 1994, 2013, 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;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class StringBuffer implements java.lang.Appendable, java.lang.CharSequence, java.io.Serializable {
+
+public StringBuffer() { throw new RuntimeException("Stub!"); }
+
+public StringBuffer(int capacity) { throw new RuntimeException("Stub!"); }
+
+public StringBuffer(@libcore.util.NonNull java.lang.String str) { throw new RuntimeException("Stub!"); }
+
+public StringBuffer(@libcore.util.NonNull java.lang.CharSequence seq) { throw new RuntimeException("Stub!"); }
+
+public synchronized int length() { throw new RuntimeException("Stub!"); }
+
+public synchronized int capacity() { throw new RuntimeException("Stub!"); }
+
+public synchronized void ensureCapacity(int minimumCapacity) { throw new RuntimeException("Stub!"); }
+
+public synchronized void trimToSize() { throw new RuntimeException("Stub!"); }
+
+public synchronized void setLength(int newLength) { throw new RuntimeException("Stub!"); }
+
+public synchronized char charAt(int index) { throw new RuntimeException("Stub!"); }
+
+public synchronized int codePointAt(int index) { throw new RuntimeException("Stub!"); }
+
+public synchronized int codePointBefore(int index) { throw new RuntimeException("Stub!"); }
+
+public synchronized int codePointCount(int beginIndex, int endIndex) { throw new RuntimeException("Stub!"); }
+
+public synchronized int offsetByCodePoints(int index, int codePointOffset) { throw new RuntimeException("Stub!"); }
+
+public synchronized void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) { throw new RuntimeException("Stub!"); }
+
+public synchronized void setCharAt(int index, char ch) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.StringBuffer append(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.StringBuffer append(@libcore.util.Nullable java.lang.String str) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.StringBuffer append(@libcore.util.Nullable java.lang.StringBuffer sb) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.StringBuffer append(@libcore.util.Nullable java.lang.CharSequence s) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.StringBuffer append(@libcore.util.Nullable java.lang.CharSequence s, int start, int end) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.StringBuffer append(char[] str) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.StringBuffer append(char[] str, int offset, int len) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.StringBuffer append(boolean b) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.StringBuffer append(char c) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.StringBuffer append(int i) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.StringBuffer appendCodePoint(int codePoint) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.StringBuffer append(long lng) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.StringBuffer append(float f) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.StringBuffer append(double d) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.StringBuffer delete(int start, int end) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.StringBuffer deleteCharAt(int index) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.StringBuffer replace(int start, int end, @libcore.util.NonNull java.lang.String str) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.String substring(int start) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.CharSequence subSequence(int start, int end) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.String substring(int start, int end) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.StringBuffer insert(int index, char[] str, int offset, int len) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.StringBuffer insert(int offset, @libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.StringBuffer insert(int offset, @libcore.util.Nullable java.lang.String str) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.StringBuffer insert(int offset, char[] str) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuffer insert(int dstOffset, @libcore.util.Nullable java.lang.CharSequence s) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.StringBuffer insert(int dstOffset, @libcore.util.Nullable java.lang.CharSequence s, int start, int end) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuffer insert(int offset, boolean b) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.StringBuffer insert(int offset, char c) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuffer insert(int offset, int i) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuffer insert(int offset, long l) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuffer insert(int offset, float f) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuffer insert(int offset, double d) { throw new RuntimeException("Stub!"); }
+
+public int indexOf(@libcore.util.NonNull java.lang.String str) { throw new RuntimeException("Stub!"); }
+
+public synchronized int indexOf(@libcore.util.NonNull java.lang.String str, int fromIndex) { throw new RuntimeException("Stub!"); }
+
+public int lastIndexOf(@libcore.util.NonNull java.lang.String str) { throw new RuntimeException("Stub!"); }
+
+public synchronized int lastIndexOf(@libcore.util.NonNull java.lang.String str, int fromIndex) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.StringBuffer reverse() { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.String toString() { throw new RuntimeException("Stub!"); }
+}
+
diff --git a/java/lang/StringBuffer.java b/java/lang/StringBuffer.java
new file mode 100644
index 0000000..6781f11
--- /dev/null
+++ b/java/lang/StringBuffer.java
@@ -0,0 +1,715 @@
+/*
+ * Copyright (c) 1994, 2013, 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;
+
+import java.util.Arrays;
+
+/**
+ * A thread-safe, mutable sequence of characters.
+ * A string buffer is like a {@link String}, but can be modified. At any
+ * point in time it contains some particular sequence of characters, but
+ * the length and content of the sequence can be changed through certain
+ * method calls.
+ * <p>
+ * String buffers are safe for use by multiple threads. The methods
+ * are synchronized where necessary so that all the operations on any
+ * particular instance behave as if they occur in some serial order
+ * that is consistent with the order of the method calls made by each of
+ * the individual threads involved.
+ * <p>
+ * The principal operations on a {@code StringBuffer} are the
+ * {@code append} and {@code insert} methods, which are
+ * overloaded so as to accept data of any type. Each effectively
+ * converts a given datum to a string and then appends or inserts the
+ * characters of that string to the string buffer. The
+ * {@code append} method always adds these characters at the end
+ * of the buffer; the {@code insert} method adds the characters at
+ * a specified point.
+ * <p>
+ * For example, if {@code z} refers to a string buffer object
+ * whose current contents are {@code "start"}, then
+ * the method call {@code z.append("le")} would cause the string
+ * buffer to contain {@code "startle"}, whereas
+ * {@code z.insert(4, "le")} would alter the string buffer to
+ * contain {@code "starlet"}.
+ * <p>
+ * In general, if sb refers to an instance of a {@code StringBuffer},
+ * then {@code sb.append(x)} has the same effect as
+ * {@code sb.insert(sb.length(), x)}.
+ * <p>
+ * Whenever an operation occurs involving a source sequence (such as
+ * appending or inserting from a source sequence), this class synchronizes
+ * only on the string buffer performing the operation, not on the source.
+ * Note that while {@code StringBuffer} is designed to be safe to use
+ * concurrently from multiple threads, if the constructor or the
+ * {@code append} or {@code insert} operation is passed a source sequence
+ * that is shared across threads, the calling code must ensure
+ * that the operation has a consistent and unchanging view of the source
+ * sequence for the duration of the operation.
+ * This could be satisfied by the caller holding a lock during the
+ * operation's call, by using an immutable source sequence, or by not
+ * sharing the source sequence across threads.
+ * <p>
+ * Every string buffer has a capacity. As long as the length of the
+ * character sequence contained in the string buffer does not exceed
+ * the capacity, it is not necessary to allocate a new internal
+ * buffer array. If the internal buffer overflows, it is
+ * automatically made larger.
+ * <p>
+ * Unless otherwise noted, passing a {@code null} argument to a constructor
+ * or method in this class will cause a {@link NullPointerException} to be
+ * thrown.
+ * <p>
+ * As of release JDK 5, this class has been supplemented with an equivalent
+ * class designed for use by a single thread, {@link StringBuilder}. The
+ * {@code StringBuilder} class should generally be used in preference to
+ * this one, as it supports all of the same operations but it is faster, as
+ * it performs no synchronization.
+ *
+ * @author Arthur van Hoff
+ * @see java.lang.StringBuilder
+ * @see java.lang.String
+ * @since JDK1.0
+ */
+ public final class StringBuffer
+ extends AbstractStringBuilder
+ implements java.io.Serializable, CharSequence
+{
+
+ /**
+ * A cache of the last value returned by toString. Cleared
+ * whenever the StringBuffer is modified.
+ */
+ private transient char[] toStringCache;
+
+ /** use serialVersionUID from JDK 1.0.2 for interoperability */
+ static final long serialVersionUID = 3388685877147921107L;
+
+ /**
+ * Constructs a string buffer with no characters in it and an
+ * initial capacity of 16 characters.
+ */
+ public StringBuffer() {
+ super(16);
+ }
+
+ /**
+ * Constructs a string buffer with no characters in it and
+ * the specified initial capacity.
+ *
+ * @param capacity the initial capacity.
+ * @exception NegativeArraySizeException if the {@code capacity}
+ * argument is less than {@code 0}.
+ */
+ public StringBuffer(int capacity) {
+ super(capacity);
+ }
+
+ /**
+ * Constructs a string buffer initialized to the contents of the
+ * specified string. The initial capacity of the string buffer is
+ * {@code 16} plus the length of the string argument.
+ *
+ * @param str the initial contents of the buffer.
+ */
+ public StringBuffer(String str) {
+ super(str.length() + 16);
+ append(str);
+ }
+
+ /**
+ * Constructs a string buffer that contains the same characters
+ * as the specified {@code CharSequence}. The initial capacity of
+ * the string buffer is {@code 16} plus the length of the
+ * {@code CharSequence} argument.
+ * <p>
+ * If the length of the specified {@code CharSequence} is
+ * less than or equal to zero, then an empty buffer of capacity
+ * {@code 16} is returned.
+ *
+ * @param seq the sequence to copy.
+ * @since 1.5
+ */
+ public StringBuffer(CharSequence seq) {
+ this(seq.length() + 16);
+ append(seq);
+ }
+
+ @Override
+ public synchronized int length() {
+ return count;
+ }
+
+ @Override
+ public synchronized int capacity() {
+ return value.length;
+ }
+
+
+ @Override
+ public synchronized void ensureCapacity(int minimumCapacity) {
+ super.ensureCapacity(minimumCapacity);
+ }
+
+ /**
+ * @since 1.5
+ */
+ @Override
+ public synchronized void trimToSize() {
+ super.trimToSize();
+ }
+
+ /**
+ * @throws IndexOutOfBoundsException {@inheritDoc}
+ * @see #length()
+ */
+ @Override
+ public synchronized void setLength(int newLength) {
+ toStringCache = null;
+ super.setLength(newLength);
+ }
+
+ /**
+ * @throws IndexOutOfBoundsException {@inheritDoc}
+ * @see #length()
+ */
+ @Override
+ public synchronized char charAt(int index) {
+ if ((index < 0) || (index >= count))
+ throw new StringIndexOutOfBoundsException(index);
+ return value[index];
+ }
+
+ /**
+ * @since 1.5
+ */
+ @Override
+ public synchronized int codePointAt(int index) {
+ return super.codePointAt(index);
+ }
+
+ /**
+ * @since 1.5
+ */
+ @Override
+ public synchronized int codePointBefore(int index) {
+ return super.codePointBefore(index);
+ }
+
+ /**
+ * @since 1.5
+ */
+ @Override
+ public synchronized int codePointCount(int beginIndex, int endIndex) {
+ return super.codePointCount(beginIndex, endIndex);
+ }
+
+ /**
+ * @since 1.5
+ */
+ @Override
+ public synchronized int offsetByCodePoints(int index, int codePointOffset) {
+ return super.offsetByCodePoints(index, codePointOffset);
+ }
+
+ /**
+ * @throws IndexOutOfBoundsException {@inheritDoc}
+ */
+ @Override
+ public synchronized void getChars(int srcBegin, int srcEnd, char[] dst,
+ int dstBegin)
+ {
+ super.getChars(srcBegin, srcEnd, dst, dstBegin);
+ }
+
+ /**
+ * @throws IndexOutOfBoundsException {@inheritDoc}
+ * @see #length()
+ */
+ @Override
+ public synchronized void setCharAt(int index, char ch) {
+ if ((index < 0) || (index >= count))
+ throw new StringIndexOutOfBoundsException(index);
+ toStringCache = null;
+ value[index] = ch;
+ }
+
+ @Override
+ public synchronized StringBuffer append(Object obj) {
+ toStringCache = null;
+ super.append(String.valueOf(obj));
+ return this;
+ }
+
+ @Override
+ public synchronized StringBuffer append(String str) {
+ toStringCache = null;
+ super.append(str);
+ return this;
+ }
+
+ /**
+ * Appends the specified {@code StringBuffer} to this sequence.
+ * <p>
+ * The characters of the {@code StringBuffer} argument are appended,
+ * in order, to the contents of this {@code StringBuffer}, increasing the
+ * length of this {@code StringBuffer} by the length of the argument.
+ * If {@code sb} is {@code null}, then the four characters
+ * {@code "null"} are appended to this {@code StringBuffer}.
+ * <p>
+ * Let <i>n</i> be the length of the old character sequence, the one
+ * contained in the {@code StringBuffer} just prior to execution of the
+ * {@code append} method. Then the character at index <i>k</i> in
+ * the new character sequence is equal to the character at index <i>k</i>
+ * in the old character sequence, if <i>k</i> is less than <i>n</i>;
+ * otherwise, it is equal to the character at index <i>k-n</i> in the
+ * argument {@code sb}.
+ * <p>
+ * This method synchronizes on {@code this}, the destination
+ * object, but does not synchronize on the source ({@code sb}).
+ *
+ * @param sb the {@code StringBuffer} to append.
+ * @return a reference to this object.
+ * @since 1.4
+ */
+ public synchronized StringBuffer append(StringBuffer sb) {
+ toStringCache = null;
+ super.append(sb);
+ return this;
+ }
+
+ /**
+ * @since 1.8
+ */
+ @Override
+ synchronized StringBuffer append(AbstractStringBuilder asb) {
+ toStringCache = null;
+ super.append(asb);
+ return this;
+ }
+
+ /**
+ * Appends the specified {@code CharSequence} to this
+ * sequence.
+ * <p>
+ * The characters of the {@code CharSequence} argument are appended,
+ * in order, increasing the length of this sequence by the length of the
+ * argument.
+ *
+ * <p>The result of this method is exactly the same as if it were an
+ * invocation of this.append(s, 0, s.length());
+ *
+ * <p>This method synchronizes on {@code this}, the destination
+ * object, but does not synchronize on the source ({@code s}).
+ *
+ * <p>If {@code s} is {@code null}, then the four characters
+ * {@code "null"} are appended.
+ *
+ * @param s the {@code CharSequence} to append.
+ * @return a reference to this object.
+ * @since 1.5
+ */
+ @Override
+ public synchronized StringBuffer append(CharSequence s) {
+ toStringCache = null;
+ super.append(s);
+ return this;
+ }
+
+ /**
+ * @throws IndexOutOfBoundsException {@inheritDoc}
+ * @since 1.5
+ */
+ @Override
+ public synchronized StringBuffer append(CharSequence s, int start, int end)
+ {
+ toStringCache = null;
+ super.append(s, start, end);
+ return this;
+ }
+
+ @Override
+ public synchronized StringBuffer append(char[] str) {
+ toStringCache = null;
+ super.append(str);
+ return this;
+ }
+
+ /**
+ * @throws IndexOutOfBoundsException {@inheritDoc}
+ */
+ @Override
+ public synchronized StringBuffer append(char[] str, int offset, int len) {
+ toStringCache = null;
+ super.append(str, offset, len);
+ return this;
+ }
+
+ @Override
+ public synchronized StringBuffer append(boolean b) {
+ toStringCache = null;
+ super.append(b);
+ return this;
+ }
+
+ @Override
+ public synchronized StringBuffer append(char c) {
+ toStringCache = null;
+ super.append(c);
+ return this;
+ }
+
+ @Override
+ public synchronized StringBuffer append(int i) {
+ toStringCache = null;
+ super.append(i);
+ return this;
+ }
+
+ /**
+ * @since 1.5
+ */
+ @Override
+ public synchronized StringBuffer appendCodePoint(int codePoint) {
+ toStringCache = null;
+ super.appendCodePoint(codePoint);
+ return this;
+ }
+
+ @Override
+ public synchronized StringBuffer append(long lng) {
+ toStringCache = null;
+ super.append(lng);
+ return this;
+ }
+
+ @Override
+ public synchronized StringBuffer append(float f) {
+ toStringCache = null;
+ super.append(f);
+ return this;
+ }
+
+ @Override
+ public synchronized StringBuffer append(double d) {
+ toStringCache = null;
+ super.append(d);
+ return this;
+ }
+
+ /**
+ * @throws StringIndexOutOfBoundsException {@inheritDoc}
+ * @since 1.2
+ */
+ @Override
+ public synchronized StringBuffer delete(int start, int end) {
+ toStringCache = null;
+ super.delete(start, end);
+ return this;
+ }
+
+ /**
+ * @throws StringIndexOutOfBoundsException {@inheritDoc}
+ * @since 1.2
+ */
+ @Override
+ public synchronized StringBuffer deleteCharAt(int index) {
+ toStringCache = null;
+ super.deleteCharAt(index);
+ return this;
+ }
+
+ /**
+ * @throws StringIndexOutOfBoundsException {@inheritDoc}
+ * @since 1.2
+ */
+ @Override
+ public synchronized StringBuffer replace(int start, int end, String str) {
+ toStringCache = null;
+ super.replace(start, end, str);
+ return this;
+ }
+
+ /**
+ * @throws StringIndexOutOfBoundsException {@inheritDoc}
+ * @since 1.2
+ */
+ @Override
+ public synchronized String substring(int start) {
+ return substring(start, count);
+ }
+
+ /**
+ * @throws IndexOutOfBoundsException {@inheritDoc}
+ * @since 1.4
+ */
+ @Override
+ public synchronized CharSequence subSequence(int start, int end) {
+ return super.substring(start, end);
+ }
+
+ /**
+ * @throws StringIndexOutOfBoundsException {@inheritDoc}
+ * @since 1.2
+ */
+ @Override
+ public synchronized String substring(int start, int end) {
+ return super.substring(start, end);
+ }
+
+ /**
+ * @throws StringIndexOutOfBoundsException {@inheritDoc}
+ * @since 1.2
+ */
+ @Override
+ public synchronized StringBuffer insert(int index, char[] str, int offset,
+ int len)
+ {
+ toStringCache = null;
+ super.insert(index, str, offset, len);
+ return this;
+ }
+
+ /**
+ * @throws StringIndexOutOfBoundsException {@inheritDoc}
+ */
+ @Override
+ public synchronized StringBuffer insert(int offset, Object obj) {
+ toStringCache = null;
+ super.insert(offset, String.valueOf(obj));
+ return this;
+ }
+
+ /**
+ * @throws StringIndexOutOfBoundsException {@inheritDoc}
+ */
+ @Override
+ public synchronized StringBuffer insert(int offset, String str) {
+ toStringCache = null;
+ super.insert(offset, str);
+ return this;
+ }
+
+ /**
+ * @throws StringIndexOutOfBoundsException {@inheritDoc}
+ */
+ @Override
+ public synchronized StringBuffer insert(int offset, char[] str) {
+ toStringCache = null;
+ super.insert(offset, str);
+ return this;
+ }
+
+ /**
+ * @throws IndexOutOfBoundsException {@inheritDoc}
+ * @since 1.5
+ */
+ @Override
+ public StringBuffer insert(int dstOffset, CharSequence s) {
+ // Note, synchronization achieved via invocations of other StringBuffer methods
+ // after narrowing of s to specific type
+ // Ditto for toStringCache clearing
+ super.insert(dstOffset, s);
+ return this;
+ }
+
+ /**
+ * @throws IndexOutOfBoundsException {@inheritDoc}
+ * @since 1.5
+ */
+ @Override
+ public synchronized StringBuffer insert(int dstOffset, CharSequence s,
+ int start, int end)
+ {
+ toStringCache = null;
+ super.insert(dstOffset, s, start, end);
+ return this;
+ }
+
+ /**
+ * @throws StringIndexOutOfBoundsException {@inheritDoc}
+ */
+ @Override
+ public StringBuffer insert(int offset, boolean b) {
+ // Note, synchronization achieved via invocation of StringBuffer insert(int, String)
+ // after conversion of b to String by super class method
+ // Ditto for toStringCache clearing
+ super.insert(offset, b);
+ return this;
+ }
+
+ /**
+ * @throws IndexOutOfBoundsException {@inheritDoc}
+ */
+ @Override
+ public synchronized StringBuffer insert(int offset, char c) {
+ toStringCache = null;
+ super.insert(offset, c);
+ return this;
+ }
+
+ /**
+ * @throws StringIndexOutOfBoundsException {@inheritDoc}
+ */
+ @Override
+ public StringBuffer insert(int offset, int i) {
+ // Note, synchronization achieved via invocation of StringBuffer insert(int, String)
+ // after conversion of i to String by super class method
+ // Ditto for toStringCache clearing
+ super.insert(offset, i);
+ return this;
+ }
+
+ /**
+ * @throws StringIndexOutOfBoundsException {@inheritDoc}
+ */
+ @Override
+ public StringBuffer insert(int offset, long l) {
+ // Note, synchronization achieved via invocation of StringBuffer insert(int, String)
+ // after conversion of l to String by super class method
+ // Ditto for toStringCache clearing
+ super.insert(offset, l);
+ return this;
+ }
+
+ /**
+ * @throws StringIndexOutOfBoundsException {@inheritDoc}
+ */
+ @Override
+ public StringBuffer insert(int offset, float f) {
+ // Note, synchronization achieved via invocation of StringBuffer insert(int, String)
+ // after conversion of f to String by super class method
+ // Ditto for toStringCache clearing
+ super.insert(offset, f);
+ return this;
+ }
+
+ /**
+ * @throws StringIndexOutOfBoundsException {@inheritDoc}
+ */
+ @Override
+ public StringBuffer insert(int offset, double d) {
+ // Note, synchronization achieved via invocation of StringBuffer insert(int, String)
+ // after conversion of d to String by super class method
+ // Ditto for toStringCache clearing
+ super.insert(offset, d);
+ return this;
+ }
+
+ /**
+ * @since 1.4
+ */
+ @Override
+ public int indexOf(String str) {
+ // Note, synchronization achieved via invocations of other StringBuffer methods
+ return super.indexOf(str);
+ }
+
+ /**
+ * @since 1.4
+ */
+ @Override
+ public synchronized int indexOf(String str, int fromIndex) {
+ return super.indexOf(str, fromIndex);
+ }
+
+ /**
+ * @since 1.4
+ */
+ @Override
+ public int lastIndexOf(String str) {
+ // Note, synchronization achieved via invocations of other StringBuffer methods
+ return lastIndexOf(str, count);
+ }
+
+ /**
+ * @since 1.4
+ */
+ @Override
+ public synchronized int lastIndexOf(String str, int fromIndex) {
+ return super.lastIndexOf(str, fromIndex);
+ }
+
+ /**
+ * @since JDK1.0.2
+ */
+ @Override
+ public synchronized StringBuffer reverse() {
+ toStringCache = null;
+ super.reverse();
+ return this;
+ }
+
+ @Override
+ public synchronized String toString() {
+ if (toStringCache == null) {
+ toStringCache = Arrays.copyOfRange(value, 0, count);
+ }
+ return new String(toStringCache, 0, count);
+ }
+
+ /**
+ * Serializable fields for StringBuffer.
+ *
+ * @serialField value char[]
+ * The backing character array of this StringBuffer.
+ * @serialField count int
+ * The number of characters in this StringBuffer.
+ * @serialField shared boolean
+ * A flag indicating whether the backing array is shared.
+ * The value is ignored upon deserialization.
+ */
+ private static final java.io.ObjectStreamField[] serialPersistentFields =
+ {
+ new java.io.ObjectStreamField("value", char[].class),
+ new java.io.ObjectStreamField("count", Integer.TYPE),
+ new java.io.ObjectStreamField("shared", Boolean.TYPE),
+ };
+
+ /**
+ * readObject is called to restore the state of the StringBuffer from
+ * a stream.
+ */
+ private synchronized void writeObject(java.io.ObjectOutputStream s)
+ throws java.io.IOException {
+ java.io.ObjectOutputStream.PutField fields = s.putFields();
+ fields.put("value", value);
+ fields.put("count", count);
+ fields.put("shared", false);
+ s.writeFields();
+ }
+
+ /**
+ * readObject is called to restore the state of the StringBuffer from
+ * a stream.
+ */
+ private void readObject(java.io.ObjectInputStream s)
+ throws java.io.IOException, ClassNotFoundException {
+ java.io.ObjectInputStream.GetField fields = s.readFields();
+ value = (char[])fields.get("value", null);
+ count = fields.get("count", 0);
+ }
+}
diff --git a/java/lang/StringBuilder.annotated.java b/java/lang/StringBuilder.annotated.java
new file mode 100644
index 0000000..6fdde8a
--- /dev/null
+++ b/java/lang/StringBuilder.annotated.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2003, 2013, 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;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class StringBuilder implements java.lang.Appendable, java.lang.CharSequence, java.io.Serializable {
+
+public StringBuilder() { throw new RuntimeException("Stub!"); }
+
+public StringBuilder(int capacity) { throw new RuntimeException("Stub!"); }
+
+public StringBuilder(@libcore.util.NonNull java.lang.String str) { throw new RuntimeException("Stub!"); }
+
+public StringBuilder(@libcore.util.NonNull java.lang.CharSequence seq) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder append(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder append(@libcore.util.Nullable java.lang.String str) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder append(@libcore.util.Nullable java.lang.StringBuffer sb) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder append(@libcore.util.Nullable java.lang.CharSequence s) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder append(@libcore.util.Nullable java.lang.CharSequence s, int start, int end) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder append(char[] str) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder append(char[] str, int offset, int len) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder append(boolean b) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder append(char c) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder append(int i) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder append(long lng) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder append(float f) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder append(double d) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder appendCodePoint(int codePoint) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder delete(int start, int end) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder deleteCharAt(int index) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder replace(int start, int end, @libcore.util.NonNull java.lang.String str) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder insert(int index, char[] str, int offset, int len) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder insert(int offset, @libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder insert(int offset, @libcore.util.Nullable java.lang.String str) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder insert(int offset, char[] str) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder insert(int dstOffset, @libcore.util.Nullable java.lang.CharSequence s) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder insert(int dstOffset, @libcore.util.Nullable java.lang.CharSequence s, int start, int end) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder insert(int offset, boolean b) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder insert(int offset, char c) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder insert(int offset, int i) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder insert(int offset, long l) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder insert(int offset, float f) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder insert(int offset, double d) { throw new RuntimeException("Stub!"); }
+
+public int indexOf(@libcore.util.NonNull java.lang.String str) { throw new RuntimeException("Stub!"); }
+
+public int indexOf(@libcore.util.NonNull java.lang.String str, int fromIndex) { throw new RuntimeException("Stub!"); }
+
+public int lastIndexOf(@libcore.util.NonNull java.lang.String str) { throw new RuntimeException("Stub!"); }
+
+public int lastIndexOf(@libcore.util.NonNull java.lang.String str, int fromIndex) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.StringBuilder reverse() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public void trimToSize() { throw new RuntimeException("Stub!"); }
+
+public int codePointAt(int index) { throw new RuntimeException("Stub!"); }
+
+public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) { throw new RuntimeException("Stub!"); }
+
+public int length() { throw new RuntimeException("Stub!"); }
+
+public void setCharAt(int index, char ch) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.CharSequence subSequence(int start, int end) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String substring(int start) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String substring(int start, int end) { throw new RuntimeException("Stub!"); }
+
+public int capacity() { throw new RuntimeException("Stub!"); }
+
+public void setLength(int newLength) { throw new RuntimeException("Stub!"); }
+
+public void ensureCapacity(int minimumCapacity) { throw new RuntimeException("Stub!"); }
+
+public int codePointBefore(int index) { throw new RuntimeException("Stub!"); }
+
+public char charAt(int index) { throw new RuntimeException("Stub!"); }
+
+public int codePointCount(int beginIndex, int endIndex) { throw new RuntimeException("Stub!"); }
+
+public int offsetByCodePoints(int index, int codePointOffset) { throw new RuntimeException("Stub!"); }
+}
+
diff --git a/java/lang/StringBuilder.java b/java/lang/StringBuilder.java
new file mode 100644
index 0000000..325c9c5
--- /dev/null
+++ b/java/lang/StringBuilder.java
@@ -0,0 +1,445 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2003, 2013, 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;
+
+
+/**
+ * A mutable sequence of characters. This class provides an API compatible
+ * with {@code StringBuffer}, but with no guarantee of synchronization.
+ * This class is designed for use as a drop-in replacement for
+ * {@code StringBuffer} in places where the string buffer was being
+ * used by a single thread (as is generally the case). Where possible,
+ * it is recommended that this class be used in preference to
+ * {@code StringBuffer} as it will be faster under most implementations.
+ *
+ * <p>The principal operations on a {@code StringBuilder} are the
+ * {@code append} and {@code insert} methods, which are
+ * overloaded so as to accept data of any type. Each effectively
+ * converts a given datum to a string and then appends or inserts the
+ * characters of that string to the string builder. The
+ * {@code append} method always adds these characters at the end
+ * of the builder; the {@code insert} method adds the characters at
+ * a specified point.
+ * <p>
+ * For example, if {@code z} refers to a string builder object
+ * whose current contents are "{@code start}", then
+ * the method call {@code z.append("le")} would cause the string
+ * builder to contain "{@code startle}", whereas
+ * {@code z.insert(4, "le")} would alter the string builder to
+ * contain "{@code starlet}".
+ * <p>
+ * In general, if sb refers to an instance of a {@code StringBuilder},
+ * then {@code sb.append(x)} has the same effect as
+ * {@code sb.insert(sb.length(), x)}.
+ * <p>
+ * Every string builder has a capacity. As long as the length of the
+ * character sequence contained in the string builder does not exceed
+ * the capacity, it is not necessary to allocate a new internal
+ * buffer. If the internal buffer overflows, it is automatically made larger.
+ *
+ * <p>Instances of {@code StringBuilder} are not safe for
+ * use by multiple threads. If such synchronization is required then it is
+ * recommended that {@link java.lang.StringBuffer} be used.
+ *
+ * <p>Unless otherwise noted, passing a {@code null} argument to a constructor
+ * or method in this class will cause a {@link NullPointerException} to be
+ * thrown.
+ *
+ * @author Michael McCloskey
+ * @see java.lang.StringBuffer
+ * @see java.lang.String
+ * @since 1.5
+ */
+public final class StringBuilder
+ extends AbstractStringBuilder
+ implements java.io.Serializable, CharSequence
+{
+
+ /** use serialVersionUID for interoperability */
+ static final long serialVersionUID = 4383685877147921099L;
+
+ /**
+ * Constructs a string builder with no characters in it and an
+ * initial capacity of 16 characters.
+ */
+ public StringBuilder() {
+ super(16);
+ }
+
+ /**
+ * Constructs a string builder with no characters in it and an
+ * initial capacity specified by the {@code capacity} argument.
+ *
+ * @param capacity the initial capacity.
+ * @throws NegativeArraySizeException if the {@code capacity}
+ * argument is less than {@code 0}.
+ */
+ public StringBuilder(int capacity) {
+ super(capacity);
+ }
+
+ /**
+ * Constructs a string builder initialized to the contents of the
+ * specified string. The initial capacity of the string builder is
+ * {@code 16} plus the length of the string argument.
+ *
+ * @param str the initial contents of the buffer.
+ */
+ public StringBuilder(String str) {
+ super(str.length() + 16);
+ append(str);
+ }
+
+ /**
+ * Constructs a string builder that contains the same characters
+ * as the specified {@code CharSequence}. The initial capacity of
+ * the string builder is {@code 16} plus the length of the
+ * {@code CharSequence} argument.
+ *
+ * @param seq the sequence to copy.
+ */
+ public StringBuilder(CharSequence seq) {
+ this(seq.length() + 16);
+ append(seq);
+ }
+
+ @Override
+ public StringBuilder append(Object obj) {
+ return append(String.valueOf(obj));
+ }
+
+ @Override
+ public StringBuilder append(String str) {
+ super.append(str);
+ return this;
+ }
+
+ /**
+ * Appends the specified {@code StringBuffer} to this sequence.
+ * <p>
+ * The characters of the {@code StringBuffer} argument are appended,
+ * in order, to this sequence, increasing the
+ * length of this sequence by the length of the argument.
+ * If {@code sb} is {@code null}, then the four characters
+ * {@code "null"} are appended to this sequence.
+ * <p>
+ * Let <i>n</i> be the length of this character sequence just prior to
+ * execution of the {@code append} method. Then the character at index
+ * <i>k</i> in the new character sequence is equal to the character at
+ * index <i>k</i> in the old character sequence, if <i>k</i> is less than
+ * <i>n</i>; otherwise, it is equal to the character at index <i>k-n</i>
+ * in the argument {@code sb}.
+ *
+ * @param sb the {@code StringBuffer} to append.
+ * @return a reference to this object.
+ */
+ public StringBuilder append(StringBuffer sb) {
+ super.append(sb);
+ return this;
+ }
+
+ @Override
+ public StringBuilder append(CharSequence s) {
+ super.append(s);
+ return this;
+ }
+
+ /**
+ * @throws IndexOutOfBoundsException {@inheritDoc}
+ */
+ @Override
+ public StringBuilder append(CharSequence s, int start, int end) {
+ super.append(s, start, end);
+ return this;
+ }
+
+ @Override
+ public StringBuilder append(char[] str) {
+ super.append(str);
+ return this;
+ }
+
+ /**
+ * @throws IndexOutOfBoundsException {@inheritDoc}
+ */
+ @Override
+ public StringBuilder append(char[] str, int offset, int len) {
+ super.append(str, offset, len);
+ return this;
+ }
+
+ @Override
+ public StringBuilder append(boolean b) {
+ super.append(b);
+ return this;
+ }
+
+ @Override
+ public StringBuilder append(char c) {
+ super.append(c);
+ return this;
+ }
+
+ @Override
+ public StringBuilder append(int i) {
+ super.append(i);
+ return this;
+ }
+
+ @Override
+ public StringBuilder append(long lng) {
+ super.append(lng);
+ return this;
+ }
+
+ @Override
+ public StringBuilder append(float f) {
+ super.append(f);
+ return this;
+ }
+
+ @Override
+ public StringBuilder append(double d) {
+ super.append(d);
+ return this;
+ }
+
+ /**
+ * @since 1.5
+ */
+ @Override
+ public StringBuilder appendCodePoint(int codePoint) {
+ super.appendCodePoint(codePoint);
+ return this;
+ }
+
+ /**
+ * @throws StringIndexOutOfBoundsException {@inheritDoc}
+ */
+ @Override
+ public StringBuilder delete(int start, int end) {
+ super.delete(start, end);
+ return this;
+ }
+
+ /**
+ * @throws StringIndexOutOfBoundsException {@inheritDoc}
+ */
+ @Override
+ public StringBuilder deleteCharAt(int index) {
+ super.deleteCharAt(index);
+ return this;
+ }
+
+ /**
+ * @throws StringIndexOutOfBoundsException {@inheritDoc}
+ */
+ @Override
+ public StringBuilder replace(int start, int end, String str) {
+ super.replace(start, end, str);
+ return this;
+ }
+
+ /**
+ * @throws StringIndexOutOfBoundsException {@inheritDoc}
+ */
+ @Override
+ public StringBuilder insert(int index, char[] str, int offset,
+ int len)
+ {
+ super.insert(index, str, offset, len);
+ return this;
+ }
+
+ /**
+ * @throws StringIndexOutOfBoundsException {@inheritDoc}
+ */
+ @Override
+ public StringBuilder insert(int offset, Object obj) {
+ super.insert(offset, obj);
+ return this;
+ }
+
+ /**
+ * @throws StringIndexOutOfBoundsException {@inheritDoc}
+ */
+ @Override
+ public StringBuilder insert(int offset, String str) {
+ super.insert(offset, str);
+ return this;
+ }
+
+ /**
+ * @throws StringIndexOutOfBoundsException {@inheritDoc}
+ */
+ @Override
+ public StringBuilder insert(int offset, char[] str) {
+ super.insert(offset, str);
+ return this;
+ }
+
+ /**
+ * @throws IndexOutOfBoundsException {@inheritDoc}
+ */
+ @Override
+ public StringBuilder insert(int dstOffset, CharSequence s) {
+ super.insert(dstOffset, s);
+ return this;
+ }
+
+ /**
+ * @throws IndexOutOfBoundsException {@inheritDoc}
+ */
+ @Override
+ public StringBuilder insert(int dstOffset, CharSequence s,
+ int start, int end)
+ {
+ super.insert(dstOffset, s, start, end);
+ return this;
+ }
+
+ /**
+ * @throws StringIndexOutOfBoundsException {@inheritDoc}
+ */
+ @Override
+ public StringBuilder insert(int offset, boolean b) {
+ super.insert(offset, b);
+ return this;
+ }
+
+ /**
+ * @throws IndexOutOfBoundsException {@inheritDoc}
+ */
+ @Override
+ public StringBuilder insert(int offset, char c) {
+ super.insert(offset, c);
+ return this;
+ }
+
+ /**
+ * @throws StringIndexOutOfBoundsException {@inheritDoc}
+ */
+ @Override
+ public StringBuilder insert(int offset, int i) {
+ super.insert(offset, i);
+ return this;
+ }
+
+ /**
+ * @throws StringIndexOutOfBoundsException {@inheritDoc}
+ */
+ @Override
+ public StringBuilder insert(int offset, long l) {
+ super.insert(offset, l);
+ return this;
+ }
+
+ /**
+ * @throws StringIndexOutOfBoundsException {@inheritDoc}
+ */
+ @Override
+ public StringBuilder insert(int offset, float f) {
+ super.insert(offset, f);
+ return this;
+ }
+
+ /**
+ * @throws StringIndexOutOfBoundsException {@inheritDoc}
+ */
+ @Override
+ public StringBuilder insert(int offset, double d) {
+ super.insert(offset, d);
+ return this;
+ }
+
+ @Override
+ public int indexOf(String str) {
+ return super.indexOf(str);
+ }
+
+ @Override
+ public int indexOf(String str, int fromIndex) {
+ return super.indexOf(str, fromIndex);
+ }
+
+ @Override
+ public int lastIndexOf(String str) {
+ return super.lastIndexOf(str);
+ }
+
+ @Override
+ public int lastIndexOf(String str, int fromIndex) {
+ return super.lastIndexOf(str, fromIndex);
+ }
+
+ @Override
+ public StringBuilder reverse() {
+ super.reverse();
+ return this;
+ }
+
+ @Override
+ public String toString() {
+ // BEGIN Android-added: Return a constant "" for an empty buffer to keep historic behavior.
+ if (count == 0) {
+ return "";
+ }
+ // END Android-added: Return a constant "" for an empty buffer to keep historic behavior.
+ // Create a copy, don't share the array
+ return new String(value, 0, count);
+ }
+
+ /**
+ * Save the state of the {@code StringBuilder} instance to a stream
+ * (that is, serialize it).
+ *
+ * @serialData the number of characters currently stored in the string
+ * builder ({@code int}), followed by the characters in the
+ * string builder ({@code char[]}). The length of the
+ * {@code char} array may be greater than the number of
+ * characters currently stored in the string builder, in which
+ * case extra characters are ignored.
+ */
+ private void writeObject(java.io.ObjectOutputStream s)
+ throws java.io.IOException {
+ s.defaultWriteObject();
+ s.writeInt(count);
+ s.writeObject(value);
+ }
+
+ /**
+ * readObject is called to restore the state of the StringBuffer from
+ * a stream.
+ */
+ private void readObject(java.io.ObjectInputStream s)
+ throws java.io.IOException, ClassNotFoundException {
+ s.defaultReadObject();
+ count = s.readInt();
+ value = (char[]) s.readObject();
+ }
+
+}
diff --git a/java/lang/StringFactory.java b/java/lang/StringFactory.java
new file mode 100644
index 0000000..6ef664b
--- /dev/null
+++ b/java/lang/StringFactory.java
@@ -0,0 +1,296 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.lang;
+
+import dalvik.annotation.optimization.FastNative;
+import java.io.Serializable;
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.util.Arrays;
+import java.util.Comparator;
+import libcore.util.CharsetUtils;
+import libcore.util.EmptyArray;
+
+/**
+ * Class used to generate strings instead of calling String.<init>.
+ *
+ * @hide
+ */
+public final class StringFactory {
+
+ // TODO: Remove once native methods are in place.
+ private static final char REPLACEMENT_CHAR = (char) 0xfffd;
+
+ public static String newEmptyString() {
+ return newStringFromChars(EmptyArray.CHAR, 0, 0);
+ }
+
+ public static String newStringFromBytes(byte[] data) {
+ return newStringFromBytes(data, 0, data.length);
+ }
+
+ public static String newStringFromBytes(byte[] data, int high) {
+ return newStringFromBytes(data, high, 0, data.length);
+ }
+
+ public static String newStringFromBytes(byte[] data, int offset, int byteCount) {
+ return newStringFromBytes(data, offset, byteCount, Charset.defaultCharset());
+ }
+
+ @FastNative
+ public static native String newStringFromBytes(byte[] data, int high, int offset, int byteCount);
+
+ public static String newStringFromBytes(byte[] data, int offset, int byteCount, String charsetName) throws UnsupportedEncodingException {
+ return newStringFromBytes(data, offset, byteCount, Charset.forNameUEE(charsetName));
+ }
+
+ public static String newStringFromBytes(byte[] data, String charsetName) throws UnsupportedEncodingException {
+ return newStringFromBytes(data, 0, data.length, Charset.forNameUEE(charsetName));
+ }
+
+ private static final int[] TABLE_UTF8_NEEDED = new int[] {
+ // 0 1 2 3 4 5 6 7 8 9 a b c d e f
+ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xc0 - 0xcf
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xd0 - 0xdf
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xe0 - 0xef
+ 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xf0 - 0xff
+ };
+
+ // TODO: Implement this method natively.
+ public static String newStringFromBytes(byte[] data, int offset, int byteCount, Charset charset) {
+ if ((offset | byteCount) < 0 || byteCount > data.length - offset) {
+ throw new StringIndexOutOfBoundsException(data.length, offset, byteCount);
+ }
+
+ char[] value;
+ int length;
+
+ // We inline UTF-8, ISO-8859-1, and US-ASCII decoders for speed.
+ String canonicalCharsetName = charset.name();
+ if (canonicalCharsetName.equals("UTF-8")) {
+ /*
+ This code converts a UTF-8 byte sequence to a Java String (UTF-16).
+ It implements the W3C recommended UTF-8 decoder.
+ https://www.w3.org/TR/encoding/#utf-8-decoder
+
+ Unicode 3.2 Well-Formed UTF-8 Byte Sequences
+ Code Points First Second Third Fourth
+ U+0000..U+007F 00..7F
+ U+0080..U+07FF C2..DF 80..BF
+ U+0800..U+0FFF E0 A0..BF 80..BF
+ U+1000..U+CFFF E1..EC 80..BF 80..BF
+ U+D000..U+D7FF ED 80..9F 80..BF
+ U+E000..U+FFFF EE..EF 80..BF 80..BF
+ U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
+ U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
+ U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
+
+ Please refer to Unicode as the authority.
+ p.126 Table 3-7 in http://www.unicode.org/versions/Unicode10.0.0/ch03.pdf
+
+ Handling Malformed Input
+ The maximal subpart should be replaced by a single U+FFFD. Maximal subpart is
+ the longest code unit subsequence starting at an unconvertible offset that is either
+ 1) the initial subsequence of a well-formed code unit sequence, or
+ 2) a subsequence of length one:
+ One U+FFFD should be emitted for every sequence of bytes that is an incomplete prefix
+ of a valid sequence, and with the conversion to restart after the incomplete sequence.
+
+ For example, in byte sequence "41 C0 AF 41 F4 80 80 41", the maximal subparts are
+ "C0", "AF", and "F4 80 80". "F4 80 80" can be the initial subsequence of "F4 80 80 80",
+ but "C0" can't be the initial subsequence of any well-formed code unit sequence.
+ Thus, the output should be "A\ufffd\ufffdA\ufffdA".
+
+ Please refer to section "Best Practices for Using U+FFFD." in
+ http://www.unicode.org/versions/Unicode10.0.0/ch03.pdf
+ */
+ byte[] d = data;
+ char[] v = new char[byteCount];
+
+ int idx = offset;
+ int last = offset + byteCount;
+ int s = 0;
+
+ int codePoint = 0;
+ int utf8BytesSeen = 0;
+ int utf8BytesNeeded = 0;
+ int lowerBound = 0x80;
+ int upperBound = 0xbf;
+
+ while (idx < last) {
+ int b = d[idx++] & 0xff;
+ if (utf8BytesNeeded == 0) {
+ if ((b & 0x80) == 0) { // ASCII char. 0xxxxxxx
+ v[s++] = (char) b;
+ continue;
+ }
+
+ if ((b & 0x40) == 0) { // 10xxxxxx is illegal as first byte
+ v[s++] = REPLACEMENT_CHAR;
+ continue;
+ }
+
+ // 11xxxxxx
+ int tableLookupIndex = b & 0x3f;
+ utf8BytesNeeded = TABLE_UTF8_NEEDED[tableLookupIndex];
+ if (utf8BytesNeeded == 0) {
+ v[s++] = REPLACEMENT_CHAR;
+ continue;
+ }
+
+ // utf8BytesNeeded
+ // 1: b & 0x1f
+ // 2: b & 0x0f
+ // 3: b & 0x07
+ codePoint = b & (0x3f >> utf8BytesNeeded);
+ if (b == 0xe0) {
+ lowerBound = 0xa0;
+ } else if (b == 0xed) {
+ upperBound = 0x9f;
+ } else if (b == 0xf0) {
+ lowerBound = 0x90;
+ } else if (b == 0xf4) {
+ upperBound = 0x8f;
+ }
+ } else {
+ if (b < lowerBound || b > upperBound) {
+ // The bytes seen are ill-formed. Substitute them with U+FFFD
+ v[s++] = REPLACEMENT_CHAR;
+ codePoint = 0;
+ utf8BytesNeeded = 0;
+ utf8BytesSeen = 0;
+ lowerBound = 0x80;
+ upperBound = 0xbf;
+ /*
+ * According to the Unicode Standard,
+ * "a UTF-8 conversion process is required to never consume well-formed
+ * subsequences as part of its error handling for ill-formed subsequences"
+ * The current byte could be part of well-formed subsequences. Reduce the
+ * index by 1 to parse it in next loop.
+ */
+ idx--;
+ continue;
+ }
+
+ lowerBound = 0x80;
+ upperBound = 0xbf;
+ codePoint = (codePoint << 6) | (b & 0x3f);
+ utf8BytesSeen++;
+ if (utf8BytesNeeded != utf8BytesSeen) {
+ continue;
+ }
+
+ // Encode chars from U+10000 up as surrogate pairs
+ if (codePoint < 0x10000) {
+ v[s++] = (char) codePoint;
+ } else {
+ v[s++] = (char) ((codePoint >> 10) + 0xd7c0);
+ v[s++] = (char) ((codePoint & 0x3ff) + 0xdc00);
+ }
+
+ utf8BytesSeen = 0;
+ utf8BytesNeeded = 0;
+ codePoint = 0;
+ }
+ }
+
+ // The bytes seen are ill-formed. Substitute them by U+FFFD
+ if (utf8BytesNeeded != 0) {
+ v[s++] = REPLACEMENT_CHAR;
+ }
+
+ if (s == byteCount) {
+ // We guessed right, so we can use our temporary array as-is.
+ value = v;
+ length = s;
+ } else {
+ // Our temporary array was too big, so reallocate and copy.
+ value = new char[s];
+ length = s;
+ System.arraycopy(v, 0, value, 0, s);
+ }
+ } else if (canonicalCharsetName.equals("ISO-8859-1")) {
+ value = new char[byteCount];
+ length = byteCount;
+ CharsetUtils.isoLatin1BytesToChars(data, offset, byteCount, value);
+ } else if (canonicalCharsetName.equals("US-ASCII")) {
+ value = new char[byteCount];
+ length = byteCount;
+ CharsetUtils.asciiBytesToChars(data, offset, byteCount, value);
+ } else {
+ CharBuffer cb = charset.decode(ByteBuffer.wrap(data, offset, byteCount));
+ length = cb.length();
+ // The call to newStringFromChars below will copy length bytes out of value, so it does
+ // not matter that cb.array().length may be > cb.length() or that a Charset could keep a
+ // reference to the CharBuffer it returns and later mutate it.
+ value = cb.array();
+ }
+ return newStringFromChars(value, 0, length);
+ }
+
+ public static String newStringFromBytes(byte[] data, Charset charset) {
+ return newStringFromBytes(data, 0, data.length, charset);
+ }
+
+ public static String newStringFromChars(char[] data) {
+ return newStringFromChars(data, 0, data.length);
+ }
+
+ public static String newStringFromChars(char[] data, int offset, int charCount) {
+ if ((offset | charCount) < 0 || charCount > data.length - offset) {
+ throw new StringIndexOutOfBoundsException(data.length, offset, charCount);
+ }
+ return newStringFromChars(offset, charCount, data);
+ }
+
+ // The char array passed as {@code java_data} must not be a null reference.
+ @FastNative
+ static native String newStringFromChars(int offset, int charCount, char[] data);
+
+ @FastNative
+ public static native String newStringFromString(String toCopy);
+
+ public static String newStringFromStringBuffer(StringBuffer stringBuffer) {
+ synchronized (stringBuffer) {
+ return newStringFromChars(stringBuffer.getValue(), 0, stringBuffer.length());
+ }
+ }
+
+ // TODO: Implement this method natively.
+ public static String newStringFromCodePoints(int[] codePoints, int offset, int count) {
+ if (codePoints == null) {
+ throw new NullPointerException("codePoints == null");
+ }
+ if ((offset | count) < 0 || count > codePoints.length - offset) {
+ throw new StringIndexOutOfBoundsException(codePoints.length, offset, count);
+ }
+ char[] value = new char[count * 2];
+ int end = offset + count;
+ int length = 0;
+ for (int i = offset; i < end; i++) {
+ length += Character.toChars(codePoints[i], value, length);
+ }
+ return newStringFromChars(value, 0, length);
+ }
+
+ public static String newStringFromStringBuilder(StringBuilder stringBuilder) {
+ return newStringFromChars(stringBuilder.getValue(), 0, stringBuilder.length());
+ }
+}
diff --git a/java/lang/StringIndexOutOfBoundsException.java b/java/lang/StringIndexOutOfBoundsException.java
new file mode 100644
index 0000000..a40bd29
--- /dev/null
+++ b/java/lang/StringIndexOutOfBoundsException.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 2012, 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;
+
+/**
+ * Thrown by {@code String} methods to indicate that an index
+ * is either negative or greater than the size of the string. For
+ * some methods such as the charAt method, this exception also is
+ * thrown when the index is equal to the size of the string.
+ *
+ * @author unascribed
+ * @see java.lang.String#charAt(int)
+ * @since JDK1.0
+ */
+public
+class StringIndexOutOfBoundsException extends IndexOutOfBoundsException {
+ private static final long serialVersionUID = -6762910422159637258L;
+
+ /**
+ * Constructs a {@code StringIndexOutOfBoundsException} with no
+ * detail message.
+ *
+ * @since JDK1.0.
+ */
+ public StringIndexOutOfBoundsException() {
+ super();
+ }
+
+ /**
+ * Constructs a {@code StringIndexOutOfBoundsException} with
+ * the specified detail message.
+ *
+ * @param s the detail message.
+ */
+ public StringIndexOutOfBoundsException(String s) {
+ super(s);
+ }
+
+ /**
+ * Constructs a new {@code StringIndexOutOfBoundsException}
+ * class with an argument indicating the illegal index.
+ *
+ * @param index the illegal index.
+ */
+ public StringIndexOutOfBoundsException(int index) {
+ super("String index out of range: " + index);
+ }
+
+ // BEGIN Android-added: Additional constructors for internal use.
+ /**
+ * Used internally for consistent high-quality error reporting.
+ * @hide
+ */
+ StringIndexOutOfBoundsException(String s, int index) {
+ this(s.length(), index);
+ }
+
+ /**
+ * Used internally for consistent high-quality error reporting.
+ * @hide
+ */
+ StringIndexOutOfBoundsException(int sourceLength, int index) {
+ super("length=" + sourceLength + "; index=" + index);
+ }
+
+ /**
+ * Used internally for consistent high-quality error reporting.
+ * @hide
+ */
+ StringIndexOutOfBoundsException(String s, int offset, int count) {
+ this(s.length(), offset, count);
+ }
+
+ /**
+ * Used internally for consistent high-quality error reporting.
+ * @hide
+ */
+ StringIndexOutOfBoundsException(int sourceLength, int offset,
+ int count) {
+ super("length=" + sourceLength + "; regionStart=" + offset
+ + "; regionLength=" + count);
+ }
+ // END Android-added: Additional constructors for internal use.
+}
diff --git a/java/lang/SuppressWarnings.java b/java/lang/SuppressWarnings.java
new file mode 100644
index 0000000..d315ddb
--- /dev/null
+++ b/java/lang/SuppressWarnings.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2004, 2013, 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;
+
+import java.lang.annotation.*;
+import static java.lang.annotation.ElementType.*;
+
+/**
+ * Indicates that the named compiler warnings should be suppressed in the
+ * annotated element (and in all program elements contained in the annotated
+ * element). Note that the set of warnings suppressed in a given element is
+ * a superset of the warnings suppressed in all containing elements. For
+ * example, if you annotate a class to suppress one warning and annotate a
+ * method to suppress another, both warnings will be suppressed in the method.
+ *
+ * <p>As a matter of style, programmers should always use this annotation
+ * on the most deeply nested element where it is effective. If you want to
+ * suppress a warning in a particular method, you should annotate that
+ * method rather than its class.
+ *
+ * @author Josh Bloch
+ * @since 1.5
+ * @jls 4.8 Raw Types
+ * @jls 4.12.2 Variables of Reference Type
+ * @jls 5.1.9 Unchecked Conversion
+ * @jls 5.5.2 Checked Casts and Unchecked Casts
+ * @jls 9.6.3.5 @SuppressWarnings
+ */
+@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
+@Retention(RetentionPolicy.SOURCE)
+public @interface SuppressWarnings {
+ /**
+ * The set of warnings that are to be suppressed by the compiler in the
+ * annotated element. Duplicate names are permitted. The second and
+ * successive occurrences of a name are ignored. The presence of
+ * unrecognized warning names is <i>not</i> an error: Compilers must
+ * ignore any warning names they do not recognize. They are, however,
+ * free to emit a warning if an annotation contains an unrecognized
+ * warning name.
+ *
+ * <p> The string {@code "unchecked"} is used to suppress
+ * unchecked warnings. Compiler vendors should document the
+ * additional warning names they support in conjunction with this
+ * annotation type. They are encouraged to cooperate to ensure
+ * that the same names work across multiple compilers.
+ * @return the set of warnings to be suppressed
+ */
+ String[] value();
+}
diff --git a/java/lang/System.annotated.java b/java/lang/System.annotated.java
new file mode 100644
index 0000000..918b3da
--- /dev/null
+++ b/java/lang/System.annotated.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 2013, 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;
+
+import java.io.*;
+import java.nio.channels.spi.SelectorProvider;
+import java.nio.channels.Channel;
+import java.util.Properties;
+import java.util.PropertyPermission;
+import java.util.Map;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class System {
+
+System() { throw new RuntimeException("Stub!"); }
+
+public static void setIn(java.io.InputStream in) { throw new RuntimeException("Stub!"); }
+
+public static void setOut(java.io.PrintStream out) { throw new RuntimeException("Stub!"); }
+
+public static void setErr(java.io.PrintStream err) { throw new RuntimeException("Stub!"); }
+
+public static java.io.Console console() { throw new RuntimeException("Stub!"); }
+
+public static java.nio.channels.Channel inheritedChannel() throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public static void setSecurityManager(java.lang.SecurityManager s) { throw new RuntimeException("Stub!"); }
+
+public static java.lang.SecurityManager getSecurityManager() { throw new RuntimeException("Stub!"); }
+
+public static native long currentTimeMillis();
+
+public static native long nanoTime();
+
+public static native void arraycopy(java.lang.Object src, int srcPos, java.lang.Object dest, int destPos, int length);
+
+public static int identityHashCode(java.lang.Object x) { throw new RuntimeException("Stub!"); }
+
+public static java.util.Properties getProperties() { throw new RuntimeException("Stub!"); }
+
+public static java.lang.String lineSeparator() { throw new RuntimeException("Stub!"); }
+
+public static void setProperties(java.util.Properties props) { throw new RuntimeException("Stub!"); }
+
+public static java.lang.String getProperty(java.lang.String key) { throw new RuntimeException("Stub!"); }
+
+public static java.lang.String getProperty(java.lang.String key, java.lang.String def) { throw new RuntimeException("Stub!"); }
+
+public static java.lang.String setProperty(java.lang.String key, java.lang.String value) { throw new RuntimeException("Stub!"); }
+
+public static java.lang.String clearProperty(java.lang.String key) { throw new RuntimeException("Stub!"); }
+
+public static java.lang.String getenv(java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+public static java.util.Map<java.lang.String,java.lang.String> getenv() { throw new RuntimeException("Stub!"); }
+
+public static void exit(int status) { throw new RuntimeException("Stub!"); }
+
+public static void gc() { throw new RuntimeException("Stub!"); }
+
+public static void runFinalization() { throw new RuntimeException("Stub!"); }
+
+@Deprecated
+public static void runFinalizersOnExit(boolean value) { throw new RuntimeException("Stub!"); }
+
+public static void load(java.lang.String filename) { throw new RuntimeException("Stub!"); }
+
+public static void loadLibrary(java.lang.String libname) { throw new RuntimeException("Stub!"); }
+
+public static native java.lang.String mapLibraryName(java.lang.String libname);
+
+public static final java.io.PrintStream err;
+static { err = null; }
+
+public static final java.io.InputStream in;
+static { in = null; }
+
+public static final java.io.PrintStream out;
+static { out = null; }
+
[email protected]
+public static void logE(String message, Throwable th) { throw new RuntimeException("Stub!"); }
+
+}
+
diff --git a/java/lang/System.java b/java/lang/System.java
new file mode 100644
index 0000000..352d9ec
--- /dev/null
+++ b/java/lang/System.java
@@ -0,0 +1,1774 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 2013, 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;
+
+import com.android.icu.util.Icu4cMetadata;
+import dalvik.annotation.optimization.CriticalNative;
+import dalvik.annotation.optimization.FastNative;
+import android.system.ErrnoException;
+import android.system.StructPasswd;
+import android.system.StructUtsname;
+import dalvik.system.VMRuntime;
+import java.io.*;
+import java.nio.channels.Channel;
+import java.nio.channels.spi.SelectorProvider;
+import java.util.Locale;
+import java.util.Properties;
+import java.util.PropertyPermission;
+import libcore.io.Libcore;
+import libcore.timezone.TimeZoneDataFiles;
+
+import sun.reflect.CallerSensitive;
+import sun.reflect.Reflection;
+import sun.security.util.SecurityConstants;
+/**
+ * The <code>System</code> class contains several useful class fields
+ * and methods. It cannot be instantiated.
+ *
+ * <p>Among the facilities provided by the <code>System</code> class
+ * are standard input, standard output, and error output streams;
+ * access to externally defined properties and environment
+ * variables; a means of loading files and libraries; and a utility
+ * method for quickly copying a portion of an array.
+ *
+ * @author unascribed
+ * @since JDK1.0
+ */
+public final class System {
+ /** Don't let anyone instantiate this class */
+ private System() {
+ }
+
+ /**
+ * The "standard" input stream. This stream is already
+ * open and ready to supply input data. Typically this stream
+ * corresponds to keyboard input or another input source specified by
+ * the host environment or user.
+ */
+ public final static InputStream in;
+
+ /**
+ * The "standard" output stream. This stream is already
+ * open and ready to accept output data. Typically this stream
+ * corresponds to display output or another output destination
+ * specified by the host environment or user.
+ * <p>
+ * For simple stand-alone Java applications, a typical way to write
+ * a line of output data is:
+ * <blockquote><pre>
+ * System.out.println(data)
+ * </pre></blockquote>
+ * <p>
+ * See the <code>println</code> methods in class <code>PrintStream</code>.
+ *
+ * @see java.io.PrintStream#println()
+ * @see java.io.PrintStream#println(boolean)
+ * @see java.io.PrintStream#println(char)
+ * @see java.io.PrintStream#println(char[])
+ * @see java.io.PrintStream#println(double)
+ * @see java.io.PrintStream#println(float)
+ * @see java.io.PrintStream#println(int)
+ * @see java.io.PrintStream#println(long)
+ * @see java.io.PrintStream#println(java.lang.Object)
+ * @see java.io.PrintStream#println(java.lang.String)
+ */
+ public final static PrintStream out;
+
+ /**
+ * The "standard" error output stream. This stream is already
+ * open and ready to accept output data.
+ * <p>
+ * Typically this stream corresponds to display output or another
+ * output destination specified by the host environment or user. By
+ * convention, this output stream is used to display error messages
+ * or other information that should come to the immediate attention
+ * of a user even if the principal output stream, the value of the
+ * variable <code>out</code>, has been redirected to a file or other
+ * destination that is typically not continuously monitored.
+ */
+ public final static PrintStream err;
+
+ /**
+ * Dedicated lock for GC / Finalization logic.
+ */
+ private static final Object LOCK = new Object();
+
+ /**
+ * Whether or not we need to do a GC before running the finalizers.
+ */
+ private static boolean runGC;
+
+ /**
+ * If we just ran finalization, we might want to do a GC to free the finalized objects.
+ * This lets us do gc/runFinlization/gc sequences but prevents back to back System.gc().
+ */
+ private static boolean justRanFinalization;
+
+ /**
+ * Reassigns the "standard" input stream.
+ *
+ * <p>First, if there is a security manager, its <code>checkPermission</code>
+ * method is called with a <code>RuntimePermission("setIO")</code> permission
+ * to see if it's ok to reassign the "standard" input stream.
+ * <p>
+ *
+ * @param in the new standard input stream.
+ *
+ * @throws SecurityException
+ * if a security manager exists and its
+ * <code>checkPermission</code> method doesn't allow
+ * reassigning of the standard input stream.
+ *
+ * @see SecurityManager#checkPermission
+ * @see java.lang.RuntimePermission
+ *
+ * @since JDK1.1
+ */
+ public static void setIn(InputStream in) {
+ setIn0(in);
+ }
+
+ /**
+ * Reassigns the "standard" output stream.
+ *
+ * <p>First, if there is a security manager, its <code>checkPermission</code>
+ * method is called with a <code>RuntimePermission("setIO")</code> permission
+ * to see if it's ok to reassign the "standard" output stream.
+ *
+ * @param out the new standard output stream
+ *
+ * @throws SecurityException
+ * if a security manager exists and its
+ * <code>checkPermission</code> method doesn't allow
+ * reassigning of the standard output stream.
+ *
+ * @see SecurityManager#checkPermission
+ * @see java.lang.RuntimePermission
+ *
+ * @since JDK1.1
+ */
+ public static void setOut(PrintStream out) {
+ setOut0(out);
+ }
+
+ /**
+ * Reassigns the "standard" error output stream.
+ *
+ * <p>First, if there is a security manager, its <code>checkPermission</code>
+ * method is called with a <code>RuntimePermission("setIO")</code> permission
+ * to see if it's ok to reassign the "standard" error output stream.
+ *
+ * @param err the new standard error output stream.
+ *
+ * @throws SecurityException
+ * if a security manager exists and its
+ * <code>checkPermission</code> method doesn't allow
+ * reassigning of the standard error output stream.
+ *
+ * @see SecurityManager#checkPermission
+ * @see java.lang.RuntimePermission
+ *
+ * @since JDK1.1
+ */
+ public static void setErr(PrintStream err) {
+ setErr0(err);
+ }
+
+ private static volatile Console cons = null;
+ /**
+ * Returns the unique {@link java.io.Console Console} object associated
+ * with the current Java virtual machine, if any.
+ *
+ * @return The system console, if any, otherwise <tt>null</tt>.
+ *
+ * @since 1.6
+ */
+ public static Console console() {
+ // Android-changed: Added proper double checked locking for cons access
+ if (cons == null) {
+ synchronized (System.class) {
+ if (cons == null) {
+ cons = Console.console();
+ }
+ }
+ }
+ return cons;
+ }
+
+ /**
+ * Returns the channel inherited from the entity that created this
+ * Java virtual machine.
+ *
+ * <p> This method returns the channel obtained by invoking the
+ * {@link java.nio.channels.spi.SelectorProvider#inheritedChannel
+ * inheritedChannel} method of the system-wide default
+ * {@link java.nio.channels.spi.SelectorProvider} object. </p>
+ *
+ * <p> In addition to the network-oriented channels described in
+ * {@link java.nio.channels.spi.SelectorProvider#inheritedChannel
+ * inheritedChannel}, this method may return other kinds of
+ * channels in the future.
+ *
+ * @return The inherited channel, if any, otherwise <tt>null</tt>.
+ *
+ * @throws IOException
+ * If an I/O error occurs
+ *
+ * @throws SecurityException
+ * If a security manager is present and it does not
+ * permit access to the channel.
+ *
+ * @since 1.5
+ */
+ public static Channel inheritedChannel() throws IOException {
+ return SelectorProvider.provider().inheritedChannel();
+ }
+
+ private static native void setIn0(InputStream in);
+ private static native void setOut0(PrintStream out);
+ private static native void setErr0(PrintStream err);
+
+ /**
+ * Throws {@code SecurityException} (except in case {@code sm == null}).
+ *
+ * <p>Security managers do <i>not</i> provide a secure environment for
+ * executing untrusted code and are unsupported on Android. Untrusted code
+ * cannot be safely isolated within a single VM on Android, so this method
+ * <i>always</i> throws a {@code SecurityException} when passed a non-null SecurityManager
+ *
+ * @param s a security manager
+ * @throws SecurityException always, unless {@code sm == null}
+ */
+ public static
+ void setSecurityManager(final SecurityManager s) {
+ if (s != null) {
+ throw new SecurityException();
+ }
+ }
+
+ /**
+ * Always returns {@code null} in Android
+ *
+ * @return {@code null} in Android
+ */
+ public static SecurityManager getSecurityManager() {
+ // No-op on android.
+ return null;
+ }
+
+ /**
+ * Returns the current time in milliseconds. Note that
+ * while the unit of time of the return value is a millisecond,
+ * the granularity of the value depends on the underlying
+ * operating system and may be larger. For example, many
+ * operating systems measure time in units of tens of
+ * milliseconds.
+ *
+ * <p> See the description of the class <code>Date</code> for
+ * a discussion of slight discrepancies that may arise between
+ * "computer time" and coordinated universal time (UTC).
+ *
+ * @return the difference, measured in milliseconds, between
+ * the current time and midnight, January 1, 1970 UTC.
+ * @see java.util.Date
+ */
+ @CriticalNative
+ public static native long currentTimeMillis();
+
+ /**
+ * Returns the current value of the running Java Virtual Machine's
+ * high-resolution time source, in nanoseconds.
+ *
+ * <p>This method can only be used to measure elapsed time and is
+ * not related to any other notion of system or wall-clock time.
+ * The value returned represents nanoseconds since some fixed but
+ * arbitrary <i>origin</i> time (perhaps in the future, so values
+ * may be negative). The same origin is used by all invocations of
+ * this method in an instance of a Java virtual machine; other
+ * virtual machine instances are likely to use a different origin.
+ *
+ * <p>This method provides nanosecond precision, but not necessarily
+ * nanosecond resolution (that is, how frequently the value changes)
+ * - no guarantees are made except that the resolution is at least as
+ * good as that of {@link #currentTimeMillis()}.
+ *
+ * <p>Differences in successive calls that span greater than
+ * approximately 292 years (2<sup>63</sup> nanoseconds) will not
+ * correctly compute elapsed time due to numerical overflow.
+ *
+ * <p>The values returned by this method become meaningful only when
+ * the difference between two such values, obtained within the same
+ * instance of a Java virtual machine, is computed.
+ *
+ * <p> For example, to measure how long some code takes to execute:
+ * <pre> {@code
+ * long startTime = System.nanoTime();
+ * // ... the code being measured ...
+ * long estimatedTime = System.nanoTime() - startTime;}</pre>
+ *
+ * <p>To compare two nanoTime values
+ * <pre> {@code
+ * long t0 = System.nanoTime();
+ * ...
+ * long t1 = System.nanoTime();}</pre>
+ *
+ * one should use {@code t1 - t0 < 0}, not {@code t1 < t0},
+ * because of the possibility of numerical overflow.
+ *
+ * @return the current value of the running Java Virtual Machine's
+ * high-resolution time source, in nanoseconds
+ * @since 1.5
+ */
+ @CriticalNative
+ public static native long nanoTime();
+
+ /**
+ * Copies an array from the specified source array, beginning at the
+ * specified position, to the specified position of the destination array.
+ * A subsequence of array components are copied from the source
+ * array referenced by <code>src</code> to the destination array
+ * referenced by <code>dest</code>. The number of components copied is
+ * equal to the <code>length</code> argument. The components at
+ * positions <code>srcPos</code> through
+ * <code>srcPos+length-1</code> in the source array are copied into
+ * positions <code>destPos</code> through
+ * <code>destPos+length-1</code>, respectively, of the destination
+ * array.
+ * <p>
+ * If the <code>src</code> and <code>dest</code> arguments refer to the
+ * same array object, then the copying is performed as if the
+ * components at positions <code>srcPos</code> through
+ * <code>srcPos+length-1</code> were first copied to a temporary
+ * array with <code>length</code> components and then the contents of
+ * the temporary array were copied into positions
+ * <code>destPos</code> through <code>destPos+length-1</code> of the
+ * destination array.
+ * <p>
+ * If <code>dest</code> is <code>null</code>, then a
+ * <code>NullPointerException</code> is thrown.
+ * <p>
+ * If <code>src</code> is <code>null</code>, then a
+ * <code>NullPointerException</code> is thrown and the destination
+ * array is not modified.
+ * <p>
+ * Otherwise, if any of the following is true, an
+ * <code>ArrayStoreException</code> is thrown and the destination is
+ * not modified:
+ * <ul>
+ * <li>The <code>src</code> argument refers to an object that is not an
+ * array.
+ * <li>The <code>dest</code> argument refers to an object that is not an
+ * array.
+ * <li>The <code>src</code> argument and <code>dest</code> argument refer
+ * to arrays whose component types are different primitive types.
+ * <li>The <code>src</code> argument refers to an array with a primitive
+ * component type and the <code>dest</code> argument refers to an array
+ * with a reference component type.
+ * <li>The <code>src</code> argument refers to an array with a reference
+ * component type and the <code>dest</code> argument refers to an array
+ * with a primitive component type.
+ * </ul>
+ * <p>
+ * Otherwise, if any of the following is true, an
+ * <code>IndexOutOfBoundsException</code> is
+ * thrown and the destination is not modified:
+ * <ul>
+ * <li>The <code>srcPos</code> argument is negative.
+ * <li>The <code>destPos</code> argument is negative.
+ * <li>The <code>length</code> argument is negative.
+ * <li><code>srcPos+length</code> is greater than
+ * <code>src.length</code>, the length of the source array.
+ * <li><code>destPos+length</code> is greater than
+ * <code>dest.length</code>, the length of the destination array.
+ * </ul>
+ * <p>
+ * Otherwise, if any actual component of the source array from
+ * position <code>srcPos</code> through
+ * <code>srcPos+length-1</code> cannot be converted to the component
+ * type of the destination array by assignment conversion, an
+ * <code>ArrayStoreException</code> is thrown. In this case, let
+ * <b><i>k</i></b> be the smallest nonnegative integer less than
+ * length such that <code>src[srcPos+</code><i>k</i><code>]</code>
+ * cannot be converted to the component type of the destination
+ * array; when the exception is thrown, source array components from
+ * positions <code>srcPos</code> through
+ * <code>srcPos+</code><i>k</i><code>-1</code>
+ * will already have been copied to destination array positions
+ * <code>destPos</code> through
+ * <code>destPos+</code><i>k</I><code>-1</code> and no other
+ * positions of the destination array will have been modified.
+ * (Because of the restrictions already itemized, this
+ * paragraph effectively applies only to the situation where both
+ * arrays have component types that are reference types.)
+ *
+ * @param src the source array.
+ * @param srcPos starting position in the source array.
+ * @param dest the destination array.
+ * @param destPos starting position in the destination data.
+ * @param length the number of array elements to be copied.
+ * @exception IndexOutOfBoundsException if copying would cause
+ * access of data outside array bounds.
+ * @exception ArrayStoreException if an element in the <code>src</code>
+ * array could not be stored into the <code>dest</code> array
+ * because of a type mismatch.
+ * @exception NullPointerException if either <code>src</code> or
+ * <code>dest</code> is <code>null</code>.
+ */
+ @FastNative
+ public static native void arraycopy(Object src, int srcPos,
+ Object dest, int destPos,
+ int length);
+
+
+ // BEGIN Android-changed
+ /**
+ * The char array length threshold below which to use a Java
+ * (non-native) version of arraycopy() instead of the native
+ * version. See b/7103825.
+ */
+ private static final int ARRAYCOPY_SHORT_CHAR_ARRAY_THRESHOLD = 32;
+
+ /**
+ * The char[] specialized version of arraycopy().
+ * Note: This method is required for runtime ART compiler optimizations.
+ * Do not remove or change the signature.
+ */
+ @SuppressWarnings("unused")
+ private static void arraycopy(char[] src, int srcPos, char[] dst, int dstPos, int length) {
+ if (src == null) {
+ throw new NullPointerException("src == null");
+ }
+ if (dst == null) {
+ throw new NullPointerException("dst == null");
+ }
+ if (srcPos < 0 || dstPos < 0 || length < 0 ||
+ srcPos > src.length - length || dstPos > dst.length - length) {
+ throw new ArrayIndexOutOfBoundsException(
+ "src.length=" + src.length + " srcPos=" + srcPos +
+ " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length);
+ }
+ if (length <= ARRAYCOPY_SHORT_CHAR_ARRAY_THRESHOLD) {
+ // Copy char by char for shorter arrays.
+ if (src == dst && srcPos < dstPos && dstPos < srcPos + length) {
+ // Copy backward (to avoid overwriting elements before
+ // they are copied in case of an overlap on the same
+ // array.)
+ for (int i = length - 1; i >= 0; --i) {
+ dst[dstPos + i] = src[srcPos + i];
+ }
+ } else {
+ // Copy forward.
+ for (int i = 0; i < length; ++i) {
+ dst[dstPos + i] = src[srcPos + i];
+ }
+ }
+ } else {
+ // Call the native version for longer arrays.
+ arraycopyCharUnchecked(src, srcPos, dst, dstPos, length);
+ }
+ }
+
+ /**
+ * The char[] specialized, unchecked, native version of
+ * arraycopy(). This assumes error checking has been done.
+ */
+ @FastNative
+ private static native void arraycopyCharUnchecked(char[] src, int srcPos,
+ char[] dst, int dstPos, int length);
+
+ /**
+ * The byte array length threshold below which to use a Java
+ * (non-native) version of arraycopy() instead of the native
+ * version. See b/7103825.
+ */
+ private static final int ARRAYCOPY_SHORT_BYTE_ARRAY_THRESHOLD = 32;
+
+ /**
+ * The byte[] specialized version of arraycopy().
+ * Note: This method is required for runtime ART compiler optimizations.
+ * Do not remove or change the signature.
+ */
+ @SuppressWarnings("unused")
+ private static void arraycopy(byte[] src, int srcPos, byte[] dst, int dstPos, int length) {
+ if (src == null) {
+ throw new NullPointerException("src == null");
+ }
+ if (dst == null) {
+ throw new NullPointerException("dst == null");
+ }
+ if (srcPos < 0 || dstPos < 0 || length < 0 ||
+ srcPos > src.length - length || dstPos > dst.length - length) {
+ throw new ArrayIndexOutOfBoundsException(
+ "src.length=" + src.length + " srcPos=" + srcPos +
+ " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length);
+ }
+ if (length <= ARRAYCOPY_SHORT_BYTE_ARRAY_THRESHOLD) {
+ // Copy byte by byte for shorter arrays.
+ if (src == dst && srcPos < dstPos && dstPos < srcPos + length) {
+ // Copy backward (to avoid overwriting elements before
+ // they are copied in case of an overlap on the same
+ // array.)
+ for (int i = length - 1; i >= 0; --i) {
+ dst[dstPos + i] = src[srcPos + i];
+ }
+ } else {
+ // Copy forward.
+ for (int i = 0; i < length; ++i) {
+ dst[dstPos + i] = src[srcPos + i];
+ }
+ }
+ } else {
+ // Call the native version for longer arrays.
+ arraycopyByteUnchecked(src, srcPos, dst, dstPos, length);
+ }
+ }
+
+ /**
+ * The byte[] specialized, unchecked, native version of
+ * arraycopy(). This assumes error checking has been done.
+ */
+ @FastNative
+ private static native void arraycopyByteUnchecked(byte[] src, int srcPos,
+ byte[] dst, int dstPos, int length);
+
+ /**
+ * The short array length threshold below which to use a Java
+ * (non-native) version of arraycopy() instead of the native
+ * version. See b/7103825.
+ */
+ private static final int ARRAYCOPY_SHORT_SHORT_ARRAY_THRESHOLD = 32;
+
+ /**
+ * The short[] specialized version of arraycopy().
+ * Note: This method is required for runtime ART compiler optimizations.
+ * Do not remove or change the signature.
+ */
+ @SuppressWarnings("unused")
+ private static void arraycopy(short[] src, int srcPos, short[] dst, int dstPos, int length) {
+ if (src == null) {
+ throw new NullPointerException("src == null");
+ }
+ if (dst == null) {
+ throw new NullPointerException("dst == null");
+ }
+ if (srcPos < 0 || dstPos < 0 || length < 0 ||
+ srcPos > src.length - length || dstPos > dst.length - length) {
+ throw new ArrayIndexOutOfBoundsException(
+ "src.length=" + src.length + " srcPos=" + srcPos +
+ " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length);
+ }
+ if (length <= ARRAYCOPY_SHORT_SHORT_ARRAY_THRESHOLD) {
+ // Copy short by short for shorter arrays.
+ if (src == dst && srcPos < dstPos && dstPos < srcPos + length) {
+ // Copy backward (to avoid overwriting elements before
+ // they are copied in case of an overlap on the same
+ // array.)
+ for (int i = length - 1; i >= 0; --i) {
+ dst[dstPos + i] = src[srcPos + i];
+ }
+ } else {
+ // Copy forward.
+ for (int i = 0; i < length; ++i) {
+ dst[dstPos + i] = src[srcPos + i];
+ }
+ }
+ } else {
+ // Call the native version for longer arrays.
+ arraycopyShortUnchecked(src, srcPos, dst, dstPos, length);
+ }
+ }
+
+ /**
+ * The short[] specialized, unchecked, native version of
+ * arraycopy(). This assumes error checking has been done.
+ */
+ @FastNative
+ private static native void arraycopyShortUnchecked(short[] src, int srcPos,
+ short[] dst, int dstPos, int length);
+
+ /**
+ * The short array length threshold below which to use a Java
+ * (non-native) version of arraycopy() instead of the native
+ * version. See b/7103825.
+ */
+ private static final int ARRAYCOPY_SHORT_INT_ARRAY_THRESHOLD = 32;
+
+ /**
+ * The int[] specialized version of arraycopy().
+ * Note: This method is required for runtime ART compiler optimizations.
+ * Do not remove or change the signature.
+ */
+ @SuppressWarnings("unused")
+ private static void arraycopy(int[] src, int srcPos, int[] dst, int dstPos, int length) {
+ if (src == null) {
+ throw new NullPointerException("src == null");
+ }
+ if (dst == null) {
+ throw new NullPointerException("dst == null");
+ }
+ if (srcPos < 0 || dstPos < 0 || length < 0 ||
+ srcPos > src.length - length || dstPos > dst.length - length) {
+ throw new ArrayIndexOutOfBoundsException(
+ "src.length=" + src.length + " srcPos=" + srcPos +
+ " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length);
+ }
+ if (length <= ARRAYCOPY_SHORT_INT_ARRAY_THRESHOLD) {
+ // Copy int by int for shorter arrays.
+ if (src == dst && srcPos < dstPos && dstPos < srcPos + length) {
+ // Copy backward (to avoid overwriting elements before
+ // they are copied in case of an overlap on the same
+ // array.)
+ for (int i = length - 1; i >= 0; --i) {
+ dst[dstPos + i] = src[srcPos + i];
+ }
+ } else {
+ // Copy forward.
+ for (int i = 0; i < length; ++i) {
+ dst[dstPos + i] = src[srcPos + i];
+ }
+ }
+ } else {
+ // Call the native version for longer arrays.
+ arraycopyIntUnchecked(src, srcPos, dst, dstPos, length);
+ }
+ }
+
+ /**
+ * The int[] specialized, unchecked, native version of
+ * arraycopy(). This assumes error checking has been done.
+ */
+ @FastNative
+ private static native void arraycopyIntUnchecked(int[] src, int srcPos,
+ int[] dst, int dstPos, int length);
+
+ /**
+ * The short array length threshold below which to use a Java
+ * (non-native) version of arraycopy() instead of the native
+ * version. See b/7103825.
+ */
+ private static final int ARRAYCOPY_SHORT_LONG_ARRAY_THRESHOLD = 32;
+
+ /**
+ * The long[] specialized version of arraycopy().
+ * Note: This method is required for runtime ART compiler optimizations.
+ * Do not remove or change the signature.
+ */
+ @SuppressWarnings("unused")
+ private static void arraycopy(long[] src, int srcPos, long[] dst, int dstPos, int length) {
+ if (src == null) {
+ throw new NullPointerException("src == null");
+ }
+ if (dst == null) {
+ throw new NullPointerException("dst == null");
+ }
+ if (srcPos < 0 || dstPos < 0 || length < 0 ||
+ srcPos > src.length - length || dstPos > dst.length - length) {
+ throw new ArrayIndexOutOfBoundsException(
+ "src.length=" + src.length + " srcPos=" + srcPos +
+ " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length);
+ }
+ if (length <= ARRAYCOPY_SHORT_LONG_ARRAY_THRESHOLD) {
+ // Copy long by long for shorter arrays.
+ if (src == dst && srcPos < dstPos && dstPos < srcPos + length) {
+ // Copy backward (to avoid overwriting elements before
+ // they are copied in case of an overlap on the same
+ // array.)
+ for (int i = length - 1; i >= 0; --i) {
+ dst[dstPos + i] = src[srcPos + i];
+ }
+ } else {
+ // Copy forward.
+ for (int i = 0; i < length; ++i) {
+ dst[dstPos + i] = src[srcPos + i];
+ }
+ }
+ } else {
+ // Call the native version for longer arrays.
+ arraycopyLongUnchecked(src, srcPos, dst, dstPos, length);
+ }
+ }
+
+ /**
+ * The long[] specialized, unchecked, native version of
+ * arraycopy(). This assumes error checking has been done.
+ */
+ @FastNative
+ private static native void arraycopyLongUnchecked(long[] src, int srcPos,
+ long[] dst, int dstPos, int length);
+
+ /**
+ * The short array length threshold below which to use a Java
+ * (non-native) version of arraycopy() instead of the native
+ * version. See b/7103825.
+ */
+ private static final int ARRAYCOPY_SHORT_FLOAT_ARRAY_THRESHOLD = 32;
+
+ /**
+ * The float[] specialized version of arraycopy().
+ * Note: This method is required for runtime ART compiler optimizations.
+ * Do not remove or change the signature.
+ */
+ @SuppressWarnings("unused")
+ private static void arraycopy(float[] src, int srcPos, float[] dst, int dstPos, int length) {
+ if (src == null) {
+ throw new NullPointerException("src == null");
+ }
+ if (dst == null) {
+ throw new NullPointerException("dst == null");
+ }
+ if (srcPos < 0 || dstPos < 0 || length < 0 ||
+ srcPos > src.length - length || dstPos > dst.length - length) {
+ throw new ArrayIndexOutOfBoundsException(
+ "src.length=" + src.length + " srcPos=" + srcPos +
+ " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length);
+ }
+ if (length <= ARRAYCOPY_SHORT_FLOAT_ARRAY_THRESHOLD) {
+ // Copy float by float for shorter arrays.
+ if (src == dst && srcPos < dstPos && dstPos < srcPos + length) {
+ // Copy backward (to avoid overwriting elements before
+ // they are copied in case of an overlap on the same
+ // array.)
+ for (int i = length - 1; i >= 0; --i) {
+ dst[dstPos + i] = src[srcPos + i];
+ }
+ } else {
+ // Copy forward.
+ for (int i = 0; i < length; ++i) {
+ dst[dstPos + i] = src[srcPos + i];
+ }
+ }
+ } else {
+ // Call the native version for floater arrays.
+ arraycopyFloatUnchecked(src, srcPos, dst, dstPos, length);
+ }
+ }
+
+ /**
+ * The float[] specialized, unchecked, native version of
+ * arraycopy(). This assumes error checking has been done.
+ */
+ @FastNative
+ private static native void arraycopyFloatUnchecked(float[] src, int srcPos,
+ float[] dst, int dstPos, int length);
+
+ /**
+ * The short array length threshold below which to use a Java
+ * (non-native) version of arraycopy() instead of the native
+ * version. See b/7103825.
+ */
+ private static final int ARRAYCOPY_SHORT_DOUBLE_ARRAY_THRESHOLD = 32;
+
+ /**
+ * The double[] specialized version of arraycopy().
+ * Note: This method is required for runtime ART compiler optimizations.
+ * Do not remove or change the signature.
+ */
+ @SuppressWarnings("unused")
+ private static void arraycopy(double[] src, int srcPos, double[] dst, int dstPos, int length) {
+ if (src == null) {
+ throw new NullPointerException("src == null");
+ }
+ if (dst == null) {
+ throw new NullPointerException("dst == null");
+ }
+ if (srcPos < 0 || dstPos < 0 || length < 0 ||
+ srcPos > src.length - length || dstPos > dst.length - length) {
+ throw new ArrayIndexOutOfBoundsException(
+ "src.length=" + src.length + " srcPos=" + srcPos +
+ " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length);
+ }
+ if (length <= ARRAYCOPY_SHORT_DOUBLE_ARRAY_THRESHOLD) {
+ // Copy double by double for shorter arrays.
+ if (src == dst && srcPos < dstPos && dstPos < srcPos + length) {
+ // Copy backward (to avoid overwriting elements before
+ // they are copied in case of an overlap on the same
+ // array.)
+ for (int i = length - 1; i >= 0; --i) {
+ dst[dstPos + i] = src[srcPos + i];
+ }
+ } else {
+ // Copy forward.
+ for (int i = 0; i < length; ++i) {
+ dst[dstPos + i] = src[srcPos + i];
+ }
+ }
+ } else {
+ // Call the native version for floater arrays.
+ arraycopyDoubleUnchecked(src, srcPos, dst, dstPos, length);
+ }
+ }
+
+ /**
+ * The double[] specialized, unchecked, native version of
+ * arraycopy(). This assumes error checking has been done.
+ */
+ @FastNative
+ private static native void arraycopyDoubleUnchecked(double[] src, int srcPos,
+ double[] dst, int dstPos, int length);
+
+ /**
+ * The short array length threshold below which to use a Java
+ * (non-native) version of arraycopy() instead of the native
+ * version. See b/7103825.
+ */
+ private static final int ARRAYCOPY_SHORT_BOOLEAN_ARRAY_THRESHOLD = 32;
+
+ /**
+ * The boolean[] specialized version of arraycopy().
+ * Note: This method is required for runtime ART compiler optimizations.
+ * Do not remove or change the signature.
+ */
+ @SuppressWarnings("unused")
+ private static void arraycopy(boolean[] src, int srcPos, boolean[] dst, int dstPos, int length) {
+ if (src == null) {
+ throw new NullPointerException("src == null");
+ }
+ if (dst == null) {
+ throw new NullPointerException("dst == null");
+ }
+ if (srcPos < 0 || dstPos < 0 || length < 0 ||
+ srcPos > src.length - length || dstPos > dst.length - length) {
+ throw new ArrayIndexOutOfBoundsException(
+ "src.length=" + src.length + " srcPos=" + srcPos +
+ " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length);
+ }
+ if (length <= ARRAYCOPY_SHORT_BOOLEAN_ARRAY_THRESHOLD) {
+ // Copy boolean by boolean for shorter arrays.
+ if (src == dst && srcPos < dstPos && dstPos < srcPos + length) {
+ // Copy backward (to avoid overwriting elements before
+ // they are copied in case of an overlap on the same
+ // array.)
+ for (int i = length - 1; i >= 0; --i) {
+ dst[dstPos + i] = src[srcPos + i];
+ }
+ } else {
+ // Copy forward.
+ for (int i = 0; i < length; ++i) {
+ dst[dstPos + i] = src[srcPos + i];
+ }
+ }
+ } else {
+ // Call the native version for floater arrays.
+ arraycopyBooleanUnchecked(src, srcPos, dst, dstPos, length);
+ }
+ }
+
+ /**
+ * The boolean[] specialized, unchecked, native version of
+ * arraycopy(). This assumes error checking has been done.
+ */
+ @FastNative
+ private static native void arraycopyBooleanUnchecked(boolean[] src, int srcPos,
+ boolean[] dst, int dstPos, int length);
+ // END Android-changed
+
+ /**
+ * Returns the same hash code for the given object as
+ * would be returned by the default method hashCode(),
+ * whether or not the given object's class overrides
+ * hashCode().
+ * The hash code for the null reference is zero.
+ *
+ * @param x object for which the hashCode is to be calculated
+ * @return the hashCode
+ * @since JDK1.1
+ */
+ public static int identityHashCode(Object x) {
+ if (x == null) {
+ return 0;
+ }
+ return Object.identityHashCode(x);
+ }
+
+ /**
+ * System properties. The following properties are guaranteed to be defined:
+ * <dl>
+ * <dt>java.version <dd>Java version number
+ * <dt>java.vendor <dd>Java vendor specific string
+ * <dt>java.vendor.url <dd>Java vendor URL
+ * <dt>java.home <dd>Java installation directory
+ * <dt>java.class.version <dd>Java class version number
+ * <dt>java.class.path <dd>Java classpath
+ * <dt>os.name <dd>Operating System Name
+ * <dt>os.arch <dd>Operating System Architecture
+ * <dt>os.version <dd>Operating System Version
+ * <dt>file.separator <dd>File separator ("/" on Unix)
+ * <dt>path.separator <dd>Path separator (":" on Unix)
+ * <dt>line.separator <dd>Line separator ("\n" on Unix)
+ * <dt>user.name <dd>User account name
+ * <dt>user.home <dd>User home directory
+ * <dt>user.dir <dd>User's current working directory
+ * </dl>
+ */
+
+ private static Properties props;
+ private static Properties unchangeableProps;
+
+ private static native String[] specialProperties();
+
+ static final class PropertiesWithNonOverrideableDefaults extends Properties {
+ PropertiesWithNonOverrideableDefaults(Properties defaults) {
+ super(defaults);
+ }
+
+ @Override
+ public Object put(Object key, Object value) {
+ if (defaults.containsKey(key)) {
+ logE("Ignoring attempt to set property \"" + key +
+ "\" to value \"" + value + "\".");
+ return defaults.get(key);
+ }
+
+ return super.put(key, value);
+ }
+
+ @Override
+ public Object remove(Object key) {
+ if (defaults.containsKey(key)) {
+ logE("Ignoring attempt to remove property \"" + key + "\".");
+ return null;
+ }
+
+ return super.remove(key);
+ }
+ }
+
+ private static void parsePropertyAssignments(Properties p, String[] assignments) {
+ for (String assignment : assignments) {
+ int split = assignment.indexOf('=');
+ String key = assignment.substring(0, split);
+ String value = assignment.substring(split + 1);
+ p.put(key, value);
+ }
+ }
+
+ private static Properties initUnchangeableSystemProperties() {
+ VMRuntime runtime = VMRuntime.getRuntime();
+ Properties p = new Properties();
+
+ // Set non-static properties.
+ p.put("java.boot.class.path", runtime.bootClassPath());
+ p.put("java.class.path", runtime.classPath());
+
+ // TODO: does this make any sense? Should we just leave java.home unset?
+ String javaHome = getenv("JAVA_HOME");
+ if (javaHome == null) {
+ javaHome = "/system";
+ }
+ p.put("java.home", javaHome);
+
+ p.put("java.vm.version", runtime.vmVersion());
+
+ try {
+ StructPasswd passwd = Libcore.os.getpwuid(Libcore.os.getuid());
+ p.put("user.name", passwd.pw_name);
+ } catch (ErrnoException exception) {
+ throw new AssertionError(exception);
+ }
+
+ StructUtsname info = Libcore.os.uname();
+ p.put("os.arch", info.machine);
+ // os.name was previously hardcoded to "Linux", but was reverted due to support
+ // for Fuchsia. b/121268567 shows initialization regressions.
+ p.put("os.name", info.sysname);
+ p.put("os.version", info.release);
+
+ // Android-added: Undocumented properties that exist only on Android.
+ p.put("android.icu.library.version", Icu4cMetadata.getIcuVersion());
+ p.put("android.icu.unicode.version", Icu4cMetadata.getUnicodeVersion());
+ p.put("android.icu.cldr.version", Icu4cMetadata.getCldrVersion());
+
+ // Property override for ICU4J : this is the location of the ICU4C data. This
+ // is prioritized over the properties in ICUConfig.properties. The issue with using
+ // that is that it doesn't play well with jarjar and it needs complicated build rules
+ // to change its default value.
+ String icuDataPath = TimeZoneDataFiles.generateIcuDataPath();
+ p.put("android.icu.impl.ICUBinary.dataPath", icuDataPath);
+
+ parsePropertyAssignments(p, specialProperties());
+
+ // Override built-in properties with settings from the command line.
+ // Note: it is not possible to override hardcoded values.
+ parsePropertyAssignments(p, runtime.properties());
+
+
+ // Set static hardcoded properties.
+ // These come last, as they must be guaranteed to agree with what a backend compiler
+ // may assume when compiling the boot image on Android.
+ for (String[] pair : AndroidHardcodedSystemProperties.STATIC_PROPERTIES) {
+ if (p.containsKey(pair[0])) {
+ logE("Ignoring command line argument: -D" + pair[0]);
+ }
+ if (pair[1] == null) {
+ p.remove(pair[0]);
+ } else {
+ p.put(pair[0], pair[1]);
+ }
+ }
+
+ return p;
+ }
+
+ private static Properties initProperties() {
+ Properties p = new PropertiesWithNonOverrideableDefaults(unchangeableProps);
+ setDefaultChangeableProperties(p);
+ return p;
+ }
+
+ private static Properties setDefaultChangeableProperties(Properties p) {
+ // On Android, each app gets its own temporary directory.
+ // (See android.app.ActivityThread.) This is just a fallback default,
+ // useful only on the host.
+ // We check first if the property has not been set already: note that it
+ // can only be set from the command line through the '-Djava.io.tmpdir=' option.
+ if (!unchangeableProps.containsKey("java.io.tmpdir")) {
+ p.put("java.io.tmpdir", "/tmp");
+ }
+
+ // Android has always had an empty "user.home" (see docs for getProperty).
+ // This is not useful for normal android apps which need to use android specific
+ // APIs such as {@code Context.getFilesDir} and {@code Context.getCacheDir} but
+ // we make it changeable for backward compatibility, so that they can change it
+ // to a writeable location if required.
+ // We check first if the property has not been set already: note that it
+ // can only be set from the command line through the '-Duser.home=' option.
+ if (!unchangeableProps.containsKey("user.home")) {
+ p.put("user.home", "");
+ }
+
+ return p;
+ }
+
+ /**
+ * Inits an unchangeable system property with the given value.
+ *
+ * This is called from native code when the environment needs to change under native
+ * bridge emulation.
+ *
+ * @hide also visible for tests.
+ */
+ public static void setUnchangeableSystemProperty(String key, String value) {
+ checkKey(key);
+ unchangeableProps.put(key, value);
+ }
+
+ private static void addLegacyLocaleSystemProperties() {
+ final String locale = getProperty("user.locale", "");
+ if (!locale.isEmpty()) {
+ Locale l = Locale.forLanguageTag(locale);
+ setUnchangeableSystemProperty("user.language", l.getLanguage());
+ setUnchangeableSystemProperty("user.region", l.getCountry());
+ setUnchangeableSystemProperty("user.variant", l.getVariant());
+ } else {
+ // If "user.locale" isn't set we fall back to our old defaults of
+ // language="en" and region="US" (if unset) and don't attempt to set it.
+ // The Locale class will fall back to using user.language and
+ // user.region if unset.
+ final String language = getProperty("user.language", "");
+ final String region = getProperty("user.region", "");
+
+ if (language.isEmpty()) {
+ setUnchangeableSystemProperty("user.language", "en");
+ }
+
+ if (region.isEmpty()) {
+ setUnchangeableSystemProperty("user.region", "US");
+ }
+ }
+ }
+
+ /**
+ * Determines the current system properties.
+ *
+ *
+ * <p>The following properties are always provided by the Dalvik VM:</p>
+ * <p><table BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+ * <tr BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+ * <td><b>Name</b></td> <td><b>Meaning</b></td> <td><b>Example</b></td></tr>
+ * <tr><td>file.separator</td> <td>{@link java.io.File#separator}</td> <td>{@code /}</td></tr>
+ *
+ * <tr><td>java.class.path</td> <td>System class path</td> <td>{@code .}</td></tr>
+ * <tr><td>java.class.version</td> <td>(Not useful on Android)</td> <td>{@code 50.0}</td></tr>
+ * <tr><td>java.compiler</td> <td>(Not useful on Android)</td> <td>Empty</td></tr>
+ * <tr><td>java.ext.dirs</td> <td>(Not useful on Android)</td> <td>Empty</td></tr>
+ * <tr><td>java.home</td> <td>Location of the VM on the file system</td> <td>{@code /system}</td></tr>
+ * <tr><td>java.io.tmpdir</td> <td>See {@link java.io.File#createTempFile}</td> <td>{@code /sdcard}</td></tr>
+ * <tr><td>java.library.path</td> <td>Search path for JNI libraries</td> <td>{@code /vendor/lib:/system/lib}</td></tr>
+ * <tr><td>java.vendor</td> <td>Human-readable VM vendor</td> <td>{@code The Android Project}</td></tr>
+ * <tr><td>java.vendor.url</td> <td>URL for VM vendor's web site</td> <td>{@code http://www.android.com/}</td></tr>
+ * <tr><td>java.version</td> <td>(Not useful on Android)</td> <td>{@code 0}</td></tr>
+ *
+ * <tr><td>java.specification.version</td> <td>VM libraries version</td> <td>{@code 0.9}</td></tr>
+ * <tr><td>java.specification.vendor</td> <td>VM libraries vendor</td> <td>{@code The Android Project}</td></tr>
+ * <tr><td>java.specification.name</td> <td>VM libraries name</td> <td>{@code Dalvik Core Library}</td></tr>
+ * <tr><td>java.vm.version</td> <td>VM implementation version</td> <td>{@code 1.2.0}</td></tr>
+ * <tr><td>java.vm.vendor</td> <td>VM implementation vendor</td> <td>{@code The Android Project}</td></tr>
+ * <tr><td>java.vm.name</td> <td>VM implementation name</td> <td>{@code Dalvik}</td></tr>
+ * <tr><td>java.vm.specification.version</td> <td>VM specification version</td> <td>{@code 0.9}</td></tr>
+ * <tr><td>java.vm.specification.vendor</td> <td>VM specification vendor</td> <td>{@code The Android Project}</td></tr>
+ * <tr><td>java.vm.specification.name</td> <td>VM specification name</td> <td>{@code Dalvik Virtual Machine Specification}</td></tr>
+ *
+ * <tr><td>line.separator</td> <td>The system line separator</td> <td>{@code \n}</td></tr>
+ *
+ * <tr><td>os.arch</td> <td>OS architecture</td> <td>{@code armv7l}</td></tr>
+ * <tr><td>os.name</td> <td>OS (kernel) name</td> <td>{@code Linux}</td></tr>
+ * <tr><td>os.version</td> <td>OS (kernel) version</td> <td>{@code 2.6.32.9-g103d848}</td></tr>
+ *
+ * <tr><td>path.separator</td> <td>See {@link java.io.File#pathSeparator}</td> <td>{@code :}</td></tr>
+ *
+ * <tr><td>user.dir</td> <td>Base of non-absolute paths</td> <td>{@code /}</td></tr>
+ * <tr><td>user.home</td> <td>(Not useful on Android)</td> <td>Empty</td></tr>
+ * <tr><td>user.name</td> <td>(Not useful on Android)</td> <td>Empty</td></tr>
+ *
+ * </table>
+ * <p>
+ * Multiple paths in a system property value are separated by the path
+ * separator character of the platform.
+ * <p>
+ * Note that even if the security manager does not permit the
+ * <code>getProperties</code> operation, it may choose to permit the
+ * {@link #getProperty(String)} operation.
+ *
+ * @return the system properties
+ * @exception SecurityException if a security manager exists and its
+ * <code>checkPropertiesAccess</code> method doesn't allow access
+ * to the system properties.
+ * @see #setProperties
+ * @see java.lang.SecurityException
+ * @see java.lang.SecurityManager#checkPropertiesAccess()
+ * @see java.util.Properties
+ */
+ public static Properties getProperties() {
+ SecurityManager sm = getSecurityManager();
+ if (sm != null) {
+ sm.checkPropertiesAccess();
+ }
+
+ return props;
+ }
+
+ /**
+ * Returns the system-dependent line separator string. It always
+ * returns the same value - the initial value of the {@linkplain
+ * #getProperty(String) system property} {@code line.separator}.
+ *
+ * <p>On UNIX systems, it returns {@code "\n"}; on Microsoft
+ * Windows systems it returns {@code "\r\n"}.
+ *
+ * @return the system-dependent line separator string
+ * @since 1.7
+ */
+ public static String lineSeparator() {
+ return lineSeparator;
+ }
+
+ private static String lineSeparator;
+
+
+ // Comment replaced with android one.
+ /**
+ * Attempts to set all system properties. Copies all properties from
+ * {@code p} and discards system properties that are read only and cannot
+ * be modified. See {@link #getProperty} for a list of such properties.
+ */
+ public static void setProperties(Properties props) {
+ Properties baseProperties = new PropertiesWithNonOverrideableDefaults(unchangeableProps);
+ if (props != null) {
+ baseProperties.putAll(props);
+ } else {
+ setDefaultChangeableProperties(baseProperties);
+ }
+
+ System.props = baseProperties;
+ }
+
+ /**
+ * Gets the system property indicated by the specified key.
+ * <p>
+ * First, if there is a security manager, its
+ * <code>checkPropertyAccess</code> method is called with the key as
+ * its argument. This may result in a SecurityException.
+ * <p>
+ * If there is no current set of system properties, a set of system
+ * properties is first created and initialized in the same manner as
+ * for the <code>getProperties</code> method.
+ *
+ * @param key the name of the system property.
+ * @return the string value of the system property,
+ * or <code>null</code> if there is no property with that key.
+ *
+ * @exception SecurityException if a security manager exists and its
+ * <code>checkPropertyAccess</code> method doesn't allow
+ * access to the specified system property.
+ * @exception NullPointerException if <code>key</code> is
+ * <code>null</code>.
+ * @exception IllegalArgumentException if <code>key</code> is empty.
+ * @see #setProperty
+ * @see java.lang.SecurityException
+ * @see java.lang.SecurityManager#checkPropertyAccess(java.lang.String)
+ * @see java.lang.System#getProperties()
+ */
+ public static String getProperty(String key) {
+ checkKey(key);
+ SecurityManager sm = getSecurityManager();
+ if (sm != null) {
+ sm.checkPropertyAccess(key);
+ }
+
+ return props.getProperty(key);
+ }
+
+ /**
+ * Gets the system property indicated by the specified key.
+ * <p>
+ * First, if there is a security manager, its
+ * <code>checkPropertyAccess</code> method is called with the
+ * <code>key</code> as its argument.
+ * <p>
+ * If there is no current set of system properties, a set of system
+ * properties is first created and initialized in the same manner as
+ * for the <code>getProperties</code> method.
+ *
+ * @param key the name of the system property.
+ * @param def a default value.
+ * @return the string value of the system property,
+ * or the default value if there is no property with that key.
+ *
+ * @exception SecurityException if a security manager exists and its
+ * <code>checkPropertyAccess</code> method doesn't allow
+ * access to the specified system property.
+ * @exception NullPointerException if <code>key</code> is
+ * <code>null</code>.
+ * @exception IllegalArgumentException if <code>key</code> is empty.
+ * @see #setProperty
+ * @see java.lang.SecurityManager#checkPropertyAccess(java.lang.String)
+ * @see java.lang.System#getProperties()
+ */
+ public static String getProperty(String key, String def) {
+ checkKey(key);
+ SecurityManager sm = getSecurityManager();
+ if (sm != null) {
+ sm.checkPropertyAccess(key);
+ }
+
+ return props.getProperty(key, def);
+ }
+
+ /**
+ * Sets the system property indicated by the specified key.
+ * <p>
+ * First, if a security manager exists, its
+ * <code>SecurityManager.checkPermission</code> method
+ * is called with a <code>PropertyPermission(key, "write")</code>
+ * permission. This may result in a SecurityException being thrown.
+ * If no exception is thrown, the specified property is set to the given
+ * value.
+ * <p>
+ *
+ * @param key the name of the system property.
+ * @param value the value of the system property.
+ * @return the previous value of the system property,
+ * or <code>null</code> if it did not have one.
+ *
+ * @exception SecurityException if a security manager exists and its
+ * <code>checkPermission</code> method doesn't allow
+ * setting of the specified property.
+ * @exception NullPointerException if <code>key</code> or
+ * <code>value</code> is <code>null</code>.
+ * @exception IllegalArgumentException if <code>key</code> is empty.
+ * @see #getProperty
+ * @see java.lang.System#getProperty(java.lang.String)
+ * @see java.lang.System#getProperty(java.lang.String, java.lang.String)
+ * @see java.util.PropertyPermission
+ * @see SecurityManager#checkPermission
+ * @since 1.2
+ */
+ public static String setProperty(String key, String value) {
+ checkKey(key);
+ SecurityManager sm = getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(new PropertyPermission(key,
+ SecurityConstants.PROPERTY_WRITE_ACTION));
+ }
+
+ return (String) props.setProperty(key, value);
+ }
+
+ /**
+ * Removes the system property indicated by the specified key.
+ * <p>
+ * First, if a security manager exists, its
+ * <code>SecurityManager.checkPermission</code> method
+ * is called with a <code>PropertyPermission(key, "write")</code>
+ * permission. This may result in a SecurityException being thrown.
+ * If no exception is thrown, the specified property is removed.
+ * <p>
+ *
+ * @param key the name of the system property to be removed.
+ * @return the previous string value of the system property,
+ * or <code>null</code> if there was no property with that key.
+ *
+ * @exception SecurityException if a security manager exists and its
+ * <code>checkPropertyAccess</code> method doesn't allow
+ * access to the specified system property.
+ * @exception NullPointerException if <code>key</code> is
+ * <code>null</code>.
+ * @exception IllegalArgumentException if <code>key</code> is empty.
+ * @see #getProperty
+ * @see #setProperty
+ * @see java.util.Properties
+ * @see java.lang.SecurityException
+ * @see java.lang.SecurityManager#checkPropertiesAccess()
+ * @since 1.5
+ */
+ public static String clearProperty(String key) {
+ checkKey(key);
+ SecurityManager sm = getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(new PropertyPermission(key, "write"));
+ }
+
+ return (String) props.remove(key);
+ }
+
+ private static void checkKey(String key) {
+ if (key == null) {
+ throw new NullPointerException("key can't be null");
+ }
+ if (key.equals("")) {
+ throw new IllegalArgumentException("key can't be empty");
+ }
+ }
+
+ /**
+ * Gets the value of the specified environment variable. An
+ * environment variable is a system-dependent external named
+ * value.
+ *
+ * <p>If a security manager exists, its
+ * {@link SecurityManager#checkPermission checkPermission}
+ * method is called with a
+ * <code>{@link RuntimePermission}("getenv."+name)</code>
+ * permission. This may result in a {@link SecurityException}
+ * being thrown. If no exception is thrown the value of the
+ * variable <code>name</code> is returned.
+ *
+ * <p><a name="EnvironmentVSSystemProperties"><i>System
+ * properties</i> and <i>environment variables</i></a> are both
+ * conceptually mappings between names and values. Both
+ * mechanisms can be used to pass user-defined information to a
+ * Java process. Environment variables have a more global effect,
+ * because they are visible to all descendants of the process
+ * which defines them, not just the immediate Java subprocess.
+ * They can have subtly different semantics, such as case
+ * insensitivity, on different operating systems. For these
+ * reasons, environment variables are more likely to have
+ * unintended side effects. It is best to use system properties
+ * where possible. Environment variables should be used when a
+ * global effect is desired, or when an external system interface
+ * requires an environment variable (such as <code>PATH</code>).
+ *
+ * <p>On UNIX systems the alphabetic case of <code>name</code> is
+ * typically significant, while on Microsoft Windows systems it is
+ * typically not. For example, the expression
+ * <code>System.getenv("FOO").equals(System.getenv("foo"))</code>
+ * is likely to be true on Microsoft Windows.
+ *
+ * @param name the name of the environment variable
+ * @return the string value of the variable, or <code>null</code>
+ * if the variable is not defined in the system environment
+ * @throws NullPointerException if <code>name</code> is <code>null</code>
+ * @throws SecurityException
+ * if a security manager exists and its
+ * {@link SecurityManager#checkPermission checkPermission}
+ * method doesn't allow access to the environment variable
+ * <code>name</code>
+ * @see #getenv()
+ * @see ProcessBuilder#environment()
+ */
+ public static String getenv(String name) {
+ if (name == null) {
+ throw new NullPointerException("name == null");
+ }
+
+ return Libcore.os.getenv(name);
+ }
+
+
+ /**
+ * Returns an unmodifiable string map view of the current system environment.
+ * The environment is a system-dependent mapping from names to
+ * values which is passed from parent to child processes.
+ *
+ * <p>If the system does not support environment variables, an
+ * empty map is returned.
+ *
+ * <p>The returned map will never contain null keys or values.
+ * Attempting to query the presence of a null key or value will
+ * throw a {@link NullPointerException}. Attempting to query
+ * the presence of a key or value which is not of type
+ * {@link String} will throw a {@link ClassCastException}.
+ *
+ * <p>The returned map and its collection views may not obey the
+ * general contract of the {@link Object#equals} and
+ * {@link Object#hashCode} methods.
+ *
+ * <p>The returned map is typically case-sensitive on all platforms.
+ *
+ * <p>If a security manager exists, its
+ * {@link SecurityManager#checkPermission checkPermission}
+ * method is called with a
+ * <code>{@link RuntimePermission}("getenv.*")</code>
+ * permission. This may result in a {@link SecurityException} being
+ * thrown.
+ *
+ * <p>When passing information to a Java subprocess,
+ * <a href=#EnvironmentVSSystemProperties>system properties</a>
+ * are generally preferred over environment variables.
+ *
+ * @return the environment as a map of variable names to values
+ * @throws SecurityException
+ * if a security manager exists and its
+ * {@link SecurityManager#checkPermission checkPermission}
+ * method doesn't allow access to the process environment
+ * @see #getenv(String)
+ * @see ProcessBuilder#environment()
+ * @since 1.5
+ */
+ public static java.util.Map<String,String> getenv() {
+ SecurityManager sm = getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(new RuntimePermission("getenv.*"));
+ }
+
+ return ProcessEnvironment.getenv();
+ }
+
+ /**
+ * Terminates the currently running Java Virtual Machine. The
+ * argument serves as a status code; by convention, a nonzero status
+ * code indicates abnormal termination.
+ * <p>
+ * This method calls the <code>exit</code> method in class
+ * <code>Runtime</code>. This method never returns normally.
+ * <p>
+ * The call <code>System.exit(n)</code> is effectively equivalent to
+ * the call:
+ * <blockquote><pre>
+ * Runtime.getRuntime().exit(n)
+ * </pre></blockquote>
+ *
+ * @param status exit status.
+ * @throws SecurityException
+ * if a security manager exists and its <code>checkExit</code>
+ * method doesn't allow exit with the specified status.
+ * @see java.lang.Runtime#exit(int)
+ */
+ public static void exit(int status) {
+ Runtime.getRuntime().exit(status);
+ }
+
+ /**
+ * Runs the garbage collector.
+ * <p>
+ * Calling the <code>gc</code> method suggests that the Java Virtual
+ * Machine expend effort toward recycling unused objects in order to
+ * make the memory they currently occupy available for quick reuse.
+ * When control returns from the method call, the Java Virtual
+ * Machine has made a best effort to reclaim space from all discarded
+ * objects.
+ * <p>
+ * The call <code>System.gc()</code> is effectively equivalent to the
+ * call:
+ * <blockquote><pre>
+ * Runtime.getRuntime().gc()
+ * </pre></blockquote>
+ *
+ * @see java.lang.Runtime#gc()
+ */
+ public static void gc() {
+ boolean shouldRunGC;
+ synchronized (LOCK) {
+ shouldRunGC = justRanFinalization;
+ if (shouldRunGC) {
+ justRanFinalization = false;
+ } else {
+ runGC = true;
+ }
+ }
+ if (shouldRunGC) {
+ Runtime.getRuntime().gc();
+ }
+ }
+
+ /**
+ * Runs the finalization methods of any objects pending finalization.
+ * <p>
+ * Calling this method suggests that the Java Virtual Machine expend
+ * effort toward running the <code>finalize</code> methods of objects
+ * that have been found to be discarded but whose <code>finalize</code>
+ * methods have not yet been run. When control returns from the
+ * method call, the Java Virtual Machine has made a best effort to
+ * complete all outstanding finalizations.
+ * <p>
+ * The call <code>System.runFinalization()</code> is effectively
+ * equivalent to the call:
+ * <blockquote><pre>
+ * Runtime.getRuntime().runFinalization()
+ * </pre></blockquote>
+ *
+ * @see java.lang.Runtime#runFinalization()
+ */
+ public static void runFinalization() {
+ boolean shouldRunGC;
+ synchronized (LOCK) {
+ shouldRunGC = runGC;
+ runGC = false;
+ }
+ if (shouldRunGC) {
+ Runtime.getRuntime().gc();
+ }
+ Runtime.getRuntime().runFinalization();
+ synchronized (LOCK) {
+ justRanFinalization = true;
+ }
+ }
+
+ /**
+ * Enable or disable finalization on exit; doing so specifies that the
+ * finalizers of all objects that have finalizers that have not yet been
+ * automatically invoked are to be run before the Java runtime exits.
+ * By default, finalization on exit is disabled.
+ *
+ * <p>If there is a security manager,
+ * its <code>checkExit</code> method is first called
+ * with 0 as its argument to ensure the exit is allowed.
+ * This could result in a SecurityException.
+ *
+ * @deprecated This method is inherently unsafe. It may result in
+ * finalizers being called on live objects while other threads are
+ * concurrently manipulating those objects, resulting in erratic
+ * behavior or deadlock.
+ * @param value indicating enabling or disabling of finalization
+ * @throws SecurityException
+ * if a security manager exists and its <code>checkExit</code>
+ * method doesn't allow the exit.
+ *
+ * @see java.lang.Runtime#exit(int)
+ * @see java.lang.Runtime#gc()
+ * @see java.lang.SecurityManager#checkExit(int)
+ * @since JDK1.1
+ */
+ @Deprecated
+ public static void runFinalizersOnExit(boolean value) {
+ Runtime.runFinalizersOnExit(value);
+ }
+
+ /**
+ * Loads the native library specified by the filename argument. The filename
+ * argument must be an absolute path name.
+ *
+ * If the filename argument, when stripped of any platform-specific library
+ * prefix, path, and file extension, indicates a library whose name is,
+ * for example, L, and a native library called L is statically linked
+ * with the VM, then the JNI_OnLoad_L function exported by the library
+ * is invoked rather than attempting to load a dynamic library.
+ * A filename matching the argument does not have to exist in the
+ * file system.
+ * See the JNI Specification for more details.
+ *
+ * Otherwise, the filename argument is mapped to a native library image in
+ * an implementation-dependent manner.
+ *
+ * <p>
+ * The call <code>System.load(name)</code> is effectively equivalent
+ * to the call:
+ * <blockquote><pre>
+ * Runtime.getRuntime().load(name)
+ * </pre></blockquote>
+ *
+ * @param filename the file to load.
+ * @exception SecurityException if a security manager exists and its
+ * <code>checkLink</code> method doesn't allow
+ * loading of the specified dynamic library
+ * @exception UnsatisfiedLinkError if either the filename is not an
+ * absolute path name, the native library is not statically
+ * linked with the VM, or the library cannot be mapped to
+ * a native library image by the host system.
+ * @exception NullPointerException if <code>filename</code> is
+ * <code>null</code>
+ * @see java.lang.Runtime#load(java.lang.String)
+ * @see java.lang.SecurityManager#checkLink(java.lang.String)
+ */
+ @CallerSensitive
+ public static void load(String filename) {
+ Runtime.getRuntime().load0(Reflection.getCallerClass(), filename);
+ }
+
+ /**
+ * Loads the native library specified by the <code>libname</code>
+ * argument. The <code>libname</code> argument must not contain any platform
+ * specific prefix, file extension or path. If a native library
+ * called <code>libname</code> is statically linked with the VM, then the
+ * JNI_OnLoad_<code>libname</code> function exported by the library is invoked.
+ * See the JNI Specification for more details.
+ *
+ * Otherwise, the libname argument is loaded from a system library
+ * location and mapped to a native library image in an implementation-
+ * dependent manner.
+ * <p>
+ * The call <code>System.loadLibrary(name)</code> is effectively
+ * equivalent to the call
+ * <blockquote><pre>
+ * Runtime.getRuntime().loadLibrary(name)
+ * </pre></blockquote>
+ *
+ * @param libname the name of the library.
+ * @exception SecurityException if a security manager exists and its
+ * <code>checkLink</code> method doesn't allow
+ * loading of the specified dynamic library
+ * @exception UnsatisfiedLinkError if either the libname argument
+ * contains a file path, the native library is not statically
+ * linked with the VM, or the library cannot be mapped to a
+ * native library image by the host system.
+ * @exception NullPointerException if <code>libname</code> is
+ * <code>null</code>
+ * @see java.lang.Runtime#loadLibrary(java.lang.String)
+ * @see java.lang.SecurityManager#checkLink(java.lang.String)
+ */
+ @CallerSensitive
+ public static void loadLibrary(String libname) {
+ Runtime.getRuntime().loadLibrary0(Reflection.getCallerClass(), libname);
+ }
+
+ /**
+ * Maps a library name into a platform-specific string representing
+ * a native library.
+ *
+ * @param libname the name of the library.
+ * @return a platform-dependent native library name.
+ * @exception NullPointerException if <code>libname</code> is
+ * <code>null</code>
+ * @see java.lang.System#loadLibrary(java.lang.String)
+ * @see java.lang.ClassLoader#findLibrary(java.lang.String)
+ * @since 1.2
+ */
+ public static native String mapLibraryName(String libname);
+
+ /**
+ * Create PrintStream for stdout/err based on encoding.
+ */
+ private static PrintStream newPrintStream(FileOutputStream fos, String enc) {
+ if (enc != null) {
+ try {
+ return new PrintStream(new BufferedOutputStream(fos, 128), true, enc);
+ } catch (UnsupportedEncodingException uee) {}
+ }
+ return new PrintStream(new BufferedOutputStream(fos, 128), true);
+ }
+
+
+ /**
+ * Initialize the system class. Called after thread initialization.
+ */
+ static {
+ unchangeableProps = initUnchangeableSystemProperties();
+ props = initProperties();
+ addLegacyLocaleSystemProperties();
+ sun.misc.Version.initSystemProperties();
+
+ // TODO: Confirm that this isn't something super important.
+ // sun.misc.VM.saveAndRemoveProperties(props);
+
+ lineSeparator = props.getProperty("line.separator");
+
+ FileInputStream fdIn = new FileInputStream(FileDescriptor.in);
+ FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out);
+ FileOutputStream fdErr = new FileOutputStream(FileDescriptor.err);
+ // BEGIN Android-changed: lower buffer size.
+ // in = new BufferedInputStream(fdIn);
+ in = new BufferedInputStream(fdIn, 128);
+ // END Android-changed: lower buffer size.
+ out = newPrintStream(fdOut, props.getProperty("sun.stdout.encoding"));
+ err = newPrintStream(fdErr, props.getProperty("sun.stderr.encoding"));
+
+ // Initialize any miscellenous operating system settings that need to be
+ // set for the class libraries. Currently this is no-op everywhere except
+ // for Windows where the process-wide error mode is set before the java.io
+ // classes are used.
+ sun.misc.VM.initializeOSEnvironment();
+
+ // Subsystems that are invoked during initialization can invoke
+ // sun.misc.VM.isBooted() in order to avoid doing things that should
+ // wait until the application class loader has been set up.
+ // IMPORTANT: Ensure that this remains the last initialization action!
+ sun.misc.VM.booted();
+ }
+
+ /**
+ * @hide internal use only
+ */
+ public static void logE(String message) {
+ log('E', message, null);
+ }
+
+ /**
+ * @hide internal use only
+ */
+ public static void logE(String message, Throwable th) {
+ log('E', message, th);
+ }
+
+ /**
+ * @hide internal use only
+ */
+ public static void logI(String message) {
+ log('I', message, null);
+ }
+
+ /**
+ * @hide internal use only
+ */
+ public static void logI(String message, Throwable th) {
+ log('I', message, th);
+ }
+
+ /**
+ * @hide internal use only
+ */
+ public static void logW(String message) {
+ log('W', message, null);
+ }
+
+ /**
+ * @hide internal use only
+ */
+ public static void logW(String message, Throwable th) {
+ log('W', message, th);
+ }
+
+ private static native void log(char type, String message, Throwable th);
+}
diff --git a/java/lang/Thread.annotated.java b/java/lang/Thread.annotated.java
new file mode 100644
index 0000000..2499518
--- /dev/null
+++ b/java/lang/Thread.annotated.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 2013, 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;
+
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.util.Map;
+import java.util.concurrent.locks.LockSupport;
+import java.lang.ref.Reference;
+import java.lang.ref.WeakReference;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class Thread implements java.lang.Runnable {
+
+public Thread() { throw new RuntimeException("Stub!"); }
+
+public Thread(java.lang.Runnable target) { throw new RuntimeException("Stub!"); }
+
+public Thread(java.lang.ThreadGroup group, java.lang.Runnable target) { throw new RuntimeException("Stub!"); }
+
+public Thread(java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+public Thread(java.lang.ThreadGroup group, java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+public Thread(java.lang.Runnable target, java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+public Thread(java.lang.ThreadGroup group, java.lang.Runnable target, java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+public Thread(java.lang.ThreadGroup group, java.lang.Runnable target, java.lang.String name, long stackSize) { throw new RuntimeException("Stub!"); }
+
+public static native java.lang.Thread currentThread();
+
+public static native void yield();
+
+public static void sleep(long millis) throws java.lang.InterruptedException { throw new RuntimeException("Stub!"); }
+
+public static void sleep(long millis, int nanos) throws java.lang.InterruptedException { throw new RuntimeException("Stub!"); }
+
+protected java.lang.Object clone() throws java.lang.CloneNotSupportedException { throw new RuntimeException("Stub!"); }
+
+public synchronized void start() { throw new RuntimeException("Stub!"); }
+
+public void run() { throw new RuntimeException("Stub!"); }
+
+@Deprecated
+public final void stop() { throw new RuntimeException("Stub!"); }
+
+@Deprecated
+public final synchronized void stop(java.lang.Throwable obj) { throw new RuntimeException("Stub!"); }
+
+public void interrupt() { throw new RuntimeException("Stub!"); }
+
+public static native boolean interrupted();
+
+public native boolean isInterrupted();
+
+@Deprecated
+public void destroy() { throw new RuntimeException("Stub!"); }
+
+public final boolean isAlive() { throw new RuntimeException("Stub!"); }
+
+@Deprecated
+public final void suspend() { throw new RuntimeException("Stub!"); }
+
+@Deprecated
+public final void resume() { throw new RuntimeException("Stub!"); }
+
+public final void setPriority(int newPriority) { throw new RuntimeException("Stub!"); }
+
+public final int getPriority() { throw new RuntimeException("Stub!"); }
+
+public final synchronized void setName(java.lang.String name) { throw new RuntimeException("Stub!"); }
+
+public final java.lang.String getName() { throw new RuntimeException("Stub!"); }
+
+public final java.lang.ThreadGroup getThreadGroup() { throw new RuntimeException("Stub!"); }
+
+public static int activeCount() { throw new RuntimeException("Stub!"); }
+
+public static int enumerate(java.lang.Thread[] tarray) { throw new RuntimeException("Stub!"); }
+
+@Deprecated
+public int countStackFrames() { throw new RuntimeException("Stub!"); }
+
+public final void join(long millis) throws java.lang.InterruptedException { throw new RuntimeException("Stub!"); }
+
+public final void join(long millis, int nanos) throws java.lang.InterruptedException { throw new RuntimeException("Stub!"); }
+
+public final void join() throws java.lang.InterruptedException { throw new RuntimeException("Stub!"); }
+
+public static void dumpStack() { throw new RuntimeException("Stub!"); }
+
+public final void setDaemon(boolean on) { throw new RuntimeException("Stub!"); }
+
+public final boolean isDaemon() { throw new RuntimeException("Stub!"); }
+
+public final void checkAccess() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public java.lang.ClassLoader getContextClassLoader() { throw new RuntimeException("Stub!"); }
+
+public void setContextClassLoader(java.lang.ClassLoader cl) { throw new RuntimeException("Stub!"); }
+
+public static native boolean holdsLock(java.lang.Object obj);
+
+public java.lang.StackTraceElement[] getStackTrace() { throw new RuntimeException("Stub!"); }
+
+public static java.util.Map<java.lang.Thread,java.lang.StackTraceElement[]> getAllStackTraces() { throw new RuntimeException("Stub!"); }
+
+public long getId() { throw new RuntimeException("Stub!"); }
+
+public java.lang.Thread.State getState() { throw new RuntimeException("Stub!"); }
+
+public static void setDefaultUncaughtExceptionHandler(java.lang.Thread.UncaughtExceptionHandler eh) { throw new RuntimeException("Stub!"); }
+
+public static java.lang.Thread.UncaughtExceptionHandler getDefaultUncaughtExceptionHandler() { throw new RuntimeException("Stub!"); }
+
[email protected]
+public static void setUncaughtExceptionPreHandler(UncaughtExceptionHandler eh) { throw new RuntimeException("Stub!"); }
+
[email protected]
+public static UncaughtExceptionHandler getUncaughtExceptionPreHandler() { throw new RuntimeException("Stub!"); }
+
+public java.lang.Thread.UncaughtExceptionHandler getUncaughtExceptionHandler() { throw new RuntimeException("Stub!"); }
+
+public void setUncaughtExceptionHandler(java.lang.Thread.UncaughtExceptionHandler eh) { throw new RuntimeException("Stub!"); }
+
+public static final int MAX_PRIORITY = 10; // 0xa
+
+public static final int MIN_PRIORITY = 1; // 0x1
+
+public static final int NORM_PRIORITY = 5; // 0x5
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public static enum State {
+NEW,
+RUNNABLE,
+BLOCKED,
+WAITING,
+TIMED_WAITING,
+TERMINATED;
+}
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
[email protected]
+public static interface UncaughtExceptionHandler {
+
+public void uncaughtException(java.lang.Thread t, java.lang.Throwable e);
+}
+
+}
+
diff --git a/java/lang/Thread.java b/java/lang/Thread.java
new file mode 100644
index 0000000..699a1ac
--- /dev/null
+++ b/java/lang/Thread.java
@@ -0,0 +1,2353 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 2013, 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;
+
+import dalvik.annotation.optimization.FastNative;
+import java.lang.ref.Reference;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
+import java.security.AccessController;
+import java.security.AccessControlContext;
+import java.security.PrivilegedAction;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.locks.LockSupport;
+import sun.nio.ch.Interruptible;
+import sun.reflect.CallerSensitive;
+import dalvik.system.RuntimeHooks;
+import dalvik.system.ThreadPrioritySetter;
+import dalvik.system.VMStack;
+import libcore.util.EmptyArray;
+
+
+/**
+ * A <i>thread</i> is a thread of execution in a program. The Java
+ * Virtual Machine allows an application to have multiple threads of
+ * execution running concurrently.
+ * <p>
+ * Every thread has a priority. Threads with higher priority are
+ * executed in preference to threads with lower priority. Each thread
+ * may or may not also be marked as a daemon. When code running in
+ * some thread creates a new <code>Thread</code> object, the new
+ * thread has its priority initially set equal to the priority of the
+ * creating thread, and is a daemon thread if and only if the
+ * creating thread is a daemon.
+ * <p>
+ * When a Java Virtual Machine starts up, there is usually a single
+ * non-daemon thread (which typically calls the method named
+ * <code>main</code> of some designated class). The Java Virtual
+ * Machine continues to execute threads until either of the following
+ * occurs:
+ * <ul>
+ * <li>The <code>exit</code> method of class <code>Runtime</code> has been
+ * called and the security manager has permitted the exit operation
+ * to take place.
+ * <li>All threads that are not daemon threads have died, either by
+ * returning from the call to the <code>run</code> method or by
+ * throwing an exception that propagates beyond the <code>run</code>
+ * method.
+ * </ul>
+ * <p>
+ * There are two ways to create a new thread of execution. One is to
+ * declare a class to be a subclass of <code>Thread</code>. This
+ * subclass should override the <code>run</code> method of class
+ * <code>Thread</code>. An instance of the subclass can then be
+ * allocated and started. For example, a thread that computes primes
+ * larger than a stated value could be written as follows:
+ * <hr><blockquote><pre>
+ * class PrimeThread extends Thread {
+ * long minPrime;
+ * PrimeThread(long minPrime) {
+ * this.minPrime = minPrime;
+ * }
+ *
+ * public void run() {
+ * // compute primes larger than minPrime
+ * . . .
+ * }
+ * }
+ * </pre></blockquote><hr>
+ * <p>
+ * The following code would then create a thread and start it running:
+ * <blockquote><pre>
+ * PrimeThread p = new PrimeThread(143);
+ * p.start();
+ * </pre></blockquote>
+ * <p>
+ * The other way to create a thread is to declare a class that
+ * implements the <code>Runnable</code> interface. That class then
+ * implements the <code>run</code> method. An instance of the class can
+ * then be allocated, passed as an argument when creating
+ * <code>Thread</code>, and started. The same example in this other
+ * style looks like the following:
+ * <hr><blockquote><pre>
+ * class PrimeRun implements Runnable {
+ * long minPrime;
+ * PrimeRun(long minPrime) {
+ * this.minPrime = minPrime;
+ * }
+ *
+ * public void run() {
+ * // compute primes larger than minPrime
+ * . . .
+ * }
+ * }
+ * </pre></blockquote><hr>
+ * <p>
+ * The following code would then create a thread and start it running:
+ * <blockquote><pre>
+ * PrimeRun p = new PrimeRun(143);
+ * new Thread(p).start();
+ * </pre></blockquote>
+ * <p>
+ * Every thread has a name for identification purposes. More than
+ * one thread may have the same name. If a name is not specified when
+ * a thread is created, a new name is generated for it.
+ * <p>
+ * Unless otherwise noted, passing a {@code null} argument to a constructor
+ * or method in this class will cause a {@link NullPointerException} to be
+ * thrown.
+ *
+ * @author unascribed
+ * @see Runnable
+ * @see Runtime#exit(int)
+ * @see #run()
+ * @see #stop()
+ * @since JDK1.0
+ */
+public
+class Thread implements Runnable {
+ // Android-removed: registerNatives() not used on Android.
+ /*
+ /* Make sure registerNatives is the first thing <clinit> does. *
+ private static native void registerNatives();
+ static {
+ registerNatives();
+ }
+ */
+
+ // BEGIN Android-added: Android specific fields lock, nativePeer.
+ /**
+ * The synchronization object responsible for this thread's join/sleep/park operations.
+ */
+ private final Object lock = new Object();
+
+ /**
+ * Reference to the native thread object.
+ *
+ * <p>Is 0 if the native thread has not yet been created/started, or has been destroyed.
+ */
+ private volatile long nativePeer;
+ // END Android-added: Android specific fields lock, nativePeer.
+
+ private volatile String name;
+ private int priority;
+ private Thread threadQ;
+ private long eetop;
+
+ /* Whether or not to single_step this thread. */
+ private boolean single_step;
+
+ /* Whether or not the thread is a daemon thread. */
+ private boolean daemon = false;
+
+ /* JVM state */
+ private boolean stillborn = false;
+
+ /* What will be run. */
+ private Runnable target;
+
+ /* The group of this thread */
+ private ThreadGroup group;
+
+ /* The context ClassLoader for this thread */
+ private ClassLoader contextClassLoader;
+
+ /* The inherited AccessControlContext of this thread */
+ private AccessControlContext inheritedAccessControlContext;
+
+ /* For autonumbering anonymous threads. */
+ private static int threadInitNumber;
+ private static synchronized int nextThreadNum() {
+ return threadInitNumber++;
+ }
+
+ /* ThreadLocal values pertaining to this thread. This map is maintained
+ * by the ThreadLocal class. */
+ ThreadLocal.ThreadLocalMap threadLocals = null;
+
+ /*
+ * InheritableThreadLocal values pertaining to this thread. This map is
+ * maintained by the InheritableThreadLocal class.
+ */
+ ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
+
+ /*
+ * The requested stack size for this thread, or 0 if the creator did
+ * not specify a stack size. It is up to the VM to do whatever it
+ * likes with this number; some VMs will ignore it.
+ */
+ private long stackSize;
+
+ // BEGIN Android-changed: Keep track of whether this thread was unparked while not alive.
+ /*
+ /*
+ * JVM-private state that persists after native thread termination.
+ *
+ private long nativeParkEventPointer;
+ */
+ /**
+ * Indicates whether this thread was unpark()ed while not alive, in which case start()ing
+ * it should leave it in unparked state. This field is read and written by native code in
+ * the runtime, guarded by thread_list_lock. See http://b/28845097#comment49
+ */
+ private boolean unparkedBeforeStart;
+ // END Android-changed: Keep track of whether this thread was unparked while not alive.
+
+ /*
+ * Thread ID
+ */
+ private long tid;
+
+ /* For generating thread ID */
+ private static long threadSeqNumber;
+
+
+ // Android-added: The concept of "system-daemon" threads. See java.lang.Daemons.
+ /** True if this thread is managed by {@link Daemons}. */
+ private boolean systemDaemon = false;
+
+ /* Java thread status for tools,
+ * initialized to indicate thread 'not yet started'
+ */
+
+ // BEGIN Android-changed: Replace unused threadStatus field with started field.
+ // Upstream this is modified by the native code and read in the start() and getState() methods
+ // but in Android it is unused. The threadStatus is essentially an internal representation of
+ // the Thread.State enum. Android uses two sources for that information, the native thread
+ // state and the started field. The reason two sources are needed is because the native thread
+ // is created when the thread is started and destroyed when the thread is stopped. That means
+ // that the native thread state does not exist before the Thread has started (in State.NEW) or
+ // after it has been stopped (in State.TERMINATED). In that case (i.e. when the nativePeer = 0)
+ // the started field differentiates between the two states, i.e. if started = false then the
+ // thread is in State.NEW and if started = true then the thread is in State.TERMINATED.
+ // private volatile int threadStatus = 0;
+ /**
+ * True if the the Thread has been started, even it has since been stopped.
+ */
+ boolean started = false;
+ // END Android-changed: Replace unused threadStatus field with started field.
+
+
+ private static synchronized long nextThreadID() {
+ return ++threadSeqNumber;
+ }
+
+ /**
+ * The argument supplied to the current call to
+ * java.util.concurrent.locks.LockSupport.park.
+ * Set by (private) java.util.concurrent.locks.LockSupport.setBlocker
+ * Accessed using java.util.concurrent.locks.LockSupport.getBlocker
+ */
+ volatile Object parkBlocker;
+
+ /* The object in which this thread is blocked in an interruptible I/O
+ * operation, if any. The blocker's interrupt method should be invoked
+ * after setting this thread's interrupt status.
+ */
+ private volatile Interruptible blocker;
+ private final Object blockerLock = new Object();
+
+ // Android-changed: Make blockedOn() @hide public, for internal use.
+ // Changed comment to reflect usage on Android
+ /* Set the blocker field; used by java.nio.channels.spi.AbstractInterruptibleChannel
+ */
+ /** @hide */
+ public void blockedOn(Interruptible b) {
+ synchronized (blockerLock) {
+ blocker = b;
+ }
+ }
+
+ /**
+ * The minimum priority that a thread can have.
+ */
+ public final static int MIN_PRIORITY = 1;
+
+ /**
+ * The default priority that is assigned to a thread.
+ */
+ public final static int NORM_PRIORITY = 5;
+
+ /**
+ * The maximum priority that a thread can have.
+ */
+ public final static int MAX_PRIORITY = 10;
+
+ /**
+ * Returns a reference to the currently executing thread object.
+ *
+ * @return the currently executing thread.
+ */
+ @FastNative
+ public static native Thread currentThread();
+
+ /**
+ * A hint to the scheduler that the current thread is willing to yield
+ * its current use of a processor. The scheduler is free to ignore this
+ * hint.
+ *
+ * <p> Yield is a heuristic attempt to improve relative progression
+ * between threads that would otherwise over-utilise a CPU. Its use
+ * should be combined with detailed profiling and benchmarking to
+ * ensure that it actually has the desired effect.
+ *
+ * <p> It is rarely appropriate to use this method. It may be useful
+ * for debugging or testing purposes, where it may help to reproduce
+ * bugs due to race conditions. It may also be useful when designing
+ * concurrency control constructs such as the ones in the
+ * {@link java.util.concurrent.locks} package.
+ */
+ public static native void yield();
+
+ /**
+ * Causes the currently executing thread to sleep (temporarily cease
+ * execution) for the specified number of milliseconds, subject to
+ * the precision and accuracy of system timers and schedulers. The thread
+ * does not lose ownership of any monitors.
+ *
+ * @param millis
+ * the length of time to sleep in milliseconds
+ *
+ * @throws IllegalArgumentException
+ * if the value of {@code millis} is negative
+ *
+ * @throws InterruptedException
+ * if any thread has interrupted the current thread. The
+ * <i>interrupted status</i> of the current thread is
+ * cleared when this exception is thrown.
+ */
+ // BEGIN Android-changed: Implement sleep() methods using a shared native implementation.
+ public static void sleep(long millis) throws InterruptedException {
+ sleep(millis, 0);
+ }
+
+ @FastNative
+ private static native void sleep(Object lock, long millis, int nanos)
+ throws InterruptedException;
+ // END Android-changed: Implement sleep() methods using a shared native implementation.
+
+ /**
+ * Causes the currently executing thread to sleep (temporarily cease
+ * execution) for the specified number of milliseconds plus the specified
+ * number of nanoseconds, subject to the precision and accuracy of system
+ * timers and schedulers. The thread does not lose ownership of any
+ * monitors.
+ *
+ * @param millis
+ * the length of time to sleep in milliseconds
+ *
+ * @param nanos
+ * {@code 0-999999} additional nanoseconds to sleep
+ *
+ * @throws IllegalArgumentException
+ * if the value of {@code millis} is negative, or the value of
+ * {@code nanos} is not in the range {@code 0-999999}
+ *
+ * @throws InterruptedException
+ * if any thread has interrupted the current thread. The
+ * <i>interrupted status</i> of the current thread is
+ * cleared when this exception is thrown.
+ */
+ public static void sleep(long millis, int nanos)
+ throws InterruptedException {
+ // BEGIN Android-changed: Improve exception messages.
+ /*
+ if (millis < 0) {
+ throw new IllegalArgumentException("timeout value is negative");
+ }
+
+ if (nanos < 0 || nanos > 999999) {
+ throw new IllegalArgumentException(
+ "nanosecond timeout value out of range");
+ }
+ */
+ if (millis < 0) {
+ throw new IllegalArgumentException("millis < 0: " + millis);
+ }
+ if (nanos < 0) {
+ throw new IllegalArgumentException("nanos < 0: " + nanos);
+ }
+ if (nanos > 999999) {
+ throw new IllegalArgumentException("nanos > 999999: " + nanos);
+ }
+ // END Android-changed: Improve exception messages.
+
+ // BEGIN Android-changed: Implement sleep() methods using a shared native implementation.
+ // Attempt nanosecond rather than millisecond accuracy for sleep();
+ // RI code rounds to the nearest millisecond.
+ /*
+ if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
+ millis++;
+ }
+
+ sleep(millis);
+ */
+ // The JLS 3rd edition, section 17.9 says: "...sleep for zero
+ // time...need not have observable effects."
+ if (millis == 0 && nanos == 0) {
+ // ...but we still have to handle being interrupted.
+ if (Thread.interrupted()) {
+ throw new InterruptedException();
+ }
+ return;
+ }
+
+ final int nanosPerMilli = 1000000;
+ long start = System.nanoTime();
+ long duration = (millis * nanosPerMilli) + nanos;
+
+ Object lock = currentThread().lock;
+
+ // The native sleep(...) method actually performs a special type of wait, which may return
+ // early, so loop until sleep duration passes.
+ synchronized (lock) {
+ while (true) {
+ sleep(lock, millis, nanos);
+
+ long now = System.nanoTime();
+ long elapsed = now - start;
+
+ if (elapsed >= duration) {
+ break;
+ }
+
+ duration -= elapsed;
+ start = now;
+ millis = duration / nanosPerMilli;
+ nanos = (int) (duration % nanosPerMilli);
+ }
+ }
+ // END Android-changed: Implement sleep() methods using a shared native implementation.
+ }
+
+ /**
+ * Initializes a Thread with the current AccessControlContext.
+ * @see #init(ThreadGroup,Runnable,String,long,AccessControlContext)
+ */
+ private void init(ThreadGroup g, Runnable target, String name,
+ long stackSize) {
+ init(g, target, name, stackSize, null);
+ }
+
+ /**
+ * Initializes a Thread.
+ *
+ * @param g the Thread group
+ * @param target the object whose run() method gets called
+ * @param name the name of the new Thread
+ * @param stackSize the desired stack size for the new thread, or
+ * zero to indicate that this parameter is to be ignored.
+ * @param acc the AccessControlContext to inherit, or
+ * AccessController.getContext() if null
+ */
+ private void init(ThreadGroup g, Runnable target, String name,
+ long stackSize, AccessControlContext acc) {
+ if (name == null) {
+ throw new NullPointerException("name cannot be null");
+ }
+
+ this.name = name;
+
+ Thread parent = currentThread();
+ // Android-removed: SecurityManager stubbed out on Android
+ // SecurityManager security = System.getSecurityManager();
+ if (g == null) {
+ // Android-changed: SecurityManager stubbed out on Android
+ /*
+ /* Determine if it's an applet or not *
+
+ /* If there is a security manager, ask the security manager
+ what to do. *
+ if (security != null) {
+ g = security.getThreadGroup();
+ }
+
+ /* If the security doesn't have a strong opinion of the matter
+ use the parent thread group. *
+ if (g == null) {
+ */
+ g = parent.getThreadGroup();
+ // }
+ }
+
+ // Android-removed: SecurityManager stubbed out on Android
+ /*
+ /* checkAccess regardless of whether or not threadgroup is
+ explicitly passed in. *
+ g.checkAccess();
+
+ /*
+ * Do we have the required permissions?
+ *
+ if (security != null) {
+ if (isCCLOverridden(getClass())) {
+ security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
+ }
+ }
+ */
+
+ g.addUnstarted();
+
+ this.group = g;
+ this.daemon = parent.isDaemon();
+ this.priority = parent.getPriority();
+ // Android-changed: Moved into init2(Thread) helper method.
+ /*
+ if (security == null || isCCLOverridden(parent.getClass()))
+ this.contextClassLoader = parent.getContextClassLoader();
+ else
+ this.contextClassLoader = parent.contextClassLoader;
+ this.inheritedAccessControlContext =
+ acc != null ? acc : AccessController.getContext();
+ */
+ this.target = target;
+ // Android-removed: The priority parameter is unchecked on Android.
+ // It is unclear why this is not being done (b/80180276).
+ // setPriority(priority);
+ // Android-changed: Moved into init2(Thread) helper method.
+ // if (parent.inheritableThreadLocals != null)
+ // this.inheritableThreadLocals =
+ // ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
+ init2(parent);
+
+ /* Stash the specified stack size in case the VM cares */
+ this.stackSize = stackSize;
+
+ /* Set thread ID */
+ tid = nextThreadID();
+ }
+
+ /**
+ * Throws CloneNotSupportedException as a Thread can not be meaningfully
+ * cloned. Construct a new Thread instead.
+ *
+ * @throws CloneNotSupportedException
+ * always
+ */
+ @Override
+ protected Object clone() throws CloneNotSupportedException {
+ throw new CloneNotSupportedException();
+ }
+
+ /**
+ * Allocates a new {@code Thread} object. This constructor has the same
+ * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}
+ * {@code (null, null, gname)}, where {@code gname} is a newly generated
+ * name. Automatically generated names are of the form
+ * {@code "Thread-"+}<i>n</i>, where <i>n</i> is an integer.
+ */
+ public Thread() {
+ init(null, null, "Thread-" + nextThreadNum(), 0);
+ }
+
+ /**
+ * Allocates a new {@code Thread} object. This constructor has the same
+ * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}
+ * {@code (null, target, gname)}, where {@code gname} is a newly generated
+ * name. Automatically generated names are of the form
+ * {@code "Thread-"+}<i>n</i>, where <i>n</i> is an integer.
+ *
+ * @param target
+ * the object whose {@code run} method is invoked when this thread
+ * is started. If {@code null}, this classes {@code run} method does
+ * nothing.
+ */
+ public Thread(Runnable target) {
+ init(null, target, "Thread-" + nextThreadNum(), 0);
+ }
+
+ /**
+ * Creates a new Thread that inherits the given AccessControlContext.
+ * This is not a public constructor.
+ */
+ Thread(Runnable target, AccessControlContext acc) {
+ init(null, target, "Thread-" + nextThreadNum(), 0, acc);
+ }
+
+ /**
+ * Allocates a new {@code Thread} object. This constructor has the same
+ * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}
+ * {@code (group, target, gname)} ,where {@code gname} is a newly generated
+ * name. Automatically generated names are of the form
+ * {@code "Thread-"+}<i>n</i>, where <i>n</i> is an integer.
+ *
+ * @param group
+ * the thread group. If {@code null} and there is a security
+ * manager, the group is determined by {@linkplain
+ * SecurityManager#getThreadGroup SecurityManager.getThreadGroup()}.
+ * If there is not a security manager or {@code
+ * SecurityManager.getThreadGroup()} returns {@code null}, the group
+ * is set to the current thread's thread group.
+ *
+ * @param target
+ * the object whose {@code run} method is invoked when this thread
+ * is started. If {@code null}, this thread's run method is invoked.
+ *
+ * @throws SecurityException
+ * if the current thread cannot create a thread in the specified
+ * thread group
+ */
+ public Thread(ThreadGroup group, Runnable target) {
+ init(group, target, "Thread-" + nextThreadNum(), 0);
+ }
+
+ /**
+ * Allocates a new {@code Thread} object. This constructor has the same
+ * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}
+ * {@code (null, null, name)}.
+ *
+ * @param name
+ * the name of the new thread
+ */
+ public Thread(String name) {
+ init(null, null, name, 0);
+ }
+
+ /**
+ * Allocates a new {@code Thread} object. This constructor has the same
+ * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}
+ * {@code (group, null, name)}.
+ *
+ * @param group
+ * the thread group. If {@code null} and there is a security
+ * manager, the group is determined by {@linkplain
+ * SecurityManager#getThreadGroup SecurityManager.getThreadGroup()}.
+ * If there is not a security manager or {@code
+ * SecurityManager.getThreadGroup()} returns {@code null}, the group
+ * is set to the current thread's thread group.
+ *
+ * @param name
+ * the name of the new thread
+ *
+ * @throws SecurityException
+ * if the current thread cannot create a thread in the specified
+ * thread group
+ */
+ public Thread(ThreadGroup group, String name) {
+ init(group, null, name, 0);
+ }
+
+ // BEGIN Android-added: Private constructor - used by the runtime.
+ /** @hide */
+ Thread(ThreadGroup group, String name, int priority, boolean daemon) {
+ this.group = group;
+ this.group.addUnstarted();
+ // Must be tolerant of threads without a name.
+ if (name == null) {
+ name = "Thread-" + nextThreadNum();
+ }
+
+ // NOTE: Resist the temptation to call setName() here. This constructor is only called
+ // by the runtime to construct peers for threads that have attached via JNI and it's
+ // undesirable to clobber their natively set name.
+ this.name = name;
+
+ this.priority = priority;
+ this.daemon = daemon;
+ init2(currentThread());
+ tid = nextThreadID();
+ }
+
+ // Android-added: Helper method for previous constructor and init(...) method.
+ private void init2(Thread parent) {
+ this.contextClassLoader = parent.getContextClassLoader();
+ this.inheritedAccessControlContext = AccessController.getContext();
+ if (parent.inheritableThreadLocals != null) {
+ this.inheritableThreadLocals = ThreadLocal.createInheritedMap(
+ parent.inheritableThreadLocals);
+ }
+ }
+ // END Android-added: Private constructor - used by the runtime.
+
+
+ /**
+ * Allocates a new {@code Thread} object. This constructor has the same
+ * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}
+ * {@code (null, target, name)}.
+ *
+ * @param target
+ * the object whose {@code run} method is invoked when this thread
+ * is started. If {@code null}, this thread's run method is invoked.
+ *
+ * @param name
+ * the name of the new thread
+ */
+ public Thread(Runnable target, String name) {
+ init(null, target, name, 0);
+ }
+
+ /**
+ * Allocates a new {@code Thread} object so that it has {@code target}
+ * as its run object, has the specified {@code name} as its name,
+ * and belongs to the thread group referred to by {@code group}.
+ *
+ * <p>If there is a security manager, its
+ * {@link SecurityManager#checkAccess(ThreadGroup) checkAccess}
+ * method is invoked with the ThreadGroup as its argument.
+ *
+ * <p>In addition, its {@code checkPermission} method is invoked with
+ * the {@code RuntimePermission("enableContextClassLoaderOverride")}
+ * permission when invoked directly or indirectly by the constructor
+ * of a subclass which overrides the {@code getContextClassLoader}
+ * or {@code setContextClassLoader} methods.
+ *
+ * <p>The priority of the newly created thread is set equal to the
+ * priority of the thread creating it, that is, the currently running
+ * thread. The method {@linkplain #setPriority setPriority} may be
+ * used to change the priority to a new value.
+ *
+ * <p>The newly created thread is initially marked as being a daemon
+ * thread if and only if the thread creating it is currently marked
+ * as a daemon thread. The method {@linkplain #setDaemon setDaemon}
+ * may be used to change whether or not a thread is a daemon.
+ *
+ * @param group
+ * the thread group. If {@code null} and there is a security
+ * manager, the group is determined by {@linkplain
+ * SecurityManager#getThreadGroup SecurityManager.getThreadGroup()}.
+ * If there is not a security manager or {@code
+ * SecurityManager.getThreadGroup()} returns {@code null}, the group
+ * is set to the current thread's thread group.
+ *
+ * @param target
+ * the object whose {@code run} method is invoked when this thread
+ * is started. If {@code null}, this thread's run method is invoked.
+ *
+ * @param name
+ * the name of the new thread
+ *
+ * @throws SecurityException
+ * if the current thread cannot create a thread in the specified
+ * thread group or cannot override the context class loader methods.
+ */
+ public Thread(ThreadGroup group, Runnable target, String name) {
+ init(group, target, name, 0);
+ }
+
+ /**
+ * Allocates a new {@code Thread} object so that it has {@code target}
+ * as its run object, has the specified {@code name} as its name,
+ * and belongs to the thread group referred to by {@code group}, and has
+ * the specified <i>stack size</i>.
+ *
+ * <p>This constructor is identical to {@link
+ * #Thread(ThreadGroup,Runnable,String)} with the exception of the fact
+ * that it allows the thread stack size to be specified. The stack size
+ * is the approximate number of bytes of address space that the virtual
+ * machine is to allocate for this thread's stack. <b>The effect of the
+ * {@code stackSize} parameter, if any, is highly platform dependent.</b>
+ *
+ * <p>On some platforms, specifying a higher value for the
+ * {@code stackSize} parameter may allow a thread to achieve greater
+ * recursion depth before throwing a {@link StackOverflowError}.
+ * Similarly, specifying a lower value may allow a greater number of
+ * threads to exist concurrently without throwing an {@link
+ * OutOfMemoryError} (or other internal error). The details of
+ * the relationship between the value of the <tt>stackSize</tt> parameter
+ * and the maximum recursion depth and concurrency level are
+ * platform-dependent. <b>On some platforms, the value of the
+ * {@code stackSize} parameter may have no effect whatsoever.</b>
+ *
+ * <p>The virtual machine is free to treat the {@code stackSize}
+ * parameter as a suggestion. If the specified value is unreasonably low
+ * for the platform, the virtual machine may instead use some
+ * platform-specific minimum value; if the specified value is unreasonably
+ * high, the virtual machine may instead use some platform-specific
+ * maximum. Likewise, the virtual machine is free to round the specified
+ * value up or down as it sees fit (or to ignore it completely).
+ *
+ * <p>Specifying a value of zero for the {@code stackSize} parameter will
+ * cause this constructor to behave exactly like the
+ * {@code Thread(ThreadGroup, Runnable, String)} constructor.
+ *
+ * <p><i>Due to the platform-dependent nature of the behavior of this
+ * constructor, extreme care should be exercised in its use.
+ * The thread stack size necessary to perform a given computation will
+ * likely vary from one JRE implementation to another. In light of this
+ * variation, careful tuning of the stack size parameter may be required,
+ * and the tuning may need to be repeated for each JRE implementation on
+ * which an application is to run.</i>
+ *
+ * <p>Implementation note: Java platform implementers are encouraged to
+ * document their implementation's behavior with respect to the
+ * {@code stackSize} parameter.
+ *
+ *
+ * @param group
+ * the thread group. If {@code null} and there is a security
+ * manager, the group is determined by {@linkplain
+ * SecurityManager#getThreadGroup SecurityManager.getThreadGroup()}.
+ * If there is not a security manager or {@code
+ * SecurityManager.getThreadGroup()} returns {@code null}, the group
+ * is set to the current thread's thread group.
+ *
+ * @param target
+ * the object whose {@code run} method is invoked when this thread
+ * is started. If {@code null}, this thread's run method is invoked.
+ *
+ * @param name
+ * the name of the new thread
+ *
+ * @param stackSize
+ * the desired stack size for the new thread, or zero to indicate
+ * that this parameter is to be ignored.
+ *
+ * @throws SecurityException
+ * if the current thread cannot create a thread in the specified
+ * thread group
+ *
+ * @since 1.4
+ */
+ public Thread(ThreadGroup group, Runnable target, String name,
+ long stackSize) {
+ init(group, target, name, stackSize);
+ }
+
+ /**
+ * Causes this thread to begin execution; the Java Virtual Machine
+ * calls the <code>run</code> method of this thread.
+ * <p>
+ * The result is that two threads are running concurrently: the
+ * current thread (which returns from the call to the
+ * <code>start</code> method) and the other thread (which executes its
+ * <code>run</code> method).
+ * <p>
+ * It is never legal to start a thread more than once.
+ * In particular, a thread may not be restarted once it has completed
+ * execution.
+ *
+ * @exception IllegalThreadStateException if the thread was already
+ * started.
+ * @see #run()
+ * @see #stop()
+ */
+ public synchronized void start() {
+ /**
+ * This method is not invoked for the main method thread or "system"
+ * group threads created/set up by the VM. Any new functionality added
+ * to this method in the future may have to also be added to the VM.
+ *
+ * A zero status value corresponds to state "NEW".
+ */
+ // Android-changed: Replace unused threadStatus field with started field.
+ // The threadStatus field is unused on Android.
+ if (started)
+ throw new IllegalThreadStateException();
+
+ /* Notify the group that this thread is about to be started
+ * so that it can be added to the group's list of threads
+ * and the group's unstarted count can be decremented. */
+ group.add(this);
+
+ // Android-changed: Use field instead of local variable.
+ // It is necessary to remember the state of this across calls to this method so that it
+ // can throw an IllegalThreadStateException if this method is called on an already
+ // started thread.
+ started = false;
+ try {
+ // Android-changed: Use Android specific nativeCreate() method to create/start thread.
+ // start0();
+ nativeCreate(this, stackSize, daemon);
+ started = true;
+ } finally {
+ try {
+ if (!started) {
+ group.threadStartFailed(this);
+ }
+ } catch (Throwable ignore) {
+ /* do nothing. If start0 threw a Throwable then
+ it will be passed up the call stack */
+ }
+ }
+ }
+
+ // Android-changed: Use Android specific nativeCreate() method to create/start thread.
+ // The upstream native method start0() only takes a reference to this object and so must obtain
+ // the stack size and daemon status directly from the field whereas Android supplies the values
+ // explicitly on the method call.
+ // private native void start0();
+ private native static void nativeCreate(Thread t, long stackSize, boolean daemon);
+
+ /**
+ * If this thread was constructed using a separate
+ * <code>Runnable</code> run object, then that
+ * <code>Runnable</code> object's <code>run</code> method is called;
+ * otherwise, this method does nothing and returns.
+ * <p>
+ * Subclasses of <code>Thread</code> should override this method.
+ *
+ * @see #start()
+ * @see #stop()
+ * @see #Thread(ThreadGroup, Runnable, String)
+ */
+ @Override
+ public void run() {
+ if (target != null) {
+ target.run();
+ }
+ }
+
+ /**
+ * This method is called by the system to give a Thread
+ * a chance to clean up before it actually exits.
+ */
+ private void exit() {
+ if (group != null) {
+ group.threadTerminated(this);
+ group = null;
+ }
+ /* Aggressively null out all reference fields: see bug 4006245 */
+ target = null;
+ /* Speed the release of some of these resources */
+ threadLocals = null;
+ inheritableThreadLocals = null;
+ inheritedAccessControlContext = null;
+ blocker = null;
+ uncaughtExceptionHandler = null;
+ }
+
+ // Android-changed: Throws UnsupportedOperationException.
+ /**
+ * Throws {@code UnsupportedOperationException}.
+ *
+ * @deprecated This method was originally designed to force a thread to stop
+ * and throw a {@code ThreadDeath} as an exception. It was inherently unsafe.
+ * Stopping a thread with
+ * Thread.stop causes it to unlock all of the monitors that it
+ * has locked (as a natural consequence of the unchecked
+ * <code>ThreadDeath</code> exception propagating up the stack). If
+ * any of the objects previously protected by these monitors were in
+ * an inconsistent state, the damaged objects become visible to
+ * other threads, potentially resulting in arbitrary behavior. Many
+ * uses of <code>stop</code> should be replaced by code that simply
+ * modifies some variable to indicate that the target thread should
+ * stop running. The target thread should check this variable
+ * regularly, and return from its run method in an orderly fashion
+ * if the variable indicates that it is to stop running. If the
+ * target thread waits for long periods (on a condition variable,
+ * for example), the <code>interrupt</code> method should be used to
+ * interrupt the wait.
+ * For more information, see
+ * <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
+ * are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
+ */
+ @Deprecated
+ public final void stop() {
+ /*
+ SecurityManager security = System.getSecurityManager();
+ if (security != null) {
+ checkAccess();
+ if (this != Thread.currentThread()) {
+ security.checkPermission(SecurityConstants.STOP_THREAD_PERMISSION);
+ }
+ }
+ // A zero status value corresponds to "NEW", it can't change to
+ // not-NEW because we hold the lock.
+ if (threadStatus != 0) {
+ resume(); // Wake up thread if it was suspended; no-op otherwise
+ }
+
+ // The VM can handle all thread states
+ stop0(new ThreadDeath());
+ */
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Throws {@code UnsupportedOperationException}.
+ *
+ * @param obj ignored
+ *
+ * @deprecated This method was originally designed to force a thread to stop
+ * and throw a given {@code Throwable} as an exception. It was
+ * inherently unsafe (see {@link #stop()} for details), and furthermore
+ * could be used to generate exceptions that the target thread was
+ * not prepared to handle.
+ * For more information, see
+ * <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
+ * are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
+ */
+ @Deprecated
+ public final synchronized void stop(Throwable obj) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Interrupts this thread.
+ *
+ * <p> Unless the current thread is interrupting itself, which is
+ * always permitted, the {@link #checkAccess() checkAccess} method
+ * of this thread is invoked, which may cause a {@link
+ * SecurityException} to be thrown.
+ *
+ * <p> If this thread is blocked in an invocation of the {@link
+ * Object#wait() wait()}, {@link Object#wait(long) wait(long)}, or {@link
+ * Object#wait(long, int) wait(long, int)} methods of the {@link Object}
+ * class, or of the {@link #join()}, {@link #join(long)}, {@link
+ * #join(long, int)}, {@link #sleep(long)}, or {@link #sleep(long, int)},
+ * methods of this class, then its interrupt status will be cleared and it
+ * will receive an {@link InterruptedException}.
+ *
+ * <p> If this thread is blocked in an I/O operation upon an {@link
+ * java.nio.channels.InterruptibleChannel InterruptibleChannel}
+ * then the channel will be closed, the thread's interrupt
+ * status will be set, and the thread will receive a {@link
+ * java.nio.channels.ClosedByInterruptException}.
+ *
+ * <p> If this thread is blocked in a {@link java.nio.channels.Selector}
+ * then the thread's interrupt status will be set and it will return
+ * immediately from the selection operation, possibly with a non-zero
+ * value, just as if the selector's {@link
+ * java.nio.channels.Selector#wakeup wakeup} method were invoked.
+ *
+ * <p> If none of the previous conditions hold then this thread's interrupt
+ * status will be set. </p>
+ *
+ * <p> Interrupting a thread that is not alive need not have any effect.
+ *
+ * @throws SecurityException
+ * if the current thread cannot modify this thread
+ *
+ * @revised 6.0
+ * @spec JSR-51
+ */
+ public void interrupt() {
+ if (this != Thread.currentThread())
+ checkAccess();
+
+ synchronized (blockerLock) {
+ Interruptible b = blocker;
+ if (b != null) {
+ interrupt0(); // Just to set the interrupt flag
+ b.interrupt(this);
+ return;
+ }
+ }
+ interrupt0();
+ }
+
+ /**
+ * Tests whether the current thread has been interrupted. The
+ * <i>interrupted status</i> of the thread is cleared by this method. In
+ * other words, if this method were to be called twice in succession, the
+ * second call would return false (unless the current thread were
+ * interrupted again, after the first call had cleared its interrupted
+ * status and before the second call had examined it).
+ *
+ * <p>A thread interruption ignored because a thread was not alive
+ * at the time of the interrupt will be reflected by this method
+ * returning false.
+ *
+ * @return <code>true</code> if the current thread has been interrupted;
+ * <code>false</code> otherwise.
+ * @see #isInterrupted()
+ * @revised 6.0
+ */
+ // Android-changed: Use native interrupted()/isInterrupted() methods.
+ // Upstream has one native method for both these methods that takes a boolean parameter that
+ // determines whether the interrupted status of the thread should be cleared after reading
+ // it. While that approach does allow code reuse it is less efficient/more complex than having
+ // a native implementation of each method because:
+ // * The pure Java interrupted() method requires two native calls, one to get the current
+ // thread and one to get its interrupted status.
+ // * Updating the interrupted flag is more complex than simply reading it. Knowing that only
+ // the current thread can clear the interrupted status makes the code simpler as it does not
+ // need to be concerned about multiple threads trying to clear the status simultaneously.
+ // public static boolean interrupted() {
+ // return currentThread().isInterrupted(true);
+ // }
+ @FastNative
+ public static native boolean interrupted();
+
+ /**
+ * Tests whether this thread has been interrupted. The <i>interrupted
+ * status</i> of the thread is unaffected by this method.
+ *
+ * <p>A thread interruption ignored because a thread was not alive
+ * at the time of the interrupt will be reflected by this method
+ * returning false.
+ *
+ * @return <code>true</code> if this thread has been interrupted;
+ * <code>false</code> otherwise.
+ * @see #interrupted()
+ * @revised 6.0
+ */
+ // Android-changed: Use native interrupted()/isInterrupted() methods.
+ // public boolean isInterrupted() {
+ // return isInterrupted(false);
+ // }
+ @FastNative
+ public native boolean isInterrupted();
+
+ // Android-removed: Use native interrupted()/isInterrupted() methods.
+ /*
+ /**
+ * Tests if some Thread has been interrupted. The interrupted state
+ * is reset or not based on the value of ClearInterrupted that is
+ * passed.
+ *
+ private native boolean isInterrupted(boolean ClearInterrupted);
+ */
+
+ // BEGIN Android-changed: Throw UnsupportedOperationException instead of NoSuchMethodError.
+ /**
+ * Throws {@link UnsupportedOperationException}.
+ *
+ * @deprecated This method was originally designed to destroy this
+ * thread without any cleanup. Any monitors it held would have
+ * remained locked. However, the method was never implemented.
+ * If if were to be implemented, it would be deadlock-prone in
+ * much the manner of {@link #suspend}. If the target thread held
+ * a lock protecting a critical system resource when it was
+ * destroyed, no thread could ever access this resource again.
+ * If another thread ever attempted to lock this resource, deadlock
+ * would result. Such deadlocks typically manifest themselves as
+ * "frozen" processes. For more information, see
+ * <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">
+ * Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
+ * @throws UnsupportedOperationException always
+ */
+ @Deprecated
+ public void destroy() {
+ throw new UnsupportedOperationException();
+ }
+ // END Android-changed: Throw UnsupportedOperationException instead of NoSuchMethodError.
+
+ /**
+ * Tests if this thread is alive. A thread is alive if it has
+ * been started and has not yet died.
+ *
+ * @return <code>true</code> if this thread is alive;
+ * <code>false</code> otherwise.
+ */
+ // Android-changed: Provide pure Java implementation of isAlive().
+ public final boolean isAlive() {
+ return nativePeer != 0;
+ }
+
+ // Android-changed: Updated JavaDoc as it always throws an UnsupportedOperationException.
+ /**
+ * Throws {@link UnsupportedOperationException}.
+ *
+ * @deprecated This method was designed to suspend the Thread but it was
+ * inherently deadlock-prone. If the target thread holds a lock on the
+ * monitor protecting a critical system resource when it is suspended, no
+ * thread can access this resource until the target thread is resumed. If
+ * the thread that would resume the target thread attempts to lock this
+ * monitor prior to calling <code>resume</code>, deadlock results. Such
+ * deadlocks typically manifest themselves as "frozen" processes.
+ * For more information, see
+ * <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
+ * are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
+ * @throws UnsupportedOperationException always
+ */
+ @Deprecated
+ public final void suspend() {
+ // Android-changed: Unsupported on Android.
+ // checkAccess();
+ // suspend0();
+
+ throw new UnsupportedOperationException();
+ }
+
+ // Android-changed: Updated JavaDoc as it always throws an UnsupportedOperationException.
+ /**
+ * Throws {@link UnsupportedOperationException}.
+ *
+ * @deprecated This method exists solely for use with {@link #suspend},
+ * which has been deprecated because it is deadlock-prone.
+ * For more information, see
+ * <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
+ * are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
+ * @throws UnsupportedOperationException always
+ */
+ @Deprecated
+ public final void resume() {
+ // Android-changed: Unsupported on Android.
+ // checkAccess();
+ // resume0();
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Changes the priority of this thread.
+ * <p>
+ * First the <code>checkAccess</code> method of this thread is called
+ * with no arguments. This may result in throwing a
+ * <code>SecurityException</code>.
+ * <p>
+ * Otherwise, the priority of this thread is set to the smaller of
+ * the specified <code>newPriority</code> and the maximum permitted
+ * priority of the thread's thread group.
+ *
+ * @param newPriority priority to set this thread to
+ * @exception IllegalArgumentException If the priority is not in the
+ * range <code>MIN_PRIORITY</code> to
+ * <code>MAX_PRIORITY</code>.
+ * @exception SecurityException if the current thread cannot modify
+ * this thread.
+ * @see #getPriority
+ * @see #checkAccess()
+ * @see #getThreadGroup()
+ * @see #MAX_PRIORITY
+ * @see #MIN_PRIORITY
+ * @see ThreadGroup#getMaxPriority()
+ */
+ public final void setPriority(int newPriority) {
+ ThreadGroup g;
+ checkAccess();
+ if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {
+ // Android-changed: Improve exception message when the new priority is out of bounds.
+ throw new IllegalArgumentException("Priority out of range: " + newPriority);
+ }
+ if((g = getThreadGroup()) != null) {
+ if (newPriority > g.getMaxPriority()) {
+ newPriority = g.getMaxPriority();
+ }
+ // Android-changed: Avoid native call if Thread is not yet started.
+ // setPriority0(priority = newPriority);
+ synchronized(this) {
+ this.priority = newPriority;
+ if (isAlive()) {
+ // BEGIN Android-added: Customize behavior of Thread.setPriority().
+ // http://b/139521784
+ // setPriority0(newPriority);
+ ThreadPrioritySetter threadPrioritySetter =
+ RuntimeHooks.getThreadPrioritySetter();
+ int nativeTid = this.getNativeTid();
+ if (threadPrioritySetter != null && nativeTid != 0) {
+ threadPrioritySetter.setPriority(nativeTid, newPriority);
+ } else {
+ setPriority0(newPriority);
+ }
+ // END Android-added: Customize behavior of Thread.setPriority().
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns this thread's priority.
+ *
+ * @return this thread's priority.
+ * @see #setPriority
+ */
+ public final int getPriority() {
+ return priority;
+ }
+
+ /**
+ * Changes the name of this thread to be equal to the argument
+ * <code>name</code>.
+ * <p>
+ * First the <code>checkAccess</code> method of this thread is called
+ * with no arguments. This may result in throwing a
+ * <code>SecurityException</code>.
+ *
+ * @param name the new name for this thread.
+ * @exception SecurityException if the current thread cannot modify this
+ * thread.
+ * @see #getName
+ * @see #checkAccess()
+ */
+ public final synchronized void setName(String name) {
+ checkAccess();
+ if (name == null) {
+ throw new NullPointerException("name cannot be null");
+ }
+
+ this.name = name;
+ // Android-changed: Use isAlive() not threadStatus to check whether Thread has started.
+ // The threadStatus field is not used in Android.
+ // if (threadStatus != 0) {
+ if (isAlive()) {
+ setNativeName(name);
+ }
+ }
+
+ /**
+ * Returns this thread's name.
+ *
+ * @return this thread's name.
+ * @see #setName(String)
+ */
+ public final String getName() {
+ return name;
+ }
+
+ /**
+ * Returns the thread group to which this thread belongs.
+ * This method returns null if this thread has died
+ * (been stopped).
+ *
+ * @return this thread's thread group.
+ */
+ public final ThreadGroup getThreadGroup() {
+ // BEGIN Android-added: Work around exit() not being called.
+ // Android runtime does not call exit() when a Thread exits so the group field is not
+ // set to null so it needs to pretend as if it did. If we are not going to call exit()
+ // then this should probably just check isAlive() here rather than getState() as the
+ // latter requires a native call.
+ if (getState() == Thread.State.TERMINATED) {
+ return null;
+ }
+ // END Android-added: Work around exit() not being called.
+ return group;
+ }
+
+ /**
+ * Returns an estimate of the number of active threads in the current
+ * thread's {@linkplain java.lang.ThreadGroup thread group} and its
+ * subgroups. Recursively iterates over all subgroups in the current
+ * thread's thread group.
+ *
+ * <p> The value returned is only an estimate because the number of
+ * threads may change dynamically while this method traverses internal
+ * data structures, and might be affected by the presence of certain
+ * system threads. This method is intended primarily for debugging
+ * and monitoring purposes.
+ *
+ * @return an estimate of the number of active threads in the current
+ * thread's thread group and in any other thread group that
+ * has the current thread's thread group as an ancestor
+ */
+ public static int activeCount() {
+ return currentThread().getThreadGroup().activeCount();
+ }
+
+ /**
+ * Copies into the specified array every active thread in the current
+ * thread's thread group and its subgroups. This method simply
+ * invokes the {@link java.lang.ThreadGroup#enumerate(Thread[])}
+ * method of the current thread's thread group.
+ *
+ * <p> An application might use the {@linkplain #activeCount activeCount}
+ * method to get an estimate of how big the array should be, however
+ * <i>if the array is too short to hold all the threads, the extra threads
+ * are silently ignored.</i> If it is critical to obtain every active
+ * thread in the current thread's thread group and its subgroups, the
+ * invoker should verify that the returned int value is strictly less
+ * than the length of {@code tarray}.
+ *
+ * <p> Due to the inherent race condition in this method, it is recommended
+ * that the method only be used for debugging and monitoring purposes.
+ *
+ * @param tarray
+ * an array into which to put the list of threads
+ *
+ * @return the number of threads put into the array
+ *
+ * @throws SecurityException
+ * if {@link java.lang.ThreadGroup#checkAccess} determines that
+ * the current thread cannot access its thread group
+ */
+ public static int enumerate(Thread tarray[]) {
+ return currentThread().getThreadGroup().enumerate(tarray);
+ }
+
+ /**
+ * Counts the number of stack frames in this thread. The thread must
+ * be suspended.
+ *
+ * @return the number of stack frames in this thread.
+ * @exception IllegalThreadStateException if this thread is not
+ * suspended.
+ * @deprecated The definition of this call depends on {@link #suspend},
+ * which is deprecated. Further, the results of this call
+ * were never well-defined.
+ */
+ @Deprecated
+ // Android-changed: Provide non-native implementation of countStackFrames().
+ // public native int countStackFrames();
+ public int countStackFrames() {
+ return getStackTrace().length;
+ }
+
+ /**
+ * Waits at most {@code millis} milliseconds for this thread to
+ * die. A timeout of {@code 0} means to wait forever.
+ *
+ * <p> This implementation uses a loop of {@code this.wait} calls
+ * conditioned on {@code this.isAlive}. As a thread terminates the
+ * {@code this.notifyAll} method is invoked. It is recommended that
+ * applications not use {@code wait}, {@code notify}, or
+ * {@code notifyAll} on {@code Thread} instances.
+ *
+ * @param millis
+ * the time to wait in milliseconds
+ *
+ * @throws IllegalArgumentException
+ * if the value of {@code millis} is negative
+ *
+ * @throws InterruptedException
+ * if any thread has interrupted the current thread. The
+ * <i>interrupted status</i> of the current thread is
+ * cleared when this exception is thrown.
+ */
+ // BEGIN Android-changed: Synchronize on separate lock object not this Thread.
+ // public final synchronized void join(long millis)
+ public final void join(long millis)
+ throws InterruptedException {
+ synchronized(lock) {
+ long base = System.currentTimeMillis();
+ long now = 0;
+
+ if (millis < 0) {
+ throw new IllegalArgumentException("timeout value is negative");
+ }
+
+ if (millis == 0) {
+ while (isAlive()) {
+ lock.wait(0);
+ }
+ } else {
+ while (isAlive()) {
+ long delay = millis - now;
+ if (delay <= 0) {
+ break;
+ }
+ lock.wait(delay);
+ now = System.currentTimeMillis() - base;
+ }
+ }
+ }
+ }
+ // END Android-changed: Synchronize on separate lock object not this Thread.
+
+ /**
+ * Waits at most {@code millis} milliseconds plus
+ * {@code nanos} nanoseconds for this thread to die.
+ *
+ * <p> This implementation uses a loop of {@code this.wait} calls
+ * conditioned on {@code this.isAlive}. As a thread terminates the
+ * {@code this.notifyAll} method is invoked. It is recommended that
+ * applications not use {@code wait}, {@code notify}, or
+ * {@code notifyAll} on {@code Thread} instances.
+ *
+ * @param millis
+ * the time to wait in milliseconds
+ *
+ * @param nanos
+ * {@code 0-999999} additional nanoseconds to wait
+ *
+ * @throws IllegalArgumentException
+ * if the value of {@code millis} is negative, or the value
+ * of {@code nanos} is not in the range {@code 0-999999}
+ *
+ * @throws InterruptedException
+ * if any thread has interrupted the current thread. The
+ * <i>interrupted status</i> of the current thread is
+ * cleared when this exception is thrown.
+ */
+ // BEGIN Android-changed: Synchronize on separate lock object not this Thread.
+ // public final synchronized void join(long millis, int nanos)
+ public final void join(long millis, int nanos)
+ throws InterruptedException {
+
+ synchronized(lock) {
+ if (millis < 0) {
+ throw new IllegalArgumentException("timeout value is negative");
+ }
+
+ if (nanos < 0 || nanos > 999999) {
+ throw new IllegalArgumentException(
+ "nanosecond timeout value out of range");
+ }
+
+ if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
+ millis++;
+ }
+
+ join(millis);
+ }
+ }
+ // END Android-changed: Synchronize on separate lock object not this Thread.
+
+ /**
+ * Waits for this thread to die.
+ *
+ * <p> An invocation of this method behaves in exactly the same
+ * way as the invocation
+ *
+ * <blockquote>
+ * {@linkplain #join(long) join}{@code (0)}
+ * </blockquote>
+ *
+ * @throws InterruptedException
+ * if any thread has interrupted the current thread. The
+ * <i>interrupted status</i> of the current thread is
+ * cleared when this exception is thrown.
+ */
+ public final void join() throws InterruptedException {
+ join(0);
+ }
+
+ /**
+ * Prints a stack trace of the current thread to the standard error stream.
+ * This method is used only for debugging.
+ *
+ * @see Throwable#printStackTrace()
+ */
+ public static void dumpStack() {
+ new Exception("Stack trace").printStackTrace();
+ }
+
+ /**
+ * Marks this thread as either a {@linkplain #isDaemon daemon} thread
+ * or a user thread. The Java Virtual Machine exits when the only
+ * threads running are all daemon threads.
+ *
+ * <p> This method must be invoked before the thread is started.
+ *
+ * @param on
+ * if {@code true}, marks this thread as a daemon thread
+ *
+ * @throws IllegalThreadStateException
+ * if this thread is {@linkplain #isAlive alive}
+ *
+ * @throws SecurityException
+ * if {@link #checkAccess} determines that the current
+ * thread cannot modify this thread
+ */
+ public final void setDaemon(boolean on) {
+ checkAccess();
+ if (isAlive()) {
+ throw new IllegalThreadStateException();
+ }
+ daemon = on;
+ }
+
+ /**
+ * Tests if this thread is a daemon thread.
+ *
+ * @return <code>true</code> if this thread is a daemon thread;
+ * <code>false</code> otherwise.
+ * @see #setDaemon(boolean)
+ */
+ public final boolean isDaemon() {
+ return daemon;
+ }
+
+ /**
+ * Determines if the currently running thread has permission to
+ * modify this thread.
+ * <p>
+ * If there is a security manager, its <code>checkAccess</code> method
+ * is called with this thread as its argument. This may result in
+ * throwing a <code>SecurityException</code>.
+ *
+ * @exception SecurityException if the current thread is not allowed to
+ * access this thread.
+ * @see SecurityManager#checkAccess(Thread)
+ */
+ public final void checkAccess() {
+ // Android-removed: SecurityManager stubbed out on Android
+ // SecurityManager security = System.getSecurityManager();
+ // if (security != null) {
+ // security.checkAccess(this);
+ // }
+ }
+
+ /**
+ * Returns a string representation of this thread, including the
+ * thread's name, priority, and thread group.
+ *
+ * @return a string representation of this thread.
+ */
+ public String toString() {
+ ThreadGroup group = getThreadGroup();
+ if (group != null) {
+ return "Thread[" + getName() + "," + getPriority() + "," +
+ group.getName() + "]";
+ } else {
+ return "Thread[" + getName() + "," + getPriority() + "," +
+ "" + "]";
+ }
+ }
+
+ /**
+ * Returns the context ClassLoader for this Thread. The context
+ * ClassLoader is provided by the creator of the thread for use
+ * by code running in this thread when loading classes and resources.
+ * If not {@linkplain #setContextClassLoader set}, the default is the
+ * ClassLoader context of the parent Thread. The context ClassLoader of the
+ * primordial thread is typically set to the class loader used to load the
+ * application.
+ *
+ * <p>If a security manager is present, and the invoker's class loader is not
+ * {@code null} and is not the same as or an ancestor of the context class
+ * loader, then this method invokes the security manager's {@link
+ * SecurityManager#checkPermission(java.security.Permission) checkPermission}
+ * method with a {@link RuntimePermission RuntimePermission}{@code
+ * ("getClassLoader")} permission to verify that retrieval of the context
+ * class loader is permitted.
+ *
+ * @return the context ClassLoader for this Thread, or {@code null}
+ * indicating the system class loader (or, failing that, the
+ * bootstrap class loader)
+ *
+ * @throws SecurityException
+ * if the current thread cannot get the context ClassLoader
+ *
+ * @since 1.2
+ */
+ @CallerSensitive
+ public ClassLoader getContextClassLoader() {
+ // Android-removed: SecurityManager stubbed out on Android
+ /*
+ if (contextClassLoader == null)
+ return null;
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ ClassLoader.checkClassLoaderPermission(contextClassLoader,
+ Reflection.getCallerClass());
+ }
+ */
+ return contextClassLoader;
+ }
+
+ /**
+ * Sets the context ClassLoader for this Thread. The context
+ * ClassLoader can be set when a thread is created, and allows
+ * the creator of the thread to provide the appropriate class loader,
+ * through {@code getContextClassLoader}, to code running in the thread
+ * when loading classes and resources.
+ *
+ * <p>If a security manager is present, its {@link
+ * SecurityManager#checkPermission(java.security.Permission) checkPermission}
+ * method is invoked with a {@link RuntimePermission RuntimePermission}{@code
+ * ("setContextClassLoader")} permission to see if setting the context
+ * ClassLoader is permitted.
+ *
+ * @param cl
+ * the context ClassLoader for this Thread, or null indicating the
+ * system class loader (or, failing that, the bootstrap class loader)
+ *
+ * @throws SecurityException
+ * if the current thread cannot set the context ClassLoader
+ *
+ * @since 1.2
+ */
+ public void setContextClassLoader(ClassLoader cl) {
+ // Android-removed: SecurityManager stubbed out on Android
+ // SecurityManager sm = System.getSecurityManager();
+ // if (sm != null) {
+ // sm.checkPermission(new RuntimePermission("setContextClassLoader"));
+ // }
+ contextClassLoader = cl;
+ }
+
+ /**
+ * Returns <tt>true</tt> if and only if the current thread holds the
+ * monitor lock on the specified object.
+ *
+ * <p>This method is designed to allow a program to assert that
+ * the current thread already holds a specified lock:
+ * <pre>
+ * assert Thread.holdsLock(obj);
+ * </pre>
+ *
+ * @param obj the object on which to test lock ownership
+ * @throws NullPointerException if obj is <tt>null</tt>
+ * @return <tt>true</tt> if the current thread holds the monitor lock on
+ * the specified object.
+ * @since 1.4
+ */
+ public static native boolean holdsLock(Object obj);
+
+ private static final StackTraceElement[] EMPTY_STACK_TRACE
+ = new StackTraceElement[0];
+
+ /**
+ * Returns an array of stack trace elements representing the stack dump
+ * of this thread. This method will return a zero-length array if
+ * this thread has not started, has started but has not yet been
+ * scheduled to run by the system, or has terminated.
+ * If the returned array is of non-zero length then the first element of
+ * the array represents the top of the stack, which is the most recent
+ * method invocation in the sequence. The last element of the array
+ * represents the bottom of the stack, which is the least recent method
+ * invocation in the sequence.
+ *
+ * <p>If there is a security manager, and this thread is not
+ * the current thread, then the security manager's
+ * <tt>checkPermission</tt> method is called with a
+ * <tt>RuntimePermission("getStackTrace")</tt> permission
+ * to see if it's ok to get the stack trace.
+ *
+ * <p>Some virtual machines may, under some circumstances, omit one
+ * or more stack frames from the stack trace. In the extreme case,
+ * a virtual machine that has no stack trace information concerning
+ * this thread is permitted to return a zero-length array from this
+ * method.
+ *
+ * @return an array of <tt>StackTraceElement</tt>,
+ * each represents one stack frame.
+ *
+ * @throws SecurityException
+ * if a security manager exists and its
+ * <tt>checkPermission</tt> method doesn't allow
+ * getting the stack trace of thread.
+ * @see SecurityManager#checkPermission
+ * @see RuntimePermission
+ * @see Throwable#getStackTrace
+ *
+ * @since 1.5
+ */
+ public StackTraceElement[] getStackTrace() {
+ // Android-changed: Use native VMStack to get stack trace.
+ StackTraceElement ste[] = VMStack.getThreadStackTrace(this);
+ return ste != null ? ste : EmptyArray.STACK_TRACE_ELEMENT;
+ }
+
+ /**
+ * Returns a map of stack traces for all live threads.
+ * The map keys are threads and each map value is an array of
+ * <tt>StackTraceElement</tt> that represents the stack dump
+ * of the corresponding <tt>Thread</tt>.
+ * The returned stack traces are in the format specified for
+ * the {@link #getStackTrace getStackTrace} method.
+ *
+ * <p>The threads may be executing while this method is called.
+ * The stack trace of each thread only represents a snapshot and
+ * each stack trace may be obtained at different time. A zero-length
+ * array will be returned in the map value if the virtual machine has
+ * no stack trace information about a thread.
+ *
+ * <p>If there is a security manager, then the security manager's
+ * <tt>checkPermission</tt> method is called with a
+ * <tt>RuntimePermission("getStackTrace")</tt> permission as well as
+ * <tt>RuntimePermission("modifyThreadGroup")</tt> permission
+ * to see if it is ok to get the stack trace of all threads.
+ *
+ * @return a <tt>Map</tt> from <tt>Thread</tt> to an array of
+ * <tt>StackTraceElement</tt> that represents the stack trace of
+ * the corresponding thread.
+ *
+ * @throws SecurityException
+ * if a security manager exists and its
+ * <tt>checkPermission</tt> method doesn't allow
+ * getting the stack trace of thread.
+ * @see #getStackTrace
+ * @see SecurityManager#checkPermission
+ * @see RuntimePermission
+ * @see Throwable#getStackTrace
+ *
+ * @since 1.5
+ */
+ public static Map<Thread, StackTraceElement[]> getAllStackTraces() {
+ // Android-removed: SecurityManager stubbed out on Android
+ /*
+ // check for getStackTrace permission
+ SecurityManager security = System.getSecurityManager();
+ if (security != null) {
+ security.checkPermission(
+ SecurityConstants.GET_STACK_TRACE_PERMISSION);
+ security.checkPermission(
+ SecurityConstants.MODIFY_THREADGROUP_PERMISSION);
+ }
+ */
+
+ // Get a snapshot of the list of all threads
+ // BEGIN Android-changed: Use ThreadGroup and getStackTrace() instead of native methods.
+ // Allocate a bit more space than needed, in case new ones are just being created.
+ /*
+ Thread[] threads = getThreads();
+ StackTraceElement[][] traces = dumpThreads(threads);
+ Map<Thread, StackTraceElement[]> m = new HashMap<>(threads.length);
+ for (int i = 0; i < threads.length; i++) {
+ StackTraceElement[] stackTrace = traces[i];
+ if (stackTrace != null) {
+ m.put(threads[i], stackTrace);
+ }
+ // else terminated so we don't put it in the map
+ }
+ */
+ int count = ThreadGroup.systemThreadGroup.activeCount();
+ Thread[] threads = new Thread[count + count / 2];
+
+ // Enumerate the threads.
+ count = ThreadGroup.systemThreadGroup.enumerate(threads);
+
+ // Collect the stacktraces
+ Map<Thread, StackTraceElement[]> m = new HashMap<Thread, StackTraceElement[]>();
+ for (int i = 0; i < count; i++) {
+ StackTraceElement[] stackTrace = threads[i].getStackTrace();
+ m.put(threads[i], stackTrace);
+ }
+ // END Android-changed: Use ThreadGroup and getStackTrace() instead of native methods.
+ return m;
+ }
+
+
+ private static final RuntimePermission SUBCLASS_IMPLEMENTATION_PERMISSION =
+ new RuntimePermission("enableContextClassLoaderOverride");
+
+ /** cache of subclass security audit results */
+ /* Replace with ConcurrentReferenceHashMap when/if it appears in a future
+ * release */
+ private static class Caches {
+ /** cache of subclass security audit results */
+ static final ConcurrentMap<WeakClassKey,Boolean> subclassAudits =
+ new ConcurrentHashMap<>();
+
+ /** queue for WeakReferences to audited subclasses */
+ static final ReferenceQueue<Class<?>> subclassAuditsQueue =
+ new ReferenceQueue<>();
+ }
+
+ /**
+ * Verifies that this (possibly subclass) instance can be constructed
+ * without violating security constraints: the subclass must not override
+ * security-sensitive non-final methods, or else the
+ * "enableContextClassLoaderOverride" RuntimePermission is checked.
+ */
+ private static boolean isCCLOverridden(Class<?> cl) {
+ if (cl == Thread.class)
+ return false;
+
+ processQueue(Caches.subclassAuditsQueue, Caches.subclassAudits);
+ WeakClassKey key = new WeakClassKey(cl, Caches.subclassAuditsQueue);
+ Boolean result = Caches.subclassAudits.get(key);
+ if (result == null) {
+ result = Boolean.valueOf(auditSubclass(cl));
+ Caches.subclassAudits.putIfAbsent(key, result);
+ }
+
+ return result.booleanValue();
+ }
+
+ /**
+ * Performs reflective checks on given subclass to verify that it doesn't
+ * override security-sensitive non-final methods. Returns true if the
+ * subclass overrides any of the methods, false otherwise.
+ */
+ private static boolean auditSubclass(final Class<?> subcl) {
+ Boolean result = AccessController.doPrivileged(
+ new PrivilegedAction<Boolean>() {
+ public Boolean run() {
+ for (Class<?> cl = subcl;
+ cl != Thread.class;
+ cl = cl.getSuperclass())
+ {
+ try {
+ cl.getDeclaredMethod("getContextClassLoader", new Class<?>[0]);
+ return Boolean.TRUE;
+ } catch (NoSuchMethodException ex) {
+ }
+ try {
+ Class<?>[] params = {ClassLoader.class};
+ cl.getDeclaredMethod("setContextClassLoader", params);
+ return Boolean.TRUE;
+ } catch (NoSuchMethodException ex) {
+ }
+ }
+ return Boolean.FALSE;
+ }
+ }
+ );
+ return result.booleanValue();
+ }
+
+ // Android-removed: Native methods that are unused on Android.
+ // private native static StackTraceElement[][] dumpThreads(Thread[] threads);
+ // private native static Thread[] getThreads();
+
+ /**
+ * Returns the identifier of this Thread. The thread ID is a positive
+ * <tt>long</tt> number generated when this thread was created.
+ * The thread ID is unique and remains unchanged during its lifetime.
+ * When a thread is terminated, this thread ID may be reused.
+ *
+ * @return this thread's ID.
+ * @since 1.5
+ */
+ public long getId() {
+ return tid;
+ }
+
+ /**
+ * A thread state. A thread can be in one of the following states:
+ * <ul>
+ * <li>{@link #NEW}<br>
+ * A thread that has not yet started is in this state.
+ * </li>
+ * <li>{@link #RUNNABLE}<br>
+ * A thread executing in the Java virtual machine is in this state.
+ * </li>
+ * <li>{@link #BLOCKED}<br>
+ * A thread that is blocked waiting for a monitor lock
+ * is in this state.
+ * </li>
+ * <li>{@link #WAITING}<br>
+ * A thread that is waiting indefinitely for another thread to
+ * perform a particular action is in this state.
+ * </li>
+ * <li>{@link #TIMED_WAITING}<br>
+ * A thread that is waiting for another thread to perform an action
+ * for up to a specified waiting time is in this state.
+ * </li>
+ * <li>{@link #TERMINATED}<br>
+ * A thread that has exited is in this state.
+ * </li>
+ * </ul>
+ *
+ * <p>
+ * A thread can be in only one state at a given point in time.
+ * These states are virtual machine states which do not reflect
+ * any operating system thread states.
+ *
+ * @since 1.5
+ * @see #getState
+ */
+ public enum State {
+ /**
+ * Thread state for a thread which has not yet started.
+ */
+ NEW,
+
+ /**
+ * Thread state for a runnable thread. A thread in the runnable
+ * state is executing in the Java virtual machine but it may
+ * be waiting for other resources from the operating system
+ * such as processor.
+ */
+ RUNNABLE,
+
+ /**
+ * Thread state for a thread blocked waiting for a monitor lock.
+ * A thread in the blocked state is waiting for a monitor lock
+ * to enter a synchronized block/method or
+ * reenter a synchronized block/method after calling
+ * {@link Object#wait() Object.wait}.
+ */
+ BLOCKED,
+
+ /**
+ * Thread state for a waiting thread.
+ * A thread is in the waiting state due to calling one of the
+ * following methods:
+ * <ul>
+ * <li>{@link Object#wait() Object.wait} with no timeout</li>
+ * <li>{@link #join() Thread.join} with no timeout</li>
+ * <li>{@link LockSupport#park() LockSupport.park}</li>
+ * </ul>
+ *
+ * <p>A thread in the waiting state is waiting for another thread to
+ * perform a particular action.
+ *
+ * For example, a thread that has called <tt>Object.wait()</tt>
+ * on an object is waiting for another thread to call
+ * <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on
+ * that object. A thread that has called <tt>Thread.join()</tt>
+ * is waiting for a specified thread to terminate.
+ */
+ WAITING,
+
+ /**
+ * Thread state for a waiting thread with a specified waiting time.
+ * A thread is in the timed waiting state due to calling one of
+ * the following methods with a specified positive waiting time:
+ * <ul>
+ * <li>{@link #sleep Thread.sleep}</li>
+ * <li>{@link Object#wait(long) Object.wait} with timeout</li>
+ * <li>{@link #join(long) Thread.join} with timeout</li>
+ * <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
+ * <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
+ * </ul>
+ */
+ TIMED_WAITING,
+
+ /**
+ * Thread state for a terminated thread.
+ * The thread has completed execution.
+ */
+ TERMINATED;
+ }
+
+ /**
+ * Returns the state of this thread.
+ * This method is designed for use in monitoring of the system state,
+ * not for synchronization control.
+ *
+ * @return this thread's state.
+ * @since 1.5
+ */
+ public State getState() {
+ // get current thread state
+ // Android-changed: Replace unused threadStatus field with started field.
+ // Use Android specific nativeGetStatus() method. See comment on started field for more
+ // information.
+ // return sun.misc.VM.toThreadState(threadStatus);
+ return State.values()[nativeGetStatus(started)];
+ }
+
+ // Added in JSR-166
+
+ /**
+ * Interface for handlers invoked when a <tt>Thread</tt> abruptly
+ * terminates due to an uncaught exception.
+ * <p>When a thread is about to terminate due to an uncaught exception
+ * the Java Virtual Machine will query the thread for its
+ * <tt>UncaughtExceptionHandler</tt> using
+ * {@link #getUncaughtExceptionHandler} and will invoke the handler's
+ * <tt>uncaughtException</tt> method, passing the thread and the
+ * exception as arguments.
+ * If a thread has not had its <tt>UncaughtExceptionHandler</tt>
+ * explicitly set, then its <tt>ThreadGroup</tt> object acts as its
+ * <tt>UncaughtExceptionHandler</tt>. If the <tt>ThreadGroup</tt> object
+ * has no
+ * special requirements for dealing with the exception, it can forward
+ * the invocation to the {@linkplain #getDefaultUncaughtExceptionHandler
+ * default uncaught exception handler}.
+ *
+ * @see #setDefaultUncaughtExceptionHandler
+ * @see #setUncaughtExceptionHandler
+ * @see ThreadGroup#uncaughtException
+ * @since 1.5
+ */
+ @FunctionalInterface
+ public interface UncaughtExceptionHandler {
+ /**
+ * Method invoked when the given thread terminates due to the
+ * given uncaught exception.
+ * <p>Any exception thrown by this method will be ignored by the
+ * Java Virtual Machine.
+ * @param t the thread
+ * @param e the exception
+ */
+ void uncaughtException(Thread t, Throwable e);
+ }
+
+ // null unless explicitly set
+ private volatile UncaughtExceptionHandler uncaughtExceptionHandler;
+
+ // null unless explicitly set
+ private static volatile UncaughtExceptionHandler defaultUncaughtExceptionHandler;
+
+ /**
+ * Set the default handler invoked when a thread abruptly terminates
+ * due to an uncaught exception, and no other handler has been defined
+ * for that thread.
+ *
+ * <p>Uncaught exception handling is controlled first by the thread, then
+ * by the thread's {@link ThreadGroup} object and finally by the default
+ * uncaught exception handler. If the thread does not have an explicit
+ * uncaught exception handler set, and the thread's thread group
+ * (including parent thread groups) does not specialize its
+ * <tt>uncaughtException</tt> method, then the default handler's
+ * <tt>uncaughtException</tt> method will be invoked.
+ * <p>By setting the default uncaught exception handler, an application
+ * can change the way in which uncaught exceptions are handled (such as
+ * logging to a specific device, or file) for those threads that would
+ * already accept whatever "default" behavior the system
+ * provided.
+ *
+ * <p>Note that the default uncaught exception handler should not usually
+ * defer to the thread's <tt>ThreadGroup</tt> object, as that could cause
+ * infinite recursion.
+ *
+ * @param eh the object to use as the default uncaught exception handler.
+ * If <tt>null</tt> then there is no default handler.
+ *
+ * @throws SecurityException if a security manager is present and it
+ * denies <tt>{@link RuntimePermission}
+ * ("setDefaultUncaughtExceptionHandler")</tt>
+ *
+ * @see #setUncaughtExceptionHandler
+ * @see #getUncaughtExceptionHandler
+ * @see ThreadGroup#uncaughtException
+ * @since 1.5
+ */
+ public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh) {
+ // Android-removed: SecurityManager stubbed out on Android
+ /*
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(
+ new RuntimePermission("setDefaultUncaughtExceptionHandler")
+ );
+ }
+ */
+
+ defaultUncaughtExceptionHandler = eh;
+ }
+
+ /**
+ * Returns the default handler invoked when a thread abruptly terminates
+ * due to an uncaught exception. If the returned value is <tt>null</tt>,
+ * there is no default.
+ * @since 1.5
+ * @see #setDefaultUncaughtExceptionHandler
+ * @return the default uncaught exception handler for all threads
+ */
+ public static UncaughtExceptionHandler getDefaultUncaughtExceptionHandler(){
+ return defaultUncaughtExceptionHandler;
+ }
+
+ // BEGIN Android-added: The concept of an uncaughtExceptionPreHandler for use by platform.
+ // See http://b/29624607 for background information.
+ // null unless explicitly set
+ private static volatile UncaughtExceptionHandler uncaughtExceptionPreHandler;
+
+ /**
+ * Sets an {@link UncaughtExceptionHandler} that will be called before any
+ * returned by {@link #getUncaughtExceptionHandler()}. To allow the standard
+ * handlers to run, this handler should never terminate this process. Any
+ * throwables thrown by the handler will be ignored by
+ * {@link #dispatchUncaughtException(Throwable)}.
+ *
+ * @hide used when configuring the runtime for exception logging; see
+ * {@link dalvik.system.RuntimeHooks} b/29624607
+ */
+ public static void setUncaughtExceptionPreHandler(UncaughtExceptionHandler eh) {
+ uncaughtExceptionPreHandler = eh;
+ }
+
+ /** @hide */
+ public static UncaughtExceptionHandler getUncaughtExceptionPreHandler() {
+ return uncaughtExceptionPreHandler;
+ }
+ // END Android-added: The concept of an uncaughtExceptionPreHandler for use by platform.
+
+ /**
+ * Returns the handler invoked when this thread abruptly terminates
+ * due to an uncaught exception. If this thread has not had an
+ * uncaught exception handler explicitly set then this thread's
+ * <tt>ThreadGroup</tt> object is returned, unless this thread
+ * has terminated, in which case <tt>null</tt> is returned.
+ * @since 1.5
+ * @return the uncaught exception handler for this thread
+ */
+ public UncaughtExceptionHandler getUncaughtExceptionHandler() {
+ return uncaughtExceptionHandler != null ?
+ uncaughtExceptionHandler : group;
+ }
+
+ /**
+ * Set the handler invoked when this thread abruptly terminates
+ * due to an uncaught exception.
+ * <p>A thread can take full control of how it responds to uncaught
+ * exceptions by having its uncaught exception handler explicitly set.
+ * If no such handler is set then the thread's <tt>ThreadGroup</tt>
+ * object acts as its handler.
+ * @param eh the object to use as this thread's uncaught exception
+ * handler. If <tt>null</tt> then this thread has no explicit handler.
+ * @throws SecurityException if the current thread is not allowed to
+ * modify this thread.
+ * @see #setDefaultUncaughtExceptionHandler
+ * @see ThreadGroup#uncaughtException
+ * @since 1.5
+ */
+ public void setUncaughtExceptionHandler(UncaughtExceptionHandler eh) {
+ checkAccess();
+ uncaughtExceptionHandler = eh;
+ }
+
+ /**
+ * Dispatch an uncaught exception to the handler. This method is
+ * intended to be called only by the runtime and by tests.
+ *
+ * @hide
+ */
+ // Android-changed: Make dispatchUncaughtException() public, for use by tests.
+ public final void dispatchUncaughtException(Throwable e) {
+ // BEGIN Android-added: uncaughtExceptionPreHandler for use by platform.
+ Thread.UncaughtExceptionHandler initialUeh =
+ Thread.getUncaughtExceptionPreHandler();
+ if (initialUeh != null) {
+ try {
+ initialUeh.uncaughtException(this, e);
+ } catch (RuntimeException | Error ignored) {
+ // Throwables thrown by the initial handler are ignored
+ }
+ }
+ // END Android-added: uncaughtExceptionPreHandler for use by platform.
+ getUncaughtExceptionHandler().uncaughtException(this, e);
+ }
+
+ // BEGIN Android-added: The concept of "system-daemon" threads. See java.lang.Daemons.
+ /**
+ * Marks this thread as either a special runtime-managed ("system daemon")
+ * thread or a normal (i.e. app code created) daemon thread.)
+ *
+ * <p>System daemon threads get special handling when starting up in some
+ * cases.
+ *
+ * <p>This method must be invoked before the thread is started.
+ *
+ * <p>This method must only be invoked on Thread instances that have already
+ * had {@code setDaemon(true)} called on them.
+ *
+ * <p>Package-private since only {@link java.lang.Daemons} needs to call
+ * this.
+ *
+ * @param on if {@code true}, marks this thread as a system daemon thread
+ *
+ * @throws IllegalThreadStateException
+ * if this thread is {@linkplain #isAlive alive} or not a
+ * {@linkplain #isDaemon daemon}
+ *
+ * @throws SecurityException
+ * if {@link #checkAccess} determines that the current
+ * thread cannot modify this thread
+ *
+ * @hide For use by Daemons.java only.
+ */
+ final void setSystemDaemon(boolean on) {
+ checkAccess();
+ if (isAlive() || !isDaemon()) {
+ throw new IllegalThreadStateException();
+ }
+ systemDaemon = on;
+ }
+ // END Android-added: The concept of "system-daemon" threads. See java.lang.Daemons.
+
+ /**
+ * Removes from the specified map any keys that have been enqueued
+ * on the specified reference queue.
+ */
+ static void processQueue(ReferenceQueue<Class<?>> queue,
+ ConcurrentMap<? extends
+ WeakReference<Class<?>>, ?> map)
+ {
+ Reference<? extends Class<?>> ref;
+ while((ref = queue.poll()) != null) {
+ map.remove(ref);
+ }
+ }
+
+ /**
+ * Weak key for Class objects.
+ **/
+ static class WeakClassKey extends WeakReference<Class<?>> {
+ /**
+ * saved value of the referent's identity hash code, to maintain
+ * a consistent hash code after the referent has been cleared
+ */
+ private final int hash;
+
+ /**
+ * Create a new WeakClassKey to the given object, registered
+ * with a queue.
+ */
+ WeakClassKey(Class<?> cl, ReferenceQueue<Class<?>> refQueue) {
+ super(cl, refQueue);
+ hash = System.identityHashCode(cl);
+ }
+
+ /**
+ * Returns the identity hash code of the original referent.
+ */
+ @Override
+ public int hashCode() {
+ return hash;
+ }
+
+ /**
+ * Returns true if the given object is this identical
+ * WeakClassKey instance, or, if this object's referent has not
+ * been cleared, if the given object is another WeakClassKey
+ * instance with the identical non-null referent as this one.
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this)
+ return true;
+
+ if (obj instanceof WeakClassKey) {
+ Object referent = get();
+ return (referent != null) &&
+ (referent == ((WeakClassKey) obj).get());
+ } else {
+ return false;
+ }
+ }
+ }
+
+
+ // The following three initially uninitialized fields are exclusively
+ // managed by class java.util.concurrent.ThreadLocalRandom. These
+ // fields are used to build the high-performance PRNGs in the
+ // concurrent code, and we can not risk accidental false sharing.
+ // Hence, the fields are isolated with @Contended.
+
+ // BEGIN Android-changed: @sun.misc.Contended is not supported on Android.
+ /** The current seed for a ThreadLocalRandom */
+ // @sun.misc.Contended("tlr")
+ long threadLocalRandomSeed;
+
+ /** Probe hash value; nonzero if threadLocalRandomSeed initialized */
+ // @sun.misc.Contended("tlr")
+ int threadLocalRandomProbe;
+
+ /** Secondary seed isolated from public ThreadLocalRandom sequence */
+ // @sun.misc.Contended("tlr")
+ int threadLocalRandomSecondarySeed;
+ // END Android-changed: @sun.misc.Contended is not supported on Android.
+
+ /* Some private helper methods */
+ private native void setPriority0(int newPriority);
+
+ // BEGIN Android-removed: Native methods that are unused on Android.
+ /*
+ private native void stop0(Object o);
+ private native void suspend0();
+ private native void resume0();
+ */
+ // END Android-removed: Native methods that are unused on Android.
+
+ @FastNative
+ private native void interrupt0();
+ private native void setNativeName(String name);
+
+ // Android-added: Android specific nativeGetStatus() method.
+ private native int nativeGetStatus(boolean hasBeenStarted);
+
+ // BEGIN Android-added: Customize behavior of Thread.setPriority(). http://b/139521784
+ /**
+ * Returns the thread ID of the underlying native thread -- which is different from
+ * the {@link #getId() managed thread ID} -- or 0 if the native thread is not
+ * started or has stopped.
+ */
+ @FastNative
+ private native int getNativeTid();
+ // END Android-added: Customize behavior of Thread.setPriority(). http://b/139521784
+}
diff --git a/java/lang/ThreadDeath.java b/java/lang/ThreadDeath.java
new file mode 100644
index 0000000..79e8bb5
--- /dev/null
+++ b/java/lang/ThreadDeath.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 1995, 2008, 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;
+
+/**
+ * An instance of {@code ThreadDeath} is thrown in the victim thread
+ * when the (deprecated) {@link Thread#stop()} method is invoked.
+ *
+ * <p>An application should catch instances of this class only if it
+ * must clean up after being terminated asynchronously. If
+ * {@code ThreadDeath} is caught by a method, it is important that it
+ * be rethrown so that the thread actually dies.
+ *
+ * <p>The {@linkplain ThreadGroup#uncaughtException top-level error
+ * handler} does not print out a message if {@code ThreadDeath} is
+ * never caught.
+ *
+ * <p>The class {@code ThreadDeath} is specifically a subclass of
+ * {@code Error} rather than {@code Exception}, even though it is a
+ * "normal occurrence", because many applications catch all
+ * occurrences of {@code Exception} and then discard the exception.
+ *
+ * @since JDK1.0
+ */
+
+public class ThreadDeath extends Error {
+ private static final long serialVersionUID = -4417128565033088268L;
+}
diff --git a/java/lang/ThreadGroup.java b/java/lang/ThreadGroup.java
new file mode 100644
index 0000000..292b536
--- /dev/null
+++ b/java/lang/ThreadGroup.java
@@ -0,0 +1,1110 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1995, 2012, 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;
+
+import java.io.PrintStream;
+import java.util.Arrays;
+import sun.misc.VM;
+
+/**
+ * A thread group represents a set of threads. In addition, a thread
+ * group can also include other thread groups. The thread groups form
+ * a tree in which every thread group except the initial thread group
+ * has a parent.
+ * <p>
+ * A thread is allowed to access information about its own thread
+ * group, but not to access information about its thread group's
+ * parent thread group or any other thread groups.
+ *
+ * @author unascribed
+ * @since JDK1.0
+ */
+/* The locking strategy for this code is to try to lock only one level of the
+ * tree wherever possible, but otherwise to lock from the bottom up.
+ * That is, from child thread groups to parents.
+ * This has the advantage of limiting the number of locks that need to be held
+ * and in particular avoids having to grab the lock for the root thread group,
+ * (or a global lock) which would be a source of contention on a
+ * multi-processor system with many thread groups.
+ * This policy often leads to taking a snapshot of the state of a thread group
+ * and working off of that snapshot, rather than holding the thread group locked
+ * while we work on the children.
+ */
+public
+class ThreadGroup implements Thread.UncaughtExceptionHandler {
+ /* the runtime uses these directly; do not rename */
+ static final ThreadGroup systemThreadGroup = new ThreadGroup();
+
+ static final ThreadGroup mainThreadGroup = new ThreadGroup(systemThreadGroup, "main");
+
+ private final ThreadGroup parent;
+ String name;
+ int maxPriority;
+ boolean destroyed;
+ boolean daemon;
+ boolean vmAllowSuspension;
+
+ int nUnstartedThreads = 0;
+ int nthreads;
+ Thread threads[];
+
+ int ngroups;
+ ThreadGroup groups[];
+
+ /**
+ * Creates an empty Thread group that is not in any Thread group.
+ * This method is used to create the system Thread group.
+ */
+ private ThreadGroup() { // called from C code
+ this.name = "system";
+ this.maxPriority = Thread.MAX_PRIORITY;
+ this.parent = null;
+ }
+
+ /**
+ * Constructs a new thread group. The parent of this new group is
+ * the thread group of the currently running thread.
+ * <p>
+ * The <code>checkAccess</code> method of the parent thread group is
+ * called with no arguments; this may result in a security exception.
+ *
+ * @param name the name of the new thread group.
+ * @exception SecurityException if the current thread cannot create a
+ * thread in the specified thread group.
+ * @see java.lang.ThreadGroup#checkAccess()
+ * @since JDK1.0
+ */
+ public ThreadGroup(String name) {
+ this(Thread.currentThread().getThreadGroup(), name);
+ }
+
+ /**
+ * Creates a new thread group. The parent of this new group is the
+ * specified thread group.
+ * <p>
+ * The <code>checkAccess</code> method of the parent thread group is
+ * called with no arguments; this may result in a security exception.
+ *
+ * @param parent the parent thread group.
+ * @param name the name of the new thread group.
+ * @exception NullPointerException if the thread group argument is
+ * <code>null</code>.
+ * @exception SecurityException if the current thread cannot create a
+ * thread in the specified thread group.
+ * @see java.lang.SecurityException
+ * @see java.lang.ThreadGroup#checkAccess()
+ * @since JDK1.0
+ */
+ public ThreadGroup(ThreadGroup parent, String name) {
+ this(checkParentAccess(parent), parent, name);
+ }
+
+ private ThreadGroup(Void unused, ThreadGroup parent, String name) {
+ this.name = name;
+ this.maxPriority = parent.maxPriority;
+ this.daemon = parent.daemon;
+ this.vmAllowSuspension = parent.vmAllowSuspension;
+ this.parent = parent;
+ parent.add(this);
+ }
+
+ /*
+ * @throws NullPointerException if the parent argument is {@code null}
+ * @throws SecurityException if the current thread cannot create a
+ * thread in the specified thread group.
+ */
+ private static Void checkParentAccess(ThreadGroup parent) {
+ parent.checkAccess();
+ return null;
+ }
+
+ /**
+ * Returns the name of this thread group.
+ *
+ * @return the name of this thread group.
+ * @since JDK1.0
+ */
+ public final String getName() {
+ return name;
+ }
+
+ /**
+ * Returns the parent of this thread group.
+ * <p>
+ * First, if the parent is not <code>null</code>, the
+ * <code>checkAccess</code> method of the parent thread group is
+ * called with no arguments; this may result in a security exception.
+ *
+ * @return the parent of this thread group. The top-level thread group
+ * is the only thread group whose parent is <code>null</code>.
+ * @exception SecurityException if the current thread cannot modify
+ * this thread group.
+ * @see java.lang.ThreadGroup#checkAccess()
+ * @see java.lang.SecurityException
+ * @see java.lang.RuntimePermission
+ * @since JDK1.0
+ */
+ public final ThreadGroup getParent() {
+ if (parent != null)
+ parent.checkAccess();
+ return parent;
+ }
+
+ /**
+ * Returns the maximum priority of this thread group. Threads that are
+ * part of this group cannot have a higher priority than the maximum
+ * priority.
+ *
+ * @return the maximum priority that a thread in this thread group
+ * can have.
+ * @see #setMaxPriority
+ * @since JDK1.0
+ */
+ public final int getMaxPriority() {
+ return maxPriority;
+ }
+
+ /**
+ * Tests if this thread group is a daemon thread group. A
+ * daemon thread group is automatically destroyed when its last
+ * thread is stopped or its last thread group is destroyed.
+ *
+ * @return <code>true</code> if this thread group is a daemon thread group;
+ * <code>false</code> otherwise.
+ * @since JDK1.0
+ */
+ public final boolean isDaemon() {
+ return daemon;
+ }
+
+ /**
+ * Tests if this thread group has been destroyed.
+ *
+ * @return true if this object is destroyed
+ * @since JDK1.1
+ */
+ public synchronized boolean isDestroyed() {
+ return destroyed;
+ }
+
+ /**
+ * Changes the daemon status of this thread group.
+ * <p>
+ * First, the <code>checkAccess</code> method of this thread group is
+ * called with no arguments; this may result in a security exception.
+ * <p>
+ * A daemon thread group is automatically destroyed when its last
+ * thread is stopped or its last thread group is destroyed.
+ *
+ * @param daemon if <code>true</code>, marks this thread group as
+ * a daemon thread group; otherwise, marks this
+ * thread group as normal.
+ * @exception SecurityException if the current thread cannot modify
+ * this thread group.
+ * @see java.lang.SecurityException
+ * @see java.lang.ThreadGroup#checkAccess()
+ * @since JDK1.0
+ */
+ public final void setDaemon(boolean daemon) {
+ checkAccess();
+ this.daemon = daemon;
+ }
+
+ /**
+ * Sets the maximum priority of the group. Threads in the thread
+ * group that already have a higher priority are not affected.
+ * <p>
+ * First, the <code>checkAccess</code> method of this thread group is
+ * called with no arguments; this may result in a security exception.
+ * <p>
+ * If the <code>pri</code> argument is less than
+ * {@link Thread#MIN_PRIORITY} or greater than
+ * {@link Thread#MAX_PRIORITY}, it is clamped to those values.
+ * <p>
+ * Otherwise, the priority of this ThreadGroup object is set to the
+ * smaller of the specified <code>pri</code> and the maximum permitted
+ * priority of the parent of this thread group. (If this thread group
+ * is the system thread group, which has no parent, then its maximum
+ * priority is simply set to <code>pri</code>.) Then this method is
+ * called recursively, with <code>pri</code> as its argument, for
+ * every thread group that belongs to this thread group.
+ *
+ * @param pri the new priority of the thread group.
+ * @exception SecurityException if the current thread cannot modify
+ * this thread group.
+ * @see #getMaxPriority
+ * @see java.lang.SecurityException
+ * @see java.lang.ThreadGroup#checkAccess()
+ * @since JDK1.0
+ */
+ public final void setMaxPriority(int pri) {
+ int ngroupsSnapshot;
+ ThreadGroup[] groupsSnapshot;
+ synchronized (this) {
+ checkAccess();
+ // BEGIN Android-changed: Clamp to the range [MIN_PRIORITY, MAX_PRIORITY].
+ // This preserves backward compatibility with previous versions of Android.
+ // if (pri < Thread.MIN_PRIORITY || pri > Thread.MAX_PRIORITY) {
+ // return;
+ // }
+ if (pri < Thread.MIN_PRIORITY) {
+ pri = Thread.MIN_PRIORITY;
+ }
+ if (pri > Thread.MAX_PRIORITY) {
+ pri = Thread.MAX_PRIORITY;
+ }
+ // END Android-changed: Clamp to the range [MIN_PRIORITY, MAX_PRIORITY].
+
+ maxPriority = (parent != null) ? Math.min(pri, parent.maxPriority) : pri;
+ ngroupsSnapshot = ngroups;
+ if (groups != null) {
+ groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot);
+ } else {
+ groupsSnapshot = null;
+ }
+ }
+ for (int i = 0 ; i < ngroupsSnapshot ; i++) {
+ groupsSnapshot[i].setMaxPriority(pri);
+ }
+ }
+
+ /**
+ * Tests if this thread group is either the thread group
+ * argument or one of its ancestor thread groups.
+ *
+ * @param g a thread group.
+ * @return <code>true</code> if this thread group is the thread group
+ * argument or one of its ancestor thread groups;
+ * <code>false</code> otherwise.
+ * @since JDK1.0
+ */
+ public final boolean parentOf(ThreadGroup g) {
+ for (; g != null ; g = g.parent) {
+ if (g == this) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Determines if the currently running thread has permission to
+ * modify this thread group.
+ * <p>
+ * If there is a security manager, its <code>checkAccess</code> method
+ * is called with this thread group as its argument. This may result
+ * in throwing a <code>SecurityException</code>.
+ *
+ * @exception SecurityException if the current thread is not allowed to
+ * access this thread group.
+ * @see java.lang.SecurityManager#checkAccess(java.lang.ThreadGroup)
+ * @since JDK1.0
+ */
+ public final void checkAccess() {
+ // Android-removed: SecurityManager stubbed out on Android.
+ // SecurityManager security = System.getSecurityManager();
+ // if (security != null) {
+ // security.checkAccess(this);
+ // }
+ }
+
+ /**
+ * Returns an estimate of the number of active threads in this thread
+ * group and its subgroups. Recursively iterates over all subgroups in
+ * this thread group.
+ *
+ * <p> The value returned is only an estimate because the number of
+ * threads may change dynamically while this method traverses internal
+ * data structures, and might be affected by the presence of certain
+ * system threads. This method is intended primarily for debugging
+ * and monitoring purposes.
+ *
+ * @return an estimate of the number of active threads in this thread
+ * group and in any other thread group that has this thread
+ * group as an ancestor
+ *
+ * @since JDK1.0
+ */
+ public int activeCount() {
+ int result;
+ // Snapshot sub-group data so we don't hold this lock
+ // while our children are computing.
+ int ngroupsSnapshot;
+ ThreadGroup[] groupsSnapshot;
+ synchronized (this) {
+ if (destroyed) {
+ return 0;
+ }
+ result = nthreads;
+ ngroupsSnapshot = ngroups;
+ if (groups != null) {
+ groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot);
+ } else {
+ groupsSnapshot = null;
+ }
+ }
+ for (int i = 0 ; i < ngroupsSnapshot ; i++) {
+ result += groupsSnapshot[i].activeCount();
+ }
+ return result;
+ }
+
+ /**
+ * Copies into the specified array every active thread in this
+ * thread group and its subgroups.
+ *
+ * <p> An invocation of this method behaves in exactly the same
+ * way as the invocation
+ *
+ * <blockquote>
+ * {@linkplain #enumerate(Thread[], boolean) enumerate}{@code (list, true)}
+ * </blockquote>
+ *
+ * @param list
+ * an array into which to put the list of threads
+ *
+ * @return the number of threads put into the array
+ *
+ * @throws SecurityException
+ * if {@linkplain #checkAccess checkAccess} determines that
+ * the current thread cannot access this thread group
+ *
+ * @since JDK1.0
+ */
+ public int enumerate(Thread list[]) {
+ checkAccess();
+ return enumerate(list, 0, true);
+ }
+
+ /**
+ * Copies into the specified array every active thread in this
+ * thread group. If {@code recurse} is {@code true},
+ * this method recursively enumerates all subgroups of this
+ * thread group and references to every active thread in these
+ * subgroups are also included. If the array is too short to
+ * hold all the threads, the extra threads are silently ignored.
+ *
+ * <p> An application might use the {@linkplain #activeCount activeCount}
+ * method to get an estimate of how big the array should be, however
+ * <i>if the array is too short to hold all the threads, the extra threads
+ * are silently ignored.</i> If it is critical to obtain every active
+ * thread in this thread group, the caller should verify that the returned
+ * int value is strictly less than the length of {@code list}.
+ *
+ * <p> Due to the inherent race condition in this method, it is recommended
+ * that the method only be used for debugging and monitoring purposes.
+ *
+ * @param list
+ * an array into which to put the list of threads
+ *
+ * @param recurse
+ * if {@code true}, recursively enumerate all subgroups of this
+ * thread group
+ *
+ * @return the number of threads put into the array
+ *
+ * @throws SecurityException
+ * if {@linkplain #checkAccess checkAccess} determines that
+ * the current thread cannot access this thread group
+ *
+ * @since JDK1.0
+ */
+ public int enumerate(Thread list[], boolean recurse) {
+ checkAccess();
+ return enumerate(list, 0, recurse);
+ }
+
+ private int enumerate(Thread list[], int n, boolean recurse) {
+ int ngroupsSnapshot = 0;
+ ThreadGroup[] groupsSnapshot = null;
+ synchronized (this) {
+ if (destroyed) {
+ return 0;
+ }
+ int nt = nthreads;
+ if (nt > list.length - n) {
+ nt = list.length - n;
+ }
+ for (int i = 0; i < nt; i++) {
+ if (threads[i].isAlive()) {
+ list[n++] = threads[i];
+ }
+ }
+ if (recurse) {
+ ngroupsSnapshot = ngroups;
+ if (groups != null) {
+ groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot);
+ } else {
+ groupsSnapshot = null;
+ }
+ }
+ }
+ if (recurse) {
+ for (int i = 0 ; i < ngroupsSnapshot ; i++) {
+ n = groupsSnapshot[i].enumerate(list, n, true);
+ }
+ }
+ return n;
+ }
+
+ /**
+ * Returns an estimate of the number of active groups in this
+ * thread group and its subgroups. Recursively iterates over
+ * all subgroups in this thread group.
+ *
+ * <p> The value returned is only an estimate because the number of
+ * thread groups may change dynamically while this method traverses
+ * internal data structures. This method is intended primarily for
+ * debugging and monitoring purposes.
+ *
+ * @return the number of active thread groups with this thread group as
+ * an ancestor
+ *
+ * @since JDK1.0
+ */
+ public int activeGroupCount() {
+ int ngroupsSnapshot;
+ ThreadGroup[] groupsSnapshot;
+ synchronized (this) {
+ if (destroyed) {
+ return 0;
+ }
+ ngroupsSnapshot = ngroups;
+ if (groups != null) {
+ groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot);
+ } else {
+ groupsSnapshot = null;
+ }
+ }
+ int n = ngroupsSnapshot;
+ for (int i = 0 ; i < ngroupsSnapshot ; i++) {
+ n += groupsSnapshot[i].activeGroupCount();
+ }
+ return n;
+ }
+
+ /**
+ * Copies into the specified array references to every active
+ * subgroup in this thread group and its subgroups.
+ *
+ * <p> An invocation of this method behaves in exactly the same
+ * way as the invocation
+ *
+ * <blockquote>
+ * {@linkplain #enumerate(ThreadGroup[], boolean) enumerate}{@code (list, true)}
+ * </blockquote>
+ *
+ * @param list
+ * an array into which to put the list of thread groups
+ *
+ * @return the number of thread groups put into the array
+ *
+ * @throws SecurityException
+ * if {@linkplain #checkAccess checkAccess} determines that
+ * the current thread cannot access this thread group
+ *
+ * @since JDK1.0
+ */
+ public int enumerate(ThreadGroup list[]) {
+ checkAccess();
+ return enumerate(list, 0, true);
+ }
+
+ /**
+ * Copies into the specified array references to every active
+ * subgroup in this thread group. If {@code recurse} is
+ * {@code true}, this method recursively enumerates all subgroups of this
+ * thread group and references to every active thread group in these
+ * subgroups are also included.
+ *
+ * <p> An application might use the
+ * {@linkplain #activeGroupCount activeGroupCount} method to
+ * get an estimate of how big the array should be, however <i>if the
+ * array is too short to hold all the thread groups, the extra thread
+ * groups are silently ignored.</i> If it is critical to obtain every
+ * active subgroup in this thread group, the caller should verify that
+ * the returned int value is strictly less than the length of
+ * {@code list}.
+ *
+ * <p> Due to the inherent race condition in this method, it is recommended
+ * that the method only be used for debugging and monitoring purposes.
+ *
+ * @param list
+ * an array into which to put the list of thread groups
+ *
+ * @param recurse
+ * if {@code true}, recursively enumerate all subgroups
+ *
+ * @return the number of thread groups put into the array
+ *
+ * @throws SecurityException
+ * if {@linkplain #checkAccess checkAccess} determines that
+ * the current thread cannot access this thread group
+ *
+ * @since JDK1.0
+ */
+ public int enumerate(ThreadGroup list[], boolean recurse) {
+ checkAccess();
+ return enumerate(list, 0, recurse);
+ }
+
+ private int enumerate(ThreadGroup list[], int n, boolean recurse) {
+ int ngroupsSnapshot = 0;
+ ThreadGroup[] groupsSnapshot = null;
+ synchronized (this) {
+ if (destroyed) {
+ return 0;
+ }
+ int ng = ngroups;
+ if (ng > list.length - n) {
+ ng = list.length - n;
+ }
+ if (ng > 0) {
+ System.arraycopy(groups, 0, list, n, ng);
+ n += ng;
+ }
+ if (recurse) {
+ ngroupsSnapshot = ngroups;
+ if (groups != null) {
+ groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot);
+ } else {
+ groupsSnapshot = null;
+ }
+ }
+ }
+ if (recurse) {
+ for (int i = 0 ; i < ngroupsSnapshot ; i++) {
+ n = groupsSnapshot[i].enumerate(list, n, true);
+ }
+ }
+ return n;
+ }
+
+ /**
+ * Stops all threads in this thread group.
+ * <p>
+ * First, the <code>checkAccess</code> method of this thread group is
+ * called with no arguments; this may result in a security exception.
+ * <p>
+ * This method then calls the <code>stop</code> method on all the
+ * threads in this thread group and in all of its subgroups.
+ *
+ * @exception SecurityException if the current thread is not allowed
+ * to access this thread group or any of the threads in
+ * the thread group.
+ * @see java.lang.SecurityException
+ * @see java.lang.Thread#stop()
+ * @see java.lang.ThreadGroup#checkAccess()
+ * @since JDK1.0
+ * @deprecated This method is inherently unsafe. See
+ * {@link Thread#stop} for details.
+ */
+ @Deprecated
+ public final void stop() {
+ if (stopOrSuspend(false))
+ Thread.currentThread().stop();
+ }
+
+ /**
+ * Interrupts all threads in this thread group.
+ * <p>
+ * First, the <code>checkAccess</code> method of this thread group is
+ * called with no arguments; this may result in a security exception.
+ * <p>
+ * This method then calls the <code>interrupt</code> method on all the
+ * threads in this thread group and in all of its subgroups.
+ *
+ * @exception SecurityException if the current thread is not allowed
+ * to access this thread group or any of the threads in
+ * the thread group.
+ * @see java.lang.Thread#interrupt()
+ * @see java.lang.SecurityException
+ * @see java.lang.ThreadGroup#checkAccess()
+ * @since 1.2
+ */
+ public final void interrupt() {
+ int ngroupsSnapshot;
+ ThreadGroup[] groupsSnapshot;
+ synchronized (this) {
+ checkAccess();
+ for (int i = 0 ; i < nthreads ; i++) {
+ threads[i].interrupt();
+ }
+ ngroupsSnapshot = ngroups;
+ if (groups != null) {
+ groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot);
+ } else {
+ groupsSnapshot = null;
+ }
+ }
+ for (int i = 0 ; i < ngroupsSnapshot ; i++) {
+ groupsSnapshot[i].interrupt();
+ }
+ }
+
+ /**
+ * Suspends all threads in this thread group.
+ * <p>
+ * First, the <code>checkAccess</code> method of this thread group is
+ * called with no arguments; this may result in a security exception.
+ * <p>
+ * This method then calls the <code>suspend</code> method on all the
+ * threads in this thread group and in all of its subgroups.
+ *
+ * @exception SecurityException if the current thread is not allowed
+ * to access this thread group or any of the threads in
+ * the thread group.
+ * @see java.lang.Thread#suspend()
+ * @see java.lang.SecurityException
+ * @see java.lang.ThreadGroup#checkAccess()
+ * @since JDK1.0
+ * @deprecated This method is inherently deadlock-prone. See
+ * {@link Thread#suspend} for details.
+ */
+ @Deprecated
+ @SuppressWarnings("deprecation")
+ public final void suspend() {
+ if (stopOrSuspend(true))
+ Thread.currentThread().suspend();
+ }
+
+ /**
+ * Helper method: recursively stops or suspends (as directed by the
+ * boolean argument) all of the threads in this thread group and its
+ * subgroups, except the current thread. This method returns true
+ * if (and only if) the current thread is found to be in this thread
+ * group or one of its subgroups.
+ */
+ @SuppressWarnings("deprecation")
+ private boolean stopOrSuspend(boolean suspend) {
+ boolean suicide = false;
+ Thread us = Thread.currentThread();
+ int ngroupsSnapshot;
+ ThreadGroup[] groupsSnapshot = null;
+ synchronized (this) {
+ checkAccess();
+ for (int i = 0 ; i < nthreads ; i++) {
+ if (threads[i]==us)
+ suicide = true;
+ else if (suspend)
+ threads[i].suspend();
+ else
+ threads[i].stop();
+ }
+
+ ngroupsSnapshot = ngroups;
+ if (groups != null) {
+ groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot);
+ }
+ }
+ for (int i = 0 ; i < ngroupsSnapshot ; i++)
+ suicide = groupsSnapshot[i].stopOrSuspend(suspend) || suicide;
+
+ return suicide;
+ }
+
+ /**
+ * Resumes all threads in this thread group.
+ * <p>
+ * First, the <code>checkAccess</code> method of this thread group is
+ * called with no arguments; this may result in a security exception.
+ * <p>
+ * This method then calls the <code>resume</code> method on all the
+ * threads in this thread group and in all of its sub groups.
+ *
+ * @exception SecurityException if the current thread is not allowed to
+ * access this thread group or any of the threads in the
+ * thread group.
+ * @see java.lang.SecurityException
+ * @see java.lang.Thread#resume()
+ * @see java.lang.ThreadGroup#checkAccess()
+ * @since JDK1.0
+ * @deprecated This method is used solely in conjunction with
+ * <tt>Thread.suspend</tt> and <tt>ThreadGroup.suspend</tt>,
+ * both of which have been deprecated, as they are inherently
+ * deadlock-prone. See {@link Thread#suspend} for details.
+ */
+ @Deprecated
+ @SuppressWarnings("deprecation")
+ public final void resume() {
+ int ngroupsSnapshot;
+ ThreadGroup[] groupsSnapshot;
+ synchronized (this) {
+ checkAccess();
+ for (int i = 0 ; i < nthreads ; i++) {
+ threads[i].resume();
+ }
+ ngroupsSnapshot = ngroups;
+ if (groups != null) {
+ groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot);
+ } else {
+ groupsSnapshot = null;
+ }
+ }
+ for (int i = 0 ; i < ngroupsSnapshot ; i++) {
+ groupsSnapshot[i].resume();
+ }
+ }
+
+ /**
+ * Destroys this thread group and all of its subgroups. This thread
+ * group must be empty, indicating that all threads that had been in
+ * this thread group have since stopped.
+ * <p>
+ * First, the <code>checkAccess</code> method of this thread group is
+ * called with no arguments; this may result in a security exception.
+ *
+ * @exception IllegalThreadStateException if the thread group is not
+ * empty or if the thread group has already been destroyed.
+ * @exception SecurityException if the current thread cannot modify this
+ * thread group.
+ * @see java.lang.ThreadGroup#checkAccess()
+ * @since JDK1.0
+ */
+ public final void destroy() {
+ int ngroupsSnapshot;
+ ThreadGroup[] groupsSnapshot;
+ synchronized (this) {
+ checkAccess();
+ if (destroyed || (nthreads > 0)) {
+ throw new IllegalThreadStateException();
+ }
+ ngroupsSnapshot = ngroups;
+ if (groups != null) {
+ groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot);
+ } else {
+ groupsSnapshot = null;
+ }
+ if (parent != null) {
+ destroyed = true;
+ ngroups = 0;
+ groups = null;
+ nthreads = 0;
+ threads = null;
+ }
+ }
+ for (int i = 0 ; i < ngroupsSnapshot ; i += 1) {
+ groupsSnapshot[i].destroy();
+ }
+ if (parent != null) {
+ parent.remove(this);
+ }
+ }
+
+ /**
+ * Adds the specified Thread group to this group.
+ * @param g the specified Thread group to be added
+ * @exception IllegalThreadStateException If the Thread group has been destroyed.
+ */
+ private final void add(ThreadGroup g){
+ synchronized (this) {
+ if (destroyed) {
+ throw new IllegalThreadStateException();
+ }
+ if (groups == null) {
+ groups = new ThreadGroup[4];
+ } else if (ngroups == groups.length) {
+ groups = Arrays.copyOf(groups, ngroups * 2);
+ }
+ groups[ngroups] = g;
+
+ // This is done last so it doesn't matter in case the
+ // thread is killed
+ ngroups++;
+ }
+ }
+
+ /**
+ * Removes the specified Thread group from this group.
+ * @param g the Thread group to be removed
+ * @return if this Thread has already been destroyed.
+ */
+ private void remove(ThreadGroup g) {
+ synchronized (this) {
+ if (destroyed) {
+ return;
+ }
+ for (int i = 0 ; i < ngroups ; i++) {
+ if (groups[i] == g) {
+ ngroups -= 1;
+ System.arraycopy(groups, i + 1, groups, i, ngroups - i);
+ // Zap dangling reference to the dead group so that
+ // the garbage collector will collect it.
+ groups[ngroups] = null;
+ break;
+ }
+ }
+ if (nthreads == 0) {
+ notifyAll();
+ }
+ if (daemon && (nthreads == 0) &&
+ (nUnstartedThreads == 0) && (ngroups == 0))
+ {
+ destroy();
+ }
+ }
+ }
+
+
+ /**
+ * Increments the count of unstarted threads in the thread group.
+ * Unstarted threads are not added to the thread group so that they
+ * can be collected if they are never started, but they must be
+ * counted so that daemon thread groups with unstarted threads in
+ * them are not destroyed.
+ */
+ void addUnstarted() {
+ synchronized(this) {
+ if (destroyed) {
+ throw new IllegalThreadStateException();
+ }
+ nUnstartedThreads++;
+ }
+ }
+
+ /**
+ * Adds the specified thread to this thread group.
+ *
+ * <p> Note: This method is called from both library code
+ * and the Virtual Machine. It is called from VM to add
+ * certain system threads to the system thread group.
+ *
+ * @param t
+ * the Thread to be added
+ *
+ * @throws IllegalThreadStateException
+ * if the Thread group has been destroyed
+ */
+ void add(Thread t) {
+ synchronized (this) {
+ if (destroyed) {
+ throw new IllegalThreadStateException();
+ }
+ if (threads == null) {
+ threads = new Thread[4];
+ } else if (nthreads == threads.length) {
+ threads = Arrays.copyOf(threads, nthreads * 2);
+ }
+ threads[nthreads] = t;
+
+ // This is done last so it doesn't matter in case the
+ // thread is killed
+ nthreads++;
+
+ // The thread is now a fully fledged member of the group, even
+ // though it may, or may not, have been started yet. It will prevent
+ // the group from being destroyed so the unstarted Threads count is
+ // decremented.
+ nUnstartedThreads--;
+ }
+ }
+
+ /**
+ * Notifies the group that the thread {@code t} has failed
+ * an attempt to start.
+ *
+ * <p> The state of this thread group is rolled back as if the
+ * attempt to start the thread has never occurred. The thread is again
+ * considered an unstarted member of the thread group, and a subsequent
+ * attempt to start the thread is permitted.
+ *
+ * @param t
+ * the Thread whose start method was invoked
+ */
+ void threadStartFailed(Thread t) {
+ synchronized(this) {
+ remove(t);
+ nUnstartedThreads++;
+ }
+ }
+
+ /**
+ * Notifies the group that the thread {@code t} has terminated.
+ *
+ * <p> Destroy the group if all of the following conditions are
+ * true: this is a daemon thread group; there are no more alive
+ * or unstarted threads in the group; there are no subgroups in
+ * this thread group.
+ *
+ * @param t
+ * the Thread that has terminated
+ */
+ void threadTerminated(Thread t) {
+ synchronized (this) {
+ remove(t);
+
+ if (nthreads == 0) {
+ notifyAll();
+ }
+ if (daemon && (nthreads == 0) &&
+ (nUnstartedThreads == 0) && (ngroups == 0))
+ {
+ destroy();
+ }
+ }
+ }
+
+ /**
+ * Removes the specified Thread from this group. Invoking this method
+ * on a thread group that has been destroyed has no effect.
+ *
+ * @param t
+ * the Thread to be removed
+ */
+ private void remove(Thread t) {
+ synchronized (this) {
+ if (destroyed) {
+ return;
+ }
+ for (int i = 0 ; i < nthreads ; i++) {
+ if (threads[i] == t) {
+ System.arraycopy(threads, i + 1, threads, i, --nthreads - i);
+ // Zap dangling reference to the dead thread so that
+ // the garbage collector will collect it.
+ threads[nthreads] = null;
+ break;
+ }
+ }
+ }
+ }
+
+ /**
+ * Prints information about this thread group to the standard
+ * output. This method is useful only for debugging.
+ *
+ * @since JDK1.0
+ */
+ public void list() {
+ list(System.out, 0);
+ }
+ void list(PrintStream out, int indent) {
+ int ngroupsSnapshot;
+ ThreadGroup[] groupsSnapshot;
+ synchronized (this) {
+ for (int j = 0 ; j < indent ; j++) {
+ out.print(" ");
+ }
+ out.println(this);
+ indent += 4;
+ for (int i = 0 ; i < nthreads ; i++) {
+ for (int j = 0 ; j < indent ; j++) {
+ out.print(" ");
+ }
+ out.println(threads[i]);
+ }
+ ngroupsSnapshot = ngroups;
+ if (groups != null) {
+ groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot);
+ } else {
+ groupsSnapshot = null;
+ }
+ }
+ for (int i = 0 ; i < ngroupsSnapshot ; i++) {
+ groupsSnapshot[i].list(out, indent);
+ }
+ }
+
+ /**
+ * Called by the Java Virtual Machine when a thread in this
+ * thread group stops because of an uncaught exception, and the thread
+ * does not have a specific {@link Thread.UncaughtExceptionHandler}
+ * installed.
+ * <p>
+ * The <code>uncaughtException</code> method of
+ * <code>ThreadGroup</code> does the following:
+ * <ul>
+ * <li>If this thread group has a parent thread group, the
+ * <code>uncaughtException</code> method of that parent is called
+ * with the same two arguments.
+ * <li>Otherwise, this method checks to see if there is a
+ * {@linkplain Thread#getDefaultUncaughtExceptionHandler default
+ * uncaught exception handler} installed, and if so, its
+ * <code>uncaughtException</code> method is called with the same
+ * two arguments.
+ * <li>Otherwise, this method determines if the <code>Throwable</code>
+ * argument is an instance of {@link ThreadDeath}. If so, nothing
+ * special is done. Otherwise, a message containing the
+ * thread's name, as returned from the thread's {@link
+ * Thread#getName getName} method, and a stack backtrace,
+ * using the <code>Throwable</code>'s {@link
+ * Throwable#printStackTrace printStackTrace} method, is
+ * printed to the {@linkplain System#err standard error stream}.
+ * </ul>
+ * <p>
+ * Applications can override this method in subclasses of
+ * <code>ThreadGroup</code> to provide alternative handling of
+ * uncaught exceptions.
+ *
+ * @param t the thread that is about to exit.
+ * @param e the uncaught exception.
+ * @since JDK1.0
+ */
+ public void uncaughtException(Thread t, Throwable e) {
+ if (parent != null) {
+ parent.uncaughtException(t, e);
+ } else {
+ Thread.UncaughtExceptionHandler ueh =
+ Thread.getDefaultUncaughtExceptionHandler();
+ if (ueh != null) {
+ ueh.uncaughtException(t, e);
+ } else if (!(e instanceof ThreadDeath)) {
+ System.err.print("Exception in thread \""
+ + t.getName() + "\" ");
+ e.printStackTrace(System.err);
+ }
+ }
+ }
+
+ /**
+ * Used by VM to control lowmem implicit suspension.
+ *
+ * @param b boolean to allow or disallow suspension
+ * @return true on success
+ * @since JDK1.1
+ * @deprecated The definition of this call depends on {@link #suspend},
+ * which is deprecated. Further, the behavior of this call
+ * was never specified.
+ */
+ @Deprecated
+ public boolean allowThreadSuspension(boolean b) {
+ this.vmAllowSuspension = b;
+ if (!b) {
+ VM.unsuspendSomeThreads();
+ }
+ return true;
+ }
+
+ /**
+ * Returns a string representation of this Thread group.
+ *
+ * @return a string representation of this thread group.
+ * @since JDK1.0
+ */
+ public String toString() {
+ return getClass().getName() + "[name=" + getName() + ",maxpri=" + maxPriority + "]";
+ }
+}
diff --git a/java/lang/ThreadLocal.annotated.java b/java/lang/ThreadLocal.annotated.java
new file mode 100644
index 0000000..b8cf527
--- /dev/null
+++ b/java/lang/ThreadLocal.annotated.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 1997, 2013, 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;
+
+import java.lang.ref.*;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Supplier;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class ThreadLocal<T> {
+
+public ThreadLocal() { throw new RuntimeException("Stub!"); }
+
[email protected] protected T initialValue() { throw new RuntimeException("Stub!"); }
+
[email protected] public static <S> java.lang.ThreadLocal<S> withInitial(@libcore.util.NonNull java.util.function.Supplier<? extends S> supplier) { throw new RuntimeException("Stub!"); }
+
[email protected] public T get() { throw new RuntimeException("Stub!"); }
+
+public void set(@libcore.util.NullFromTypeParam T value) { throw new RuntimeException("Stub!"); }
+
+public void remove() { throw new RuntimeException("Stub!"); }
+}
diff --git a/java/lang/ThreadLocal.java b/java/lang/ThreadLocal.java
new file mode 100644
index 0000000..c29ce7e
--- /dev/null
+++ b/java/lang/ThreadLocal.java
@@ -0,0 +1,722 @@
+/*
+ * Copyright (c) 1997, 2013, 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;
+import java.lang.ref.*;
+import java.util.Objects;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Supplier;
+
+/**
+ * This class provides thread-local variables. These variables differ from
+ * their normal counterparts in that each thread that accesses one (via its
+ * {@code get} or {@code set} method) has its own, independently initialized
+ * copy of the variable. {@code ThreadLocal} instances are typically private
+ * static fields in classes that wish to associate state with a thread (e.g.,
+ * a user ID or Transaction ID).
+ *
+ * <p>For example, the class below generates unique identifiers local to each
+ * thread.
+ * A thread's id is assigned the first time it invokes {@code ThreadId.get()}
+ * and remains unchanged on subsequent calls.
+ * <pre>
+ * import java.util.concurrent.atomic.AtomicInteger;
+ *
+ * public class ThreadId {
+ * // Atomic integer containing the next thread ID to be assigned
+ * private static final AtomicInteger nextId = new AtomicInteger(0);
+ *
+ * // Thread local variable containing each thread's ID
+ * private static final ThreadLocal<Integer> threadId =
+ * new ThreadLocal<Integer>() {
+ * @Override protected Integer initialValue() {
+ * return nextId.getAndIncrement();
+ * }
+ * };
+ *
+ * // Returns the current thread's unique ID, assigning it if necessary
+ * public static int get() {
+ * return threadId.get();
+ * }
+ * }
+ * </pre>
+ * <p>Each thread holds an implicit reference to its copy of a thread-local
+ * variable as long as the thread is alive and the {@code ThreadLocal}
+ * instance is accessible; after a thread goes away, all of its copies of
+ * thread-local instances are subject to garbage collection (unless other
+ * references to these copies exist).
+ *
+ * @author Josh Bloch and Doug Lea
+ * @since 1.2
+ */
+public class ThreadLocal<T> {
+ /**
+ * ThreadLocals rely on per-thread linear-probe hash maps attached
+ * to each thread (Thread.threadLocals and
+ * inheritableThreadLocals). The ThreadLocal objects act as keys,
+ * searched via threadLocalHashCode. This is a custom hash code
+ * (useful only within ThreadLocalMaps) that eliminates collisions
+ * in the common case where consecutively constructed ThreadLocals
+ * are used by the same threads, while remaining well-behaved in
+ * less common cases.
+ */
+ private final int threadLocalHashCode = nextHashCode();
+
+ /**
+ * The next hash code to be given out. Updated atomically. Starts at
+ * zero.
+ */
+ private static AtomicInteger nextHashCode =
+ new AtomicInteger();
+
+ /**
+ * The difference between successively generated hash codes - turns
+ * implicit sequential thread-local IDs into near-optimally spread
+ * multiplicative hash values for power-of-two-sized tables.
+ */
+ private static final int HASH_INCREMENT = 0x61c88647;
+
+ /**
+ * Returns the next hash code.
+ */
+ private static int nextHashCode() {
+ return nextHashCode.getAndAdd(HASH_INCREMENT);
+ }
+
+ /**
+ * Returns the current thread's "initial value" for this
+ * thread-local variable. This method will be invoked the first
+ * time a thread accesses the variable with the {@link #get}
+ * method, unless the thread previously invoked the {@link #set}
+ * method, in which case the {@code initialValue} method will not
+ * be invoked for the thread. Normally, this method is invoked at
+ * most once per thread, but it may be invoked again in case of
+ * subsequent invocations of {@link #remove} followed by {@link #get}.
+ *
+ * <p>This implementation simply returns {@code null}; if the
+ * programmer desires thread-local variables to have an initial
+ * value other than {@code null}, {@code ThreadLocal} must be
+ * subclassed, and this method overridden. Typically, an
+ * anonymous inner class will be used.
+ *
+ * @return the initial value for this thread-local
+ */
+ protected T initialValue() {
+ return null;
+ }
+
+ /**
+ * Creates a thread local variable. The initial value of the variable is
+ * determined by invoking the {@code get} method on the {@code Supplier}.
+ *
+ * @param <S> the type of the thread local's value
+ * @param supplier the supplier to be used to determine the initial value
+ * @return a new thread local variable
+ * @throws NullPointerException if the specified supplier is null
+ * @since 1.8
+ */
+ public static <S> ThreadLocal<S> withInitial(Supplier<? extends S> supplier) {
+ return new SuppliedThreadLocal<>(supplier);
+ }
+
+ /**
+ * Creates a thread local variable.
+ * @see #withInitial(java.util.function.Supplier)
+ */
+ public ThreadLocal() {
+ }
+
+ /**
+ * Returns the value in the current thread's copy of this
+ * thread-local variable. If the variable has no value for the
+ * current thread, it is first initialized to the value returned
+ * by an invocation of the {@link #initialValue} method.
+ *
+ * @return the current thread's value of this thread-local
+ */
+ public T get() {
+ Thread t = Thread.currentThread();
+ ThreadLocalMap map = getMap(t);
+ if (map != null) {
+ ThreadLocalMap.Entry e = map.getEntry(this);
+ if (e != null) {
+ @SuppressWarnings("unchecked")
+ T result = (T)e.value;
+ return result;
+ }
+ }
+ return setInitialValue();
+ }
+
+ /**
+ * Variant of set() to establish initialValue. Used instead
+ * of set() in case user has overridden the set() method.
+ *
+ * @return the initial value
+ */
+ private T setInitialValue() {
+ T value = initialValue();
+ Thread t = Thread.currentThread();
+ ThreadLocalMap map = getMap(t);
+ if (map != null)
+ map.set(this, value);
+ else
+ createMap(t, value);
+ return value;
+ }
+
+ /**
+ * Sets the current thread's copy of this thread-local variable
+ * to the specified value. Most subclasses will have no need to
+ * override this method, relying solely on the {@link #initialValue}
+ * method to set the values of thread-locals.
+ *
+ * @param value the value to be stored in the current thread's copy of
+ * this thread-local.
+ */
+ public void set(T value) {
+ Thread t = Thread.currentThread();
+ ThreadLocalMap map = getMap(t);
+ if (map != null)
+ map.set(this, value);
+ else
+ createMap(t, value);
+ }
+
+ /**
+ * Removes the current thread's value for this thread-local
+ * variable. If this thread-local variable is subsequently
+ * {@linkplain #get read} by the current thread, its value will be
+ * reinitialized by invoking its {@link #initialValue} method,
+ * unless its value is {@linkplain #set set} by the current thread
+ * in the interim. This may result in multiple invocations of the
+ * {@code initialValue} method in the current thread.
+ *
+ * @since 1.5
+ */
+ public void remove() {
+ ThreadLocalMap m = getMap(Thread.currentThread());
+ if (m != null)
+ m.remove(this);
+ }
+
+ /**
+ * Get the map associated with a ThreadLocal. Overridden in
+ * InheritableThreadLocal.
+ *
+ * @param t the current thread
+ * @return the map
+ */
+ ThreadLocalMap getMap(Thread t) {
+ return t.threadLocals;
+ }
+
+ /**
+ * Create the map associated with a ThreadLocal. Overridden in
+ * InheritableThreadLocal.
+ *
+ * @param t the current thread
+ * @param firstValue value for the initial entry of the map
+ */
+ void createMap(Thread t, T firstValue) {
+ t.threadLocals = new ThreadLocalMap(this, firstValue);
+ }
+
+ /**
+ * Factory method to create map of inherited thread locals.
+ * Designed to be called only from Thread constructor.
+ *
+ * @param parentMap the map associated with parent thread
+ * @return a map containing the parent's inheritable bindings
+ */
+ static ThreadLocalMap createInheritedMap(ThreadLocalMap parentMap) {
+ return new ThreadLocalMap(parentMap);
+ }
+
+ /**
+ * Method childValue is visibly defined in subclass
+ * InheritableThreadLocal, but is internally defined here for the
+ * sake of providing createInheritedMap factory method without
+ * needing to subclass the map class in InheritableThreadLocal.
+ * This technique is preferable to the alternative of embedding
+ * instanceof tests in methods.
+ */
+ T childValue(T parentValue) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * An extension of ThreadLocal that obtains its initial value from
+ * the specified {@code Supplier}.
+ */
+ static final class SuppliedThreadLocal<T> extends ThreadLocal<T> {
+
+ private final Supplier<? extends T> supplier;
+
+ SuppliedThreadLocal(Supplier<? extends T> supplier) {
+ this.supplier = Objects.requireNonNull(supplier);
+ }
+
+ @Override
+ protected T initialValue() {
+ return supplier.get();
+ }
+ }
+
+ /**
+ * ThreadLocalMap is a customized hash map suitable only for
+ * maintaining thread local values. No operations are exported
+ * outside of the ThreadLocal class. The class is package private to
+ * allow declaration of fields in class Thread. To help deal with
+ * very large and long-lived usages, the hash table entries use
+ * WeakReferences for keys. However, since reference queues are not
+ * used, stale entries are guaranteed to be removed only when
+ * the table starts running out of space.
+ */
+ static class ThreadLocalMap {
+
+ /**
+ * The entries in this hash map extend WeakReference, using
+ * its main ref field as the key (which is always a
+ * ThreadLocal object). Note that null keys (i.e. entry.get()
+ * == null) mean that the key is no longer referenced, so the
+ * entry can be expunged from table. Such entries are referred to
+ * as "stale entries" in the code that follows.
+ */
+ static class Entry extends WeakReference<ThreadLocal<?>> {
+ /** The value associated with this ThreadLocal. */
+ Object value;
+
+ Entry(ThreadLocal<?> k, Object v) {
+ super(k);
+ value = v;
+ }
+ }
+
+ /**
+ * The initial capacity -- MUST be a power of two.
+ */
+ private static final int INITIAL_CAPACITY = 16;
+
+ /**
+ * The table, resized as necessary.
+ * table.length MUST always be a power of two.
+ */
+ private Entry[] table;
+
+ /**
+ * The number of entries in the table.
+ */
+ private int size = 0;
+
+ /**
+ * The next size value at which to resize.
+ */
+ private int threshold; // Default to 0
+
+ /**
+ * Set the resize threshold to maintain at worst a 2/3 load factor.
+ */
+ private void setThreshold(int len) {
+ threshold = len * 2 / 3;
+ }
+
+ /**
+ * Increment i modulo len.
+ */
+ private static int nextIndex(int i, int len) {
+ return ((i + 1 < len) ? i + 1 : 0);
+ }
+
+ /**
+ * Decrement i modulo len.
+ */
+ private static int prevIndex(int i, int len) {
+ return ((i - 1 >= 0) ? i - 1 : len - 1);
+ }
+
+ /**
+ * Construct a new map initially containing (firstKey, firstValue).
+ * ThreadLocalMaps are constructed lazily, so we only create
+ * one when we have at least one entry to put in it.
+ */
+ ThreadLocalMap(ThreadLocal<?> firstKey, Object firstValue) {
+ table = new Entry[INITIAL_CAPACITY];
+ int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY - 1);
+ table[i] = new Entry(firstKey, firstValue);
+ size = 1;
+ setThreshold(INITIAL_CAPACITY);
+ }
+
+ /**
+ * Construct a new map including all Inheritable ThreadLocals
+ * from given parent map. Called only by createInheritedMap.
+ *
+ * @param parentMap the map associated with parent thread.
+ */
+ private ThreadLocalMap(ThreadLocalMap parentMap) {
+ Entry[] parentTable = parentMap.table;
+ int len = parentTable.length;
+ setThreshold(len);
+ table = new Entry[len];
+
+ for (int j = 0; j < len; j++) {
+ Entry e = parentTable[j];
+ if (e != null) {
+ @SuppressWarnings("unchecked")
+ ThreadLocal<Object> key = (ThreadLocal<Object>) e.get();
+ if (key != null) {
+ Object value = key.childValue(e.value);
+ Entry c = new Entry(key, value);
+ int h = key.threadLocalHashCode & (len - 1);
+ while (table[h] != null)
+ h = nextIndex(h, len);
+ table[h] = c;
+ size++;
+ }
+ }
+ }
+ }
+
+ /**
+ * Get the entry associated with key. This method
+ * itself handles only the fast path: a direct hit of existing
+ * key. It otherwise relays to getEntryAfterMiss. This is
+ * designed to maximize performance for direct hits, in part
+ * by making this method readily inlinable.
+ *
+ * @param key the thread local object
+ * @return the entry associated with key, or null if no such
+ */
+ private Entry getEntry(ThreadLocal<?> key) {
+ int i = key.threadLocalHashCode & (table.length - 1);
+ Entry e = table[i];
+ if (e != null && e.get() == key)
+ return e;
+ else
+ return getEntryAfterMiss(key, i, e);
+ }
+
+ /**
+ * Version of getEntry method for use when key is not found in
+ * its direct hash slot.
+ *
+ * @param key the thread local object
+ * @param i the table index for key's hash code
+ * @param e the entry at table[i]
+ * @return the entry associated with key, or null if no such
+ */
+ private Entry getEntryAfterMiss(ThreadLocal<?> key, int i, Entry e) {
+ Entry[] tab = table;
+ int len = tab.length;
+
+ while (e != null) {
+ ThreadLocal<?> k = e.get();
+ if (k == key)
+ return e;
+ if (k == null)
+ expungeStaleEntry(i);
+ else
+ i = nextIndex(i, len);
+ e = tab[i];
+ }
+ return null;
+ }
+
+ /**
+ * Set the value associated with key.
+ *
+ * @param key the thread local object
+ * @param value the value to be set
+ */
+ private void set(ThreadLocal<?> key, Object value) {
+
+ // We don't use a fast path as with get() because it is at
+ // least as common to use set() to create new entries as
+ // it is to replace existing ones, in which case, a fast
+ // path would fail more often than not.
+
+ Entry[] tab = table;
+ int len = tab.length;
+ int i = key.threadLocalHashCode & (len-1);
+
+ for (Entry e = tab[i];
+ e != null;
+ e = tab[i = nextIndex(i, len)]) {
+ ThreadLocal<?> k = e.get();
+
+ if (k == key) {
+ e.value = value;
+ return;
+ }
+
+ if (k == null) {
+ replaceStaleEntry(key, value, i);
+ return;
+ }
+ }
+
+ tab[i] = new Entry(key, value);
+ int sz = ++size;
+ if (!cleanSomeSlots(i, sz) && sz >= threshold)
+ rehash();
+ }
+
+ /**
+ * Remove the entry for key.
+ */
+ private void remove(ThreadLocal<?> key) {
+ Entry[] tab = table;
+ int len = tab.length;
+ int i = key.threadLocalHashCode & (len-1);
+ for (Entry e = tab[i];
+ e != null;
+ e = tab[i = nextIndex(i, len)]) {
+ if (e.get() == key) {
+ e.clear();
+ expungeStaleEntry(i);
+ return;
+ }
+ }
+ }
+
+ /**
+ * Replace a stale entry encountered during a set operation
+ * with an entry for the specified key. The value passed in
+ * the value parameter is stored in the entry, whether or not
+ * an entry already exists for the specified key.
+ *
+ * As a side effect, this method expunges all stale entries in the
+ * "run" containing the stale entry. (A run is a sequence of entries
+ * between two null slots.)
+ *
+ * @param key the key
+ * @param value the value to be associated with key
+ * @param staleSlot index of the first stale entry encountered while
+ * searching for key.
+ */
+ private void replaceStaleEntry(ThreadLocal<?> key, Object value,
+ int staleSlot) {
+ Entry[] tab = table;
+ int len = tab.length;
+ Entry e;
+
+ // Back up to check for prior stale entry in current run.
+ // We clean out whole runs at a time to avoid continual
+ // incremental rehashing due to garbage collector freeing
+ // up refs in bunches (i.e., whenever the collector runs).
+ int slotToExpunge = staleSlot;
+ for (int i = prevIndex(staleSlot, len);
+ (e = tab[i]) != null;
+ i = prevIndex(i, len))
+ if (e.get() == null)
+ slotToExpunge = i;
+
+ // Find either the key or trailing null slot of run, whichever
+ // occurs first
+ for (int i = nextIndex(staleSlot, len);
+ (e = tab[i]) != null;
+ i = nextIndex(i, len)) {
+ ThreadLocal<?> k = e.get();
+
+ // If we find key, then we need to swap it
+ // with the stale entry to maintain hash table order.
+ // The newly stale slot, or any other stale slot
+ // encountered above it, can then be sent to expungeStaleEntry
+ // to remove or rehash all of the other entries in run.
+ if (k == key) {
+ e.value = value;
+
+ tab[i] = tab[staleSlot];
+ tab[staleSlot] = e;
+
+ // Start expunge at preceding stale entry if it exists
+ if (slotToExpunge == staleSlot)
+ slotToExpunge = i;
+ cleanSomeSlots(expungeStaleEntry(slotToExpunge), len);
+ return;
+ }
+
+ // If we didn't find stale entry on backward scan, the
+ // first stale entry seen while scanning for key is the
+ // first still present in the run.
+ if (k == null && slotToExpunge == staleSlot)
+ slotToExpunge = i;
+ }
+
+ // If key not found, put new entry in stale slot
+ tab[staleSlot].value = null;
+ tab[staleSlot] = new Entry(key, value);
+
+ // If there are any other stale entries in run, expunge them
+ if (slotToExpunge != staleSlot)
+ cleanSomeSlots(expungeStaleEntry(slotToExpunge), len);
+ }
+
+ /**
+ * Expunge a stale entry by rehashing any possibly colliding entries
+ * lying between staleSlot and the next null slot. This also expunges
+ * any other stale entries encountered before the trailing null. See
+ * Knuth, Section 6.4
+ *
+ * @param staleSlot index of slot known to have null key
+ * @return the index of the next null slot after staleSlot
+ * (all between staleSlot and this slot will have been checked
+ * for expunging).
+ */
+ private int expungeStaleEntry(int staleSlot) {
+ Entry[] tab = table;
+ int len = tab.length;
+
+ // expunge entry at staleSlot
+ tab[staleSlot].value = null;
+ tab[staleSlot] = null;
+ size--;
+
+ // Rehash until we encounter null
+ Entry e;
+ int i;
+ for (i = nextIndex(staleSlot, len);
+ (e = tab[i]) != null;
+ i = nextIndex(i, len)) {
+ ThreadLocal<?> k = e.get();
+ if (k == null) {
+ e.value = null;
+ tab[i] = null;
+ size--;
+ } else {
+ int h = k.threadLocalHashCode & (len - 1);
+ if (h != i) {
+ tab[i] = null;
+
+ // Unlike Knuth 6.4 Algorithm R, we must scan until
+ // null because multiple entries could have been stale.
+ while (tab[h] != null)
+ h = nextIndex(h, len);
+ tab[h] = e;
+ }
+ }
+ }
+ return i;
+ }
+
+ /**
+ * Heuristically scan some cells looking for stale entries.
+ * This is invoked when either a new element is added, or
+ * another stale one has been expunged. It performs a
+ * logarithmic number of scans, as a balance between no
+ * scanning (fast but retains garbage) and a number of scans
+ * proportional to number of elements, that would find all
+ * garbage but would cause some insertions to take O(n) time.
+ *
+ * @param i a position known NOT to hold a stale entry. The
+ * scan starts at the element after i.
+ *
+ * @param n scan control: {@code log2(n)} cells are scanned,
+ * unless a stale entry is found, in which case
+ * {@code log2(table.length)-1} additional cells are scanned.
+ * When called from insertions, this parameter is the number
+ * of elements, but when from replaceStaleEntry, it is the
+ * table length. (Note: all this could be changed to be either
+ * more or less aggressive by weighting n instead of just
+ * using straight log n. But this version is simple, fast, and
+ * seems to work well.)
+ *
+ * @return true if any stale entries have been removed.
+ */
+ private boolean cleanSomeSlots(int i, int n) {
+ boolean removed = false;
+ Entry[] tab = table;
+ int len = tab.length;
+ do {
+ i = nextIndex(i, len);
+ Entry e = tab[i];
+ if (e != null && e.get() == null) {
+ n = len;
+ removed = true;
+ i = expungeStaleEntry(i);
+ }
+ } while ( (n >>>= 1) != 0);
+ return removed;
+ }
+
+ /**
+ * Re-pack and/or re-size the table. First scan the entire
+ * table removing stale entries. If this doesn't sufficiently
+ * shrink the size of the table, double the table size.
+ */
+ private void rehash() {
+ expungeStaleEntries();
+
+ // Use lower threshold for doubling to avoid hysteresis
+ if (size >= threshold - threshold / 4)
+ resize();
+ }
+
+ /**
+ * Double the capacity of the table.
+ */
+ private void resize() {
+ Entry[] oldTab = table;
+ int oldLen = oldTab.length;
+ int newLen = oldLen * 2;
+ Entry[] newTab = new Entry[newLen];
+ int count = 0;
+
+ for (int j = 0; j < oldLen; ++j) {
+ Entry e = oldTab[j];
+ if (e != null) {
+ ThreadLocal<?> k = e.get();
+ if (k == null) {
+ e.value = null; // Help the GC
+ } else {
+ int h = k.threadLocalHashCode & (newLen - 1);
+ while (newTab[h] != null)
+ h = nextIndex(h, newLen);
+ newTab[h] = e;
+ count++;
+ }
+ }
+ }
+
+ setThreshold(newLen);
+ size = count;
+ table = newTab;
+ }
+
+ /**
+ * Expunge all stale entries in the table.
+ */
+ private void expungeStaleEntries() {
+ Entry[] tab = table;
+ int len = tab.length;
+ for (int j = 0; j < len; j++) {
+ Entry e = tab[j];
+ if (e != null && e.get() == null)
+ expungeStaleEntry(j);
+ }
+ }
+ }
+}
diff --git a/java/lang/Throwable.annotated.java b/java/lang/Throwable.annotated.java
new file mode 100644
index 0000000..f6cef0c
--- /dev/null
+++ b/java/lang/Throwable.annotated.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 2013, 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;
+
+import java.io.*;
+import java.util.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class Throwable implements java.io.Serializable {
+
+public Throwable() { throw new RuntimeException("Stub!"); }
+
+public Throwable(@libcore.util.Nullable java.lang.String message) { throw new RuntimeException("Stub!"); }
+
+public Throwable(@libcore.util.Nullable java.lang.String message, @libcore.util.Nullable java.lang.Throwable cause) { throw new RuntimeException("Stub!"); }
+
+public Throwable(@libcore.util.Nullable java.lang.Throwable cause) { throw new RuntimeException("Stub!"); }
+
+protected Throwable(@libcore.util.Nullable java.lang.String message, @libcore.util.Nullable java.lang.Throwable cause, boolean enableSuppression, boolean writableStackTrace) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String getMessage() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String getLocalizedMessage() { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.Throwable getCause() { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.Throwable initCause(@libcore.util.Nullable java.lang.Throwable cause) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public void printStackTrace() { throw new RuntimeException("Stub!"); }
+
+public void printStackTrace(@libcore.util.NonNull java.io.PrintStream s) { throw new RuntimeException("Stub!"); }
+
+public void printStackTrace(@libcore.util.NonNull java.io.PrintWriter s) { throw new RuntimeException("Stub!"); }
+
[email protected] public synchronized java.lang.Throwable fillInStackTrace() { throw new RuntimeException("Stub!"); }
+
+public [email protected] StackTraceElement @libcore.util.NonNull [] getStackTrace() { throw new RuntimeException("Stub!"); }
+
+public void setStackTrace([email protected] StackTraceElement @libcore.util.NonNull [] stackTrace) { throw new RuntimeException("Stub!"); }
+
+public final synchronized void addSuppressed(@libcore.util.NonNull java.lang.Throwable exception) { throw new RuntimeException("Stub!"); }
+
+public final synchronized [email protected] Throwable @libcore.util.NonNull [] getSuppressed() { throw new RuntimeException("Stub!"); }
+}
diff --git a/java/lang/Throwable.java b/java/lang/Throwable.java
new file mode 100644
index 0000000..5a3f8a8
--- /dev/null
+++ b/java/lang/Throwable.java
@@ -0,0 +1,1134 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1994, 2013, 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;
+import dalvik.annotation.optimization.FastNative;
+import java.io.*;
+import java.util.*;
+
+/**
+ * The {@code Throwable} class is the superclass of all errors and
+ * exceptions in the Java language. Only objects that are instances of this
+ * class (or one of its subclasses) are thrown by the Java Virtual Machine or
+ * can be thrown by the Java {@code throw} statement. Similarly, only
+ * this class or one of its subclasses can be the argument type in a
+ * {@code catch} clause.
+ *
+ * For the purposes of compile-time checking of exceptions, {@code
+ * Throwable} and any subclass of {@code Throwable} that is not also a
+ * subclass of either {@link RuntimeException} or {@link Error} are
+ * regarded as checked exceptions.
+ *
+ * <p>Instances of two subclasses, {@link java.lang.Error} and
+ * {@link java.lang.Exception}, are conventionally used to indicate
+ * that exceptional situations have occurred. Typically, these instances
+ * are freshly created in the context of the exceptional situation so
+ * as to include relevant information (such as stack trace data).
+ *
+ * <p>A throwable contains a snapshot of the execution stack of its
+ * thread at the time it was created. It can also contain a message
+ * string that gives more information about the error. Over time, a
+ * throwable can {@linkplain Throwable#addSuppressed suppress} other
+ * throwables from being propagated. Finally, the throwable can also
+ * contain a <i>cause</i>: another throwable that caused this
+ * throwable to be constructed. The recording of this causal information
+ * is referred to as the <i>chained exception</i> facility, as the
+ * cause can, itself, have a cause, and so on, leading to a "chain" of
+ * exceptions, each caused by another.
+ *
+ * <p>One reason that a throwable may have a cause is that the class that
+ * throws it is built atop a lower layered abstraction, and an operation on
+ * the upper layer fails due to a failure in the lower layer. It would be bad
+ * design to let the throwable thrown by the lower layer propagate outward, as
+ * it is generally unrelated to the abstraction provided by the upper layer.
+ * Further, doing so would tie the API of the upper layer to the details of
+ * its implementation, assuming the lower layer's exception was a checked
+ * exception. Throwing a "wrapped exception" (i.e., an exception containing a
+ * cause) allows the upper layer to communicate the details of the failure to
+ * its caller without incurring either of these shortcomings. It preserves
+ * the flexibility to change the implementation of the upper layer without
+ * changing its API (in particular, the set of exceptions thrown by its
+ * methods).
+ *
+ * <p>A second reason that a throwable may have a cause is that the method
+ * that throws it must conform to a general-purpose interface that does not
+ * permit the method to throw the cause directly. For example, suppose
+ * a persistent collection conforms to the {@link java.util.Collection
+ * Collection} interface, and that its persistence is implemented atop
+ * {@code java.io}. Suppose the internals of the {@code add} method
+ * can throw an {@link java.io.IOException IOException}. The implementation
+ * can communicate the details of the {@code IOException} to its caller
+ * while conforming to the {@code Collection} interface by wrapping the
+ * {@code IOException} in an appropriate unchecked exception. (The
+ * specification for the persistent collection should indicate that it is
+ * capable of throwing such exceptions.)
+ *
+ * <p>A cause can be associated with a throwable in two ways: via a
+ * constructor that takes the cause as an argument, or via the
+ * {@link #initCause(Throwable)} method. New throwable classes that
+ * wish to allow causes to be associated with them should provide constructors
+ * that take a cause and delegate (perhaps indirectly) to one of the
+ * {@code Throwable} constructors that takes a cause.
+ *
+ * Because the {@code initCause} method is public, it allows a cause to be
+ * associated with any throwable, even a "legacy throwable" whose
+ * implementation predates the addition of the exception chaining mechanism to
+ * {@code Throwable}.
+ *
+ * <p>By convention, class {@code Throwable} and its subclasses have two
+ * constructors, one that takes no arguments and one that takes a
+ * {@code String} argument that can be used to produce a detail message.
+ * Further, those subclasses that might likely have a cause associated with
+ * them should have two more constructors, one that takes a
+ * {@code Throwable} (the cause), and one that takes a
+ * {@code String} (the detail message) and a {@code Throwable} (the
+ * cause).
+ *
+ * @author unascribed
+ * @author Josh Bloch (Added exception chaining and programmatic access to
+ * stack trace in 1.4.)
+ * @jls 11.2 Compile-Time Checking of Exceptions
+ * @since JDK1.0
+ */
+public class Throwable implements Serializable {
+ /** use serialVersionUID from JDK 1.0.2 for interoperability */
+ private static final long serialVersionUID = -3042686055658047285L;
+
+ /**
+ * Native code saves some indication of the stack backtrace in this slot.
+ */
+ private transient Object backtrace;
+
+ /**
+ * Specific details about the Throwable. For example, for
+ * {@code FileNotFoundException}, this contains the name of
+ * the file that could not be found.
+ *
+ * @serial
+ */
+ private String detailMessage;
+
+
+ /**
+ * Holder class to defer initializing sentinel objects only used
+ * for serialization.
+ */
+ private static class SentinelHolder {
+ /**
+ * {@linkplain #setStackTrace(StackTraceElement[]) Setting the
+ * stack trace} to a one-element array containing this sentinel
+ * value indicates future attempts to set the stack trace will be
+ * ignored. The sentinal is equal to the result of calling:<br>
+ * {@code new StackTraceElement("", "", null, Integer.MIN_VALUE)}
+ */
+ public static final StackTraceElement STACK_TRACE_ELEMENT_SENTINEL =
+ new StackTraceElement("", "", null, Integer.MIN_VALUE);
+
+ /**
+ * Sentinel value used in the serial form to indicate an immutable
+ * stack trace.
+ */
+ public static final StackTraceElement[] STACK_TRACE_SENTINEL =
+ new StackTraceElement[] {STACK_TRACE_ELEMENT_SENTINEL};
+ }
+
+ // Android-removed: Use libcore.util.EmptyArray for the empty stack trace
+ // Adding the constant UNASSIGNED_STACK breaks serialization of some subclasses
+ // /**
+ // * A shared value for an empty stack.
+ // */
+ // private static final StackTraceElement[] UNASSIGNED_STACK = new StackTraceElement[0];
+
+ /*
+ * To allow Throwable objects to be made immutable and safely
+ * reused by the JVM, such as OutOfMemoryErrors, fields of
+ * Throwable that are writable in response to user actions, cause,
+ * stackTrace, and suppressedExceptions obey the following
+ * protocol:
+ *
+ * 1) The fields are initialized to a non-null sentinel value
+ * which indicates the value has logically not been set.
+ *
+ * 2) Writing a null to the field indicates further writes
+ * are forbidden
+ *
+ * 3) The sentinel value may be replaced with another non-null
+ * value.
+ *
+ * For example, implementations of the HotSpot JVM have
+ * preallocated OutOfMemoryError objects to provide for better
+ * diagnosability of that situation. These objects are created
+ * without calling the constructor for that class and the fields
+ * in question are initialized to null. To support this
+ * capability, any new fields added to Throwable that require
+ * being initialized to a non-null value require a coordinated JVM
+ * change.
+ */
+
+ /**
+ * The throwable that caused this throwable to get thrown, or null if this
+ * throwable was not caused by another throwable, or if the causative
+ * throwable is unknown. If this field is equal to this throwable itself,
+ * it indicates that the cause of this throwable has not yet been
+ * initialized.
+ *
+ * @serial
+ * @since 1.4
+ */
+ private Throwable cause = this;
+
+ /**
+ * The stack trace, as returned by {@link #getStackTrace()}.
+ *
+ * The field is initialized to a zero-length array. A {@code
+ * null} value of this field indicates subsequent calls to {@link
+ * #setStackTrace(StackTraceElement[])} and {@link
+ * #fillInStackTrace()} will be be no-ops.
+ *
+ * @serial
+ * @since 1.4
+ */
+ // Android-changed: Use libcore.util.EmptyArray for the empty stack trace
+ // private StackTraceElement[] stackTrace = UNASSIGNED_STACK;
+ private StackTraceElement[] stackTrace = libcore.util.EmptyArray.STACK_TRACE_ELEMENT;
+
+ // Android-removed: Use empty collection in place of SUPPRESSED_SENTINEL
+ // Adding this constant breaks serialization of some subclasses
+ /*
+ // Setting this static field introduces an acceptable
+ // initialization dependency on a few java.util classes.
+ private static final List<Throwable> SUPPRESSED_SENTINEL =
+ Collections.unmodifiableList(new ArrayList<Throwable>(0));
+ */
+
+ /**
+ * The list of suppressed exceptions, as returned by {@link
+ * #getSuppressed()}. The list is initialized to a zero-element
+ * unmodifiable sentinel list. When a serialized Throwable is
+ * read in, if the {@code suppressedExceptions} field points to a
+ * zero-element list, the field is reset to the sentinel value.
+ *
+ * @serial
+ * @since 1.7
+ */
+ // Android-changed: Use empty collection in place of SUPPRESSED_SENTINEL
+ // private List<Throwable> suppressedExceptions = SUPPRESSED_SENTINEL;
+ private List<Throwable> suppressedExceptions = Collections.emptyList();
+
+ /** Message for trying to suppress a null exception. */
+ private static final String NULL_CAUSE_MESSAGE = "Cannot suppress a null exception.";
+
+ /** Message for trying to suppress oneself. */
+ private static final String SELF_SUPPRESSION_MESSAGE = "Self-suppression not permitted";
+
+ /** Caption for labeling causative exception stack traces */
+ private static final String CAUSE_CAPTION = "Caused by: ";
+
+ /** Caption for labeling suppressed exception stack traces */
+ private static final String SUPPRESSED_CAPTION = "Suppressed: ";
+
+ /**
+ * Constructs a new throwable with {@code null} as its detail message.
+ * The cause is not initialized, and may subsequently be initialized by a
+ * call to {@link #initCause}.
+ *
+ * <p>The {@link #fillInStackTrace()} method is called to initialize
+ * the stack trace data in the newly created throwable.
+ */
+ public Throwable() {
+ fillInStackTrace();
+ }
+
+ /**
+ * Constructs a new throwable with the specified detail message. The
+ * cause is not initialized, and may subsequently be initialized by
+ * a call to {@link #initCause}.
+ *
+ * <p>The {@link #fillInStackTrace()} method is called to initialize
+ * the stack trace data in the newly created throwable.
+ *
+ * @param message the detail message. The detail message is saved for
+ * later retrieval by the {@link #getMessage()} method.
+ */
+ public Throwable(String message) {
+ fillInStackTrace();
+ detailMessage = message;
+ }
+
+ /**
+ * Constructs a new throwable with the specified detail message and
+ * cause. <p>Note that the detail message associated with
+ * {@code cause} is <i>not</i> automatically incorporated in
+ * this throwable's detail message.
+ *
+ * <p>The {@link #fillInStackTrace()} method is called to initialize
+ * the stack trace data in the newly created throwable.
+ *
+ * @param message the detail message (which is saved for later retrieval
+ * by the {@link #getMessage()} method).
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link #getCause()} method). (A {@code null} value is
+ * permitted, and indicates that the cause is nonexistent or
+ * unknown.)
+ * @since 1.4
+ */
+ public Throwable(String message, Throwable cause) {
+ fillInStackTrace();
+ detailMessage = message;
+ this.cause = cause;
+ }
+
+ /**
+ * Constructs a new throwable with the specified cause and a detail
+ * message of {@code (cause==null ? null : cause.toString())} (which
+ * typically contains the class and detail message of {@code cause}).
+ * This constructor is useful for throwables that are little more than
+ * wrappers for other throwables (for example, {@link
+ * java.security.PrivilegedActionException}).
+ *
+ * <p>The {@link #fillInStackTrace()} method is called to initialize
+ * the stack trace data in the newly created throwable.
+ *
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link #getCause()} method). (A {@code null} value is
+ * permitted, and indicates that the cause is nonexistent or
+ * unknown.)
+ * @since 1.4
+ */
+ public Throwable(Throwable cause) {
+ fillInStackTrace();
+ detailMessage = (cause==null ? null : cause.toString());
+ this.cause = cause;
+ }
+
+ /**
+ * Constructs a new throwable with the specified detail message,
+ * cause, {@linkplain #addSuppressed suppression} enabled or
+ * disabled, and writable stack trace enabled or disabled. If
+ * suppression is disabled, {@link #getSuppressed} for this object
+ * will return a zero-length array and calls to {@link
+ * #addSuppressed} that would otherwise append an exception to the
+ * suppressed list will have no effect. If the writable stack
+ * trace is false, this constructor will not call {@link
+ * #fillInStackTrace()}, a {@code null} will be written to the
+ * {@code stackTrace} field, and subsequent calls to {@code
+ * fillInStackTrace} and {@link
+ * #setStackTrace(StackTraceElement[])} will not set the stack
+ * trace. If the writable stack trace is false, {@link
+ * #getStackTrace} will return a zero length array.
+ *
+ * <p>Note that the other constructors of {@code Throwable} treat
+ * suppression as being enabled and the stack trace as being
+ * writable. Subclasses of {@code Throwable} should document any
+ * conditions under which suppression is disabled and document
+ * conditions under which the stack trace is not writable.
+ * Disabling of suppression should only occur in exceptional
+ * circumstances where special requirements exist, such as a
+ * virtual machine reusing exception objects under low-memory
+ * situations. Circumstances where a given exception object is
+ * repeatedly caught and rethrown, such as to implement control
+ * flow between two sub-systems, is another situation where
+ * immutable throwable objects would be appropriate.
+ *
+ * @param message the detail message.
+ * @param cause the cause. (A {@code null} value is permitted,
+ * and indicates that the cause is nonexistent or unknown.)
+ * @param enableSuppression whether or not suppression is enabled or disabled
+ * @param writableStackTrace whether or not the stack trace should be
+ * writable
+ *
+ * @see OutOfMemoryError
+ * @see NullPointerException
+ * @see ArithmeticException
+ * @since 1.7
+ */
+ protected Throwable(String message, Throwable cause,
+ boolean enableSuppression,
+ boolean writableStackTrace) {
+ if (writableStackTrace) {
+ fillInStackTrace();
+ } else {
+ stackTrace = null;
+ }
+ detailMessage = message;
+ this.cause = cause;
+ if (!enableSuppression)
+ suppressedExceptions = null;
+ }
+
+ /**
+ * Returns the detail message string of this throwable.
+ *
+ * @return the detail message string of this {@code Throwable} instance
+ * (which may be {@code null}).
+ */
+ public String getMessage() {
+ return detailMessage;
+ }
+
+ /**
+ * Creates a localized description of this throwable.
+ * Subclasses may override this method in order to produce a
+ * locale-specific message. For subclasses that do not override this
+ * method, the default implementation returns the same result as
+ * {@code getMessage()}.
+ *
+ * @return The localized description of this throwable.
+ * @since JDK1.1
+ */
+ public String getLocalizedMessage() {
+ return getMessage();
+ }
+
+ /**
+ * Returns the cause of this throwable or {@code null} if the
+ * cause is nonexistent or unknown. (The cause is the throwable that
+ * caused this throwable to get thrown.)
+ *
+ * <p>This implementation returns the cause that was supplied via one of
+ * the constructors requiring a {@code Throwable}, or that was set after
+ * creation with the {@link #initCause(Throwable)} method. While it is
+ * typically unnecessary to override this method, a subclass can override
+ * it to return a cause set by some other means. This is appropriate for
+ * a "legacy chained throwable" that predates the addition of chained
+ * exceptions to {@code Throwable}. Note that it is <i>not</i>
+ * necessary to override any of the {@code PrintStackTrace} methods,
+ * all of which invoke the {@code getCause} method to determine the
+ * cause of a throwable.
+ *
+ * @return the cause of this throwable or {@code null} if the
+ * cause is nonexistent or unknown.
+ * @since 1.4
+ */
+ public synchronized Throwable getCause() {
+ return (cause==this ? null : cause);
+ }
+
+ /**
+ * Initializes the <i>cause</i> of this throwable to the specified value.
+ * (The cause is the throwable that caused this throwable to get thrown.)
+ *
+ * <p>This method can be called at most once. It is generally called from
+ * within the constructor, or immediately after creating the
+ * throwable. If this throwable was created
+ * with {@link #Throwable(Throwable)} or
+ * {@link #Throwable(String,Throwable)}, this method cannot be called
+ * even once.
+ *
+ * <p>An example of using this method on a legacy throwable type
+ * without other support for setting the cause is:
+ *
+ * <pre>
+ * try {
+ * lowLevelOp();
+ * } catch (LowLevelException le) {
+ * throw (HighLevelException)
+ * new HighLevelException().initCause(le); // Legacy constructor
+ * }
+ * </pre>
+ *
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link #getCause()} method). (A {@code null} value is
+ * permitted, and indicates that the cause is nonexistent or
+ * unknown.)
+ * @return a reference to this {@code Throwable} instance.
+ * @throws IllegalArgumentException if {@code cause} is this
+ * throwable. (A throwable cannot be its own cause.)
+ * @throws IllegalStateException if this throwable was
+ * created with {@link #Throwable(Throwable)} or
+ * {@link #Throwable(String,Throwable)}, or this method has already
+ * been called on this throwable.
+ * @since 1.4
+ */
+ public synchronized Throwable initCause(Throwable cause) {
+ if (this.cause != this)
+ throw new IllegalStateException("Can't overwrite cause with " +
+ Objects.toString(cause, "a null"), this);
+ if (cause == this)
+ throw new IllegalArgumentException("Self-causation not permitted", this);
+ this.cause = cause;
+ return this;
+ }
+
+ /**
+ * Returns a short description of this throwable.
+ * The result is the concatenation of:
+ * <ul>
+ * <li> the {@linkplain Class#getName() name} of the class of this object
+ * <li> ": " (a colon and a space)
+ * <li> the result of invoking this object's {@link #getLocalizedMessage}
+ * method
+ * </ul>
+ * If {@code getLocalizedMessage} returns {@code null}, then just
+ * the class name is returned.
+ *
+ * @return a string representation of this throwable.
+ */
+ public String toString() {
+ String s = getClass().getName();
+ String message = getLocalizedMessage();
+ return (message != null) ? (s + ": " + message) : s;
+ }
+
+ /**
+ * Prints this throwable and its backtrace to the
+ * standard error stream. This method prints a stack trace for this
+ * {@code Throwable} object on the error output stream that is
+ * the value of the field {@code System.err}. The first line of
+ * output contains the result of the {@link #toString()} method for
+ * this object. Remaining lines represent data previously recorded by
+ * the method {@link #fillInStackTrace()}. The format of this
+ * information depends on the implementation, but the following
+ * example may be regarded as typical:
+ * <blockquote><pre>
+ * java.lang.NullPointerException
+ * at MyClass.mash(MyClass.java:9)
+ * at MyClass.crunch(MyClass.java:6)
+ * at MyClass.main(MyClass.java:3)
+ * </pre></blockquote>
+ * This example was produced by running the program:
+ * <pre>
+ * class MyClass {
+ * public static void main(String[] args) {
+ * crunch(null);
+ * }
+ * static void crunch(int[] a) {
+ * mash(a);
+ * }
+ * static void mash(int[] b) {
+ * System.out.println(b[0]);
+ * }
+ * }
+ * </pre>
+ * The backtrace for a throwable with an initialized, non-null cause
+ * should generally include the backtrace for the cause. The format
+ * of this information depends on the implementation, but the following
+ * example may be regarded as typical:
+ * <pre>
+ * HighLevelException: MidLevelException: LowLevelException
+ * at Junk.a(Junk.java:13)
+ * at Junk.main(Junk.java:4)
+ * Caused by: MidLevelException: LowLevelException
+ * at Junk.c(Junk.java:23)
+ * at Junk.b(Junk.java:17)
+ * at Junk.a(Junk.java:11)
+ * ... 1 more
+ * Caused by: LowLevelException
+ * at Junk.e(Junk.java:30)
+ * at Junk.d(Junk.java:27)
+ * at Junk.c(Junk.java:21)
+ * ... 3 more
+ * </pre>
+ * Note the presence of lines containing the characters {@code "..."}.
+ * These lines indicate that the remainder of the stack trace for this
+ * exception matches the indicated number of frames from the bottom of the
+ * stack trace of the exception that was caused by this exception (the
+ * "enclosing" exception). This shorthand can greatly reduce the length
+ * of the output in the common case where a wrapped exception is thrown
+ * from same method as the "causative exception" is caught. The above
+ * example was produced by running the program:
+ * <pre>
+ * public class Junk {
+ * public static void main(String args[]) {
+ * try {
+ * a();
+ * } catch(HighLevelException e) {
+ * e.printStackTrace();
+ * }
+ * }
+ * static void a() throws HighLevelException {
+ * try {
+ * b();
+ * } catch(MidLevelException e) {
+ * throw new HighLevelException(e);
+ * }
+ * }
+ * static void b() throws MidLevelException {
+ * c();
+ * }
+ * static void c() throws MidLevelException {
+ * try {
+ * d();
+ * } catch(LowLevelException e) {
+ * throw new MidLevelException(e);
+ * }
+ * }
+ * static void d() throws LowLevelException {
+ * e();
+ * }
+ * static void e() throws LowLevelException {
+ * throw new LowLevelException();
+ * }
+ * }
+ *
+ * class HighLevelException extends Exception {
+ * HighLevelException(Throwable cause) { super(cause); }
+ * }
+ *
+ * class MidLevelException extends Exception {
+ * MidLevelException(Throwable cause) { super(cause); }
+ * }
+ *
+ * class LowLevelException extends Exception {
+ * }
+ * </pre>
+ * As of release 7, the platform supports the notion of
+ * <i>suppressed exceptions</i> (in conjunction with the {@code
+ * try}-with-resources statement). Any exceptions that were
+ * suppressed in order to deliver an exception are printed out
+ * beneath the stack trace. The format of this information
+ * depends on the implementation, but the following example may be
+ * regarded as typical:
+ *
+ * <pre>
+ * Exception in thread "main" java.lang.Exception: Something happened
+ * at Foo.bar(Foo.java:10)
+ * at Foo.main(Foo.java:5)
+ * Suppressed: Resource$CloseFailException: Resource ID = 0
+ * at Resource.close(Resource.java:26)
+ * at Foo.bar(Foo.java:9)
+ * ... 1 more
+ * </pre>
+ * Note that the "... n more" notation is used on suppressed exceptions
+ * just at it is used on causes. Unlike causes, suppressed exceptions are
+ * indented beyond their "containing exceptions."
+ *
+ * <p>An exception can have both a cause and one or more suppressed
+ * exceptions:
+ * <pre>
+ * Exception in thread "main" java.lang.Exception: Main block
+ * at Foo3.main(Foo3.java:7)
+ * Suppressed: Resource$CloseFailException: Resource ID = 2
+ * at Resource.close(Resource.java:26)
+ * at Foo3.main(Foo3.java:5)
+ * Suppressed: Resource$CloseFailException: Resource ID = 1
+ * at Resource.close(Resource.java:26)
+ * at Foo3.main(Foo3.java:5)
+ * Caused by: java.lang.Exception: I did it
+ * at Foo3.main(Foo3.java:8)
+ * </pre>
+ * Likewise, a suppressed exception can have a cause:
+ * <pre>
+ * Exception in thread "main" java.lang.Exception: Main block
+ * at Foo4.main(Foo4.java:6)
+ * Suppressed: Resource2$CloseFailException: Resource ID = 1
+ * at Resource2.close(Resource2.java:20)
+ * at Foo4.main(Foo4.java:5)
+ * Caused by: java.lang.Exception: Rats, you caught me
+ * at Resource2$CloseFailException.<init>(Resource2.java:45)
+ * ... 2 more
+ * </pre>
+ */
+ public void printStackTrace() {
+ printStackTrace(System.err);
+ }
+
+ /**
+ * Prints this throwable and its backtrace to the specified print stream.
+ *
+ * @param s {@code PrintStream} to use for output
+ */
+ public void printStackTrace(PrintStream s) {
+ printStackTrace(new WrappedPrintStream(s));
+ }
+
+ private void printStackTrace(PrintStreamOrWriter s) {
+ // Guard against malicious overrides of Throwable.equals by
+ // using a Set with identity equality semantics.
+ Set<Throwable> dejaVu =
+ Collections.newSetFromMap(new IdentityHashMap<Throwable, Boolean>());
+ dejaVu.add(this);
+
+ synchronized (s.lock()) {
+ // Print our stack trace
+ s.println(this);
+ StackTraceElement[] trace = getOurStackTrace();
+ for (StackTraceElement traceElement : trace)
+ s.println("\tat " + traceElement);
+
+ // Print suppressed exceptions, if any
+ for (Throwable se : getSuppressed())
+ se.printEnclosedStackTrace(s, trace, SUPPRESSED_CAPTION, "\t", dejaVu);
+
+ // Print cause, if any
+ Throwable ourCause = getCause();
+ if (ourCause != null)
+ ourCause.printEnclosedStackTrace(s, trace, CAUSE_CAPTION, "", dejaVu);
+ }
+ }
+
+ /**
+ * Print our stack trace as an enclosed exception for the specified
+ * stack trace.
+ */
+ private void printEnclosedStackTrace(PrintStreamOrWriter s,
+ StackTraceElement[] enclosingTrace,
+ String caption,
+ String prefix,
+ Set<Throwable> dejaVu) {
+ // Android-removed: Use of assert keyword which breaks serialization of some subclasses
+ // (Using assert adds a static field that determines whether assertions are enabled.)
+ // assert Thread.holdsLock(s.lock());
+ if (dejaVu.contains(this)) {
+ s.println("\t[CIRCULAR REFERENCE:" + this + "]");
+ } else {
+ dejaVu.add(this);
+ // Compute number of frames in common between this and enclosing trace
+ StackTraceElement[] trace = getOurStackTrace();
+ int m = trace.length - 1;
+ int n = enclosingTrace.length - 1;
+ while (m >= 0 && n >=0 && trace[m].equals(enclosingTrace[n])) {
+ m--; n--;
+ }
+ int framesInCommon = trace.length - 1 - m;
+
+ // Print our stack trace
+ s.println(prefix + caption + this);
+ for (int i = 0; i <= m; i++)
+ s.println(prefix + "\tat " + trace[i]);
+ if (framesInCommon != 0)
+ s.println(prefix + "\t... " + framesInCommon + " more");
+
+ // Print suppressed exceptions, if any
+ for (Throwable se : getSuppressed())
+ se.printEnclosedStackTrace(s, trace, SUPPRESSED_CAPTION,
+ prefix +"\t", dejaVu);
+
+ // Print cause, if any
+ Throwable ourCause = getCause();
+ if (ourCause != null)
+ ourCause.printEnclosedStackTrace(s, trace, CAUSE_CAPTION, prefix, dejaVu);
+ }
+ }
+
+ /**
+ * Prints this throwable and its backtrace to the specified
+ * print writer.
+ *
+ * @param s {@code PrintWriter} to use for output
+ * @since JDK1.1
+ */
+ public void printStackTrace(PrintWriter s) {
+ printStackTrace(new WrappedPrintWriter(s));
+ }
+
+ /**
+ * Wrapper class for PrintStream and PrintWriter to enable a single
+ * implementation of printStackTrace.
+ */
+ private abstract static class PrintStreamOrWriter {
+ /** Returns the object to be locked when using this StreamOrWriter */
+ abstract Object lock();
+
+ /** Prints the specified string as a line on this StreamOrWriter */
+ abstract void println(Object o);
+ }
+
+ private static class WrappedPrintStream extends PrintStreamOrWriter {
+ private final PrintStream printStream;
+
+ WrappedPrintStream(PrintStream printStream) {
+ this.printStream = printStream;
+ }
+
+ Object lock() {
+ return printStream;
+ }
+
+ void println(Object o) {
+ printStream.println(o);
+ }
+ }
+
+ private static class WrappedPrintWriter extends PrintStreamOrWriter {
+ private final PrintWriter printWriter;
+
+ WrappedPrintWriter(PrintWriter printWriter) {
+ this.printWriter = printWriter;
+ }
+
+ Object lock() {
+ return printWriter;
+ }
+
+ void println(Object o) {
+ printWriter.println(o);
+ }
+ }
+
+ /**
+ * Fills in the execution stack trace. This method records within this
+ * {@code Throwable} object information about the current state of
+ * the stack frames for the current thread.
+ *
+ * <p>If the stack trace of this {@code Throwable} {@linkplain
+ * Throwable#Throwable(String, Throwable, boolean, boolean) is not
+ * writable}, calling this method has no effect.
+ *
+ * @return a reference to this {@code Throwable} instance.
+ * @see java.lang.Throwable#printStackTrace()
+ */
+ public synchronized Throwable fillInStackTrace() {
+ if (stackTrace != null ||
+ backtrace != null /* Out of protocol state */ ) {
+ // Android-changed: Use Android-specific nativeFillInStackTrace
+ // fillInStackTrace(0);
+ backtrace = nativeFillInStackTrace();
+ // Android-changed: Use libcore.util.EmptyArray for the empty stack trace
+ // stackTrace = UNASSIGNED_STACK;
+ stackTrace = libcore.util.EmptyArray.STACK_TRACE_ELEMENT;
+ }
+ return this;
+ }
+
+ // Android-changed: Use Android-specific nativeFillInStackTrace
+ // private native Throwable fillInStackTrace(int dummy);
+ @FastNative
+ private static native Object nativeFillInStackTrace();
+
+ /**
+ * Provides programmatic access to the stack trace information printed by
+ * {@link #printStackTrace()}. Returns an array of stack trace elements,
+ * each representing one stack frame. The zeroth element of the array
+ * (assuming the array's length is non-zero) represents the top of the
+ * stack, which is the last method invocation in the sequence. Typically,
+ * this is the point at which this throwable was created and thrown.
+ * The last element of the array (assuming the array's length is non-zero)
+ * represents the bottom of the stack, which is the first method invocation
+ * in the sequence.
+ *
+ * <p>Some virtual machines may, under some circumstances, omit one
+ * or more stack frames from the stack trace. In the extreme case,
+ * a virtual machine that has no stack trace information concerning
+ * this throwable is permitted to return a zero-length array from this
+ * method. Generally speaking, the array returned by this method will
+ * contain one element for every frame that would be printed by
+ * {@code printStackTrace}. Writes to the returned array do not
+ * affect future calls to this method.
+ *
+ * @return an array of stack trace elements representing the stack trace
+ * pertaining to this throwable.
+ * @since 1.4
+ */
+ public StackTraceElement[] getStackTrace() {
+ return getOurStackTrace().clone();
+ }
+
+ private synchronized StackTraceElement[] getOurStackTrace() {
+ // Initialize stack trace field with information from
+ // backtrace if this is the first call to this method
+ // Android-changed: Use libcore.util.EmptyArray for the empty stack trace
+ // if (stackTrace == UNASSIGNED_STACK ||
+ if (stackTrace == libcore.util.EmptyArray.STACK_TRACE_ELEMENT ||
+ (stackTrace == null && backtrace != null) /* Out of protocol state */) {
+ // BEGIN Android-changed: Use Android-specific nativeGetStackTrace
+ // int depth = getStackTraceDepth();
+ // stackTrace = new StackTraceElement[depth];
+ // for (int i=0; i < depth; i++)
+ // stackTrace[i] = getStackTraceElement(i);
+ stackTrace = nativeGetStackTrace(backtrace);
+ backtrace = null;
+ if (stackTrace == null) {
+ return libcore.util.EmptyArray.STACK_TRACE_ELEMENT;
+ }
+ // END Android-changed: Use Android-specific nativeGetStackTrace
+ } else if (stackTrace == null) {
+ // Android-changed: Use libcore.util.EmptyArray for the empty stack trace
+ // return UNASSIGNED_STACK;
+ return libcore.util.EmptyArray.STACK_TRACE_ELEMENT;
+ }
+ return stackTrace;
+ }
+
+ /**
+ * Sets the stack trace elements that will be returned by
+ * {@link #getStackTrace()} and printed by {@link #printStackTrace()}
+ * and related methods.
+ *
+ * This method, which is designed for use by RPC frameworks and other
+ * advanced systems, allows the client to override the default
+ * stack trace that is either generated by {@link #fillInStackTrace()}
+ * when a throwable is constructed or deserialized when a throwable is
+ * read from a serialization stream.
+ *
+ * <p>If the stack trace of this {@code Throwable} {@linkplain
+ * Throwable#Throwable(String, Throwable, boolean, boolean) is not
+ * writable}, calling this method has no effect other than
+ * validating its argument.
+ *
+ * @param stackTrace the stack trace elements to be associated with
+ * this {@code Throwable}. The specified array is copied by this
+ * call; changes in the specified array after the method invocation
+ * returns will have no affect on this {@code Throwable}'s stack
+ * trace.
+ *
+ * @throws NullPointerException if {@code stackTrace} is
+ * {@code null} or if any of the elements of
+ * {@code stackTrace} are {@code null}
+ *
+ * @since 1.4
+ */
+ public void setStackTrace(StackTraceElement[] stackTrace) {
+ // Validate argument
+ StackTraceElement[] defensiveCopy = stackTrace.clone();
+ for (int i = 0; i < defensiveCopy.length; i++) {
+ if (defensiveCopy[i] == null)
+ throw new NullPointerException("stackTrace[" + i + "]");
+ }
+
+ synchronized (this) {
+ if (this.stackTrace == null && // Immutable stack
+ backtrace == null) // Test for out of protocol state
+ return;
+ this.stackTrace = defensiveCopy;
+ }
+ }
+
+ // Android-removed: Unused native method getStackTraceDepth()
+ // /**
+ // * Returns the number of elements in the stack trace (or 0 if the stack
+ // * trace is unavailable).
+ // *
+ // * package-protection for use by SharedSecrets.
+ // */
+ // native int getStackTraceDepth();
+
+ /**
+ * Returns the specified element of the stack trace.
+ *
+ * package-protection for use by SharedSecrets.
+ *
+ * @param index index of the element to return.
+ * @throws IndexOutOfBoundsException if {@code index < 0 ||
+ * index >= getStackTraceDepth() }
+ */
+ // Android-changed: Use Android-specific nativeGetStackTrace
+ // native StackTraceElement getStackTraceElement(int index);
+ @FastNative
+ private static native StackTraceElement[] nativeGetStackTrace(Object stackState);
+
+
+ /**
+ * Reads a {@code Throwable} from a stream, enforcing
+ * well-formedness constraints on fields. Null entries and
+ * self-pointers are not allowed in the list of {@code
+ * suppressedExceptions}. Null entries are not allowed for stack
+ * trace elements. A null stack trace in the serial form results
+ * in a zero-length stack element array. A single-element stack
+ * trace whose entry is equal to {@code new StackTraceElement("",
+ * "", null, Integer.MIN_VALUE)} results in a {@code null} {@code
+ * stackTrace} field.
+ *
+ * Note that there are no constraints on the value the {@code
+ * cause} field can hold; both {@code null} and {@code this} are
+ * valid values for the field.
+ */
+ private void readObject(ObjectInputStream s)
+ throws IOException, ClassNotFoundException {
+ s.defaultReadObject(); // read in all fields
+ if (suppressedExceptions != null) {
+ List<Throwable> suppressed = null;
+ if (suppressedExceptions.isEmpty()) {
+ // Use the sentinel for a zero-length list
+ // Android-changed: Use empty collection in place of SUPPRESSED_SENTINEL
+ // suppressed = SUPPRESSED_SENTINEL;
+ suppressed = Collections.emptyList();
+ } else { // Copy Throwables to new list
+ suppressed = new ArrayList<>(1);
+ for (Throwable t : suppressedExceptions) {
+ // Enforce constraints on suppressed exceptions in
+ // case of corrupt or malicious stream.
+ if (t == null)
+ throw new NullPointerException(NULL_CAUSE_MESSAGE);
+ if (t == this)
+ throw new IllegalArgumentException(SELF_SUPPRESSION_MESSAGE);
+ suppressed.add(t);
+ }
+ }
+ suppressedExceptions = suppressed;
+ } // else a null suppressedExceptions field remains null
+
+ /*
+ * For zero-length stack traces, use a clone of
+ * UNASSIGNED_STACK rather than UNASSIGNED_STACK itself to
+ * allow identity comparison against UNASSIGNED_STACK in
+ * getOurStackTrace. The identity of UNASSIGNED_STACK in
+ * stackTrace indicates to the getOurStackTrace method that
+ * the stackTrace needs to be constructed from the information
+ * in backtrace.
+ */
+ if (stackTrace != null) {
+ if (stackTrace.length == 0) {
+ // Android-removed: clone() call not needed because of libcore.util.EmptyArray usage
+ // stackTrace = UNASSIGNED_STACK.clone();
+ } else if (stackTrace.length == 1 &&
+ // Check for the marker of an immutable stack trace
+ SentinelHolder.STACK_TRACE_ELEMENT_SENTINEL.equals(stackTrace[0])) {
+ stackTrace = null;
+ } else { // Verify stack trace elements are non-null.
+ for(StackTraceElement ste : stackTrace) {
+ if (ste == null)
+ throw new NullPointerException("null StackTraceElement in serial stream. ");
+ }
+ }
+ } else {
+ // A null stackTrace field in the serial form can result
+ // from an exception serialized without that field in
+ // older JDK releases; treat such exceptions as having
+ // empty stack traces.
+ // Android-changed: Directly create empty array instead of cloning UNASSIGNED_STACK
+ // stackTrace = UNASSIGNED_STACK.clone();
+ stackTrace = new StackTraceElement[0];
+ }
+ }
+
+ /**
+ * Write a {@code Throwable} object to a stream.
+ *
+ * A {@code null} stack trace field is represented in the serial
+ * form as a one-element array whose element is equal to {@code
+ * new StackTraceElement("", "", null, Integer.MIN_VALUE)}.
+ */
+ private synchronized void writeObject(ObjectOutputStream s)
+ throws IOException {
+ // Ensure that the stackTrace field is initialized to a
+ // non-null value, if appropriate. As of JDK 7, a null stack
+ // trace field is a valid value indicating the stack trace
+ // should not be set.
+ getOurStackTrace();
+
+ StackTraceElement[] oldStackTrace = stackTrace;
+ try {
+ if (stackTrace == null)
+ stackTrace = SentinelHolder.STACK_TRACE_SENTINEL;
+ s.defaultWriteObject();
+ } finally {
+ stackTrace = oldStackTrace;
+ }
+ }
+
+ /**
+ * Appends the specified exception to the exceptions that were
+ * suppressed in order to deliver this exception. This method is
+ * thread-safe and typically called (automatically and implicitly)
+ * by the {@code try}-with-resources statement.
+ *
+ * <p>The suppression behavior is enabled <em>unless</em> disabled
+ * {@linkplain #Throwable(String, Throwable, boolean, boolean) via
+ * a constructor}. When suppression is disabled, this method does
+ * nothing other than to validate its argument.
+ *
+ * <p>Note that when one exception {@linkplain
+ * #initCause(Throwable) causes} another exception, the first
+ * exception is usually caught and then the second exception is
+ * thrown in response. In other words, there is a causal
+ * connection between the two exceptions.
+ *
+ * In contrast, there are situations where two independent
+ * exceptions can be thrown in sibling code blocks, in particular
+ * in the {@code try} block of a {@code try}-with-resources
+ * statement and the compiler-generated {@code finally} block
+ * which closes the resource.
+ *
+ * In these situations, only one of the thrown exceptions can be
+ * propagated. In the {@code try}-with-resources statement, when
+ * there are two such exceptions, the exception originating from
+ * the {@code try} block is propagated and the exception from the
+ * {@code finally} block is added to the list of exceptions
+ * suppressed by the exception from the {@code try} block. As an
+ * exception unwinds the stack, it can accumulate multiple
+ * suppressed exceptions.
+ *
+ * <p>An exception may have suppressed exceptions while also being
+ * caused by another exception. Whether or not an exception has a
+ * cause is semantically known at the time of its creation, unlike
+ * whether or not an exception will suppress other exceptions
+ * which is typically only determined after an exception is
+ * thrown.
+ *
+ * <p>Note that programmer written code is also able to take
+ * advantage of calling this method in situations where there are
+ * multiple sibling exceptions and only one can be propagated.
+ *
+ * @param exception the exception to be added to the list of
+ * suppressed exceptions
+ * @throws IllegalArgumentException if {@code exception} is this
+ * throwable; a throwable cannot suppress itself.
+ * @throws NullPointerException if {@code exception} is {@code null}
+ * @since 1.7
+ */
+ public final synchronized void addSuppressed(Throwable exception) {
+ if (exception == this)
+ throw new IllegalArgumentException(SELF_SUPPRESSION_MESSAGE, exception);
+
+ if (exception == null)
+ throw new NullPointerException(NULL_CAUSE_MESSAGE);
+
+ if (suppressedExceptions == null) // Suppressed exceptions not recorded
+ return;
+
+ // Android-changed: Use empty collection in place of SUPPRESSED_SENTINEL
+ // if (suppressedExceptions == SUPPRESSED_SENTINEL)
+ if (suppressedExceptions.isEmpty())
+ suppressedExceptions = new ArrayList<>(1);
+
+ suppressedExceptions.add(exception);
+ }
+
+ // Android-changed: Lazily initialize EMPTY_THROWABLE_ARRAY
+ // private static final Throwable[] EMPTY_THROWABLE_ARRAY = new Throwable[0];
+ private static Throwable[] EMPTY_THROWABLE_ARRAY;
+
+ /**
+ * Returns an array containing all of the exceptions that were
+ * suppressed, typically by the {@code try}-with-resources
+ * statement, in order to deliver this exception.
+ *
+ * If no exceptions were suppressed or {@linkplain
+ * #Throwable(String, Throwable, boolean, boolean) suppression is
+ * disabled}, an empty array is returned. This method is
+ * thread-safe. Writes to the returned array do not affect future
+ * calls to this method.
+ *
+ * @return an array containing all of the exceptions that were
+ * suppressed to deliver this exception.
+ * @since 1.7
+ */
+ public final synchronized Throwable[] getSuppressed() {
+ // Android-added: Lazily initialize EMPTY_THROWABLE_ARRAY
+ if (EMPTY_THROWABLE_ARRAY == null) {
+ EMPTY_THROWABLE_ARRAY = new Throwable[0];
+ }
+
+ // Android-changed: Use empty collection in place of SUPPRESSED_SENTINEL
+ // if (suppressedExceptions == SUPPRESSED_SENTINEL ||
+ // suppressedExceptions == null)
+ if (suppressedExceptions == null || suppressedExceptions.isEmpty())
+ return EMPTY_THROWABLE_ARRAY;
+ else
+ return suppressedExceptions.toArray(EMPTY_THROWABLE_ARRAY);
+ }
+}
diff --git a/java/lang/TypeNotPresentException.java b/java/lang/TypeNotPresentException.java
new file mode 100644
index 0000000..65a0207
--- /dev/null
+++ b/java/lang/TypeNotPresentException.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2003, 2008, 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;
+
+/**
+ * Thrown when an application tries to access a type using a string
+ * representing the type's name, but no definition for the type with
+ * the specified name can be found. This exception differs from
+ * {@link ClassNotFoundException} in that <tt>ClassNotFoundException</tt> is a
+ * checked exception, whereas this exception is unchecked.
+ *
+ * <p>Note that this exception may be used when undefined type variables
+ * are accessed as well as when types (e.g., classes, interfaces or
+ * annotation types) are loaded.
+ * In particular, this exception can be thrown by the {@linkplain
+ * java.lang.reflect.AnnotatedElement API used to read annotations
+ * reflectively}.
+ *
+ * @author Josh Bloch
+ * @see java.lang.reflect.AnnotatedElement
+ * @since 1.5
+ */
+public class TypeNotPresentException extends RuntimeException {
+ private static final long serialVersionUID = -5101214195716534496L;
+
+ private String typeName;
+
+ /**
+ * Constructs a <tt>TypeNotPresentException</tt> for the named type
+ * with the specified cause.
+ *
+ * @param typeName the fully qualified name of the unavailable type
+ * @param cause the exception that was thrown when the system attempted to
+ * load the named type, or <tt>null</tt> if unavailable or inapplicable
+ */
+ public TypeNotPresentException(String typeName, Throwable cause) {
+ super("Type " + typeName + " not present", cause);
+ this.typeName = typeName;
+ }
+
+ /**
+ * Returns the fully qualified name of the unavailable type.
+ *
+ * @return the fully qualified name of the unavailable type
+ */
+ public String typeName() { return typeName;}
+}
diff --git a/java/lang/UNIXProcess.java b/java/lang/UNIXProcess.java
new file mode 100644
index 0000000..40fd8bb
--- /dev/null
+++ b/java/lang/UNIXProcess.java
@@ -0,0 +1,331 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1995, 2010, 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;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayInputStream;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Arrays;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ThreadFactory;
+import java.security.AccessController;
+import static java.security.AccessController.doPrivileged;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+/**
+ * java.lang.Process subclass in the UNIX environment.
+ *
+ * @author Mario Wolczko and Ross Knippel.
+ * @author Konstantin Kladko (ported to Linux)
+ * @author Martin Buchholz
+ */
+final class UNIXProcess extends Process {
+ private final int pid;
+ private int exitcode;
+ private boolean hasExited;
+
+ private /* final */ OutputStream stdin;
+ private /* final */ InputStream stdout;
+ private /* final */ InputStream stderr;
+
+ /* this is for the reaping thread */
+ private native int waitForProcessExit(int pid);
+
+ /**
+ * Create a process using fork(2) and exec(2).
+ *
+ * @param fds an array of three file descriptors.
+ * Indexes 0, 1, and 2 correspond to standard input,
+ * standard output and standard error, respectively. On
+ * input, a value of -1 means to create a pipe to connect
+ * child and parent processes. On output, a value which
+ * is not -1 is the parent pipe fd corresponding to the
+ * pipe which has been created. An element of this array
+ * is -1 on input if and only if it is <em>not</em> -1 on
+ * output.
+ * @return the pid of the subprocess
+ */
+ private native int forkAndExec(byte[] prog,
+ byte[] argBlock, int argc,
+ byte[] envBlock, int envc,
+ byte[] dir,
+ int[] fds,
+ boolean redirectErrorStream)
+ throws IOException;
+
+ /**
+ * The thread factory used to create "process reaper" daemon threads.
+ */
+ private static class ProcessReaperThreadFactory implements ThreadFactory {
+ private final static ThreadGroup group = getRootThreadGroup();
+
+ private static ThreadGroup getRootThreadGroup() {
+ return doPrivileged(new PrivilegedAction<ThreadGroup> () {
+ public ThreadGroup run() {
+ ThreadGroup root = Thread.currentThread().getThreadGroup();
+ while (root.getParent() != null)
+ root = root.getParent();
+ return root;
+ }});
+ }
+
+ public Thread newThread(Runnable grimReaper) {
+ // Our thread stack requirement is quite modest.
+ Thread t = new Thread(group, grimReaper, "process reaper", 32768);
+ t.setDaemon(true);
+ // A small attempt (probably futile) to avoid priority inversion
+ t.setPriority(Thread.MAX_PRIORITY);
+ return t;
+ }
+ }
+
+ /**
+ * The thread pool of "process reaper" daemon threads.
+ */
+ private static final Executor processReaperExecutor =
+ doPrivileged(new PrivilegedAction<Executor>() {
+ public Executor run() {
+ return Executors.newCachedThreadPool
+ (new ProcessReaperThreadFactory());
+ }});
+
+ UNIXProcess(final byte[] prog,
+ final byte[] argBlock, final int argc,
+ final byte[] envBlock, final int envc,
+ final byte[] dir,
+ final int[] fds,
+ final boolean redirectErrorStream)
+ throws IOException {
+
+ pid = forkAndExec(prog,
+ argBlock, argc,
+ envBlock, envc,
+ dir,
+ fds,
+ redirectErrorStream);
+
+ try {
+ doPrivileged(new PrivilegedExceptionAction<Void>() {
+ public Void run() throws IOException {
+ initStreams(fds);
+ return null;
+ }});
+ } catch (PrivilegedActionException ex) {
+ throw (IOException) ex.getException();
+ }
+ }
+
+ static FileDescriptor newFileDescriptor(int fd) {
+ FileDescriptor fileDescriptor = new FileDescriptor();
+ fileDescriptor.setInt$(fd);
+ return fileDescriptor;
+ }
+
+ void initStreams(int[] fds) throws IOException {
+ stdin = (fds[0] == -1) ?
+ ProcessBuilder.NullOutputStream.INSTANCE :
+ new ProcessPipeOutputStream(fds[0]);
+
+ stdout = (fds[1] == -1) ?
+ ProcessBuilder.NullInputStream.INSTANCE :
+ new ProcessPipeInputStream(fds[1]);
+
+ stderr = (fds[2] == -1) ?
+ ProcessBuilder.NullInputStream.INSTANCE :
+ new ProcessPipeInputStream(fds[2]);
+
+ processReaperExecutor.execute(new Runnable() {
+ public void run() {
+ int exitcode = waitForProcessExit(pid);
+ UNIXProcess.this.processExited(exitcode);
+ }});
+ }
+
+ void processExited(int exitcode) {
+ synchronized (this) {
+ this.exitcode = exitcode;
+ hasExited = true;
+ notifyAll();
+ }
+
+ if (stdout instanceof ProcessPipeInputStream)
+ ((ProcessPipeInputStream) stdout).processExited();
+
+ if (stderr instanceof ProcessPipeInputStream)
+ ((ProcessPipeInputStream) stderr).processExited();
+
+ if (stdin instanceof ProcessPipeOutputStream)
+ ((ProcessPipeOutputStream) stdin).processExited();
+ }
+
+ public OutputStream getOutputStream() {
+ return stdin;
+ }
+
+ public InputStream getInputStream() {
+ return stdout;
+ }
+
+ public InputStream getErrorStream() {
+ return stderr;
+ }
+
+ public synchronized int waitFor() throws InterruptedException {
+ while (!hasExited) {
+ wait();
+ }
+ return exitcode;
+ }
+
+ public synchronized int exitValue() {
+ if (!hasExited) {
+ throw new IllegalThreadStateException("process hasn't exited");
+ }
+ return exitcode;
+ }
+
+ private static native void destroyProcess(int pid);
+ public void destroy() {
+ // There is a risk that pid will be recycled, causing us to
+ // kill the wrong process! So we only terminate processes
+ // that appear to still be running. Even with this check,
+ // there is an unavoidable race condition here, but the window
+ // is very small, and OSes try hard to not recycle pids too
+ // soon, so this is quite safe.
+ synchronized (this) {
+ if (!hasExited)
+ destroyProcess(pid);
+ }
+ try { stdin.close(); } catch (IOException ignored) {}
+ try { stdout.close(); } catch (IOException ignored) {}
+ try { stderr.close(); } catch (IOException ignored) {}
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder("Process[pid=");
+ sb.append(pid);
+ if (hasExited) {
+ sb.append(" ,hasExited=true, exitcode=");
+ sb.append(exitcode);
+ sb.append("]");
+ } else {
+ sb.append(", hasExited=false]");
+ }
+
+ return sb.toString();
+ }
+
+ /* This routine initializes JNI field offsets for the class */
+ private static native void initIDs();
+
+ static {
+ initIDs();
+ }
+
+ /**
+ * A buffered input stream for a subprocess pipe file descriptor
+ * that allows the underlying file descriptor to be reclaimed when
+ * the process exits, via the processExited hook.
+ *
+ * This is tricky because we do not want the user-level InputStream to be
+ * closed until the user invokes close(), and we need to continue to be
+ * able to read any buffered data lingering in the OS pipe buffer.
+ */
+ static class ProcessPipeInputStream extends BufferedInputStream {
+ ProcessPipeInputStream(int fd) {
+ super(new FileInputStream(newFileDescriptor(fd), true /* isFdOwner */));
+ }
+
+ private static byte[] drainInputStream(InputStream in)
+ throws IOException {
+ if (in == null) return null;
+ int n = 0;
+ int j;
+ byte[] a = null;
+ while ((j = in.available()) > 0) {
+ a = (a == null) ? new byte[j] : Arrays.copyOf(a, n + j);
+ n += in.read(a, n, j);
+ }
+ return (a == null || n == a.length) ? a : Arrays.copyOf(a, n);
+ }
+
+ /** Called by the process reaper thread when the process exits. */
+ synchronized void processExited() {
+ // Most BufferedInputStream methods are synchronized, but close()
+ // is not, and so we have to handle concurrent racing close().
+ try {
+ InputStream in = this.in;
+ if (in != null) {
+ byte[] stragglers = drainInputStream(in);
+ in.close();
+ this.in = (stragglers == null) ?
+ ProcessBuilder.NullInputStream.INSTANCE :
+ new ByteArrayInputStream(stragglers);
+ if (buf == null) // asynchronous close()?
+ this.in = null;
+ }
+ } catch (IOException ignored) {
+ // probably an asynchronous close().
+ }
+ }
+ }
+
+ /**
+ * A buffered output stream for a subprocess pipe file descriptor
+ * that allows the underlying file descriptor to be reclaimed when
+ * the process exits, via the processExited hook.
+ */
+ static class ProcessPipeOutputStream extends BufferedOutputStream {
+ ProcessPipeOutputStream(int fd) {
+ super(new FileOutputStream(newFileDescriptor(fd), true /* isFdOwner */));
+ }
+
+ /** Called by the process reaper thread when the process exits. */
+ synchronized void processExited() {
+ OutputStream out = this.out;
+ if (out != null) {
+ try {
+ out.close();
+ } catch (IOException ignored) {
+ // We know of no reason to get an IOException, but if
+ // we do, there's nothing else to do but carry on.
+ }
+ this.out = ProcessBuilder.NullOutputStream.INSTANCE;
+ }
+ }
+ }
+}
diff --git a/java/lang/UnknownError.java b/java/lang/UnknownError.java
new file mode 100644
index 0000000..0706f81
--- /dev/null
+++ b/java/lang/UnknownError.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 1995, 2008, 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;
+
+/**
+ * Thrown when an unknown but serious exception has occurred in the
+ * Java Virtual Machine.
+ *
+ * @author unascribed
+ * @since JDK1.0
+ */
+public
+class UnknownError extends VirtualMachineError {
+ private static final long serialVersionUID = 2524784860676771849L;
+
+ /**
+ * Constructs an <code>UnknownError</code> with no detail message.
+ */
+ public UnknownError() {
+ super();
+ }
+
+ /**
+ * Constructs an <code>UnknownError</code> with the specified detail
+ * message.
+ *
+ * @param s the detail message.
+ */
+ public UnknownError(String s) {
+ super(s);
+ }
+}
diff --git a/java/lang/UnsatisfiedLinkError.java b/java/lang/UnsatisfiedLinkError.java
new file mode 100644
index 0000000..32a8ba8
--- /dev/null
+++ b/java/lang/UnsatisfiedLinkError.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 1994, 2008, 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;
+
+/**
+ * Thrown if the Java Virtual Machine cannot find an appropriate
+ * native-language definition of a method declared <code>native</code>.
+ *
+ * @author unascribed
+ * @see java.lang.Runtime
+ * @since JDK1.0
+ */
+public
+class UnsatisfiedLinkError extends LinkageError {
+ private static final long serialVersionUID = -4019343241616879428L;
+
+ /**
+ * Constructs an <code>UnsatisfiedLinkError</code> with no detail message.
+ */
+ public UnsatisfiedLinkError() {
+ super();
+ }
+
+ /**
+ * Constructs an <code>UnsatisfiedLinkError</code> with the
+ * specified detail message.
+ *
+ * @param s the detail message.
+ */
+ public UnsatisfiedLinkError(String s) {
+ super(s);
+ }
+}
diff --git a/java/lang/UnsupportedClassVersionError.java b/java/lang/UnsupportedClassVersionError.java
new file mode 100644
index 0000000..aed4d04
--- /dev/null
+++ b/java/lang/UnsupportedClassVersionError.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 1998, 2008, 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;
+
+/**
+ * Thrown when the Java Virtual Machine attempts to read a class
+ * file and determines that the major and minor version numbers
+ * in the file are not supported.
+ *
+ * @since 1.2
+ */
+public
+class UnsupportedClassVersionError extends ClassFormatError {
+ private static final long serialVersionUID = -7123279212883497373L;
+
+ /**
+ * Constructs a <code>UnsupportedClassVersionError</code>
+ * with no detail message.
+ */
+ public UnsupportedClassVersionError() {
+ super();
+ }
+
+ /**
+ * Constructs a <code>UnsupportedClassVersionError</code> with
+ * the specified detail message.
+ *
+ * @param s the detail message.
+ */
+ public UnsupportedClassVersionError(String s) {
+ super(s);
+ }
+}
diff --git a/java/lang/UnsupportedOperationException.java b/java/lang/UnsupportedOperationException.java
new file mode 100644
index 0000000..fcb355c
--- /dev/null
+++ b/java/lang/UnsupportedOperationException.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 1997, 2006, 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;
+
+/**
+ * Thrown to indicate that the requested operation is not supported.<p>
+ *
+ * This class is a member of the
+ * <a href="{@docRoot}/../technotes/guides/collections/index.html">
+ * Java Collections Framework</a>.
+ *
+ * @author Josh Bloch
+ * @since 1.2
+ */
+public class UnsupportedOperationException extends RuntimeException {
+ /**
+ * Constructs an UnsupportedOperationException with no detail message.
+ */
+ public UnsupportedOperationException() {
+ }
+
+ /**
+ * Constructs an UnsupportedOperationException with the specified
+ * detail message.
+ *
+ * @param message the detail message
+ */
+ public UnsupportedOperationException(String message) {
+ super(message);
+ }
+
+ /**
+ * Constructs a new exception with the specified detail message and
+ * cause.
+ *
+ * <p>Note that the detail message associated with <code>cause</code> is
+ * <i>not</i> automatically incorporated in this exception's detail
+ * message.
+ *
+ * @param message the detail message (which is saved for later retrieval
+ * by the {@link Throwable#getMessage()} method).
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link Throwable#getCause()} method). (A <tt>null</tt> value
+ * is permitted, and indicates that the cause is nonexistent or
+ * unknown.)
+ * @since 1.5
+ */
+ public UnsupportedOperationException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * Constructs a new exception with the specified cause and a detail
+ * message of <tt>(cause==null ? null : cause.toString())</tt> (which
+ * typically contains the class and detail message of <tt>cause</tt>).
+ * This constructor is useful for exceptions that are little more than
+ * wrappers for other throwables (for example, {@link
+ * java.security.PrivilegedActionException}).
+ *
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link Throwable#getCause()} method). (A <tt>null</tt> value is
+ * permitted, and indicates that the cause is nonexistent or
+ * unknown.)
+ * @since 1.5
+ */
+ public UnsupportedOperationException(Throwable cause) {
+ super(cause);
+ }
+
+ static final long serialVersionUID = -1242599979055084673L;
+}
diff --git a/java/lang/VMClassLoader.java b/java/lang/VMClassLoader.java
new file mode 100644
index 0000000..d44f888
--- /dev/null
+++ b/java/lang/VMClassLoader.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.lang;
+
+import dalvik.annotation.optimization.FastNative;
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLStreamHandler;
+import java.util.ArrayList;
+import java.util.List;
+import libcore.io.ClassPathURLStreamHandler;
+
+class VMClassLoader {
+
+ private static final ClassPathURLStreamHandler[] bootClassPathUrlHandlers;
+ static {
+ bootClassPathUrlHandlers = createBootClassPathUrlHandlers();
+ }
+
+ /**
+ * Creates an array of ClassPathURLStreamHandler objects for handling resource loading from
+ * the boot classpath.
+ */
+ private static ClassPathURLStreamHandler[] createBootClassPathUrlHandlers() {
+ String[] bootClassPathEntries = getBootClassPathEntries();
+ ArrayList<URLStreamHandler> urlStreamHandlers =
+ new ArrayList<URLStreamHandler>(bootClassPathEntries.length);
+ for (String bootClassPathEntry : bootClassPathEntries) {
+ try {
+ String entryUri = new File(bootClassPathEntry).toURI().toString();
+
+ // We assume all entries are zip or jar files.
+ URLStreamHandler urlStreamHandler =
+ new ClassPathURLStreamHandler(bootClassPathEntry);
+ urlStreamHandlers.add(urlStreamHandler);
+ } catch (IOException e) {
+ // Skip it
+ System.logE("Unable to open boot classpath entry: " + bootClassPathEntry, e);
+ }
+ }
+ return urlStreamHandlers.toArray(new ClassPathURLStreamHandler[urlStreamHandlers.size()]);
+ }
+
+ /**
+ * Get a resource from a file in the bootstrap class path.
+ *
+ * We assume that the bootclasspath can't change once the VM has started.
+ * This assumption seems to be supported by the spec.
+ */
+ static URL getResource(String name) {
+ for (ClassPathURLStreamHandler urlHandler : bootClassPathUrlHandlers) {
+ URL url = urlHandler.getEntryUrlOrNull(name);
+ if (url != null) {
+ return url;
+ }
+ }
+ return null;
+ }
+
+ /*
+ * Get an enumeration with all matching resources.
+ */
+ static List<URL> getResources(String name) {
+ ArrayList<URL> list = new ArrayList<URL>();
+ for (ClassPathURLStreamHandler urlHandler : bootClassPathUrlHandlers) {
+ URL url = urlHandler.getEntryUrlOrNull(name);
+ if (url != null) {
+ list.add(url);
+ }
+ }
+ return list;
+ }
+
+ @FastNative
+ native static Class findLoadedClass(ClassLoader cl, String name);
+
+ /**
+ * Boot class path manipulation, for getResources().
+ */
+ native private static String[] getBootClassPathEntries();
+
+}
diff --git a/java/lang/VerifyError.java b/java/lang/VerifyError.java
new file mode 100644
index 0000000..9ca9f90
--- /dev/null
+++ b/java/lang/VerifyError.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 1995, 2008, 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;
+
+/**
+ * Thrown when the "verifier" detects that a class file,
+ * though well formed, contains some sort of internal inconsistency
+ * or security problem.
+ *
+ * @author unascribed
+ * @since JDK1.0
+ */
+public
+class VerifyError extends LinkageError {
+ private static final long serialVersionUID = 7001962396098498785L;
+
+ /**
+ * Constructs an <code>VerifyError</code> with no detail message.
+ */
+ public VerifyError() {
+ super();
+ }
+
+ /**
+ * Constructs an <code>VerifyError</code> with the specified detail message.
+ *
+ * @param s the detail message.
+ */
+ public VerifyError(String s) {
+ super(s);
+ }
+}
diff --git a/java/lang/VirtualMachineError.java b/java/lang/VirtualMachineError.java
new file mode 100644
index 0000000..c0a2a92
--- /dev/null
+++ b/java/lang/VirtualMachineError.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 1995, 2011, 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;
+
+/**
+ * Thrown to indicate that the Java Virtual Machine is broken or has
+ * run out of resources necessary for it to continue operating.
+ *
+ *
+ * @author Frank Yellin
+ * @since JDK1.0
+ */
+abstract public class VirtualMachineError extends Error {
+ private static final long serialVersionUID = 4161983926571568670L;
+
+ /**
+ * Constructs a <code>VirtualMachineError</code> with no detail message.
+ */
+ public VirtualMachineError() {
+ super();
+ }
+
+ /**
+ * Constructs a <code>VirtualMachineError</code> with the specified
+ * detail message.
+ *
+ * @param message the detail message.
+ */
+ public VirtualMachineError(String message) {
+ super(message);
+ }
+
+ /**
+ * Constructs a {@code VirtualMachineError} with the specified
+ * detail message and cause. <p>Note that the detail message
+ * associated with {@code cause} is <i>not</i> automatically
+ * incorporated in this error's detail message.
+ *
+ * @param message the detail message (which is saved for later retrieval
+ * by the {@link #getMessage()} method).
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link #getCause()} method). (A {@code null} value is
+ * permitted, and indicates that the cause is nonexistent or
+ * unknown.)
+ * @since 1.8
+ */
+ public VirtualMachineError(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * Constructs an a {@code VirtualMachineError} with the specified
+ * cause and a detail message of {@code (cause==null ? null :
+ * cause.toString())} (which typically contains the class and
+ * detail message of {@code cause}).
+ *
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link #getCause()} method). (A {@code null} value is
+ * permitted, and indicates that the cause is nonexistent or
+ * unknown.)
+ * @since 1.8
+ */
+ public VirtualMachineError(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/java/lang/Void.java b/java/lang/Void.java
new file mode 100644
index 0000000..96dbe6d
--- /dev/null
+++ b/java/lang/Void.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 1996, 2011, 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;
+
+/**
+ * The {@code Void} class is an uninstantiable placeholder class to hold a
+ * reference to the {@code Class} object representing the Java keyword
+ * void.
+ *
+ * @author unascribed
+ * @since JDK1.1
+ */
+public final
+class Void {
+
+ /**
+ * The {@code Class} object representing the pseudo-type corresponding to
+ * the keyword {@code void}.
+ */
+ @SuppressWarnings("unchecked")
+ public static final Class<Void> TYPE = (Class<Void>) Class.getPrimitiveClass("void");
+
+ /*
+ * The Void class cannot be instantiated.
+ */
+ private Void() {}
+}
diff --git a/java/lang/annotation/Annotation.java b/java/lang/annotation/Annotation.java
new file mode 100644
index 0000000..7de6746
--- /dev/null
+++ b/java/lang/annotation/Annotation.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2003, 2013, 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.annotation;
+
+/**
+ * The common interface extended by all annotation types. Note that an
+ * interface that manually extends this one does <i>not</i> define
+ * an annotation type. Also note that this interface does not itself
+ * define an annotation type.
+ *
+ * More information about annotation types can be found in section 9.6 of
+ * <cite>The Java™ Language Specification</cite>.
+ *
+ * The {@link java.lang.reflect.AnnotatedElement} interface discusses
+ * compatibility concerns when evolving an annotation type from being
+ * non-repeatable to being repeatable.
+ *
+ * @author Josh Bloch
+ * @since 1.5
+ */
+public interface Annotation {
+ /**
+ * Returns true if the specified object represents an annotation
+ * that is logically equivalent to this one. In other words,
+ * returns true if the specified object is an instance of the same
+ * annotation type as this instance, all of whose members are equal
+ * to the corresponding member of this annotation, as defined below:
+ * <ul>
+ * <li>Two corresponding primitive typed members whose values are
+ * <tt>x</tt> and <tt>y</tt> are considered equal if <tt>x == y</tt>,
+ * unless their type is <tt>float</tt> or <tt>double</tt>.
+ *
+ * <li>Two corresponding <tt>float</tt> members whose values
+ * are <tt>x</tt> and <tt>y</tt> are considered equal if
+ * <tt>Float.valueOf(x).equals(Float.valueOf(y))</tt>.
+ * (Unlike the <tt>==</tt> operator, NaN is considered equal
+ * to itself, and <tt>0.0f</tt> unequal to <tt>-0.0f</tt>.)
+ *
+ * <li>Two corresponding <tt>double</tt> members whose values
+ * are <tt>x</tt> and <tt>y</tt> are considered equal if
+ * <tt>Double.valueOf(x).equals(Double.valueOf(y))</tt>.
+ * (Unlike the <tt>==</tt> operator, NaN is considered equal
+ * to itself, and <tt>0.0</tt> unequal to <tt>-0.0</tt>.)
+ *
+ * <li>Two corresponding <tt>String</tt>, <tt>Class</tt>, enum, or
+ * annotation typed members whose values are <tt>x</tt> and <tt>y</tt>
+ * are considered equal if <tt>x.equals(y)</tt>. (Note that this
+ * definition is recursive for annotation typed members.)
+ *
+ * <li>Two corresponding array typed members <tt>x</tt> and <tt>y</tt>
+ * are considered equal if <tt>Arrays.equals(x, y)</tt>, for the
+ * appropriate overloading of {@link java.util.Arrays#equals}.
+ * </ul>
+ *
+ * @return true if the specified object represents an annotation
+ * that is logically equivalent to this one, otherwise false
+ */
+ boolean equals(Object obj);
+
+ /**
+ * Returns the hash code of this annotation, as defined below:
+ *
+ * <p>The hash code of an annotation is the sum of the hash codes
+ * of its members (including those with default values), as defined
+ * below:
+ *
+ * The hash code of an annotation member is (127 times the hash code
+ * of the member-name as computed by {@link String#hashCode()}) XOR
+ * the hash code of the member-value, as defined below:
+ *
+ * <p>The hash code of a member-value depends on its type:
+ * <ul>
+ * <li>The hash code of a primitive value <tt><i>v</i></tt> is equal to
+ * <tt><i>WrapperType</i>.valueOf(<i>v</i>).hashCode()</tt>, where
+ * <tt><i>WrapperType</i></tt> is the wrapper type corresponding
+ * to the primitive type of <tt><i>v</i></tt> ({@link Byte},
+ * {@link Character}, {@link Double}, {@link Float}, {@link Integer},
+ * {@link Long}, {@link Short}, or {@link Boolean}).
+ *
+ * <li>The hash code of a string, enum, class, or annotation member-value
+ I <tt><i>v</i></tt> is computed as by calling
+ * <tt><i>v</i>.hashCode()</tt>. (In the case of annotation
+ * member values, this is a recursive definition.)
+ *
+ * <li>The hash code of an array member-value is computed by calling
+ * the appropriate overloading of
+ * {@link java.util.Arrays#hashCode(long[]) Arrays.hashCode}
+ * on the value. (There is one overloading for each primitive
+ * type, and one for object reference types.)
+ * </ul>
+ *
+ * @return the hash code of this annotation
+ */
+ int hashCode();
+
+ /**
+ * Returns a string representation of this annotation. The details
+ * of the representation are implementation-dependent, but the following
+ * may be regarded as typical:
+ * <pre>
+ * @com.acme.util.Name(first=Alfred, middle=E., last=Neuman)
+ * </pre>
+ *
+ * @return a string representation of this annotation
+ */
+ String toString();
+
+ /**
+ * Returns the annotation type of this annotation.
+ * @return the annotation type of this annotation
+ */
+ Class<? extends Annotation> annotationType();
+}
diff --git a/java/lang/annotation/AnnotationFormatError.java b/java/lang/annotation/AnnotationFormatError.java
new file mode 100644
index 0000000..f02104f
--- /dev/null
+++ b/java/lang/annotation/AnnotationFormatError.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2004, 2008, 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.annotation;
+
+/**
+ * Thrown when the annotation parser attempts to read an annotation
+ * from a class file and determines that the annotation is malformed.
+ * This error can be thrown by the {@linkplain
+ * java.lang.reflect.AnnotatedElement API used to read annotations
+ * reflectively}.
+ *
+ * @author Josh Bloch
+ * @see java.lang.reflect.AnnotatedElement
+ * @since 1.5
+ */
+public class AnnotationFormatError extends Error {
+ private static final long serialVersionUID = -4256701562333669892L;
+
+ /**
+ * Constructs a new <tt>AnnotationFormatError</tt> with the specified
+ * detail message.
+ *
+ * @param message the detail message.
+ */
+ public AnnotationFormatError(String message) {
+ super(message);
+ }
+
+ /**
+ * Constructs a new <tt>AnnotationFormatError</tt> with the specified
+ * detail message and cause. Note that the detail message associated
+ * with <code>cause</code> is <i>not</i> automatically incorporated in
+ * this error's detail message.
+ *
+ * @param message the detail message
+ * @param cause the cause (A <tt>null</tt> value is permitted, and
+ * indicates that the cause is nonexistent or unknown.)
+ */
+ public AnnotationFormatError(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+
+ /**
+ * Constructs a new <tt>AnnotationFormatError</tt> with the specified
+ * cause and a detail message of
+ * <tt>(cause == null ? null : cause.toString())</tt> (which
+ * typically contains the class and detail message of <tt>cause</tt>).
+ *
+ * @param cause the cause (A <tt>null</tt> value is permitted, and
+ * indicates that the cause is nonexistent or unknown.)
+ */
+ public AnnotationFormatError(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/java/lang/annotation/AnnotationTypeMismatchException.java b/java/lang/annotation/AnnotationTypeMismatchException.java
new file mode 100644
index 0000000..88e2712
--- /dev/null
+++ b/java/lang/annotation/AnnotationTypeMismatchException.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2003, 2008, 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.annotation;
+import java.lang.reflect.Method;
+
+/**
+ * Thrown to indicate that a program has attempted to access an element of
+ * an annotation whose type has changed after the annotation was compiled
+ * (or serialized).
+ * This exception can be thrown by the {@linkplain
+ * java.lang.reflect.AnnotatedElement API used to read annotations
+ * reflectively}.
+ *
+ * @author Josh Bloch
+ * @see java.lang.reflect.AnnotatedElement
+ * @since 1.5
+ */
+public class AnnotationTypeMismatchException extends RuntimeException {
+ private static final long serialVersionUID = 8125925355765570191L;
+
+ /**
+ * The <tt>Method</tt> object for the annotation element.
+ */
+ private final Method element;
+
+ /**
+ * The (erroneous) type of data found in the annotation. This string
+ * may, but is not required to, contain the value as well. The exact
+ * format of the string is unspecified.
+ */
+ private final String foundType;
+
+ /**
+ * Constructs an AnnotationTypeMismatchException for the specified
+ * annotation type element and found data type.
+ *
+ * @param element the <tt>Method</tt> object for the annotation element
+ * @param foundType the (erroneous) type of data found in the annotation.
+ * This string may, but is not required to, contain the value
+ * as well. The exact format of the string is unspecified.
+ */
+ public AnnotationTypeMismatchException(Method element, String foundType) {
+ super("Incorrectly typed data found for annotation element " + element
+ + " (Found data of type " + foundType + ")");
+ this.element = element;
+ this.foundType = foundType;
+ }
+
+ /**
+ * Returns the <tt>Method</tt> object for the incorrectly typed element.
+ *
+ * @return the <tt>Method</tt> object for the incorrectly typed element
+ */
+ public Method element() {
+ return this.element;
+ }
+
+ /**
+ * Returns the type of data found in the incorrectly typed element.
+ * The returned string may, but is not required to, contain the value
+ * as well. The exact format of the string is unspecified.
+ *
+ * @return the type of data found in the incorrectly typed element
+ */
+ public String foundType() {
+ return this.foundType;
+ }
+}
diff --git a/java/lang/annotation/Documented.java b/java/lang/annotation/Documented.java
new file mode 100644
index 0000000..348a312
--- /dev/null
+++ b/java/lang/annotation/Documented.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2003, 2004, 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.annotation;
+
+/**
+ * Indicates that annotations with a type are to be documented by javadoc
+ * and similar tools by default. This type should be used to annotate the
+ * declarations of types whose annotations affect the use of annotated
+ * elements by their clients. If a type declaration is annotated with
+ * Documented, its annotations become part of the public API
+ * of the annotated elements.
+ *
+ * @author Joshua Bloch
+ * @since 1.5
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.ANNOTATION_TYPE)
+public @interface Documented {
+}
diff --git a/java/lang/annotation/ElementType.java b/java/lang/annotation/ElementType.java
new file mode 100644
index 0000000..4590f39
--- /dev/null
+++ b/java/lang/annotation/ElementType.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2003, 2013, 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.annotation;
+
+/**
+ * The constants of this enumerated type provide a simple classification of the
+ * syntactic locations where annotations may appear in a Java program. These
+ * constants are used in {@link Target java.lang.annotation.Target}
+ * meta-annotations to specify where it is legal to write annotations of a
+ * given type.
+ *
+ * <p>The syntactic locations where annotations may appear are split into
+ * <em>declaration contexts</em> , where annotations apply to declarations, and
+ * <em>type contexts</em> , where annotations apply to types used in
+ * declarations and expressions.
+ *
+ * <p>The constants {@link #ANNOTATION_TYPE} , {@link #CONSTRUCTOR} , {@link
+ * #FIELD} , {@link #LOCAL_VARIABLE} , {@link #METHOD} , {@link #PACKAGE} ,
+ * {@link #PARAMETER} , {@link #TYPE} , and {@link #TYPE_PARAMETER} correspond
+ * to the declaration contexts in JLS 9.6.4.1.
+ *
+ * <p>For example, an annotation whose type is meta-annotated with
+ * {@code @Target(ElementType.FIELD)} may only be written as a modifier for a
+ * field declaration.
+ *
+ * <p>The constant {@link #TYPE_USE} corresponds to the 15 type contexts in JLS
+ * 4.11, as well as to two declaration contexts: type declarations (including
+ * annotation type declarations) and type parameter declarations.
+ *
+ * <p>For example, an annotation whose type is meta-annotated with
+ * {@code @Target(ElementType.TYPE_USE)} may be written on the type of a field
+ * (or within the type of the field, if it is a nested, parameterized, or array
+ * type), and may also appear as a modifier for, say, a class declaration.
+ *
+ * <p>The {@code TYPE_USE} constant includes type declarations and type
+ * parameter declarations as a convenience for designers of type checkers which
+ * give semantics to annotation types. For example, if the annotation type
+ * {@code NonNull} is meta-annotated with
+ * {@code @Target(ElementType.TYPE_USE)}, then {@code @NonNull}
+ * {@code class C {...}} could be treated by a type checker as indicating that
+ * all variables of class {@code C} are non-null, while still allowing
+ * variables of other classes to be non-null or not non-null based on whether
+ * {@code @NonNull} appears at the variable's declaration.
+ *
+ * @author Joshua Bloch
+ * @since 1.5
+ * @jls 9.6.4.1 @Target
+ * @jls 4.1 The Kinds of Types and Values
+ */
+public enum ElementType {
+ /** Class, interface (including annotation type), or enum declaration */
+ TYPE,
+
+ /** Field declaration (includes enum constants) */
+ FIELD,
+
+ /** Method declaration */
+ METHOD,
+
+ /** Formal parameter declaration */
+ PARAMETER,
+
+ /** Constructor declaration */
+ CONSTRUCTOR,
+
+ /** Local variable declaration */
+ LOCAL_VARIABLE,
+
+ /** Annotation type declaration */
+ ANNOTATION_TYPE,
+
+ /** Package declaration */
+ PACKAGE,
+
+ /**
+ * Type parameter declaration
+ *
+ * @since 1.8
+ */
+ TYPE_PARAMETER,
+
+ /**
+ * Use of a type
+ *
+ * @since 1.8
+ */
+ TYPE_USE
+}
diff --git a/java/lang/annotation/IncompleteAnnotationException.java b/java/lang/annotation/IncompleteAnnotationException.java
new file mode 100644
index 0000000..241b21a
--- /dev/null
+++ b/java/lang/annotation/IncompleteAnnotationException.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2003, 2013, 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.annotation;
+
+/**
+ * Thrown to indicate that a program has attempted to access an element of
+ * an annotation type that was added to the annotation type definition after
+ * the annotation was compiled (or serialized). This exception will not be
+ * thrown if the new element has a default value.
+ * This exception can be thrown by the {@linkplain
+ * java.lang.reflect.AnnotatedElement API used to read annotations
+ * reflectively}.
+ *
+ * @author Josh Bloch
+ * @see java.lang.reflect.AnnotatedElement
+ * @since 1.5
+ */
+public class IncompleteAnnotationException extends RuntimeException {
+ private static final long serialVersionUID = 8445097402741811912L;
+
+ private Class<? extends Annotation> annotationType;
+ private String elementName;
+
+ /**
+ * Constructs an IncompleteAnnotationException to indicate that
+ * the named element was missing from the specified annotation type.
+ *
+ * @param annotationType the Class object for the annotation type
+ * @param elementName the name of the missing element
+ * @throws NullPointerException if either parameter is {@code null}
+ */
+ public IncompleteAnnotationException(
+ Class<? extends Annotation> annotationType,
+ String elementName) {
+ super(annotationType.getName() + " missing element " +
+ elementName.toString());
+
+ this.annotationType = annotationType;
+ this.elementName = elementName;
+ }
+
+ /**
+ * Returns the Class object for the annotation type with the
+ * missing element.
+ *
+ * @return the Class object for the annotation type with the
+ * missing element
+ */
+ public Class<? extends Annotation> annotationType() {
+ return annotationType;
+ }
+
+ /**
+ * Returns the name of the missing element.
+ *
+ * @return the name of the missing element
+ */
+ public String elementName() {
+ return elementName;
+ }
+}
diff --git a/java/lang/annotation/Inherited.java b/java/lang/annotation/Inherited.java
new file mode 100644
index 0000000..83391e2
--- /dev/null
+++ b/java/lang/annotation/Inherited.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2003, 2013, 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.annotation;
+
+/**
+ * Indicates that an annotation type is automatically inherited. If
+ * an Inherited meta-annotation is present on an annotation type
+ * declaration, and the user queries the annotation type on a class
+ * declaration, and the class declaration has no annotation for this type,
+ * then the class's superclass will automatically be queried for the
+ * annotation type. This process will be repeated until an annotation for this
+ * type is found, or the top of the class hierarchy (Object)
+ * is reached. If no superclass has an annotation for this type, then
+ * the query will indicate that the class in question has no such annotation.
+ *
+ * <p>Note that this meta-annotation type has no effect if the annotated
+ * type is used to annotate anything other than a class. Note also
+ * that this meta-annotation only causes annotations to be inherited
+ * from superclasses; annotations on implemented interfaces have no
+ * effect.
+ *
+ * @author Joshua Bloch
+ * @since 1.5
+ * @jls 9.6.3.3 @Inherited
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.ANNOTATION_TYPE)
+public @interface Inherited {
+}
diff --git a/java/lang/annotation/Native.java b/java/lang/annotation/Native.java
new file mode 100644
index 0000000..861c1ff
--- /dev/null
+++ b/java/lang/annotation/Native.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2012, 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.annotation;
+
+
+/**
+ * Indicates that a field defining a constant value may be referenced
+ * from native code.
+ *
+ * The annotation may be used as a hint by tools that generate native
+ * header files to determine whether a header file is required, and
+ * if so, what declarations it should contain.
+ *
+ * @since 1.8
+ */
+@Documented
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.SOURCE)
+public @interface Native {
+}
diff --git a/java/lang/annotation/Repeatable.java b/java/lang/annotation/Repeatable.java
new file mode 100644
index 0000000..7a2daa8
--- /dev/null
+++ b/java/lang/annotation/Repeatable.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2012, 2013, 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.annotation;
+
+/**
+ * The annotation type {@code java.lang.annotation.Repeatable} is
+ * used to indicate that the annotation type whose declaration it
+ * (meta-)annotates is <em>repeatable</em>. The value of
+ * {@code @Repeatable} indicates the <em>containing annotation
+ * type</em> for the repeatable annotation type.
+ *
+ * @since 1.8
+ * @jls 9.6 Annotation Types
+ * @jls 9.7 Annotations
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.ANNOTATION_TYPE)
+public @interface Repeatable {
+ /**
+ * Indicates the <em>containing annotation type</em> for the
+ * repeatable annotation type.
+ * @return the containing annotation type
+ */
+ Class<? extends Annotation> value();
+}
diff --git a/java/lang/annotation/Retention.java b/java/lang/annotation/Retention.java
new file mode 100644
index 0000000..5efa43f
--- /dev/null
+++ b/java/lang/annotation/Retention.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2003, 2013, 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.annotation;
+
+/**
+ * Indicates how long annotations with the annotated type are to
+ * be retained. If no Retention annotation is present on
+ * an annotation type declaration, the retention policy defaults to
+ * {@code RetentionPolicy.CLASS}.
+ *
+ * <p>A Retention meta-annotation has effect only if the
+ * meta-annotated type is used directly for annotation. It has no
+ * effect if the meta-annotated type is used as a member type in
+ * another annotation type.
+ *
+ * @author Joshua Bloch
+ * @since 1.5
+ * @jls 9.6.3.2 @Retention
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.ANNOTATION_TYPE)
+public @interface Retention {
+ /**
+ * Returns the retention policy.
+ * @return the retention policy
+ */
+ RetentionPolicy value();
+}
diff --git a/java/lang/annotation/RetentionPolicy.java b/java/lang/annotation/RetentionPolicy.java
new file mode 100644
index 0000000..82aa198
--- /dev/null
+++ b/java/lang/annotation/RetentionPolicy.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2003, 2004, 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.annotation;
+
+/**
+ * Annotation retention policy. The constants of this enumerated type
+ * describe the various policies for retaining annotations. They are used
+ * in conjunction with the {@link Retention} meta-annotation type to specify
+ * how long annotations are to be retained.
+ *
+ * @author Joshua Bloch
+ * @since 1.5
+ */
+public enum RetentionPolicy {
+ /**
+ * Annotations are to be discarded by the compiler.
+ */
+ SOURCE,
+
+ /**
+ * Annotations are to be recorded in the class file by the compiler
+ * but need not be retained by the VM at run time. This is the default
+ * behavior.
+ */
+ CLASS,
+
+ /**
+ * Annotations are to be recorded in the class file by the compiler and
+ * retained by the VM at run time, so they may be read reflectively.
+ *
+ * @see java.lang.reflect.AnnotatedElement
+ */
+ RUNTIME
+}
diff --git a/java/lang/annotation/Target.java b/java/lang/annotation/Target.java
new file mode 100644
index 0000000..1ad4056
--- /dev/null
+++ b/java/lang/annotation/Target.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2003, 2013, 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.annotation;
+
+/**
+ * Indicates the contexts in which an annotation type is applicable. The
+ * declaration contexts and type contexts in which an annotation type may be
+ * applicable are specified in JLS 9.6.4.1, and denoted in source code by enum
+ * constants of {@link ElementType java.lang.annotation.ElementType}.
+ *
+ * <p>If an {@code @Target} meta-annotation is not present on an annotation type
+ * {@code T} , then an annotation of type {@code T} may be written as a
+ * modifier for any declaration except a type parameter declaration.
+ *
+ * <p>If an {@code @Target} meta-annotation is present, the compiler will enforce
+ * the usage restrictions indicated by {@code ElementType}
+ * enum constants, in line with JLS 9.7.4.
+ *
+ * <p>For example, this {@code @Target} meta-annotation indicates that the
+ * declared type is itself a meta-annotation type. It can only be used on
+ * annotation type declarations:
+ * <pre>
+ * @Target(ElementType.ANNOTATION_TYPE)
+ * public @interface MetaAnnotationType {
+ * ...
+ * }
+ * </pre>
+ *
+ * <p>This {@code @Target} meta-annotation indicates that the declared type is
+ * intended solely for use as a member type in complex annotation type
+ * declarations. It cannot be used to annotate anything directly:
+ * <pre>
+ * @Target({})
+ * public @interface MemberType {
+ * ...
+ * }
+ * </pre>
+ *
+ * <p>It is a compile-time error for a single {@code ElementType} constant to
+ * appear more than once in an {@code @Target} annotation. For example, the
+ * following {@code @Target} meta-annotation is illegal:
+ * <pre>
+ * @Target({ElementType.FIELD, ElementType.METHOD, ElementType.FIELD})
+ * public @interface Bogus {
+ * ...
+ * }
+ * </pre>
+ *
+ * @since 1.5
+ * @jls 9.6.4.1 @Target
+ * @jls 9.7.4 Where Annotations May Appear
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.ANNOTATION_TYPE)
+public @interface Target {
+ /**
+ * Returns an array of the kinds of elements an annotation type
+ * can be applied to.
+ * @return an array of the kinds of elements an annotation type
+ * can be applied to
+ */
+ ElementType[] value();
+}
diff --git a/java/lang/annotation/package-info.java b/java/lang/annotation/package-info.java
new file mode 100644
index 0000000..b2b7ec6
--- /dev/null
+++ b/java/lang/annotation/package-info.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2004, 2006, 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.
+ */
+
+/**
+ * Provides library support for the Java programming language
+ * annotation facility.
+ *
+ * @author Josh Bloch
+ * @since 1.5
+ */
+package java.lang.annotation;
diff --git a/java/lang/invoke/ArrayElementVarHandle.java b/java/lang/invoke/ArrayElementVarHandle.java
new file mode 100644
index 0000000..e315ba7
--- /dev/null
+++ b/java/lang/invoke/ArrayElementVarHandle.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.lang.invoke;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+
+/**
+ * A VarHandle to access array elements.
+ * @hide
+ */
+final class ArrayElementVarHandle extends VarHandle {
+ private ArrayElementVarHandle(Class<?> arrayClass) {
+ super(arrayClass.getComponentType(), arrayClass, false /* isFinal */,
+ arrayClass, int.class);
+ }
+
+ static ArrayElementVarHandle create(Class<?> arrayClass) {
+ return new ArrayElementVarHandle(arrayClass);
+ }
+}
diff --git a/java/lang/invoke/ByteArrayViewVarHandle.java b/java/lang/invoke/ByteArrayViewVarHandle.java
new file mode 100644
index 0000000..abdb1cb
--- /dev/null
+++ b/java/lang/invoke/ByteArrayViewVarHandle.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.lang.invoke;
+
+import java.nio.ByteOrder;
+
+/**
+ * A VarHandle to access byte array elements as an array of primitive types.
+ * @hide
+ */
+final class ByteArrayViewVarHandle extends VarHandle {
+ private boolean nativeByteOrder;
+
+ private ByteArrayViewVarHandle(Class<?> arrayClass, ByteOrder byteOrder) {
+ super(arrayClass.getComponentType(), byte[].class, false /* isFinal */,
+ byte[].class, int.class);
+ this.nativeByteOrder = byteOrder.equals(ByteOrder.nativeOrder());
+ }
+
+ static ByteArrayViewVarHandle create(Class<?> arrayClass, ByteOrder byteOrder) {
+ return new ByteArrayViewVarHandle(arrayClass, byteOrder);
+ }
+}
diff --git a/java/lang/invoke/ByteBufferViewVarHandle.java b/java/lang/invoke/ByteBufferViewVarHandle.java
new file mode 100644
index 0000000..75fcbab
--- /dev/null
+++ b/java/lang/invoke/ByteBufferViewVarHandle.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.lang.invoke;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+/**
+ * A VarHandle to access byte array elements as an array of primitive types.
+ * @hide
+ */
+final class ByteBufferViewVarHandle extends VarHandle {
+ private boolean nativeByteOrder;
+
+ private ByteBufferViewVarHandle(Class<?> arrayClass, ByteOrder byteOrder) {
+ super(arrayClass.getComponentType(), byte[].class, false /* isFinal */,
+ ByteBuffer.class, int.class);
+ this.nativeByteOrder = byteOrder.equals(ByteOrder.nativeOrder());
+ }
+
+ static ByteBufferViewVarHandle create(Class<?> arrayClass, ByteOrder byteOrder) {
+ return new ByteBufferViewVarHandle(arrayClass, byteOrder);
+ }
+}
diff --git a/java/lang/invoke/CallSite.java b/java/lang/invoke/CallSite.java
new file mode 100644
index 0000000..85b4bb9
--- /dev/null
+++ b/java/lang/invoke/CallSite.java
@@ -0,0 +1,387 @@
+/*
+ * Copyright (c) 2008, 2013, 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;
+
+// Android-changed: Not using Empty
+//import sun.invoke.empty.Empty;
+import static java.lang.invoke.MethodHandleStatics.*;
+import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
+
+/**
+ * A {@code CallSite} is a holder for a variable {@link MethodHandle},
+ * which is called its {@code target}.
+ * An {@code invokedynamic} instruction linked to a {@code CallSite} delegates
+ * all calls to the site's current target.
+ * A {@code CallSite} may be associated with several {@code invokedynamic}
+ * instructions, or it may be "free floating", associated with none.
+ * In any case, it may be invoked through an associated method handle
+ * called its {@linkplain #dynamicInvoker dynamic invoker}.
+ * <p>
+ * {@code CallSite} is an abstract class which does not allow
+ * direct subclassing by users. It has three immediate,
+ * concrete subclasses that may be either instantiated or subclassed.
+ * <ul>
+ * <li>If a mutable target is not required, an {@code invokedynamic} instruction
+ * may be permanently bound by means of a {@linkplain ConstantCallSite constant call site}.
+ * <li>If a mutable target is required which has volatile variable semantics,
+ * because updates to the target must be immediately and reliably witnessed by other threads,
+ * a {@linkplain VolatileCallSite volatile call site} may be used.
+ * <li>Otherwise, if a mutable target is required,
+ * a {@linkplain MutableCallSite mutable call site} may be used.
+ * </ul>
+ * <p>
+ * A non-constant call site may be <em>relinked</em> by changing its target.
+ * The new target must have the same {@linkplain MethodHandle#type() type}
+ * as the previous target.
+ * Thus, though a call site can be relinked to a series of
+ * successive targets, it cannot change its type.
+ * <p>
+ * Here is a sample use of call sites and bootstrap methods which links every
+ * dynamic call site to print its arguments:
+<blockquote><pre>{@code
+static void test() throws Throwable {
+ // THE FOLLOWING LINE IS PSEUDOCODE FOR A JVM INSTRUCTION
+ InvokeDynamic[#bootstrapDynamic].baz("baz arg", 2, 3.14);
+}
+private static void printArgs(Object... args) {
+ System.out.println(java.util.Arrays.deepToString(args));
+}
+private static final MethodHandle printArgs;
+static {
+ MethodHandles.Lookup lookup = MethodHandles.lookup();
+ Class thisClass = lookup.lookupClass(); // (who am I?)
+ printArgs = lookup.findStatic(thisClass,
+ "printArgs", MethodType.methodType(void.class, Object[].class));
+}
+private static CallSite bootstrapDynamic(MethodHandles.Lookup caller, String name, MethodType type) {
+ // ignore caller and name, but match the type:
+ return new ConstantCallSite(printArgs.asType(type));
+}
+}</pre></blockquote>
+ * @author John Rose, JSR 292 EG
+ */
+abstract
+public class CallSite {
+ // Android-changed: not used.
+ // static { MethodHandleImpl.initStatics(); }
+
+ // The actual payload of this call site:
+ /*package-private*/
+ MethodHandle target; // Note: This field is known to the JVM. Do not change.
+
+ /**
+ * Make a blank call site object with the given method type.
+ * An initial target method is supplied which will throw
+ * an {@link IllegalStateException} if called.
+ * <p>
+ * Before this {@code CallSite} object is returned from a bootstrap method,
+ * it is usually provided with a more useful target method,
+ * via a call to {@link CallSite#setTarget(MethodHandle) setTarget}.
+ * @throws NullPointerException if the proposed type is null
+ */
+ /*package-private*/
+ CallSite(MethodType type) {
+ // Android-changed: No cache for these so create uninitializedCallSite target here using
+ // method handle transformations to create a method handle that has the expected method
+ // type but throws an IllegalStateException.
+ // target = makeUninitializedCallSite(type);
+ this.target = MethodHandles.throwException(type.returnType(), IllegalStateException.class);
+ this.target = MethodHandles.insertArguments(
+ this.target, 0, new IllegalStateException("uninitialized call site"));
+ if (type.parameterCount() > 0) {
+ this.target = MethodHandles.dropArguments(this.target, 0, type.ptypes());
+ }
+
+ // Android-changed: Using initializer method for GET_TARGET
+ // rather than complex static initializer.
+ initializeGetTarget();
+ }
+
+ /**
+ * Make a call site object equipped with an initial target method handle.
+ * @param target the method handle which will be the initial target of the call site
+ * @throws NullPointerException if the proposed target is null
+ */
+ /*package-private*/
+ CallSite(MethodHandle target) {
+ target.type(); // null check
+ this.target = target;
+
+ // Android-changed: Using initializer method for GET_TARGET
+ // rather than complex static initializer.
+ initializeGetTarget();
+ }
+
+ /**
+ * Make a call site object equipped with an initial target method handle.
+ * @param targetType the desired type of the call site
+ * @param createTargetHook a hook which will bind the call site to the target method handle
+ * @throws WrongMethodTypeException if the hook cannot be invoked on the required arguments,
+ * or if the target returned by the hook is not of the given {@code targetType}
+ * @throws NullPointerException if the hook returns a null value
+ * @throws ClassCastException if the hook returns something other than a {@code MethodHandle}
+ * @throws Throwable anything else thrown by the hook function
+ */
+ /*package-private*/
+ CallSite(MethodType targetType, MethodHandle createTargetHook) throws Throwable {
+ this(targetType);
+ ConstantCallSite selfCCS = (ConstantCallSite) this;
+ MethodHandle boundTarget = (MethodHandle) createTargetHook.invokeWithArguments(selfCCS);
+ checkTargetChange(this.target, boundTarget);
+ this.target = boundTarget;
+
+ // Android-changed: Using initializer method for GET_TARGET
+ // rather than complex static initializer.
+ initializeGetTarget();
+ }
+
+ /**
+ * Returns the type of this call site's target.
+ * Although targets may change, any call site's type is permanent, and can never change to an unequal type.
+ * The {@code setTarget} method enforces this invariant by refusing any new target that does
+ * not have the previous target's type.
+ * @return the type of the current target, which is also the type of any future target
+ */
+ public MethodType type() {
+ // warning: do not call getTarget here, because CCS.getTarget can throw IllegalStateException
+ return target.type();
+ }
+
+ /**
+ * Returns the target method of the call site, according to the
+ * behavior defined by this call site's specific class.
+ * The immediate subclasses of {@code CallSite} document the
+ * class-specific behaviors of this method.
+ *
+ * @return the current linkage state of the call site, its target method handle
+ * @see ConstantCallSite
+ * @see VolatileCallSite
+ * @see #setTarget
+ * @see ConstantCallSite#getTarget
+ * @see MutableCallSite#getTarget
+ * @see VolatileCallSite#getTarget
+ */
+ public abstract MethodHandle getTarget();
+
+ /**
+ * Updates the target method of this call site, according to the
+ * behavior defined by this call site's specific class.
+ * The immediate subclasses of {@code CallSite} document the
+ * class-specific behaviors of this method.
+ * <p>
+ * The type of the new target must be {@linkplain MethodType#equals equal to}
+ * the type of the old target.
+ *
+ * @param newTarget the new target
+ * @throws NullPointerException if the proposed new target is null
+ * @throws WrongMethodTypeException if the proposed new target
+ * has a method type that differs from the previous target
+ * @see CallSite#getTarget
+ * @see ConstantCallSite#setTarget
+ * @see MutableCallSite#setTarget
+ * @see VolatileCallSite#setTarget
+ */
+ public abstract void setTarget(MethodHandle newTarget);
+
+ void checkTargetChange(MethodHandle oldTarget, MethodHandle newTarget) {
+ MethodType oldType = oldTarget.type();
+ MethodType newType = newTarget.type(); // null check!
+ if (!newType.equals(oldType))
+ throw wrongTargetType(newTarget, oldType);
+ }
+
+ private static WrongMethodTypeException wrongTargetType(MethodHandle target, MethodType type) {
+ return new WrongMethodTypeException(String.valueOf(target)+" should be of type "+type);
+ }
+
+ /**
+ * Produces a method handle equivalent to an invokedynamic instruction
+ * which has been linked to this call site.
+ * <p>
+ * This method is equivalent to the following code:
+ * <blockquote><pre>{@code
+ * MethodHandle getTarget, invoker, result;
+ * getTarget = MethodHandles.publicLookup().bind(this, "getTarget", MethodType.methodType(MethodHandle.class));
+ * invoker = MethodHandles.exactInvoker(this.type());
+ * result = MethodHandles.foldArguments(invoker, getTarget)
+ * }</pre></blockquote>
+ *
+ * @return a method handle which always invokes this call site's current target
+ */
+ public abstract MethodHandle dynamicInvoker();
+
+ /*non-public*/ MethodHandle makeDynamicInvoker() {
+ // Android-changed: Use bindTo() rather than bindArgumentL() (not implemented).
+ MethodHandle getTarget = GET_TARGET.bindTo(this);
+ MethodHandle invoker = MethodHandles.exactInvoker(this.type());
+ return MethodHandles.foldArguments(invoker, getTarget);
+ }
+
+ // Android-changed: no longer final. GET_TARGET assigned in initializeGetTarget().
+ private static MethodHandle GET_TARGET = null;
+
+ private void initializeGetTarget() {
+ // Android-changed: moved from static initializer for
+ // GET_TARGET to avoid issues with running early. Called from
+ // constructors. CallSite creation is not performance critical.
+ synchronized (CallSite.class) {
+ if (GET_TARGET == null) {
+ try {
+ GET_TARGET = IMPL_LOOKUP.
+ findVirtual(CallSite.class, "getTarget",
+ MethodType.methodType(MethodHandle.class));
+ } catch (ReflectiveOperationException e) {
+ throw new InternalError(e);
+ }
+ }
+ }
+ }
+
+ // Android-changed: not used.
+ // /** This guy is rolled into the default target if a MethodType is supplied to the constructor. */
+ // /*package-private*/
+ // static Empty uninitializedCallSite() {
+ // throw new IllegalStateException("uninitialized call site");
+ // }
+
+ // unsafe stuff:
+ private static final long TARGET_OFFSET;
+ static {
+ try {
+ TARGET_OFFSET = UNSAFE.objectFieldOffset(CallSite.class.getDeclaredField("target"));
+ } catch (Exception ex) { throw new Error(ex); }
+ }
+
+ /*package-private*/
+ void setTargetNormal(MethodHandle newTarget) {
+ // Android-changed: Set value directly.
+ // MethodHandleNatives.setCallSiteTargetNormal(this, newTarget);
+ target = newTarget;
+ }
+ /*package-private*/
+ MethodHandle getTargetVolatile() {
+ return (MethodHandle) UNSAFE.getObjectVolatile(this, TARGET_OFFSET);
+ }
+ /*package-private*/
+ void setTargetVolatile(MethodHandle newTarget) {
+ // Android-changed: Set value directly.
+ // MethodHandleNatives.setCallSiteTargetVolatile(this, newTarget);
+ UNSAFE.putObjectVolatile(this, TARGET_OFFSET, newTarget);
+ }
+
+ // Android-changed: not used.
+ // this implements the upcall from the JVM, MethodHandleNatives.makeDynamicCallSite:
+ // static CallSite makeSite(MethodHandle bootstrapMethod,
+ // // Callee information:
+ // String name, MethodType type,
+ // // Extra arguments for BSM, if any:
+ // Object info,
+ // // Caller information:
+ // Class<?> callerClass) {
+ // MethodHandles.Lookup caller = IMPL_LOOKUP.in(callerClass);
+ // CallSite site;
+ // try {
+ // Object binding;
+ // info = maybeReBox(info);
+ // if (info == null) {
+ // binding = bootstrapMethod.invoke(caller, name, type);
+ // } else if (!info.getClass().isArray()) {
+ // binding = bootstrapMethod.invoke(caller, name, type, info);
+ // } else {
+ // Object[] argv = (Object[]) info;
+ // maybeReBoxElements(argv);
+ // switch (argv.length) {
+ // case 0:
+ // binding = bootstrapMethod.invoke(caller, name, type);
+ // break;
+ // case 1:
+ // binding = bootstrapMethod.invoke(caller, name, type,
+ // argv[0]);
+ // break;
+ // case 2:
+ // binding = bootstrapMethod.invoke(caller, name, type,
+ // argv[0], argv[1]);
+ // break;
+ // case 3:
+ // binding = bootstrapMethod.invoke(caller, name, type,
+ // argv[0], argv[1], argv[2]);
+ // break;
+ // case 4:
+ // binding = bootstrapMethod.invoke(caller, name, type,
+ // argv[0], argv[1], argv[2], argv[3]);
+ // break;
+ // case 5:
+ // binding = bootstrapMethod.invoke(caller, name, type,
+ // argv[0], argv[1], argv[2], argv[3], argv[4]);
+ // break;
+ // case 6:
+ // binding = bootstrapMethod.invoke(caller, name, type,
+ // argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]);
+ // break;
+ // default:
+ // final int NON_SPREAD_ARG_COUNT = 3; // (caller, name, type)
+ // if (NON_SPREAD_ARG_COUNT + argv.length > MethodType.MAX_MH_ARITY)
+ // throw new BootstrapMethodError("too many bootstrap method arguments");
+ // MethodType bsmType = bootstrapMethod.type();
+ // MethodType invocationType = MethodType.genericMethodType(NON_SPREAD_ARG_COUNT + argv.length);
+ // MethodHandle typedBSM = bootstrapMethod.asType(invocationType);
+ // MethodHandle spreader = invocationType.invokers().spreadInvoker(NON_SPREAD_ARG_COUNT);
+ // binding = spreader.invokeExact(typedBSM, (Object)caller, (Object)name, (Object)type, argv);
+ // }
+ // }
+ // //System.out.println("BSM for "+name+type+" => "+binding);
+ // if (binding instanceof CallSite) {
+ // site = (CallSite) binding;
+ // } else {
+ // throw new ClassCastException("bootstrap method failed to produce a CallSite");
+ // }
+ // if (!site.getTarget().type().equals(type))
+ // throw wrongTargetType(site.getTarget(), type);
+ // } catch (Throwable ex) {
+ // BootstrapMethodError bex;
+ // if (ex instanceof BootstrapMethodError)
+ // bex = (BootstrapMethodError) ex;
+ // else
+ // bex = new BootstrapMethodError("call site initialization exception", ex);
+ // throw bex;
+ // }
+ // return site;
+ // }
+
+ // private static Object maybeReBox(Object x) {
+ // if (x instanceof Integer) {
+ // int xi = (int) x;
+ // if (xi == (byte) xi)
+ // x = xi; // must rebox; see JLS 5.1.7
+ // }
+ // return x;
+ // }
+ // private static void maybeReBoxElements(Object[] xa) {
+ // for (int i = 0; i < xa.length; i++) {
+ // xa[i] = maybeReBox(xa[i]);
+ // }
+ // }
+}
diff --git a/java/lang/invoke/ConstantCallSite.java b/java/lang/invoke/ConstantCallSite.java
new file mode 100644
index 0000000..f27d0e7
--- /dev/null
+++ b/java/lang/invoke/ConstantCallSite.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2010, 2013, 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;
+
+/**
+ * A {@code ConstantCallSite} is a {@link CallSite} whose target is permanent, and can never be changed.
+ * An {@code invokedynamic} instruction linked to a {@code ConstantCallSite} is permanently
+ * bound to the call site's target.
+ * @author John Rose, JSR 292 EG
+ */
+public class ConstantCallSite extends CallSite {
+ private final boolean isFrozen;
+
+ /**
+ * Creates a call site with a permanent target.
+ * @param target the target to be permanently associated with this call site
+ * @throws NullPointerException if the proposed target is null
+ */
+ public ConstantCallSite(MethodHandle target) {
+ super(target);
+ isFrozen = true;
+ }
+
+ /**
+ * Creates a call site with a permanent target, possibly bound to the call site itself.
+ * <p>
+ * During construction of the call site, the {@code createTargetHook} is invoked to
+ * produce the actual target, as if by a call of the form
+ * {@code (MethodHandle) createTargetHook.invoke(this)}.
+ * <p>
+ * Note that user code cannot perform such an action directly in a subclass constructor,
+ * since the target must be fixed before the {@code ConstantCallSite} constructor returns.
+ * <p>
+ * The hook is said to bind the call site to a target method handle,
+ * and a typical action would be {@code someTarget.bindTo(this)}.
+ * However, the hook is free to take any action whatever,
+ * including ignoring the call site and returning a constant target.
+ * <p>
+ * The result returned by the hook must be a method handle of exactly
+ * the same type as the call site.
+ * <p>
+ * While the hook is being called, the new {@code ConstantCallSite}
+ * object is in a partially constructed state.
+ * In this state,
+ * a call to {@code getTarget}, or any other attempt to use the target,
+ * will result in an {@code IllegalStateException}.
+ * It is legal at all times to obtain the call site's type using the {@code type} method.
+ *
+ * @param targetType the type of the method handle to be permanently associated with this call site
+ * @param createTargetHook a method handle to invoke (on the call site) to produce the call site's target
+ * @throws WrongMethodTypeException if the hook cannot be invoked on the required arguments,
+ * or if the target returned by the hook is not of the given {@code targetType}
+ * @throws NullPointerException if the hook returns a null value
+ * @throws ClassCastException if the hook returns something other than a {@code MethodHandle}
+ * @throws Throwable anything else thrown by the hook function
+ */
+ protected ConstantCallSite(MethodType targetType, MethodHandle createTargetHook) throws Throwable {
+ super(targetType, createTargetHook);
+ isFrozen = true;
+ }
+
+ /**
+ * Returns the target method of the call site, which behaves
+ * like a {@code final} field of the {@code ConstantCallSite}.
+ * That is, the target is always the original value passed
+ * to the constructor call which created this instance.
+ *
+ * @return the immutable linkage state of this call site, a constant method handle
+ * @throws IllegalStateException if the {@code ConstantCallSite} constructor has not completed
+ */
+ @Override public final MethodHandle getTarget() {
+ if (!isFrozen) throw new IllegalStateException();
+ return target;
+ }
+
+ /**
+ * Always throws an {@link UnsupportedOperationException}.
+ * This kind of call site cannot change its target.
+ * @param ignore a new target proposed for the call site, which is ignored
+ * @throws UnsupportedOperationException because this kind of call site cannot change its target
+ */
+ @Override public final void setTarget(MethodHandle ignore) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Returns this call site's permanent target.
+ * Since that target will never change, this is a correct implementation
+ * of {@link CallSite#dynamicInvoker CallSite.dynamicInvoker}.
+ * @return the immutable linkage state of this call site, a constant method handle
+ * @throws IllegalStateException if the {@code ConstantCallSite} constructor has not completed
+ */
+ @Override
+ public final MethodHandle dynamicInvoker() {
+ return getTarget();
+ }
+}
diff --git a/java/lang/invoke/FieldVarHandle.java b/java/lang/invoke/FieldVarHandle.java
new file mode 100644
index 0000000..0921040
--- /dev/null
+++ b/java/lang/invoke/FieldVarHandle.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.lang.invoke;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+
+/**
+ * A VarHandle that's associated with an ArtField.
+ * @hide
+ */
+final class FieldVarHandle extends VarHandle {
+ private final long artField;
+
+ private FieldVarHandle(Field field, Class<?> declaringClass) {
+ super(field.getType(), Modifier.isFinal(field.getModifiers()), declaringClass);
+ artField = field.getArtField();
+ }
+
+ private FieldVarHandle(Field field) {
+ super(field.getType(), Modifier.isFinal(field.getModifiers()));
+ artField = field.getArtField();
+ }
+
+ static FieldVarHandle create(Field field) {
+ if (Modifier.isStatic(field.getModifiers())) {
+ return new FieldVarHandle(field);
+ } else {
+ return new FieldVarHandle(field, field.getDeclaringClass());
+ }
+ }
+}
diff --git a/java/lang/invoke/LambdaConversionException.java b/java/lang/invoke/LambdaConversionException.java
new file mode 100644
index 0000000..e1123da
--- /dev/null
+++ b/java/lang/invoke/LambdaConversionException.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2012, 2013, 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;
+
+/**
+ * LambdaConversionException
+ */
+public class LambdaConversionException extends Exception {
+ private static final long serialVersionUID = 292L + 8L;
+
+ /**
+ * Constructs a {@code LambdaConversionException}.
+ */
+ public LambdaConversionException() {
+ }
+
+ /**
+ * Constructs a {@code LambdaConversionException} with a message.
+ * @param message the detail message
+ */
+ public LambdaConversionException(String message) {
+ super(message);
+ }
+
+ /**
+ * Constructs a {@code LambdaConversionException} with a message and cause.
+ * @param message the detail message
+ * @param cause the cause
+ */
+ public LambdaConversionException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * Constructs a {@code LambdaConversionException} with a cause.
+ * @param cause the cause
+ */
+ public LambdaConversionException(Throwable cause) {
+ super(cause);
+ }
+
+ /**
+ * Constructs a {@code LambdaConversionException} with a message,
+ * cause, and other settings.
+ * @param message the detail message
+ * @param cause the cause
+ * @param enableSuppression whether or not suppressed exceptions are enabled
+ * @param writableStackTrace whether or not the stack trace is writable
+ */
+ public LambdaConversionException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
+ super(message, cause, enableSuppression, writableStackTrace);
+ }
+}
diff --git a/java/lang/invoke/LambdaMetafactory.java b/java/lang/invoke/LambdaMetafactory.java
new file mode 100644
index 0000000..e1ce46f
--- /dev/null
+++ b/java/lang/invoke/LambdaMetafactory.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2012, 2013, 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;
+
+public class LambdaMetafactory {
+
+ public static final int FLAG_SERIALIZABLE = 1 << 0;
+
+ public static final int FLAG_MARKERS = 1 << 1;
+
+ public static final int FLAG_BRIDGES = 1 << 2;
+
+ public static CallSite metafactory(MethodHandles.Lookup caller,
+ String invokedName,
+ MethodType invokedType,
+ MethodType samMethodType,
+ MethodHandle implMethod,
+ MethodType instantiatedMethodType)
+ throws LambdaConversionException { return null; }
+
+ public static CallSite altMetafactory(MethodHandles.Lookup caller,
+ String invokedName,
+ MethodType invokedType,
+ Object... args)
+ throws LambdaConversionException { return null; }
+}
diff --git a/java/lang/invoke/MethodHandle.java b/java/lang/invoke/MethodHandle.java
new file mode 100644
index 0000000..87911c2
--- /dev/null
+++ b/java/lang/invoke/MethodHandle.java
@@ -0,0 +1,1646 @@
+/*
+ * Copyright (c) 2008, 2013, 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 dalvik.system.EmulatedStackFrame;
+
+import static java.lang.invoke.MethodHandleStatics.*;
+
+/**
+ * A method handle is a typed, directly executable reference to an underlying method,
+ * constructor, field, or similar low-level operation, with optional
+ * transformations of arguments or return values.
+ * These transformations are quite general, and include such patterns as
+ * {@linkplain #asType conversion},
+ * {@linkplain #bindTo insertion},
+ * {@linkplain java.lang.invoke.MethodHandles#dropArguments deletion},
+ * and {@linkplain java.lang.invoke.MethodHandles#filterArguments substitution}.
+ *
+ * <h1>Method handle contents</h1>
+ * Method handles are dynamically and strongly typed according to their parameter and return types.
+ * They are not distinguished by the name or the defining class of their underlying methods.
+ * A method handle must be invoked using a symbolic type descriptor which matches
+ * the method handle's own {@linkplain #type type descriptor}.
+ * <p>
+ * Every method handle reports its type descriptor via the {@link #type type} accessor.
+ * This type descriptor is a {@link java.lang.invoke.MethodType MethodType} object,
+ * whose structure is a series of classes, one of which is
+ * the return type of the method (or {@code void.class} if none).
+ * <p>
+ * A method handle's type controls the types of invocations it accepts,
+ * and the kinds of transformations that apply to it.
+ * <p>
+ * A method handle contains a pair of special invoker methods
+ * called {@link #invokeExact invokeExact} and {@link #invoke invoke}.
+ * Both invoker methods provide direct access to the method handle's
+ * underlying method, constructor, field, or other operation,
+ * as modified by transformations of arguments and return values.
+ * Both invokers accept calls which exactly match the method handle's own type.
+ * The plain, inexact invoker also accepts a range of other call types.
+ * <p>
+ * Method handles are immutable and have no visible state.
+ * Of course, they can be bound to underlying methods or data which exhibit state.
+ * With respect to the Java Memory Model, any method handle will behave
+ * as if all of its (internal) fields are final variables. This means that any method
+ * handle made visible to the application will always be fully formed.
+ * This is true even if the method handle is published through a shared
+ * variable in a data race.
+ * <p>
+ * Method handles cannot be subclassed by the user.
+ * Implementations may (or may not) create internal subclasses of {@code MethodHandle}
+ * which may be visible via the {@link java.lang.Object#getClass Object.getClass}
+ * operation. The programmer should not draw conclusions about a method handle
+ * from its specific class, as the method handle class hierarchy (if any)
+ * may change from time to time or across implementations from different vendors.
+ *
+ * <h1>Method handle compilation</h1>
+ * A Java method call expression naming {@code invokeExact} or {@code invoke}
+ * can invoke a method handle from Java source code.
+ * From the viewpoint of source code, these methods can take any arguments
+ * and their result can be cast to any return type.
+ * Formally this is accomplished by giving the invoker methods
+ * {@code Object} return types and variable arity {@code Object} arguments,
+ * but they have an additional quality called <em>signature polymorphism</em>
+ * which connects this freedom of invocation directly to the JVM execution stack.
+ * <p>
+ * As is usual with virtual methods, source-level calls to {@code invokeExact}
+ * and {@code invoke} compile to an {@code invokevirtual} instruction.
+ * More unusually, the compiler must record the actual argument types,
+ * and may not perform method invocation conversions on the arguments.
+ * Instead, it must push them on the stack according to their own unconverted types.
+ * The method handle object itself is pushed on the stack before the arguments.
+ * The compiler then calls the method handle with a symbolic type descriptor which
+ * describes the argument and return types.
+ * <p>
+ * To issue a complete symbolic type descriptor, the compiler must also determine
+ * the return type. This is based on a cast on the method invocation expression,
+ * if there is one, or else {@code Object} if the invocation is an expression
+ * or else {@code void} if the invocation is a statement.
+ * The cast may be to a primitive type (but not {@code void}).
+ * <p>
+ * As a corner case, an uncasted {@code null} argument is given
+ * a symbolic type descriptor of {@code java.lang.Void}.
+ * The ambiguity with the type {@code Void} is harmless, since there are no references of type
+ * {@code Void} except the null reference.
+ *
+ * <h1>Method handle invocation</h1>
+ * The first time a {@code invokevirtual} instruction is executed
+ * it is linked, by symbolically resolving the names in the instruction
+ * and verifying that the method call is statically legal.
+ * This is true of calls to {@code invokeExact} and {@code invoke}.
+ * In this case, the symbolic type descriptor emitted by the compiler is checked for
+ * correct syntax and names it contains are resolved.
+ * Thus, an {@code invokevirtual} instruction which invokes
+ * a method handle will always link, as long
+ * as the symbolic type descriptor is syntactically well-formed
+ * and the types exist.
+ * <p>
+ * When the {@code invokevirtual} is executed after linking,
+ * the receiving method handle's type is first checked by the JVM
+ * to ensure that it matches the symbolic type descriptor.
+ * If the type match fails, it means that the method which the
+ * caller is invoking is not present on the individual
+ * method handle being invoked.
+ * <p>
+ * In the case of {@code invokeExact}, the type descriptor of the invocation
+ * (after resolving symbolic type names) must exactly match the method type
+ * of the receiving method handle.
+ * In the case of plain, inexact {@code invoke}, the resolved type descriptor
+ * must be a valid argument to the receiver's {@link #asType asType} method.
+ * Thus, plain {@code invoke} is more permissive than {@code invokeExact}.
+ * <p>
+ * After type matching, a call to {@code invokeExact} directly
+ * and immediately invoke the method handle's underlying method
+ * (or other behavior, as the case may be).
+ * <p>
+ * A call to plain {@code invoke} works the same as a call to
+ * {@code invokeExact}, if the symbolic type descriptor specified by the caller
+ * exactly matches the method handle's own type.
+ * If there is a type mismatch, {@code invoke} attempts
+ * to adjust the type of the receiving method handle,
+ * as if by a call to {@link #asType asType},
+ * to obtain an exactly invokable method handle {@code M2}.
+ * This allows a more powerful negotiation of method type
+ * between caller and callee.
+ * <p>
+ * (<em>Note:</em> The adjusted method handle {@code M2} is not directly observable,
+ * and implementations are therefore not required to materialize it.)
+ *
+ * <h1>Invocation checking</h1>
+ * In typical programs, method handle type matching will usually succeed.
+ * But if a match fails, the JVM will throw a {@link WrongMethodTypeException},
+ * either directly (in the case of {@code invokeExact}) or indirectly as if
+ * by a failed call to {@code asType} (in the case of {@code invoke}).
+ * <p>
+ * Thus, a method type mismatch which might show up as a linkage error
+ * in a statically typed program can show up as
+ * a dynamic {@code WrongMethodTypeException}
+ * in a program which uses method handles.
+ * <p>
+ * Because method types contain "live" {@code Class} objects,
+ * method type matching takes into account both types names and class loaders.
+ * Thus, even if a method handle {@code M} is created in one
+ * class loader {@code L1} and used in another {@code L2},
+ * method handle calls are type-safe, because the caller's symbolic type
+ * descriptor, as resolved in {@code L2},
+ * is matched against the original callee method's symbolic type descriptor,
+ * as resolved in {@code L1}.
+ * The resolution in {@code L1} happens when {@code M} is created
+ * and its type is assigned, while the resolution in {@code L2} happens
+ * when the {@code invokevirtual} instruction is linked.
+ * <p>
+ * Apart from the checking of type descriptors,
+ * a method handle's capability to call its underlying method is unrestricted.
+ * If a method handle is formed on a non-public method by a class
+ * that has access to that method, the resulting handle can be used
+ * in any place by any caller who receives a reference to it.
+ * <p>
+ * Unlike with the Core Reflection API, where access is checked every time
+ * a reflective method is invoked,
+ * method handle access checking is performed
+ * <a href="MethodHandles.Lookup.html#access">when the method handle is created</a>.
+ * In the case of {@code ldc} (see below), access checking is performed as part of linking
+ * the constant pool entry underlying the constant method handle.
+ * <p>
+ * Thus, handles to non-public methods, or to methods in non-public classes,
+ * should generally be kept secret.
+ * They should not be passed to untrusted code unless their use from
+ * the untrusted code would be harmless.
+ *
+ * <h1>Method handle creation</h1>
+ * Java code can create a method handle that directly accesses
+ * any method, constructor, or field that is accessible to that code.
+ * This is done via a reflective, capability-based API called
+ * {@link java.lang.invoke.MethodHandles.Lookup MethodHandles.Lookup}
+ * For example, a static method handle can be obtained
+ * from {@link java.lang.invoke.MethodHandles.Lookup#findStatic Lookup.findStatic}.
+ * There are also conversion methods from Core Reflection API objects,
+ * such as {@link java.lang.invoke.MethodHandles.Lookup#unreflect Lookup.unreflect}.
+ * <p>
+ * Like classes and strings, method handles that correspond to accessible
+ * fields, methods, and constructors can also be represented directly
+ * in a class file's constant pool as constants to be loaded by {@code ldc} bytecodes.
+ * A new type of constant pool entry, {@code CONSTANT_MethodHandle},
+ * refers directly to an associated {@code CONSTANT_Methodref},
+ * {@code CONSTANT_InterfaceMethodref}, or {@code CONSTANT_Fieldref}
+ * constant pool entry.
+ * (For full details on method handle constants,
+ * see sections 4.4.8 and 5.4.3.5 of the Java Virtual Machine Specification.)
+ * <p>
+ * Method handles produced by lookups or constant loads from methods or
+ * constructors with the variable arity modifier bit ({@code 0x0080})
+ * have a corresponding variable arity, as if they were defined with
+ * the help of {@link #asVarargsCollector asVarargsCollector}.
+ * <p>
+ * A method reference may refer either to a static or non-static method.
+ * In the non-static case, the method handle type includes an explicit
+ * receiver argument, prepended before any other arguments.
+ * In the method handle's type, the initial receiver argument is typed
+ * according to the class under which the method was initially requested.
+ * (E.g., if a non-static method handle is obtained via {@code ldc},
+ * the type of the receiver is the class named in the constant pool entry.)
+ * <p>
+ * Method handle constants are subject to the same link-time access checks
+ * their corresponding bytecode instructions, and the {@code ldc} instruction
+ * will throw corresponding linkage errors if the bytecode behaviors would
+ * throw such errors.
+ * <p>
+ * As a corollary of this, access to protected members is restricted
+ * to receivers only of the accessing class, or one of its subclasses,
+ * and the accessing class must in turn be a subclass (or package sibling)
+ * of the protected member's defining class.
+ * If a method reference refers to a protected non-static method or field
+ * of a class outside the current package, the receiver argument will
+ * be narrowed to the type of the accessing class.
+ * <p>
+ * When a method handle to a virtual method is invoked, the method is
+ * always looked up in the receiver (that is, the first argument).
+ * <p>
+ * A non-virtual method handle to a specific virtual method implementation
+ * can also be created. These do not perform virtual lookup based on
+ * receiver type. Such a method handle simulates the effect of
+ * an {@code invokespecial} instruction to the same method.
+ *
+ * <h1>Usage examples</h1>
+ * Here are some examples of usage:
+ * <blockquote><pre>{@code
+Object x, y; String s; int i;
+MethodType mt; MethodHandle mh;
+MethodHandles.Lookup lookup = MethodHandles.lookup();
+// mt is (char,char)String
+mt = MethodType.methodType(String.class, char.class, char.class);
+mh = lookup.findVirtual(String.class, "replace", mt);
+s = (String) mh.invokeExact("daddy",'d','n');
+// invokeExact(Ljava/lang/String;CC)Ljava/lang/String;
+assertEquals(s, "nanny");
+// weakly typed invocation (using MHs.invoke)
+s = (String) mh.invokeWithArguments("sappy", 'p', 'v');
+assertEquals(s, "savvy");
+// mt is (Object[])List
+mt = MethodType.methodType(java.util.List.class, Object[].class);
+mh = lookup.findStatic(java.util.Arrays.class, "asList", mt);
+assert(mh.isVarargsCollector());
+x = mh.invoke("one", "two");
+// invoke(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;
+assertEquals(x, java.util.Arrays.asList("one","two"));
+// mt is (Object,Object,Object)Object
+mt = MethodType.genericMethodType(3);
+mh = mh.asType(mt);
+x = mh.invokeExact((Object)1, (Object)2, (Object)3);
+// invokeExact(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+assertEquals(x, java.util.Arrays.asList(1,2,3));
+// mt is ()int
+mt = MethodType.methodType(int.class);
+mh = lookup.findVirtual(java.util.List.class, "size", mt);
+i = (int) mh.invokeExact(java.util.Arrays.asList(1,2,3));
+// invokeExact(Ljava/util/List;)I
+assert(i == 3);
+mt = MethodType.methodType(void.class, String.class);
+mh = lookup.findVirtual(java.io.PrintStream.class, "println", mt);
+mh.invokeExact(System.out, "Hello, world.");
+// invokeExact(Ljava/io/PrintStream;Ljava/lang/String;)V
+ * }</pre></blockquote>
+ * Each of the above calls to {@code invokeExact} or plain {@code invoke}
+ * generates a single invokevirtual instruction with
+ * the symbolic type descriptor indicated in the following comment.
+ * In these examples, the helper method {@code assertEquals} is assumed to
+ * be a method which calls {@link java.util.Objects#equals(Object,Object) Objects.equals}
+ * on its arguments, and asserts that the result is true.
+ *
+ * <h1>Exceptions</h1>
+ * The methods {@code invokeExact} and {@code invoke} are declared
+ * to throw {@link java.lang.Throwable Throwable},
+ * which is to say that there is no static restriction on what a method handle
+ * can throw. Since the JVM does not distinguish between checked
+ * and unchecked exceptions (other than by their class, of course),
+ * there is no particular effect on bytecode shape from ascribing
+ * checked exceptions to method handle invocations. But in Java source
+ * code, methods which perform method handle calls must either explicitly
+ * throw {@code Throwable}, or else must catch all
+ * throwables locally, rethrowing only those which are legal in the context,
+ * and wrapping ones which are illegal.
+ *
+ * <h1><a name="sigpoly"></a>Signature polymorphism</h1>
+ * The unusual compilation and linkage behavior of
+ * {@code invokeExact} and plain {@code invoke}
+ * is referenced by the term <em>signature polymorphism</em>.
+ * As defined in the Java Language Specification,
+ * a signature polymorphic method is one which can operate with
+ * any of a wide range of call signatures and return types.
+ * <p>
+ * In source code, a call to a signature polymorphic method will
+ * compile, regardless of the requested symbolic type descriptor.
+ * As usual, the Java compiler emits an {@code invokevirtual}
+ * instruction with the given symbolic type descriptor against the named method.
+ * The unusual part is that the symbolic type descriptor is derived from
+ * the actual argument and return types, not from the method declaration.
+ * <p>
+ * When the JVM processes bytecode containing signature polymorphic calls,
+ * it will successfully link any such call, regardless of its symbolic type descriptor.
+ * (In order to retain type safety, the JVM will guard such calls with suitable
+ * dynamic type checks, as described elsewhere.)
+ * <p>
+ * Bytecode generators, including the compiler back end, are required to emit
+ * untransformed symbolic type descriptors for these methods.
+ * Tools which determine symbolic linkage are required to accept such
+ * untransformed descriptors, without reporting linkage errors.
+ *
+ * <h1>Interoperation between method handles and the Core Reflection API</h1>
+ * Using factory methods in the {@link java.lang.invoke.MethodHandles.Lookup Lookup} API,
+ * any class member represented by a Core Reflection API object
+ * can be converted to a behaviorally equivalent method handle.
+ * For example, a reflective {@link java.lang.reflect.Method Method} can
+ * be converted to a method handle using
+ * {@link java.lang.invoke.MethodHandles.Lookup#unreflect Lookup.unreflect}.
+ * The resulting method handles generally provide more direct and efficient
+ * access to the underlying class members.
+ * <p>
+ * As a special case,
+ * when the Core Reflection API is used to view the signature polymorphic
+ * methods {@code invokeExact} or plain {@code invoke} in this class,
+ * they appear as ordinary non-polymorphic methods.
+ * Their reflective appearance, as viewed by
+ * {@link java.lang.Class#getDeclaredMethod Class.getDeclaredMethod},
+ * is unaffected by their special status in this API.
+ * For example, {@link java.lang.reflect.Method#getModifiers Method.getModifiers}
+ * will report exactly those modifier bits required for any similarly
+ * declared method, including in this case {@code native} and {@code varargs} bits.
+ * <p>
+ * As with any reflected method, these methods (when reflected) may be
+ * invoked via {@link java.lang.reflect.Method#invoke java.lang.reflect.Method.invoke}.
+ * However, such reflective calls do not result in method handle invocations.
+ * Such a call, if passed the required argument
+ * (a single one, of type {@code Object[]}), will ignore the argument and
+ * will throw an {@code UnsupportedOperationException}.
+ * <p>
+ * Since {@code invokevirtual} instructions can natively
+ * invoke method handles under any symbolic type descriptor, this reflective view conflicts
+ * with the normal presentation of these methods via bytecodes.
+ * Thus, these two native methods, when reflectively viewed by
+ * {@code Class.getDeclaredMethod}, may be regarded as placeholders only.
+ * <p>
+ * In order to obtain an invoker method for a particular type descriptor,
+ * use {@link java.lang.invoke.MethodHandles#exactInvoker MethodHandles.exactInvoker},
+ * or {@link java.lang.invoke.MethodHandles#invoker MethodHandles.invoker}.
+ * The {@link java.lang.invoke.MethodHandles.Lookup#findVirtual Lookup.findVirtual}
+ * API is also able to return a method handle
+ * to call {@code invokeExact} or plain {@code invoke},
+ * for any specified type descriptor .
+ *
+ * <h1>Interoperation between method handles and Java generics</h1>
+ * A method handle can be obtained on a method, constructor, or field
+ * which is declared with Java generic types.
+ * As with the Core Reflection API, the type of the method handle
+ * will constructed from the erasure of the source-level type.
+ * When a method handle is invoked, the types of its arguments
+ * or the return value cast type may be generic types or type instances.
+ * If this occurs, the compiler will replace those
+ * types by their erasures when it constructs the symbolic type descriptor
+ * for the {@code invokevirtual} instruction.
+ * <p>
+ * Method handles do not represent
+ * their function-like types in terms of Java parameterized (generic) types,
+ * because there are three mismatches between function-like types and parameterized
+ * Java types.
+ * <ul>
+ * <li>Method types range over all possible arities,
+ * from no arguments to up to the <a href="MethodHandle.html#maxarity">maximum number</a> of allowed arguments.
+ * Generics are not variadic, and so cannot represent this.</li>
+ * <li>Method types can specify arguments of primitive types,
+ * which Java generic types cannot range over.</li>
+ * <li>Higher order functions over method handles (combinators) are
+ * often generic across a wide range of function types, including
+ * those of multiple arities. It is impossible to represent such
+ * genericity with a Java type parameter.</li>
+ * </ul>
+ *
+ * <h1><a name="maxarity"></a>Arity limits</h1>
+ * The JVM imposes on all methods and constructors of any kind an absolute
+ * limit of 255 stacked arguments. This limit can appear more restrictive
+ * in certain cases:
+ * <ul>
+ * <li>A {@code long} or {@code double} argument counts (for purposes of arity limits) as two argument slots.
+ * <li>A non-static method consumes an extra argument for the object on which the method is called.
+ * <li>A constructor consumes an extra argument for the object which is being constructed.
+ * <li>Since a method handle’s {@code invoke} method (or other signature-polymorphic method) is non-virtual,
+ * it consumes an extra argument for the method handle itself, in addition to any non-virtual receiver object.
+ * </ul>
+ * These limits imply that certain method handles cannot be created, solely because of the JVM limit on stacked arguments.
+ * For example, if a static JVM method accepts exactly 255 arguments, a method handle cannot be created for it.
+ * Attempts to create method handles with impossible method types lead to an {@link IllegalArgumentException}.
+ * In particular, a method handle’s type must not have an arity of the exact maximum 255.
+ *
+ * @see MethodType
+ * @see MethodHandles
+ * @author John Rose, JSR 292 EG
+ */
+public abstract class MethodHandle {
+ // Android-removed: MethodHandleImpl.initStatics() unused on Android.
+ // static { MethodHandleImpl.initStatics(); }
+
+ /**
+ * Internal marker interface which distinguishes (to the Java compiler)
+ * those methods which are <a href="MethodHandle.html#sigpoly">signature polymorphic</a>.
+ *
+ * @hide
+ */
+ @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD})
+ @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
+ // Android-changed: Made public @hide as otherwise it breaks the stubs generation.
+ // @interface PolymorphicSignature { }
+ public @interface PolymorphicSignature { }
+
+ // Android-added: Comment to differentiate between type and nominalType.
+ /**
+ * The type of this method handle, this corresponds to the exact type of the method
+ * being invoked.
+ *
+ * @see #nominalType
+ */
+ private final MethodType type;
+ // Android-removed: LambdaForm and customizationCount unused on Android.
+ // They will be substituted with appropriate implementation / delegate classes.
+ /*
+ /*private* final LambdaForm form;
+ // form is not private so that invokers can easily fetch it
+ /*private* MethodHandle asTypeCache;
+ // asTypeCache is not private so that invokers can easily fetch it
+ /*non-public* byte customizationCount;
+ // customizationCount should be accessible from invokers
+ */
+
+ // BEGIN Android-added: Android specific implementation.
+ // The MethodHandle functionality is tightly coupled with internal details of the runtime and
+ // so Android has a completely different implementation compared to the RI.
+ /**
+ * The nominal type of this method handle, will be non-null if a method handle declares
+ * a different type from its "real" type, which is either the type of the method being invoked
+ * or the type of the emulated stackframe expected by an underyling adapter.
+ */
+ private MethodType nominalType;
+
+ /**
+ * The spread invoker associated with this type with zero trailing arguments.
+ * This is used to speed up invokeWithArguments.
+ */
+ private MethodHandle cachedSpreadInvoker;
+
+ /**
+ * The INVOKE* constants and SGET/SPUT and IGET/IPUT constants specify the behaviour of this
+ * method handle with respect to the ArtField* or the ArtMethod* that it operates on. These
+ * behaviours are equivalent to the dex bytecode behaviour on the respective method_id or
+ * field_id in the equivalent instruction.
+ *
+ * INVOKE_TRANSFORM is a special type of handle which doesn't encode any dex bytecode behaviour,
+ * instead it transforms the list of input arguments or performs other higher order operations
+ * before (optionally) delegating to another method handle.
+ *
+ * INVOKE_CALLSITE_TRANSFORM is a variation on INVOKE_TRANSFORM where the method type of
+ * a MethodHandle dynamically varies based on the callsite. This is used by
+ * the VarargsCollector implementation which places any number of trailing arguments
+ * into an array before invoking an arity method. The "any number of trailing arguments" means
+ * it would otherwise generate WrongMethodTypeExceptions as the callsite method type and
+ * VarargsCollector method type appear incompatible.
+ */
+
+ /** @hide */ public static final int INVOKE_VIRTUAL = 0;
+ /** @hide */ public static final int INVOKE_SUPER = 1;
+ /** @hide */ public static final int INVOKE_DIRECT = 2;
+ /** @hide */ public static final int INVOKE_STATIC = 3;
+ /** @hide */ public static final int INVOKE_INTERFACE = 4;
+ /** @hide */ public static final int INVOKE_TRANSFORM = 5;
+ /** @hide */ public static final int INVOKE_CALLSITE_TRANSFORM = 6;
+ /** @hide */ public static final int INVOKE_VAR_HANDLE = 7;
+ /** @hide */ public static final int INVOKE_VAR_HANDLE_EXACT = 8;
+ /** @hide */ public static final int IGET = 9;
+ /** @hide */ public static final int IPUT = 10;
+ /** @hide */ public static final int SGET = 11;
+ /** @hide */ public static final int SPUT = 12;
+
+ // The kind of this method handle (used by the runtime). This is one of the INVOKE_*
+ // constants or SGET/SPUT, IGET/IPUT.
+ /** @hide */ protected final int handleKind;
+
+ // The ArtMethod* or ArtField* associated with this method handle (used by the runtime).
+ /** @hide */ protected final long artFieldOrMethod;
+
+ /** @hide */
+ protected MethodHandle(long artFieldOrMethod, int handleKind, MethodType type) {
+ this.artFieldOrMethod = artFieldOrMethod;
+ this.handleKind = handleKind;
+ this.type = type;
+ }
+ // END Android-added: Android specific implementation.
+
+ /**
+ * Reports the type of this method handle.
+ * Every invocation of this method handle via {@code invokeExact} must exactly match this type.
+ * @return the method handle type
+ */
+ public MethodType type() {
+ // Android-added: Added nominalType field.
+ if (nominalType != null) {
+ return nominalType;
+ }
+
+ return type;
+ }
+
+ // BEGIN Android-removed: LambdaForm unsupported on Android.
+ /*
+ /**
+ * Package-private constructor for the method handle implementation hierarchy.
+ * Method handle inheritance will be contained completely within
+ * the {@code java.lang.invoke} package.
+ *
+ // @param type type (permanently assigned) of the new method handle
+ /*non-public* MethodHandle(MethodType type, LambdaForm form) {
+ type.getClass(); // explicit NPE
+ form.getClass(); // explicit NPE
+ this.type = type;
+ this.form = form.uncustomize();
+
+ this.form.prepare(); // TO DO: Try to delay this step until just before invocation.
+ }
+ */
+ // END Android-removed: LambdaForm unsupported on Android.
+
+ /**
+ * Invokes the method handle, allowing any caller type descriptor, but requiring an exact type match.
+ * The symbolic type descriptor at the call site of {@code invokeExact} must
+ * exactly match this method handle's {@link #type type}.
+ * No conversions are allowed on arguments or return values.
+ * <p>
+ * When this method is observed via the Core Reflection API,
+ * it will appear as a single native method, taking an object array and returning an object.
+ * If this native method is invoked directly via
+ * {@link java.lang.reflect.Method#invoke java.lang.reflect.Method.invoke}, via JNI,
+ * or indirectly via {@link java.lang.invoke.MethodHandles.Lookup#unreflect Lookup.unreflect},
+ * it will throw an {@code UnsupportedOperationException}.
+ * @param args the signature-polymorphic parameter list, statically represented using varargs
+ * @return the signature-polymorphic result, statically represented using {@code Object}
+ * @throws WrongMethodTypeException if the target's type is not identical with the caller's symbolic type descriptor
+ * @throws Throwable anything thrown by the underlying method propagates unchanged through the method handle call
+ */
+ public final native @PolymorphicSignature Object invokeExact(Object... args) throws Throwable;
+
+ /**
+ * Invokes the method handle, allowing any caller type descriptor,
+ * and optionally performing conversions on arguments and return values.
+ * <p>
+ * If the call site's symbolic type descriptor exactly matches this method handle's {@link #type type},
+ * the call proceeds as if by {@link #invokeExact invokeExact}.
+ * <p>
+ * Otherwise, the call proceeds as if this method handle were first
+ * adjusted by calling {@link #asType asType} to adjust this method handle
+ * to the required type, and then the call proceeds as if by
+ * {@link #invokeExact invokeExact} on the adjusted method handle.
+ * <p>
+ * There is no guarantee that the {@code asType} call is actually made.
+ * If the JVM can predict the results of making the call, it may perform
+ * adaptations directly on the caller's arguments,
+ * and call the target method handle according to its own exact type.
+ * <p>
+ * The resolved type descriptor at the call site of {@code invoke} must
+ * be a valid argument to the receivers {@code asType} method.
+ * In particular, the caller must specify the same argument arity
+ * as the callee's type,
+ * if the callee is not a {@linkplain #asVarargsCollector variable arity collector}.
+ * <p>
+ * When this method is observed via the Core Reflection API,
+ * it will appear as a single native method, taking an object array and returning an object.
+ * If this native method is invoked directly via
+ * {@link java.lang.reflect.Method#invoke java.lang.reflect.Method.invoke}, via JNI,
+ * or indirectly via {@link java.lang.invoke.MethodHandles.Lookup#unreflect Lookup.unreflect},
+ * it will throw an {@code UnsupportedOperationException}.
+ * @param args the signature-polymorphic parameter list, statically represented using varargs
+ * @return the signature-polymorphic result, statically represented using {@code Object}
+ * @throws WrongMethodTypeException if the target's type cannot be adjusted to the caller's symbolic type descriptor
+ * @throws ClassCastException if the target's type can be adjusted to the caller, but a reference cast fails
+ * @throws Throwable anything thrown by the underlying method propagates unchanged through the method handle call
+ */
+ public final native @PolymorphicSignature Object invoke(Object... args) throws Throwable;
+
+ // BEGIN Android-removed: RI implementation unused on Android.
+ /*
+ /**
+ * Private method for trusted invocation of a method handle respecting simplified signatures.
+ * Type mismatches will not throw {@code WrongMethodTypeException}, but could crash the JVM.
+ * <p>
+ * The caller signature is restricted to the following basic types:
+ * Object, int, long, float, double, and void return.
+ * <p>
+ * The caller is responsible for maintaining type correctness by ensuring
+ * that the each outgoing argument value is a member of the range of the corresponding
+ * callee argument type.
+ * (The caller should therefore issue appropriate casts and integer narrowing
+ * operations on outgoing argument values.)
+ * The caller can assume that the incoming result value is part of the range
+ * of the callee's return type.
+ * @param args the signature-polymorphic parameter list, statically represented using varargs
+ * @return the signature-polymorphic result, statically represented using {@code Object}
+ *
+ /*non-public* final native @PolymorphicSignature Object invokeBasic(Object... args) throws Throwable;
+
+ /**
+ * Private method for trusted invocation of a MemberName of kind {@code REF_invokeVirtual}.
+ * The caller signature is restricted to basic types as with {@code invokeBasic}.
+ * The trailing (not leading) argument must be a MemberName.
+ * @param args the signature-polymorphic parameter list, statically represented using varargs
+ * @return the signature-polymorphic result, statically represented using {@code Object}
+ *
+ /*non-public* static native @PolymorphicSignature Object linkToVirtual(Object... args) throws Throwable;
+
+ /**
+ * Private method for trusted invocation of a MemberName of kind {@code REF_invokeStatic}.
+ * The caller signature is restricted to basic types as with {@code invokeBasic}.
+ * The trailing (not leading) argument must be a MemberName.
+ * @param args the signature-polymorphic parameter list, statically represented using varargs
+ * @return the signature-polymorphic result, statically represented using {@code Object}
+ *
+ /*non-public* static native @PolymorphicSignature Object linkToStatic(Object... args) throws Throwable;
+
+ /**
+ * Private method for trusted invocation of a MemberName of kind {@code REF_invokeSpecial}.
+ * The caller signature is restricted to basic types as with {@code invokeBasic}.
+ * The trailing (not leading) argument must be a MemberName.
+ * @param args the signature-polymorphic parameter list, statically represented using varargs
+ * @return the signature-polymorphic result, statically represented using {@code Object}
+ *
+ /*non-public* static native @PolymorphicSignature Object linkToSpecial(Object... args) throws Throwable;
+
+ /**
+ * Private method for trusted invocation of a MemberName of kind {@code REF_invokeInterface}.
+ * The caller signature is restricted to basic types as with {@code invokeBasic}.
+ * The trailing (not leading) argument must be a MemberName.
+ * @param args the signature-polymorphic parameter list, statically represented using varargs
+ * @return the signature-polymorphic result, statically represented using {@code Object}
+ *
+ /*non-public* static native @PolymorphicSignature Object linkToInterface(Object... args) throws Throwable;
+ */
+ // END Android-removed: RI implementation unused on Android.
+
+ /**
+ * Performs a variable arity invocation, passing the arguments in the given list
+ * to the method handle, as if via an inexact {@link #invoke invoke} from a call site
+ * which mentions only the type {@code Object}, and whose arity is the length
+ * of the argument list.
+ * <p>
+ * Specifically, execution proceeds as if by the following steps,
+ * although the methods are not guaranteed to be called if the JVM
+ * can predict their effects.
+ * <ul>
+ * <li>Determine the length of the argument array as {@code N}.
+ * For a null reference, {@code N=0}. </li>
+ * <li>Determine the general type {@code TN} of {@code N} arguments as
+ * as {@code TN=MethodType.genericMethodType(N)}.</li>
+ * <li>Force the original target method handle {@code MH0} to the
+ * required type, as {@code MH1 = MH0.asType(TN)}. </li>
+ * <li>Spread the array into {@code N} separate arguments {@code A0, ...}. </li>
+ * <li>Invoke the type-adjusted method handle on the unpacked arguments:
+ * MH1.invokeExact(A0, ...). </li>
+ * <li>Take the return value as an {@code Object} reference. </li>
+ * </ul>
+ * <p>
+ * Because of the action of the {@code asType} step, the following argument
+ * conversions are applied as necessary:
+ * <ul>
+ * <li>reference casting
+ * <li>unboxing
+ * <li>widening primitive conversions
+ * </ul>
+ * <p>
+ * The result returned by the call is boxed if it is a primitive,
+ * or forced to null if the return type is void.
+ * <p>
+ * This call is equivalent to the following code:
+ * <blockquote><pre>{@code
+ * MethodHandle invoker = MethodHandles.spreadInvoker(this.type(), 0);
+ * Object result = invoker.invokeExact(this, arguments);
+ * }</pre></blockquote>
+ * <p>
+ * Unlike the signature polymorphic methods {@code invokeExact} and {@code invoke},
+ * {@code invokeWithArguments} can be accessed normally via the Core Reflection API and JNI.
+ * It can therefore be used as a bridge between native or reflective code and method handles.
+ *
+ * @param arguments the arguments to pass to the target
+ * @return the result returned by the target
+ * @throws ClassCastException if an argument cannot be converted by reference casting
+ * @throws WrongMethodTypeException if the target's type cannot be adjusted to take the given number of {@code Object} arguments
+ * @throws Throwable anything thrown by the target method invocation
+ * @see MethodHandles#spreadInvoker
+ */
+ public Object invokeWithArguments(Object... arguments) throws Throwable {
+ // BEGIN Android-changed: Android specific implementation.
+ // MethodType invocationType = MethodType.genericMethodType(arguments == null ? 0 : arguments.length);
+ // return invocationType.invokers().spreadInvoker(0).invokeExact(asType(invocationType), arguments);
+ MethodHandle invoker = null;
+ synchronized (this) {
+ if (cachedSpreadInvoker == null) {
+ cachedSpreadInvoker = MethodHandles.spreadInvoker(this.type(), 0);
+ }
+
+ invoker = cachedSpreadInvoker;
+ }
+
+ return invoker.invoke(this, arguments);
+ // END Android-changed: Android specific implementation.
+ }
+
+ /**
+ * Performs a variable arity invocation, passing the arguments in the given array
+ * to the method handle, as if via an inexact {@link #invoke invoke} from a call site
+ * which mentions only the type {@code Object}, and whose arity is the length
+ * of the argument array.
+ * <p>
+ * This method is also equivalent to the following code:
+ * <blockquote><pre>{@code
+ * invokeWithArguments(arguments.toArray()
+ * }</pre></blockquote>
+ *
+ * @param arguments the arguments to pass to the target
+ * @return the result returned by the target
+ * @throws NullPointerException if {@code arguments} is a null reference
+ * @throws ClassCastException if an argument cannot be converted by reference casting
+ * @throws WrongMethodTypeException if the target's type cannot be adjusted to take the given number of {@code Object} arguments
+ * @throws Throwable anything thrown by the target method invocation
+ */
+ public Object invokeWithArguments(java.util.List<?> arguments) throws Throwable {
+ return invokeWithArguments(arguments.toArray());
+ }
+
+ /**
+ * Produces an adapter method handle which adapts the type of the
+ * current method handle to a new type.
+ * The resulting method handle is guaranteed to report a type
+ * which is equal to the desired new type.
+ * <p>
+ * If the original type and new type are equal, returns {@code this}.
+ * <p>
+ * The new method handle, when invoked, will perform the following
+ * steps:
+ * <ul>
+ * <li>Convert the incoming argument list to match the original
+ * method handle's argument list.
+ * <li>Invoke the original method handle on the converted argument list.
+ * <li>Convert any result returned by the original method handle
+ * to the return type of new method handle.
+ * </ul>
+ * <p>
+ * This method provides the crucial behavioral difference between
+ * {@link #invokeExact invokeExact} and plain, inexact {@link #invoke invoke}.
+ * The two methods
+ * perform the same steps when the caller's type descriptor exactly m atches
+ * the callee's, but when the types differ, plain {@link #invoke invoke}
+ * also calls {@code asType} (or some internal equivalent) in order
+ * to match up the caller's and callee's types.
+ * <p>
+ * If the current method is a variable arity method handle
+ * argument list conversion may involve the conversion and collection
+ * of several arguments into an array, as
+ * {@linkplain #asVarargsCollector described elsewhere}.
+ * In every other case, all conversions are applied <em>pairwise</em>,
+ * which means that each argument or return value is converted to
+ * exactly one argument or return value (or no return value).
+ * The applied conversions are defined by consulting the
+ * the corresponding component types of the old and new
+ * method handle types.
+ * <p>
+ * Let <em>T0</em> and <em>T1</em> be corresponding new and old parameter types,
+ * or old and new return types. Specifically, for some valid index {@code i}, let
+ * <em>T0</em>{@code =newType.parameterType(i)} and <em>T1</em>{@code =this.type().parameterType(i)}.
+ * Or else, going the other way for return values, let
+ * <em>T0</em>{@code =this.type().returnType()} and <em>T1</em>{@code =newType.returnType()}.
+ * If the types are the same, the new method handle makes no change
+ * to the corresponding argument or return value (if any).
+ * Otherwise, one of the following conversions is applied
+ * if possible:
+ * <ul>
+ * <li>If <em>T0</em> and <em>T1</em> are references, then a cast to <em>T1</em> is applied.
+ * (The types do not need to be related in any particular way.
+ * This is because a dynamic value of null can convert to any reference type.)
+ * <li>If <em>T0</em> and <em>T1</em> are primitives, then a Java method invocation
+ * conversion (JLS 5.3) is applied, if one exists.
+ * (Specifically, <em>T0</em> must convert to <em>T1</em> by a widening primitive conversion.)
+ * <li>If <em>T0</em> is a primitive and <em>T1</em> a reference,
+ * a Java casting conversion (JLS 5.5) is applied if one exists.
+ * (Specifically, the value is boxed from <em>T0</em> to its wrapper class,
+ * which is then widened as needed to <em>T1</em>.)
+ * <li>If <em>T0</em> is a reference and <em>T1</em> a primitive, an unboxing
+ * conversion will be applied at runtime, possibly followed
+ * by a Java method invocation conversion (JLS 5.3)
+ * on the primitive value. (These are the primitive widening conversions.)
+ * <em>T0</em> must be a wrapper class or a supertype of one.
+ * (In the case where <em>T0</em> is Object, these are the conversions
+ * allowed by {@link java.lang.reflect.Method#invoke java.lang.reflect.Method.invoke}.)
+ * The unboxing conversion must have a possibility of success, which means that
+ * if <em>T0</em> is not itself a wrapper class, there must exist at least one
+ * wrapper class <em>TW</em> which is a subtype of <em>T0</em> and whose unboxed
+ * primitive value can be widened to <em>T1</em>.
+ * <li>If the return type <em>T1</em> is marked as void, any returned value is discarded
+ * <li>If the return type <em>T0</em> is void and <em>T1</em> a reference, a null value is introduced.
+ * <li>If the return type <em>T0</em> is void and <em>T1</em> a primitive,
+ * a zero value is introduced.
+ * </ul>
+ * (<em>Note:</em> Both <em>T0</em> and <em>T1</em> may be regarded as static types,
+ * because neither corresponds specifically to the <em>dynamic type</em> of any
+ * actual argument or return value.)
+ * <p>
+ * The method handle conversion cannot be made if any one of the required
+ * pairwise conversions cannot be made.
+ * <p>
+ * At runtime, the conversions applied to reference arguments
+ * or return values may require additional runtime checks which can fail.
+ * An unboxing operation may fail because the original reference is null,
+ * causing a {@link java.lang.NullPointerException NullPointerException}.
+ * An unboxing operation or a reference cast may also fail on a reference
+ * to an object of the wrong type,
+ * causing a {@link java.lang.ClassCastException ClassCastException}.
+ * Although an unboxing operation may accept several kinds of wrappers,
+ * if none are available, a {@code ClassCastException} will be thrown.
+ *
+ * @param newType the expected type of the new method handle
+ * @return a method handle which delegates to {@code this} after performing
+ * any necessary argument conversions, and arranges for any
+ * necessary return value conversions
+ * @throws NullPointerException if {@code newType} is a null reference
+ * @throws WrongMethodTypeException if the conversion cannot be made
+ * @see MethodHandles#explicitCastArguments
+ */
+ public MethodHandle asType(MethodType newType) {
+ // Fast path alternative to a heavyweight {@code asType} call.
+ // Return 'this' if the conversion will be a no-op.
+ if (newType == type) {
+ return this;
+ }
+ // Android-removed: Type conversion memoizing is unsupported on Android.
+ /*
+ // Return 'this.asTypeCache' if the conversion is already memoized.
+ MethodHandle atc = asTypeCached(newType);
+ if (atc != null) {
+ return atc;
+ }
+ */
+ return asTypeUncached(newType);
+ }
+
+ // Android-removed: Type conversion memoizing is unsupported on Android.
+ /*
+ private MethodHandle asTypeCached(MethodType newType) {
+ MethodHandle atc = asTypeCache;
+ if (atc != null && newType == atc.type) {
+ return atc;
+ }
+ return null;
+ }
+ */
+
+ /** Override this to change asType behavior. */
+ /*non-public*/ MethodHandle asTypeUncached(MethodType newType) {
+ if (!type.isConvertibleTo(newType))
+ throw new WrongMethodTypeException("cannot convert "+this+" to "+newType);
+ // BEGIN Android-changed: Android specific implementation.
+ // return asTypeCache = MethodHandleImpl.makePairwiseConvert(this, newType, true);
+ MethodHandle mh = duplicate();
+ mh.nominalType = newType;
+ return mh;
+ // END Android-changed: Android specific implementation.
+ }
+
+ /**
+ * Makes an <em>array-spreading</em> method handle, which accepts a trailing array argument
+ * and spreads its elements as positional arguments.
+ * The new method handle adapts, as its <i>target</i>,
+ * the current method handle. The type of the adapter will be
+ * the same as the type of the target, except that the final
+ * {@code arrayLength} parameters of the target's type are replaced
+ * by a single array parameter of type {@code arrayType}.
+ * <p>
+ * If the array element type differs from any of the corresponding
+ * argument types on the original target,
+ * the original target is adapted to take the array elements directly,
+ * as if by a call to {@link #asType asType}.
+ * <p>
+ * When called, the adapter replaces a trailing array argument
+ * by the array's elements, each as its own argument to the target.
+ * (The order of the arguments is preserved.)
+ * They are converted pairwise by casting and/or unboxing
+ * to the types of the trailing parameters of the target.
+ * Finally the target is called.
+ * What the target eventually returns is returned unchanged by the adapter.
+ * <p>
+ * Before calling the target, the adapter verifies that the array
+ * contains exactly enough elements to provide a correct argument count
+ * to the target method handle.
+ * (The array may also be null when zero elements are required.)
+ * <p>
+ * If, when the adapter is called, the supplied array argument does
+ * not have the correct number of elements, the adapter will throw
+ * an {@link IllegalArgumentException} instead of invoking the target.
+ * <p>
+ * Here are some simple examples of array-spreading method handles:
+ * <blockquote><pre>{@code
+MethodHandle equals = publicLookup()
+ .findVirtual(String.class, "equals", methodType(boolean.class, Object.class));
+assert( (boolean) equals.invokeExact("me", (Object)"me"));
+assert(!(boolean) equals.invokeExact("me", (Object)"thee"));
+// spread both arguments from a 2-array:
+MethodHandle eq2 = equals.asSpreader(Object[].class, 2);
+assert( (boolean) eq2.invokeExact(new Object[]{ "me", "me" }));
+assert(!(boolean) eq2.invokeExact(new Object[]{ "me", "thee" }));
+// try to spread from anything but a 2-array:
+for (int n = 0; n <= 10; n++) {
+ Object[] badArityArgs = (n == 2 ? null : new Object[n]);
+ try { assert((boolean) eq2.invokeExact(badArityArgs) && false); }
+ catch (IllegalArgumentException ex) { } // OK
+}
+// spread both arguments from a String array:
+MethodHandle eq2s = equals.asSpreader(String[].class, 2);
+assert( (boolean) eq2s.invokeExact(new String[]{ "me", "me" }));
+assert(!(boolean) eq2s.invokeExact(new String[]{ "me", "thee" }));
+// spread second arguments from a 1-array:
+MethodHandle eq1 = equals.asSpreader(Object[].class, 1);
+assert( (boolean) eq1.invokeExact("me", new Object[]{ "me" }));
+assert(!(boolean) eq1.invokeExact("me", new Object[]{ "thee" }));
+// spread no arguments from a 0-array or null:
+MethodHandle eq0 = equals.asSpreader(Object[].class, 0);
+assert( (boolean) eq0.invokeExact("me", (Object)"me", new Object[0]));
+assert(!(boolean) eq0.invokeExact("me", (Object)"thee", (Object[])null));
+// asSpreader and asCollector are approximate inverses:
+for (int n = 0; n <= 2; n++) {
+ for (Class<?> a : new Class<?>[]{Object[].class, String[].class, CharSequence[].class}) {
+ MethodHandle equals2 = equals.asSpreader(a, n).asCollector(a, n);
+ assert( (boolean) equals2.invokeWithArguments("me", "me"));
+ assert(!(boolean) equals2.invokeWithArguments("me", "thee"));
+ }
+}
+MethodHandle caToString = publicLookup()
+ .findStatic(Arrays.class, "toString", methodType(String.class, char[].class));
+assertEquals("[A, B, C]", (String) caToString.invokeExact("ABC".toCharArray()));
+MethodHandle caString3 = caToString.asCollector(char[].class, 3);
+assertEquals("[A, B, C]", (String) caString3.invokeExact('A', 'B', 'C'));
+MethodHandle caToString2 = caString3.asSpreader(char[].class, 2);
+assertEquals("[A, B, C]", (String) caToString2.invokeExact('A', "BC".toCharArray()));
+ * }</pre></blockquote>
+ * @param arrayType usually {@code Object[]}, the type of the array argument from which to extract the spread arguments
+ * @param arrayLength the number of arguments to spread from an incoming array argument
+ * @return a new method handle which spreads its final array argument,
+ * before calling the original method handle
+ * @throws NullPointerException if {@code arrayType} is a null reference
+ * @throws IllegalArgumentException if {@code arrayType} is not an array type,
+ * or if target does not have at least
+ * {@code arrayLength} parameter types,
+ * or if {@code arrayLength} is negative,
+ * or if the resulting method handle's type would have
+ * <a href="MethodHandle.html#maxarity">too many parameters</a>
+ * @throws WrongMethodTypeException if the implied {@code asType} call fails
+ * @see #asCollector
+ */
+ public MethodHandle asSpreader(Class<?> arrayType, int arrayLength) {
+ MethodType postSpreadType = asSpreaderChecks(arrayType, arrayLength);
+ // BEGIN Android-changed: Android specific implementation.
+ /*
+ int arity = type().parameterCount();
+ int spreadArgPos = arity - arrayLength;
+ MethodHandle afterSpread = this.asType(postSpreadType);
+ BoundMethodHandle mh = afterSpread.rebind();
+ LambdaForm lform = mh.editor().spreadArgumentsForm(1 + spreadArgPos, arrayType, arrayLength);
+ MethodType preSpreadType = postSpreadType.replaceParameterTypes(spreadArgPos, arity, arrayType);
+ return mh.copyWith(preSpreadType, lform);
+ */
+ final int targetParamCount = postSpreadType.parameterCount();
+ MethodType dropArrayArgs = postSpreadType.dropParameterTypes(
+ (targetParamCount - arrayLength), targetParamCount);
+ MethodType adapterType = dropArrayArgs.appendParameterTypes(arrayType);
+
+ return new Transformers.Spreader(this, adapterType, arrayLength);
+ // END Android-changed: Android specific implementation.
+ }
+
+ /**
+ * See if {@code asSpreader} can be validly called with the given arguments.
+ * Return the type of the method handle call after spreading but before conversions.
+ */
+ private MethodType asSpreaderChecks(Class<?> arrayType, int arrayLength) {
+ spreadArrayChecks(arrayType, arrayLength);
+ int nargs = type().parameterCount();
+ if (nargs < arrayLength || arrayLength < 0)
+ throw newIllegalArgumentException("bad spread array length");
+ Class<?> arrayElement = arrayType.getComponentType();
+ MethodType mtype = type();
+ boolean match = true, fail = false;
+ for (int i = nargs - arrayLength; i < nargs; i++) {
+ Class<?> ptype = mtype.parameterType(i);
+ if (ptype != arrayElement) {
+ match = false;
+ if (!MethodType.canConvert(arrayElement, ptype)) {
+ fail = true;
+ break;
+ }
+ }
+ }
+ if (match) return mtype;
+ MethodType needType = mtype.asSpreaderType(arrayType, arrayLength);
+ if (!fail) return needType;
+ // elicit an error:
+ this.asType(needType);
+ throw newInternalError("should not return", null);
+ }
+
+ private void spreadArrayChecks(Class<?> arrayType, int arrayLength) {
+ Class<?> arrayElement = arrayType.getComponentType();
+ if (arrayElement == null)
+ throw newIllegalArgumentException("not an array type", arrayType);
+ if ((arrayLength & 0x7F) != arrayLength) {
+ if ((arrayLength & 0xFF) != arrayLength)
+ throw newIllegalArgumentException("array length is not legal", arrayLength);
+ assert(arrayLength >= 128);
+ if (arrayElement == long.class ||
+ arrayElement == double.class)
+ throw newIllegalArgumentException("array length is not legal for long[] or double[]", arrayLength);
+ }
+ }
+
+ /**
+ * Makes an <em>array-collecting</em> method handle, which accepts a given number of trailing
+ * positional arguments and collects them into an array argument.
+ * The new method handle adapts, as its <i>target</i>,
+ * the current method handle. The type of the adapter will be
+ * the same as the type of the target, except that a single trailing
+ * parameter (usually of type {@code arrayType}) is replaced by
+ * {@code arrayLength} parameters whose type is element type of {@code arrayType}.
+ * <p>
+ * If the array type differs from the final argument type on the original target,
+ * the original target is adapted to take the array type directly,
+ * as if by a call to {@link #asType asType}.
+ * <p>
+ * When called, the adapter replaces its trailing {@code arrayLength}
+ * arguments by a single new array of type {@code arrayType}, whose elements
+ * comprise (in order) the replaced arguments.
+ * Finally the target is called.
+ * What the target eventually returns is returned unchanged by the adapter.
+ * <p>
+ * (The array may also be a shared constant when {@code arrayLength} is zero.)
+ * <p>
+ * (<em>Note:</em> The {@code arrayType} is often identical to the last
+ * parameter type of the original target.
+ * It is an explicit argument for symmetry with {@code asSpreader}, and also
+ * to allow the target to use a simple {@code Object} as its last parameter type.)
+ * <p>
+ * In order to create a collecting adapter which is not restricted to a particular
+ * number of collected arguments, use {@link #asVarargsCollector asVarargsCollector} instead.
+ * <p>
+ * Here are some examples of array-collecting method handles:
+ * <blockquote><pre>{@code
+MethodHandle deepToString = publicLookup()
+ .findStatic(Arrays.class, "deepToString", methodType(String.class, Object[].class));
+assertEquals("[won]", (String) deepToString.invokeExact(new Object[]{"won"}));
+MethodHandle ts1 = deepToString.asCollector(Object[].class, 1);
+assertEquals(methodType(String.class, Object.class), ts1.type());
+//assertEquals("[won]", (String) ts1.invokeExact( new Object[]{"won"})); //FAIL
+assertEquals("[[won]]", (String) ts1.invokeExact((Object) new Object[]{"won"}));
+// arrayType can be a subtype of Object[]
+MethodHandle ts2 = deepToString.asCollector(String[].class, 2);
+assertEquals(methodType(String.class, String.class, String.class), ts2.type());
+assertEquals("[two, too]", (String) ts2.invokeExact("two", "too"));
+MethodHandle ts0 = deepToString.asCollector(Object[].class, 0);
+assertEquals("[]", (String) ts0.invokeExact());
+// collectors can be nested, Lisp-style
+MethodHandle ts22 = deepToString.asCollector(Object[].class, 3).asCollector(String[].class, 2);
+assertEquals("[A, B, [C, D]]", ((String) ts22.invokeExact((Object)'A', (Object)"B", "C", "D")));
+// arrayType can be any primitive array type
+MethodHandle bytesToString = publicLookup()
+ .findStatic(Arrays.class, "toString", methodType(String.class, byte[].class))
+ .asCollector(byte[].class, 3);
+assertEquals("[1, 2, 3]", (String) bytesToString.invokeExact((byte)1, (byte)2, (byte)3));
+MethodHandle longsToString = publicLookup()
+ .findStatic(Arrays.class, "toString", methodType(String.class, long[].class))
+ .asCollector(long[].class, 1);
+assertEquals("[123]", (String) longsToString.invokeExact((long)123));
+ * }</pre></blockquote>
+ * @param arrayType often {@code Object[]}, the type of the array argument which will collect the arguments
+ * @param arrayLength the number of arguments to collect into a new array argument
+ * @return a new method handle which collects some trailing argument
+ * into an array, before calling the original method handle
+ * @throws NullPointerException if {@code arrayType} is a null reference
+ * @throws IllegalArgumentException if {@code arrayType} is not an array type
+ * or {@code arrayType} is not assignable to this method handle's trailing parameter type,
+ * or {@code arrayLength} is not a legal array size,
+ * or the resulting method handle's type would have
+ * <a href="MethodHandle.html#maxarity">too many parameters</a>
+ * @throws WrongMethodTypeException if the implied {@code asType} call fails
+ * @see #asSpreader
+ * @see #asVarargsCollector
+ */
+ public MethodHandle asCollector(Class<?> arrayType, int arrayLength) {
+ asCollectorChecks(arrayType, arrayLength);
+ // BEGIN Android-changed: Android specific implementation.
+ /*
+ int collectArgPos = type().parameterCount() - 1;
+ BoundMethodHandle mh = rebind();
+ MethodType resultType = type().asCollectorType(arrayType, arrayLength);
+ MethodHandle newArray = MethodHandleImpl.varargsArray(arrayType, arrayLength);
+ LambdaForm lform = mh.editor().collectArgumentArrayForm(1 + collectArgPos, newArray);
+ if (lform != null) {
+ return mh.copyWith(resultType, lform);
+ }
+ lform = mh.editor().collectArgumentsForm(1 + collectArgPos, newArray.type().basicType());
+ return mh.copyWithExtendL(resultType, lform, newArray);
+ */
+ return new Transformers.Collector(this, arrayType, arrayLength);
+ // END Android-changed: Android specific implementation.
+ }
+
+ /**
+ * See if {@code asCollector} can be validly called with the given arguments.
+ * Return false if the last parameter is not an exact match to arrayType.
+ */
+ /*non-public*/ boolean asCollectorChecks(Class<?> arrayType, int arrayLength) {
+ spreadArrayChecks(arrayType, arrayLength);
+ int nargs = type().parameterCount();
+ if (nargs != 0) {
+ Class<?> lastParam = type().parameterType(nargs-1);
+ if (lastParam == arrayType) return true;
+ if (lastParam.isAssignableFrom(arrayType)) return false;
+ }
+ throw newIllegalArgumentException("array type not assignable to trailing argument", this, arrayType);
+ }
+
+ /**
+ * Makes a <em>variable arity</em> adapter which is able to accept
+ * any number of trailing positional arguments and collect them
+ * into an array argument.
+ * <p>
+ * The type and behavior of the adapter will be the same as
+ * the type and behavior of the target, except that certain
+ * {@code invoke} and {@code asType} requests can lead to
+ * trailing positional arguments being collected into target's
+ * trailing parameter.
+ * Also, the last parameter type of the adapter will be
+ * {@code arrayType}, even if the target has a different
+ * last parameter type.
+ * <p>
+ * This transformation may return {@code this} if the method handle is
+ * already of variable arity and its trailing parameter type
+ * is identical to {@code arrayType}.
+ * <p>
+ * When called with {@link #invokeExact invokeExact}, the adapter invokes
+ * the target with no argument changes.
+ * (<em>Note:</em> This behavior is different from a
+ * {@linkplain #asCollector fixed arity collector},
+ * since it accepts a whole array of indeterminate length,
+ * rather than a fixed number of arguments.)
+ * <p>
+ * When called with plain, inexact {@link #invoke invoke}, if the caller
+ * type is the same as the adapter, the adapter invokes the target as with
+ * {@code invokeExact}.
+ * (This is the normal behavior for {@code invoke} when types match.)
+ * <p>
+ * Otherwise, if the caller and adapter arity are the same, and the
+ * trailing parameter type of the caller is a reference type identical to
+ * or assignable to the trailing parameter type of the adapter,
+ * the arguments and return values are converted pairwise,
+ * as if by {@link #asType asType} on a fixed arity
+ * method handle.
+ * <p>
+ * Otherwise, the arities differ, or the adapter's trailing parameter
+ * type is not assignable from the corresponding caller type.
+ * In this case, the adapter replaces all trailing arguments from
+ * the original trailing argument position onward, by
+ * a new array of type {@code arrayType}, whose elements
+ * comprise (in order) the replaced arguments.
+ * <p>
+ * The caller type must provides as least enough arguments,
+ * and of the correct type, to satisfy the target's requirement for
+ * positional arguments before the trailing array argument.
+ * Thus, the caller must supply, at a minimum, {@code N-1} arguments,
+ * where {@code N} is the arity of the target.
+ * Also, there must exist conversions from the incoming arguments
+ * to the target's arguments.
+ * As with other uses of plain {@code invoke}, if these basic
+ * requirements are not fulfilled, a {@code WrongMethodTypeException}
+ * may be thrown.
+ * <p>
+ * In all cases, what the target eventually returns is returned unchanged by the adapter.
+ * <p>
+ * In the final case, it is exactly as if the target method handle were
+ * temporarily adapted with a {@linkplain #asCollector fixed arity collector}
+ * to the arity required by the caller type.
+ * (As with {@code asCollector}, if the array length is zero,
+ * a shared constant may be used instead of a new array.
+ * If the implied call to {@code asCollector} would throw
+ * an {@code IllegalArgumentException} or {@code WrongMethodTypeException},
+ * the call to the variable arity adapter must throw
+ * {@code WrongMethodTypeException}.)
+ * <p>
+ * The behavior of {@link #asType asType} is also specialized for
+ * variable arity adapters, to maintain the invariant that
+ * plain, inexact {@code invoke} is always equivalent to an {@code asType}
+ * call to adjust the target type, followed by {@code invokeExact}.
+ * Therefore, a variable arity adapter responds
+ * to an {@code asType} request by building a fixed arity collector,
+ * if and only if the adapter and requested type differ either
+ * in arity or trailing argument type.
+ * The resulting fixed arity collector has its type further adjusted
+ * (if necessary) to the requested type by pairwise conversion,
+ * as if by another application of {@code asType}.
+ * <p>
+ * When a method handle is obtained by executing an {@code ldc} instruction
+ * of a {@code CONSTANT_MethodHandle} constant, and the target method is marked
+ * as a variable arity method (with the modifier bit {@code 0x0080}),
+ * the method handle will accept multiple arities, as if the method handle
+ * constant were created by means of a call to {@code asVarargsCollector}.
+ * <p>
+ * In order to create a collecting adapter which collects a predetermined
+ * number of arguments, and whose type reflects this predetermined number,
+ * use {@link #asCollector asCollector} instead.
+ * <p>
+ * No method handle transformations produce new method handles with
+ * variable arity, unless they are documented as doing so.
+ * Therefore, besides {@code asVarargsCollector},
+ * all methods in {@code MethodHandle} and {@code MethodHandles}
+ * will return a method handle with fixed arity,
+ * except in the cases where they are specified to return their original
+ * operand (e.g., {@code asType} of the method handle's own type).
+ * <p>
+ * Calling {@code asVarargsCollector} on a method handle which is already
+ * of variable arity will produce a method handle with the same type and behavior.
+ * It may (or may not) return the original variable arity method handle.
+ * <p>
+ * Here is an example, of a list-making variable arity method handle:
+ * <blockquote><pre>{@code
+MethodHandle deepToString = publicLookup()
+ .findStatic(Arrays.class, "deepToString", methodType(String.class, Object[].class));
+MethodHandle ts1 = deepToString.asVarargsCollector(Object[].class);
+assertEquals("[won]", (String) ts1.invokeExact( new Object[]{"won"}));
+assertEquals("[won]", (String) ts1.invoke( new Object[]{"won"}));
+assertEquals("[won]", (String) ts1.invoke( "won" ));
+assertEquals("[[won]]", (String) ts1.invoke((Object) new Object[]{"won"}));
+// findStatic of Arrays.asList(...) produces a variable arity method handle:
+MethodHandle asList = publicLookup()
+ .findStatic(Arrays.class, "asList", methodType(List.class, Object[].class));
+assertEquals(methodType(List.class, Object[].class), asList.type());
+assert(asList.isVarargsCollector());
+assertEquals("[]", asList.invoke().toString());
+assertEquals("[1]", asList.invoke(1).toString());
+assertEquals("[two, too]", asList.invoke("two", "too").toString());
+String[] argv = { "three", "thee", "tee" };
+assertEquals("[three, thee, tee]", asList.invoke(argv).toString());
+assertEquals("[three, thee, tee]", asList.invoke((Object[])argv).toString());
+List ls = (List) asList.invoke((Object)argv);
+assertEquals(1, ls.size());
+assertEquals("[three, thee, tee]", Arrays.toString((Object[])ls.get(0)));
+ * }</pre></blockquote>
+ * <p style="font-size:smaller;">
+ * <em>Discussion:</em>
+ * These rules are designed as a dynamically-typed variation
+ * of the Java rules for variable arity methods.
+ * In both cases, callers to a variable arity method or method handle
+ * can either pass zero or more positional arguments, or else pass
+ * pre-collected arrays of any length. Users should be aware of the
+ * special role of the final argument, and of the effect of a
+ * type match on that final argument, which determines whether
+ * or not a single trailing argument is interpreted as a whole
+ * array or a single element of an array to be collected.
+ * Note that the dynamic type of the trailing argument has no
+ * effect on this decision, only a comparison between the symbolic
+ * type descriptor of the call site and the type descriptor of the method handle.)
+ *
+ * @param arrayType often {@code Object[]}, the type of the array argument which will collect the arguments
+ * @return a new method handle which can collect any number of trailing arguments
+ * into an array, before calling the original method handle
+ * @throws NullPointerException if {@code arrayType} is a null reference
+ * @throws IllegalArgumentException if {@code arrayType} is not an array type
+ * or {@code arrayType} is not assignable to this method handle's trailing parameter type
+ * @see #asCollector
+ * @see #isVarargsCollector
+ * @see #asFixedArity
+ */
+ public MethodHandle asVarargsCollector(Class<?> arrayType) {
+ arrayType.getClass(); // explicit NPE
+ boolean lastMatch = asCollectorChecks(arrayType, 0);
+ if (isVarargsCollector() && lastMatch)
+ return this;
+ // Android-changed: Android specific implementation.
+ // return MethodHandleImpl.makeVarargsCollector(this, arrayType);
+ return new Transformers.VarargsCollector(this);
+ }
+
+ /**
+ * Determines if this method handle
+ * supports {@linkplain #asVarargsCollector variable arity} calls.
+ * Such method handles arise from the following sources:
+ * <ul>
+ * <li>a call to {@linkplain #asVarargsCollector asVarargsCollector}
+ * <li>a call to a {@linkplain java.lang.invoke.MethodHandles.Lookup lookup method}
+ * which resolves to a variable arity Java method or constructor
+ * <li>an {@code ldc} instruction of a {@code CONSTANT_MethodHandle}
+ * which resolves to a variable arity Java method or constructor
+ * </ul>
+ * @return true if this method handle accepts more than one arity of plain, inexact {@code invoke} calls
+ * @see #asVarargsCollector
+ * @see #asFixedArity
+ */
+ public boolean isVarargsCollector() {
+ return false;
+ }
+
+ /**
+ * Makes a <em>fixed arity</em> method handle which is otherwise
+ * equivalent to the current method handle.
+ * <p>
+ * If the current method handle is not of
+ * {@linkplain #asVarargsCollector variable arity},
+ * the current method handle is returned.
+ * This is true even if the current method handle
+ * could not be a valid input to {@code asVarargsCollector}.
+ * <p>
+ * Otherwise, the resulting fixed-arity method handle has the same
+ * type and behavior of the current method handle,
+ * except that {@link #isVarargsCollector isVarargsCollector}
+ * will be false.
+ * The fixed-arity method handle may (or may not) be the
+ * a previous argument to {@code asVarargsCollector}.
+ * <p>
+ * Here is an example, of a list-making variable arity method handle:
+ * <blockquote><pre>{@code
+MethodHandle asListVar = publicLookup()
+ .findStatic(Arrays.class, "asList", methodType(List.class, Object[].class))
+ .asVarargsCollector(Object[].class);
+MethodHandle asListFix = asListVar.asFixedArity();
+assertEquals("[1]", asListVar.invoke(1).toString());
+Exception caught = null;
+try { asListFix.invoke((Object)1); }
+catch (Exception ex) { caught = ex; }
+assert(caught instanceof ClassCastException);
+assertEquals("[two, too]", asListVar.invoke("two", "too").toString());
+try { asListFix.invoke("two", "too"); }
+catch (Exception ex) { caught = ex; }
+assert(caught instanceof WrongMethodTypeException);
+Object[] argv = { "three", "thee", "tee" };
+assertEquals("[three, thee, tee]", asListVar.invoke(argv).toString());
+assertEquals("[three, thee, tee]", asListFix.invoke(argv).toString());
+assertEquals(1, ((List) asListVar.invoke((Object)argv)).size());
+assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString());
+ * }</pre></blockquote>
+ *
+ * @return a new method handle which accepts only a fixed number of arguments
+ * @see #asVarargsCollector
+ * @see #isVarargsCollector
+ */
+ public MethodHandle asFixedArity() {
+ // BEGIN Android-changed: Android specific implementation.
+ // assert(!isVarargsCollector());
+ // return this;
+
+ MethodHandle mh = this;
+ if (mh.isVarargsCollector()) {
+ mh = ((Transformers.VarargsCollector) mh).asFixedArity();
+ }
+ assert(!mh.isVarargsCollector());
+ return mh;
+ // END Android-changed: Android specific implementation.
+ }
+
+ /**
+ * Binds a value {@code x} to the first argument of a method handle, without invoking it.
+ * The new method handle adapts, as its <i>target</i>,
+ * the current method handle by binding it to the given argument.
+ * The type of the bound handle will be
+ * the same as the type of the target, except that a single leading
+ * reference parameter will be omitted.
+ * <p>
+ * When called, the bound handle inserts the given value {@code x}
+ * as a new leading argument to the target. The other arguments are
+ * also passed unchanged.
+ * What the target eventually returns is returned unchanged by the bound handle.
+ * <p>
+ * The reference {@code x} must be convertible to the first parameter
+ * type of the target.
+ * <p>
+ * (<em>Note:</em> Because method handles are immutable, the target method handle
+ * retains its original type and behavior.)
+ * @param x the value to bind to the first argument of the target
+ * @return a new method handle which prepends the given value to the incoming
+ * argument list, before calling the original method handle
+ * @throws IllegalArgumentException if the target does not have a
+ * leading parameter type that is a reference type
+ * @throws ClassCastException if {@code x} cannot be converted
+ * to the leading parameter type of the target
+ * @see MethodHandles#insertArguments
+ */
+ public MethodHandle bindTo(Object x) {
+ x = type.leadingReferenceParameter().cast(x); // throw CCE if needed
+ // Android-changed: Android specific implementation.
+ // return bindArgumentL(0, x);
+ return new Transformers.BindTo(this, x);
+ }
+
+ /**
+ * Returns a string representation of the method handle,
+ * starting with the string {@code "MethodHandle"} and
+ * ending with the string representation of the method handle's type.
+ * In other words, this method returns a string equal to the value of:
+ * <blockquote><pre>{@code
+ * "MethodHandle" + type().toString()
+ * }</pre></blockquote>
+ * <p>
+ * (<em>Note:</em> Future releases of this API may add further information
+ * to the string representation.
+ * Therefore, the present syntax should not be parsed by applications.)
+ *
+ * @return a string representation of the method handle
+ */
+ @Override
+ public String toString() {
+ // Android-removed: Debugging support unused on Android.
+ // if (DEBUG_METHOD_HANDLE_NAMES) return "MethodHandle"+debugString();
+ return standardString();
+ }
+ String standardString() {
+ return "MethodHandle"+type;
+ }
+
+ // BEGIN Android-removed: Debugging support unused on Android.
+ /*
+ /** Return a string with a several lines describing the method handle structure.
+ * This string would be suitable for display in an IDE debugger.
+ *
+ String debugString() {
+ return type+" : "+internalForm()+internalProperties();
+ }
+ */
+ // END Android-removed: Debugging support unused on Android.
+
+ // BEGIN Android-added: Android specific implementation.
+ /** @hide */
+ public int getHandleKind() {
+ return handleKind;
+ }
+
+ /** @hide */
+ protected void transform(EmulatedStackFrame arguments) throws Throwable {
+ throw new AssertionError("MethodHandle.transform should never be called.");
+ }
+
+ /**
+ * Creates a copy of this method handle, copying all relevant data.
+ *
+ * @hide
+ */
+ protected MethodHandle duplicate() {
+ try {
+ return (MethodHandle) this.clone();
+ } catch (CloneNotSupportedException cnse) {
+ throw new AssertionError("Subclass of Transformer is not cloneable");
+ }
+ }
+
+ /**
+ * This is the entry point for all transform calls, and dispatches to the protected
+ * transform method. This layer of indirection exists purely for convenience, because
+ * we can invoke-direct on a fixed ArtMethod for all transform variants.
+ *
+ * NOTE: If this extra layer of indirection proves to be a problem, we can get rid
+ * of this layer of indirection at the cost of some additional ugliness.
+ */
+ private void transformInternal(EmulatedStackFrame arguments) throws Throwable {
+ transform(arguments);
+ }
+ // END Android-added: Android specific implementation.
+
+ // BEGIN Android-removed: RI implementation unused on Android.
+ /*
+ //// Implementation methods.
+ //// Sub-classes can override these default implementations.
+ //// All these methods assume arguments are already validated.
+
+ // Other transforms to do: convert, explicitCast, permute, drop, filter, fold, GWT, catch
+
+ BoundMethodHandle bindArgumentL(int pos, Object value) {
+ return rebind().bindArgumentL(pos, value);
+ }
+
+ /*non-public*
+ MethodHandle setVarargs(MemberName member) throws IllegalAccessException {
+ if (!member.isVarargs()) return this;
+ Class<?> arrayType = type().lastParameterType();
+ if (arrayType.isArray()) {
+ return MethodHandleImpl.makeVarargsCollector(this, arrayType);
+ }
+ throw member.makeAccessException("cannot make variable arity", null);
+ }
+
+ /*non-public*
+ MethodHandle viewAsType(MethodType newType, boolean strict) {
+ // No actual conversions, just a new view of the same method.
+ // Note that this operation must not produce a DirectMethodHandle,
+ // because retyped DMHs, like any transformed MHs,
+ // cannot be cracked into MethodHandleInfo.
+ assert viewAsTypeChecks(newType, strict);
+ BoundMethodHandle mh = rebind();
+ assert(!((MethodHandle)mh instanceof DirectMethodHandle));
+ return mh.copyWith(newType, mh.form);
+ }
+
+ /*non-public*
+ boolean viewAsTypeChecks(MethodType newType, boolean strict) {
+ if (strict) {
+ assert(type().isViewableAs(newType, true))
+ : Arrays.asList(this, newType);
+ } else {
+ assert(type().basicType().isViewableAs(newType.basicType(), true))
+ : Arrays.asList(this, newType);
+ }
+ return true;
+ }
+
+ // Decoding
+
+ /*non-public*
+ LambdaForm internalForm() {
+ return form;
+ }
+
+ /*non-public*
+ MemberName internalMemberName() {
+ return null; // DMH returns DMH.member
+ }
+
+ /*non-public*
+ Class<?> internalCallerClass() {
+ return null; // caller-bound MH for @CallerSensitive method returns caller
+ }
+
+ /*non-public*
+ MethodHandleImpl.Intrinsic intrinsicName() {
+ // no special intrinsic meaning to most MHs
+ return MethodHandleImpl.Intrinsic.NONE;
+ }
+
+ /*non-public*
+ MethodHandle withInternalMemberName(MemberName member, boolean isInvokeSpecial) {
+ if (member != null) {
+ return MethodHandleImpl.makeWrappedMember(this, member, isInvokeSpecial);
+ } else if (internalMemberName() == null) {
+ // The required internaMemberName is null, and this MH (like most) doesn't have one.
+ return this;
+ } else {
+ // The following case is rare. Mask the internalMemberName by wrapping the MH in a BMH.
+ MethodHandle result = rebind();
+ assert (result.internalMemberName() == null);
+ return result;
+ }
+ }
+
+ /*non-public*
+ boolean isInvokeSpecial() {
+ return false; // DMH.Special returns true
+ }
+
+ /*non-public*
+ Object internalValues() {
+ return null;
+ }
+
+ /*non-public*
+ Object internalProperties() {
+ // Override to something to follow this.form, like "\n& FOO=bar"
+ return "";
+ }
+
+ //// Method handle implementation methods.
+ //// Sub-classes can override these default implementations.
+ //// All these methods assume arguments are already validated.
+
+ /*non-public*
+ abstract MethodHandle copyWith(MethodType mt, LambdaForm lf);
+
+ /** Require this method handle to be a BMH, or else replace it with a "wrapper" BMH.
+ * Many transforms are implemented only for BMHs.
+ * @return a behaviorally equivalent BMH
+ *
+ abstract BoundMethodHandle rebind();
+
+ /**
+ * Replace the old lambda form of this method handle with a new one.
+ * The new one must be functionally equivalent to the old one.
+ * Threads may continue running the old form indefinitely,
+ * but it is likely that the new one will be preferred for new executions.
+ * Use with discretion.
+ *
+ /*non-public*
+ void updateForm(LambdaForm newForm) {
+ assert(newForm.customized == null || newForm.customized == this);
+ if (form == newForm) return;
+ newForm.prepare(); // as in MethodHandle.<init>
+ UNSAFE.putObject(this, FORM_OFFSET, newForm);
+ UNSAFE.fullFence();
+ }
+
+ /** Craft a LambdaForm customized for this particular MethodHandle *
+ /*non-public*
+ void customize() {
+ if (form.customized == null) {
+ LambdaForm newForm = form.customize(this);
+ updateForm(newForm);
+ } else {
+ assert(form.customized == this);
+ }
+ }
+
+ private static final long FORM_OFFSET;
+ static {
+ try {
+ FORM_OFFSET = UNSAFE.objectFieldOffset(MethodHandle.class.getDeclaredField("form"));
+ } catch (ReflectiveOperationException ex) {
+ throw newInternalError(ex);
+ }
+ }
+ */
+ // END Android-removed: RI implementation unused on Android.
+}
diff --git a/java/lang/invoke/MethodHandleImpl.java b/java/lang/invoke/MethodHandleImpl.java
new file mode 100644
index 0000000..6514cb6
--- /dev/null
+++ b/java/lang/invoke/MethodHandleImpl.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * 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. The Android Open Source
+ * Project designates this particular file as subject to the "Classpath"
+ * exception as provided by The Android Open Source Project 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.
+ */
+
+package java.lang.invoke;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+// Android-changed: Android specific implementation.
+// The whole class was implemented from scratch for the Android runtime based
+// on the specification of the MethodHandle class.
+// The code does not originate from upstream OpenJDK.
+/**
+ * A method handle that's directly associated with an ArtField or an ArtMethod and
+ * specifies no additional transformations.
+ *
+ * @hide
+ */
+public class MethodHandleImpl extends MethodHandle implements Cloneable {
+ private HandleInfo info;
+
+ MethodHandleImpl(long artFieldOrMethod, int handleKind, MethodType type) {
+ super(artFieldOrMethod, handleKind, type);
+ }
+
+ @Override
+ public Object clone() throws CloneNotSupportedException {
+ return super.clone();
+ }
+
+ MethodHandleInfo reveal() {
+ if (info == null) {
+ final Member member = getMemberInternal();
+ info = new HandleInfo(member, this);
+ }
+
+ return info;
+ }
+
+ /**
+ * Materialize a member from this method handle's ArtField or ArtMethod pointer.
+ */
+ public native Member getMemberInternal();
+
+ /**
+ * Implementation of {@code MethodHandleInfo} in terms of the handle being cracked
+ * and its corresponding {@code java.lang.reflect.Member}.
+ */
+ static class HandleInfo implements MethodHandleInfo {
+ private final Member member;
+ private final MethodHandle handle;
+
+ HandleInfo(Member member, MethodHandle handle) {
+ this.member = member;
+ this.handle = handle;
+ }
+
+ @Override
+ public int getReferenceKind() {
+ switch (handle.getHandleKind()) {
+ case INVOKE_VIRTUAL: {
+ if (member.getDeclaringClass().isInterface()) {
+ return REF_invokeInterface;
+ } else {
+ return REF_invokeVirtual;
+ }
+ }
+
+ case INVOKE_DIRECT: {
+ if (member instanceof Constructor) {
+ return REF_newInvokeSpecial;
+ } else {
+ return REF_invokeSpecial;
+ }
+ }
+
+ case INVOKE_SUPER:
+ return MethodHandleInfo.REF_invokeSpecial;
+ case INVOKE_STATIC:
+ return MethodHandleInfo.REF_invokeStatic;
+ case IGET:
+ return MethodHandleInfo.REF_getField;
+ case IPUT:
+ return MethodHandleInfo.REF_putField;
+ case SGET:
+ return MethodHandleInfo.REF_getStatic;
+ case SPUT:
+ return MethodHandleInfo.REF_putStatic;
+ default:
+ throw new AssertionError("Unexpected handle kind: " + handle.getHandleKind());
+ }
+ }
+
+ @Override
+ public Class<?> getDeclaringClass() {
+ return member.getDeclaringClass();
+ }
+
+ @Override
+ public String getName() {
+ if (member instanceof Constructor) {
+ return "<init>";
+ }
+
+ return member.getName();
+ }
+
+ @Override
+ public MethodType getMethodType() {
+ // The "nominal" type of a cracked method handle is the same as the type
+ // of the handle itself, except in the cases enumerated below.
+ MethodType handleType = handle.type();
+
+ boolean omitLeadingParam = false;
+
+ // For constructs, the return type is always void.class, and not the type of
+ // the object returned. We also need to omit the leading reference, which is
+ // nominally the type of the object being constructed.
+ if (member instanceof Constructor) {
+ handleType = handleType.changeReturnType(void.class);
+ omitLeadingParam = true;
+ }
+
+ // For instance field gets/puts and instance method gets/puts, we omit the
+ // leading reference parameter to |this|.
+ switch (handle.getHandleKind()) {
+ case IGET:
+ case IPUT:
+ case INVOKE_INTERFACE:
+ case INVOKE_DIRECT:
+ case INVOKE_VIRTUAL:
+ case INVOKE_SUPER:
+ omitLeadingParam = true;
+ }
+
+ return omitLeadingParam ? handleType.dropParameterTypes(0, 1) : handleType;
+ }
+
+ @Override
+ public <T extends Member> T reflectAs(Class<T> expected, MethodHandles.Lookup lookup) {
+ try {
+ lookup.checkAccess(member.getDeclaringClass(), member.getDeclaringClass(),
+ member.getModifiers(), member.getName());
+ } catch (IllegalAccessException exception) {
+ throw new IllegalArgumentException("Unable to access member.", exception);
+ }
+
+ return (T) member;
+ }
+
+ @Override
+ public int getModifiers() {
+ return member.getModifiers();
+ }
+ }
+}
diff --git a/java/lang/invoke/MethodHandleInfo.java b/java/lang/invoke/MethodHandleInfo.java
new file mode 100644
index 0000000..356768d
--- /dev/null
+++ b/java/lang/invoke/MethodHandleInfo.java
@@ -0,0 +1,321 @@
+/*
+ * Copyright (c) 2012, 2013, 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.lang.reflect.*;
+import java.util.*;
+import java.lang.invoke.MethodHandleNatives.Constants;
+import java.lang.invoke.MethodHandles.Lookup;
+import static java.lang.invoke.MethodHandleStatics.*;
+
+/**
+ * A symbolic reference obtained by cracking a direct method handle
+ * into its consitutent symbolic parts.
+ * To crack a direct method handle, call {@link Lookup#revealDirect Lookup.revealDirect}.
+ * <h1><a name="directmh"></a>Direct Method Handles</h1>
+ * A <em>direct method handle</em> represents a method, constructor, or field without
+ * any intervening argument bindings or other transformations.
+ * The method, constructor, or field referred to by a direct method handle is called
+ * its <em>underlying member</em>.
+ * Direct method handles may be obtained in any of these ways:
+ * <ul>
+ * <li>By executing an {@code ldc} instruction on a {@code CONSTANT_MethodHandle} constant.
+ * (See the Java Virtual Machine Specification, sections 4.4.8 and 5.4.3.)
+ * <li>By calling one of the <a href="MethodHandles.Lookup.html#lookups">Lookup Factory Methods</a>,
+ * such as {@link Lookup#findVirtual Lookup.findVirtual},
+ * to resolve a symbolic reference into a method handle.
+ * A symbolic reference consists of a class, name string, and type.
+ * <li>By calling the factory method {@link Lookup#unreflect Lookup.unreflect}
+ * or {@link Lookup#unreflectSpecial Lookup.unreflectSpecial}
+ * to convert a {@link Method} into a method handle.
+ * <li>By calling the factory method {@link Lookup#unreflectConstructor Lookup.unreflectConstructor}
+ * to convert a {@link Constructor} into a method handle.
+ * <li>By calling the factory method {@link Lookup#unreflectGetter Lookup.unreflectGetter}
+ * or {@link Lookup#unreflectSetter Lookup.unreflectSetter}
+ * to convert a {@link Field} into a method handle.
+ * </ul>
+ *
+ * <h1>Restrictions on Cracking</h1>
+ * Given a suitable {@code Lookup} object, it is possible to crack any direct method handle
+ * to recover a symbolic reference for the underlying method, constructor, or field.
+ * Cracking must be done via a {@code Lookup} object equivalent to that which created
+ * the target method handle, or which has enough access permissions to recreate
+ * an equivalent method handle.
+ * <p>
+ * If the underlying method is <a href="MethodHandles.Lookup.html#callsens">caller sensitive</a>,
+ * the direct method handle will have been "bound" to a particular caller class, the
+ * {@linkplain java.lang.invoke.MethodHandles.Lookup#lookupClass() lookup class}
+ * of the lookup object used to create it.
+ * Cracking this method handle with a different lookup class will fail
+ * even if the underlying method is public (like {@code Class.forName}).
+ * <p>
+ * The requirement of lookup object matching provides a "fast fail" behavior
+ * for programs which may otherwise trust erroneous revelation of a method
+ * handle with symbolic information (or caller binding) from an unexpected scope.
+ * Use {@link java.lang.invoke.MethodHandles#reflectAs} to override this limitation.
+ *
+ * <h1><a name="refkinds"></a>Reference kinds</h1>
+ * The <a href="MethodHandles.Lookup.html#lookups">Lookup Factory Methods</a>
+ * correspond to all major use cases for methods, constructors, and fields.
+ * These use cases may be distinguished using small integers as follows:
+ * <table border=1 cellpadding=5 summary="reference kinds">
+ * <tr><th>reference kind</th><th>descriptive name</th><th>scope</th><th>member</th><th>behavior</th></tr>
+ * <tr>
+ * <td>{@code 1}</td><td>{@code REF_getField}</td><td>{@code class}</td>
+ * <td>{@code FT f;}</td><td>{@code (T) this.f;}</td>
+ * </tr>
+ * <tr>
+ * <td>{@code 2}</td><td>{@code REF_getStatic}</td><td>{@code class} or {@code interface}</td>
+ * <td>{@code static}<br>{@code FT f;}</td><td>{@code (T) C.f;}</td>
+ * </tr>
+ * <tr>
+ * <td>{@code 3}</td><td>{@code REF_putField}</td><td>{@code class}</td>
+ * <td>{@code FT f;}</td><td>{@code this.f = x;}</td>
+ * </tr>
+ * <tr>
+ * <td>{@code 4}</td><td>{@code REF_putStatic}</td><td>{@code class}</td>
+ * <td>{@code static}<br>{@code FT f;}</td><td>{@code C.f = arg;}</td>
+ * </tr>
+ * <tr>
+ * <td>{@code 5}</td><td>{@code REF_invokeVirtual}</td><td>{@code class}</td>
+ * <td>{@code T m(A*);}</td><td>{@code (T) this.m(arg*);}</td>
+ * </tr>
+ * <tr>
+ * <td>{@code 6}</td><td>{@code REF_invokeStatic}</td><td>{@code class} or {@code interface}</td>
+ * <td>{@code static}<br>{@code T m(A*);}</td><td>{@code (T) C.m(arg*);}</td>
+ * </tr>
+ * <tr>
+ * <td>{@code 7}</td><td>{@code REF_invokeSpecial}</td><td>{@code class} or {@code interface}</td>
+ * <td>{@code T m(A*);}</td><td>{@code (T) super.m(arg*);}</td>
+ * </tr>
+ * <tr>
+ * <td>{@code 8}</td><td>{@code REF_newInvokeSpecial}</td><td>{@code class}</td>
+ * <td>{@code C(A*);}</td><td>{@code new C(arg*);}</td>
+ * </tr>
+ * <tr>
+ * <td>{@code 9}</td><td>{@code REF_invokeInterface}</td><td>{@code interface}</td>
+ * <td>{@code T m(A*);}</td><td>{@code (T) this.m(arg*);}</td>
+ * </tr>
+ * </table>
+ * @since 1.8
+ */
+public
+interface MethodHandleInfo {
+ /**
+ * A direct method handle reference kind,
+ * as defined in the <a href="MethodHandleInfo.html#refkinds">table above</a>.
+ */
+ public static final int
+ REF_getField = Constants.REF_getField,
+ REF_getStatic = Constants.REF_getStatic,
+ REF_putField = Constants.REF_putField,
+ REF_putStatic = Constants.REF_putStatic,
+ REF_invokeVirtual = Constants.REF_invokeVirtual,
+ REF_invokeStatic = Constants.REF_invokeStatic,
+ REF_invokeSpecial = Constants.REF_invokeSpecial,
+ REF_newInvokeSpecial = Constants.REF_newInvokeSpecial,
+ REF_invokeInterface = Constants.REF_invokeInterface;
+
+ /**
+ * Returns the reference kind of the cracked method handle, which in turn
+ * determines whether the method handle's underlying member was a constructor, method, or field.
+ * See the <a href="MethodHandleInfo.html#refkinds">table above</a> for definitions.
+ * @return the integer code for the kind of reference used to access the underlying member
+ */
+ public int getReferenceKind();
+
+ /**
+ * Returns the class in which the cracked method handle's underlying member was defined.
+ * @return the declaring class of the underlying member
+ */
+ public Class<?> getDeclaringClass();
+
+ /**
+ * Returns the name of the cracked method handle's underlying member.
+ * This is {@code "<init>"} if the underlying member was a constructor,
+ * else it is a simple method name or field name.
+ * @return the simple name of the underlying member
+ */
+ public String getName();
+
+ /**
+ * Returns the nominal type of the cracked symbolic reference, expressed as a method type.
+ * If the reference is to a constructor, the return type will be {@code void}.
+ * If it is to a non-static method, the method type will not mention the {@code this} parameter.
+ * If it is to a field and the requested access is to read the field,
+ * the method type will have no parameters and return the field type.
+ * If it is to a field and the requested access is to write the field,
+ * the method type will have one parameter of the field type and return {@code void}.
+ * <p>
+ * Note that original direct method handle may include a leading {@code this} parameter,
+ * or (in the case of a constructor) will replace the {@code void} return type
+ * with the constructed class.
+ * The nominal type does not include any {@code this} parameter,
+ * and (in the case of a constructor) will return {@code void}.
+ * @return the type of the underlying member, expressed as a method type
+ */
+ public MethodType getMethodType();
+
+ // Utility methods.
+ // NOTE: class/name/type and reference kind constitute a symbolic reference
+ // member and modifiers are an add-on, derived from Core Reflection (or the equivalent)
+
+ /**
+ * Reflects the underlying member as a method, constructor, or field object.
+ * If the underlying member is public, it is reflected as if by
+ * {@code getMethod}, {@code getConstructor}, or {@code getField}.
+ * Otherwise, it is reflected as if by
+ * {@code getDeclaredMethod}, {@code getDeclaredConstructor}, or {@code getDeclaredField}.
+ * The underlying member must be accessible to the given lookup object.
+ * @param <T> the desired type of the result, either {@link Member} or a subtype
+ * @param expected a class object representing the desired result type {@code T}
+ * @param lookup the lookup object that created this MethodHandleInfo, or one with equivalent access privileges
+ * @return a reference to the method, constructor, or field object
+ * @exception ClassCastException if the member is not of the expected type
+ * @exception NullPointerException if either argument is {@code null}
+ * @exception IllegalArgumentException if the underlying member is not accessible to the given lookup object
+ */
+ public <T extends Member> T reflectAs(Class<T> expected, Lookup lookup);
+
+ /**
+ * Returns the access modifiers of the underlying member.
+ * @return the Java language modifiers for underlying member,
+ * or -1 if the member cannot be accessed
+ * @see Modifier
+ * @see #reflectAs
+ */
+ public int getModifiers();
+
+ /**
+ * Determines if the underlying member was a variable arity method or constructor.
+ * Such members are represented by method handles that are varargs collectors.
+ * @implSpec
+ * This produces a result equivalent to:
+ * <pre>{@code
+ * getReferenceKind() >= REF_invokeVirtual && Modifier.isTransient(getModifiers())
+ * }</pre>
+ *
+ *
+ * @return {@code true} if and only if the underlying member was declared with variable arity.
+ */
+ // spelling derived from java.lang.reflect.Executable, not MethodHandle.isVarargsCollector
+ public default boolean isVarArgs() {
+ // fields are never varargs:
+ if (MethodHandleNatives.refKindIsField((byte) getReferenceKind()))
+ return false;
+ // not in the public API: Modifier.VARARGS
+ final int ACC_VARARGS = 0x00000080; // from JVMS 4.6 (Table 4.20)
+ assert(ACC_VARARGS == Modifier.TRANSIENT);
+ return Modifier.isTransient(getModifiers());
+ }
+
+ /**
+ * Returns the descriptive name of the given reference kind,
+ * as defined in the <a href="MethodHandleInfo.html#refkinds">table above</a>.
+ * The conventional prefix "REF_" is omitted.
+ * @param referenceKind an integer code for a kind of reference used to access a class member
+ * @return a mixed-case string such as {@code "getField"}
+ * @exception IllegalArgumentException if the argument is not a valid
+ * <a href="MethodHandleInfo.html#refkinds">reference kind number</a>
+ */
+ public static String referenceKindToString(int referenceKind) {
+ if (!MethodHandleNatives.refKindIsValid(referenceKind))
+ throw newIllegalArgumentException("invalid reference kind", referenceKind);
+ return MethodHandleNatives.refKindName((byte)referenceKind);
+ }
+
+ /**
+ * Returns a string representation for a {@code MethodHandleInfo},
+ * given the four parts of its symbolic reference.
+ * This is defined to be of the form {@code "RK C.N:MT"}, where {@code RK} is the
+ * {@linkplain #referenceKindToString reference kind string} for {@code kind},
+ * {@code C} is the {@linkplain java.lang.Class#getName name} of {@code defc}
+ * {@code N} is the {@code name}, and
+ * {@code MT} is the {@code type}.
+ * These four values may be obtained from the
+ * {@linkplain #getReferenceKind reference kind},
+ * {@linkplain #getDeclaringClass declaring class},
+ * {@linkplain #getName member name},
+ * and {@linkplain #getMethodType method type}
+ * of a {@code MethodHandleInfo} object.
+ *
+ * @implSpec
+ * This produces a result equivalent to:
+ * <pre>{@code
+ * String.format("%s %s.%s:%s", referenceKindToString(kind), defc.getName(), name, type)
+ * }</pre>
+ *
+ * @param kind the {@linkplain #getReferenceKind reference kind} part of the symbolic reference
+ * @param defc the {@linkplain #getDeclaringClass declaring class} part of the symbolic reference
+ * @param name the {@linkplain #getName member name} part of the symbolic reference
+ * @param type the {@linkplain #getMethodType method type} part of the symbolic reference
+ * @return a string of the form {@code "RK C.N:MT"}
+ * @exception IllegalArgumentException if the first argument is not a valid
+ * <a href="MethodHandleInfo.html#refkinds">reference kind number</a>
+ * @exception NullPointerException if any reference argument is {@code null}
+ */
+ public static String toString(int kind, Class<?> defc, String name, MethodType type) {
+ Objects.requireNonNull(name); Objects.requireNonNull(type);
+ return String.format("%s %s.%s:%s", referenceKindToString(kind), defc.getName(), name, type);
+ }
+
+ // BEGIN Android-added: refKind...() methods needed for API compatibility with 26.
+ // These methods were accidentally added into the public API in API level. They are now
+ // deprecated as a prelude to being removed from the public API.
+ /**
+ * @deprecated This internal method was accidentally added to API 26 and must not be used. No
+ * replacement is available but it is possible to replicate using information from
+ * the <a href="MethodHandleInfo.html#refkinds">table above</a>, e.g.
+ * {@code refKind >= 1 && refKind <= 9}. There are no guarantees that this logic
+ * will work if future versions extend the table.
+ */
+ @Deprecated
+ static boolean refKindIsValid(int refKind) {
+ return MethodHandleNatives.refKindIsValid(refKind);
+ }
+
+ /**
+ * @deprecated This internal method was accidentally added to API 26 and must not be used. No
+ * replacement is available but it is possible to replicate using information from
+ * the <a href="MethodHandleInfo.html#refkinds">table above</a>, e.g.
+ * {@code refKind >= 1 && refKind <= 4}. There are no guarantees that this logic
+ * will work if future versions extend the table.
+ */
+ @Deprecated
+ static boolean refKindIsField(int refKind) {
+ return MethodHandleNatives.refKindIsField((byte) refKind);
+ }
+
+ /**
+ * @deprecated This internal method was accidentally added to API 26 and must not be used. Use
+ * {@link MethodHandleInfo#referenceKindToString(int)} instead.
+ */
+ @Deprecated
+ static String refKindName(int refKind) {
+ return MethodHandleNatives.refKindName((byte) refKind);
+ }
+ // END Android-added: refKind...() methods needed for API compatibility with 26.
+}
diff --git a/java/lang/invoke/MethodHandleNatives.java b/java/lang/invoke/MethodHandleNatives.java
new file mode 100644
index 0000000..87f95ff
--- /dev/null
+++ b/java/lang/invoke/MethodHandleNatives.java
@@ -0,0 +1,551 @@
+/*
+ * Copyright (c) 2008, 2013, 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 static java.lang.invoke.MethodHandleNatives.Constants.*;
+
+/**
+ * The JVM interface for the method handles package is all here.
+ * This is an interface internal and private to an implementation of JSR 292.
+ * <em>This class is not part of the JSR 292 standard.</em>
+ * @author jrose
+ */
+class MethodHandleNatives {
+
+ // BEGIN Android-removed: Unused implementation code.
+ /*
+ private MethodHandleNatives() { } // static only
+
+ /// MemberName support
+
+ static native void init(MemberName self, Object ref);
+ static native void expand(MemberName self);
+ static native MemberName resolve(MemberName self, Class<?> caller) throws LinkageError, ClassNotFoundException;
+ static native int getMembers(Class<?> defc, String matchName, String matchSig,
+ int matchFlags, Class<?> caller, int skip, MemberName[] results);
+
+ /// Field layout queries parallel to sun.misc.Unsafe:
+ static native long objectFieldOffset(MemberName self); // e.g., returns vmindex
+ static native long staticFieldOffset(MemberName self); // e.g., returns vmindex
+ static native Object staticFieldBase(MemberName self); // e.g., returns clazz
+ static native Object getMemberVMInfo(MemberName self); // returns {vmindex,vmtarget}
+
+ /// MethodHandle support
+
+ /** Fetch MH-related JVM parameter.
+ * which=0 retrieves MethodHandlePushLimit
+ * which=1 retrieves stack slot push size (in address units)
+ *
+ static native int getConstant(int which);
+
+ static final boolean COUNT_GWT;
+
+ /// CallSite support
+
+ /** Tell the JVM that we need to change the target of a CallSite. *
+ static native void setCallSiteTargetNormal(CallSite site, MethodHandle target);
+ static native void setCallSiteTargetVolatile(CallSite site, MethodHandle target);
+
+ private static native void registerNatives();
+ static {
+ registerNatives();
+ COUNT_GWT = getConstant(Constants.GC_COUNT_GWT) != 0;
+
+ // The JVM calls MethodHandleNatives.<clinit>. Cascade the <clinit> calls as needed:
+ MethodHandleImpl.initStatics();
+ }
+ */
+ // END Android-removed: Unused implementation code.
+
+ // All compile-time constants go here.
+ // There is an opportunity to check them against the JVM's idea of them.
+ static class Constants {
+ Constants() { } // static only
+ // BEGIN Android-removed: Unused implementation code.
+ /*
+ // MethodHandleImpl
+ static final int // for getConstant
+ GC_COUNT_GWT = 4,
+ GC_LAMBDA_SUPPORT = 5;
+
+ // MemberName
+ // The JVM uses values of -2 and above for vtable indexes.
+ // Field values are simple positive offsets.
+ // Ref: src/share/vm/oops/methodOop.hpp
+ // This value is negative enough to avoid such numbers,
+ // but not too negative.
+ static final int
+ MN_IS_METHOD = 0x00010000, // method (not constructor)
+ MN_IS_CONSTRUCTOR = 0x00020000, // constructor
+ MN_IS_FIELD = 0x00040000, // field
+ MN_IS_TYPE = 0x00080000, // nested type
+ MN_CALLER_SENSITIVE = 0x00100000, // @CallerSensitive annotation detected
+ MN_REFERENCE_KIND_SHIFT = 24, // refKind
+ MN_REFERENCE_KIND_MASK = 0x0F000000 >> MN_REFERENCE_KIND_SHIFT,
+ // The SEARCH_* bits are not for MN.flags but for the matchFlags argument of MHN.getMembers:
+ MN_SEARCH_SUPERCLASSES = 0x00100000,
+ MN_SEARCH_INTERFACES = 0x00200000;
+
+ /**
+ * Basic types as encoded in the JVM. These code values are not
+ * intended for use outside this class. They are used as part of
+ * a private interface between the JVM and this class.
+ *
+ static final int
+ T_BOOLEAN = 4,
+ T_CHAR = 5,
+ T_FLOAT = 6,
+ T_DOUBLE = 7,
+ T_BYTE = 8,
+ T_SHORT = 9,
+ T_INT = 10,
+ T_LONG = 11,
+ T_OBJECT = 12,
+ //T_ARRAY = 13
+ T_VOID = 14,
+ //T_ADDRESS = 15
+ T_ILLEGAL = 99;
+
+ /**
+ * Constant pool entry types.
+ *
+ static final byte
+ CONSTANT_Utf8 = 1,
+ CONSTANT_Integer = 3,
+ CONSTANT_Float = 4,
+ CONSTANT_Long = 5,
+ CONSTANT_Double = 6,
+ CONSTANT_Class = 7,
+ CONSTANT_String = 8,
+ CONSTANT_Fieldref = 9,
+ CONSTANT_Methodref = 10,
+ CONSTANT_InterfaceMethodref = 11,
+ CONSTANT_NameAndType = 12,
+ CONSTANT_MethodHandle = 15, // JSR 292
+ CONSTANT_MethodType = 16, // JSR 292
+ CONSTANT_InvokeDynamic = 18,
+ CONSTANT_LIMIT = 19; // Limit to tags found in classfiles
+
+ /**
+ * Access modifier flags.
+ *
+ static final char
+ ACC_PUBLIC = 0x0001,
+ ACC_PRIVATE = 0x0002,
+ ACC_PROTECTED = 0x0004,
+ ACC_STATIC = 0x0008,
+ ACC_FINAL = 0x0010,
+ ACC_SYNCHRONIZED = 0x0020,
+ ACC_VOLATILE = 0x0040,
+ ACC_TRANSIENT = 0x0080,
+ ACC_NATIVE = 0x0100,
+ ACC_INTERFACE = 0x0200,
+ ACC_ABSTRACT = 0x0400,
+ ACC_STRICT = 0x0800,
+ ACC_SYNTHETIC = 0x1000,
+ ACC_ANNOTATION = 0x2000,
+ ACC_ENUM = 0x4000,
+ // aliases:
+ ACC_SUPER = ACC_SYNCHRONIZED,
+ ACC_BRIDGE = ACC_VOLATILE,
+ ACC_VARARGS = ACC_TRANSIENT;
+ */
+ // END Android-removed: Unused implementation code.
+
+ /**
+ * Constant pool reference-kind codes, as used by CONSTANT_MethodHandle CP entries.
+ */
+ static final byte
+ REF_NONE = 0, // null value
+ REF_getField = 1,
+ REF_getStatic = 2,
+ REF_putField = 3,
+ REF_putStatic = 4,
+ REF_invokeVirtual = 5,
+ REF_invokeStatic = 6,
+ REF_invokeSpecial = 7,
+ REF_newInvokeSpecial = 8,
+ REF_invokeInterface = 9,
+ REF_LIMIT = 10;
+ }
+
+ static boolean refKindIsValid(int refKind) {
+ return (refKind > REF_NONE && refKind < REF_LIMIT);
+ }
+ static boolean refKindIsField(byte refKind) {
+ assert(refKindIsValid(refKind));
+ return (refKind <= REF_putStatic);
+ }
+ // BEGIN Android-removed: Unused implementation code.
+ /*
+ static boolean refKindIsGetter(byte refKind) {
+ assert(refKindIsValid(refKind));
+ return (refKind <= REF_getStatic);
+ }
+ static boolean refKindIsSetter(byte refKind) {
+ return refKindIsField(refKind) && !refKindIsGetter(refKind);
+ }
+ static boolean refKindIsMethod(byte refKind) {
+ return !refKindIsField(refKind) && (refKind != REF_newInvokeSpecial);
+ }
+ static boolean refKindIsConstructor(byte refKind) {
+ return (refKind == REF_newInvokeSpecial);
+ }
+ static boolean refKindHasReceiver(byte refKind) {
+ assert(refKindIsValid(refKind));
+ return (refKind & 1) != 0;
+ }
+ static boolean refKindIsStatic(byte refKind) {
+ return !refKindHasReceiver(refKind) && (refKind != REF_newInvokeSpecial);
+ }
+ static boolean refKindDoesDispatch(byte refKind) {
+ assert(refKindIsValid(refKind));
+ return (refKind == REF_invokeVirtual ||
+ refKind == REF_invokeInterface);
+ }
+ static {
+ final int HR_MASK = ((1 << REF_getField) |
+ (1 << REF_putField) |
+ (1 << REF_invokeVirtual) |
+ (1 << REF_invokeSpecial) |
+ (1 << REF_invokeInterface)
+ );
+ for (byte refKind = REF_NONE+1; refKind < REF_LIMIT; refKind++) {
+ assert(refKindHasReceiver(refKind) == (((1<<refKind) & HR_MASK) != 0)) : refKind;
+ }
+ }
+ */
+ // END Android-removed: Unused implementation code.
+ static String refKindName(byte refKind) {
+ assert(refKindIsValid(refKind));
+ switch (refKind) {
+ case REF_getField: return "getField";
+ case REF_getStatic: return "getStatic";
+ case REF_putField: return "putField";
+ case REF_putStatic: return "putStatic";
+ case REF_invokeVirtual: return "invokeVirtual";
+ case REF_invokeStatic: return "invokeStatic";
+ case REF_invokeSpecial: return "invokeSpecial";
+ case REF_newInvokeSpecial: return "newInvokeSpecial";
+ case REF_invokeInterface: return "invokeInterface";
+ default: return "REF_???";
+ }
+ }
+ // BEGIN Android-removed: Unused implementation code.
+ /*
+ private static native int getNamedCon(int which, Object[] name);
+ static boolean verifyConstants() {
+ Object[] box = { null };
+ for (int i = 0; ; i++) {
+ box[0] = null;
+ int vmval = getNamedCon(i, box);
+ if (box[0] == null) break;
+ String name = (String) box[0];
+ try {
+ Field con = Constants.class.getDeclaredField(name);
+ int jval = con.getInt(null);
+ if (jval == vmval) continue;
+ String err = (name+": JVM has "+vmval+" while Java has "+jval);
+ if (name.equals("CONV_OP_LIMIT")) {
+ System.err.println("warning: "+err);
+ continue;
+ }
+ throw new InternalError(err);
+ } catch (NoSuchFieldException | IllegalAccessException ex) {
+ String err = (name+": JVM has "+vmval+" which Java does not define");
+ // ignore exotic ops the JVM cares about; we just wont issue them
+ //System.err.println("warning: "+err);
+ continue;
+ }
+ }
+ return true;
+ }
+ static {
+ assert(verifyConstants());
+ }
+
+ // Up-calls from the JVM.
+ // These must NOT be public.
+
+ /**
+ * The JVM is linking an invokedynamic instruction. Create a reified call site for it.
+ *
+ static MemberName linkCallSite(Object callerObj,
+ Object bootstrapMethodObj,
+ Object nameObj, Object typeObj,
+ Object staticArguments,
+ Object[] appendixResult) {
+ MethodHandle bootstrapMethod = (MethodHandle)bootstrapMethodObj;
+ Class<?> caller = (Class<?>)callerObj;
+ String name = nameObj.toString().intern();
+ MethodType type = (MethodType)typeObj;
+ if (!TRACE_METHOD_LINKAGE)
+ return linkCallSiteImpl(caller, bootstrapMethod, name, type,
+ staticArguments, appendixResult);
+ return linkCallSiteTracing(caller, bootstrapMethod, name, type,
+ staticArguments, appendixResult);
+ }
+ static MemberName linkCallSiteImpl(Class<?> caller,
+ MethodHandle bootstrapMethod,
+ String name, MethodType type,
+ Object staticArguments,
+ Object[] appendixResult) {
+ CallSite callSite = CallSite.makeSite(bootstrapMethod,
+ name,
+ type,
+ staticArguments,
+ caller);
+ if (callSite instanceof ConstantCallSite) {
+ appendixResult[0] = callSite.dynamicInvoker();
+ return Invokers.linkToTargetMethod(type);
+ } else {
+ appendixResult[0] = callSite;
+ return Invokers.linkToCallSiteMethod(type);
+ }
+ }
+ // Tracing logic:
+ static MemberName linkCallSiteTracing(Class<?> caller,
+ MethodHandle bootstrapMethod,
+ String name, MethodType type,
+ Object staticArguments,
+ Object[] appendixResult) {
+ Object bsmReference = bootstrapMethod.internalMemberName();
+ if (bsmReference == null) bsmReference = bootstrapMethod;
+ Object staticArglist = (staticArguments instanceof Object[] ?
+ java.util.Arrays.asList((Object[]) staticArguments) :
+ staticArguments);
+ System.out.println("linkCallSite "+caller.getName()+" "+
+ bsmReference+" "+
+ name+type+"/"+staticArglist);
+ try {
+ MemberName res = linkCallSiteImpl(caller, bootstrapMethod, name, type,
+ staticArguments, appendixResult);
+ System.out.println("linkCallSite => "+res+" + "+appendixResult[0]);
+ return res;
+ } catch (Throwable ex) {
+ System.out.println("linkCallSite => throw "+ex);
+ throw ex;
+ }
+ }
+
+ /**
+ * The JVM wants a pointer to a MethodType. Oblige it by finding or creating one.
+ *
+ static MethodType findMethodHandleType(Class<?> rtype, Class<?>[] ptypes) {
+ return MethodType.makeImpl(rtype, ptypes, true);
+ }
+
+ /**
+ * The JVM wants to link a call site that requires a dynamic type check.
+ * Name is a type-checking invoker, invokeExact or invoke.
+ * Return a JVM method (MemberName) to handle the invoking.
+ * The method assumes the following arguments on the stack:
+ * 0: the method handle being invoked
+ * 1-N: the arguments to the method handle invocation
+ * N+1: an optional, implicitly added argument (typically the given MethodType)
+ * <p>
+ * The nominal method at such a call site is an instance of
+ * a signature-polymorphic method (see @PolymorphicSignature).
+ * Such method instances are user-visible entities which are
+ * "split" from the generic placeholder method in {@code MethodHandle}.
+ * (Note that the placeholder method is not identical with any of
+ * its instances. If invoked reflectively, is guaranteed to throw an
+ * {@code UnsupportedOperationException}.)
+ * If the signature-polymorphic method instance is ever reified,
+ * it appears as a "copy" of the original placeholder
+ * (a native final member of {@code MethodHandle}) except
+ * that its type descriptor has shape required by the instance,
+ * and the method instance is <em>not</em> varargs.
+ * The method instance is also marked synthetic, since the
+ * method (by definition) does not appear in Java source code.
+ * <p>
+ * The JVM is allowed to reify this method as instance metadata.
+ * For example, {@code invokeBasic} is always reified.
+ * But the JVM may instead call {@code linkMethod}.
+ * If the result is an * ordered pair of a {@code (method, appendix)},
+ * the method gets all the arguments (0..N inclusive)
+ * plus the appendix (N+1), and uses the appendix to complete the call.
+ * In this way, one reusable method (called a "linker method")
+ * can perform the function of any number of polymorphic instance
+ * methods.
+ * <p>
+ * Linker methods are allowed to be weakly typed, with any or
+ * all references rewritten to {@code Object} and any primitives
+ * (except {@code long}/{@code float}/{@code double})
+ * rewritten to {@code int}.
+ * A linker method is trusted to return a strongly typed result,
+ * according to the specific method type descriptor of the
+ * signature-polymorphic instance it is emulating.
+ * This can involve (as necessary) a dynamic check using
+ * data extracted from the appendix argument.
+ * <p>
+ * The JVM does not inspect the appendix, other than to pass
+ * it verbatim to the linker method at every call.
+ * This means that the JDK runtime has wide latitude
+ * for choosing the shape of each linker method and its
+ * corresponding appendix.
+ * Linker methods should be generated from {@code LambdaForm}s
+ * so that they do not become visible on stack traces.
+ * <p>
+ * The {@code linkMethod} call is free to omit the appendix
+ * (returning null) and instead emulate the required function
+ * completely in the linker method.
+ * As a corner case, if N==255, no appendix is possible.
+ * In this case, the method returned must be custom-generated to
+ * to perform any needed type checking.
+ * <p>
+ * If the JVM does not reify a method at a call site, but instead
+ * calls {@code linkMethod}, the corresponding call represented
+ * in the bytecodes may mention a valid method which is not
+ * representable with a {@code MemberName}.
+ * Therefore, use cases for {@code linkMethod} tend to correspond to
+ * special cases in reflective code such as {@code findVirtual}
+ * or {@code revealDirect}.
+ *
+ static MemberName linkMethod(Class<?> callerClass, int refKind,
+ Class<?> defc, String name, Object type,
+ Object[] appendixResult) {
+ if (!TRACE_METHOD_LINKAGE)
+ return linkMethodImpl(callerClass, refKind, defc, name, type, appendixResult);
+ return linkMethodTracing(callerClass, refKind, defc, name, type, appendixResult);
+ }
+ static MemberName linkMethodImpl(Class<?> callerClass, int refKind,
+ Class<?> defc, String name, Object type,
+ Object[] appendixResult) {
+ try {
+ if (defc == MethodHandle.class && refKind == REF_invokeVirtual) {
+ return Invokers.methodHandleInvokeLinkerMethod(name, fixMethodType(callerClass, type), appendixResult);
+ }
+ } catch (Throwable ex) {
+ if (ex instanceof LinkageError)
+ throw (LinkageError) ex;
+ else
+ throw new LinkageError(ex.getMessage(), ex);
+ }
+ throw new LinkageError("no such method "+defc.getName()+"."+name+type);
+ }
+ private static MethodType fixMethodType(Class<?> callerClass, Object type) {
+ if (type instanceof MethodType)
+ return (MethodType) type;
+ else
+ return MethodType.fromMethodDescriptorString((String)type, callerClass.getClassLoader());
+ }
+ // Tracing logic:
+ static MemberName linkMethodTracing(Class<?> callerClass, int refKind,
+ Class<?> defc, String name, Object type,
+ Object[] appendixResult) {
+ System.out.println("linkMethod "+defc.getName()+"."+
+ name+type+"/"+Integer.toHexString(refKind));
+ try {
+ MemberName res = linkMethodImpl(callerClass, refKind, defc, name, type, appendixResult);
+ System.out.println("linkMethod => "+res+" + "+appendixResult[0]);
+ return res;
+ } catch (Throwable ex) {
+ System.out.println("linkMethod => throw "+ex);
+ throw ex;
+ }
+ }
+
+
+ /**
+ * The JVM is resolving a CONSTANT_MethodHandle CP entry. And it wants our help.
+ * It will make an up-call to this method. (Do not change the name or signature.)
+ * The type argument is a Class for field requests and a MethodType for non-fields.
+ * <p>
+ * Recent versions of the JVM may also pass a resolved MemberName for the type.
+ * In that case, the name is ignored and may be null.
+ *
+ static MethodHandle linkMethodHandleConstant(Class<?> callerClass, int refKind,
+ Class<?> defc, String name, Object type) {
+ try {
+ Lookup lookup = IMPL_LOOKUP.in(callerClass);
+ assert(refKindIsValid(refKind));
+ return lookup.linkMethodHandleConstant((byte) refKind, defc, name, type);
+ } catch (IllegalAccessException ex) {
+ Throwable cause = ex.getCause();
+ if (cause instanceof AbstractMethodError) {
+ throw (AbstractMethodError) cause;
+ } else {
+ Error err = new IllegalAccessError(ex.getMessage());
+ throw initCauseFrom(err, ex);
+ }
+ } catch (NoSuchMethodException ex) {
+ Error err = new NoSuchMethodError(ex.getMessage());
+ throw initCauseFrom(err, ex);
+ } catch (NoSuchFieldException ex) {
+ Error err = new NoSuchFieldError(ex.getMessage());
+ throw initCauseFrom(err, ex);
+ } catch (ReflectiveOperationException ex) {
+ Error err = new IncompatibleClassChangeError();
+ throw initCauseFrom(err, ex);
+ }
+ }
+
+ /**
+ * Use best possible cause for err.initCause(), substituting the
+ * cause for err itself if the cause has the same (or better) type.
+ *
+ static private Error initCauseFrom(Error err, Exception ex) {
+ Throwable th = ex.getCause();
+ if (err.getClass().isInstance(th))
+ return (Error) th;
+ err.initCause(th == null ? ex : th);
+ return err;
+ }
+
+ /**
+ * Is this method a caller-sensitive method?
+ * I.e., does it call Reflection.getCallerClass or a similer method
+ * to ask about the identity of its caller?
+ *
+ static boolean isCallerSensitive(MemberName mem) {
+ if (!mem.isInvocable()) return false; // fields are not caller sensitive
+
+ return mem.isCallerSensitive() || canBeCalledVirtual(mem);
+ }
+
+ static boolean canBeCalledVirtual(MemberName mem) {
+ assert(mem.isInvocable());
+ Class<?> defc = mem.getDeclaringClass();
+ switch (mem.getName()) {
+ case "checkMemberAccess":
+ return canBeCalledVirtual(mem, java.lang.SecurityManager.class);
+ case "getContextClassLoader":
+ return canBeCalledVirtual(mem, java.lang.Thread.class);
+ }
+ return false;
+ }
+
+ static boolean canBeCalledVirtual(MemberName symbolicRef, Class<?> definingClass) {
+ Class<?> symbolicRefClass = symbolicRef.getDeclaringClass();
+ if (symbolicRefClass == definingClass) return true;
+ if (symbolicRef.isStatic() || symbolicRef.isPrivate()) return false;
+ return (definingClass.isAssignableFrom(symbolicRefClass) || // Msym overrides Mdef
+ symbolicRefClass.isInterface()); // Mdef implements Msym
+ }
+ */
+ // END Android-removed: Unused implementation code.
+}
diff --git a/java/lang/invoke/MethodHandleStatics.java b/java/lang/invoke/MethodHandleStatics.java
new file mode 100644
index 0000000..90265cc
--- /dev/null
+++ b/java/lang/invoke/MethodHandleStatics.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2011, 2012, 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 sun.misc.Unsafe;
+
+/**
+ * This class consists exclusively of static names internal to the
+ * method handle implementation.
+ * Usage: {@code import static java.lang.invoke.MethodHandleStatics.*}
+ * @author John Rose, JSR 292 EG
+ */
+/*non-public*/ class MethodHandleStatics {
+
+ private MethodHandleStatics() { } // do not instantiate
+
+ static final Unsafe UNSAFE = Unsafe.getUnsafe();
+
+ // Android-changed: Remove debugging related static fields.
+ // They are unused and have no equivalent on Android.
+ /*
+ static final boolean DEBUG_METHOD_HANDLE_NAMES;
+ static final boolean DUMP_CLASS_FILES;
+ static final boolean TRACE_INTERPRETER;
+ static final boolean TRACE_METHOD_LINKAGE;
+ static final int COMPILE_THRESHOLD;
+ static final int DONT_INLINE_THRESHOLD;
+ static final int PROFILE_LEVEL;
+ static final boolean PROFILE_GWT;
+ static final int CUSTOMIZE_THRESHOLD;
+
+ static {
+ final Object[] values = new Object[9];
+ AccessController.doPrivileged(new PrivilegedAction<Void>() {
+ public Void run() {
+ values[0] = Boolean.getBoolean("java.lang.invoke.MethodHandle.DEBUG_NAMES");
+ values[1] = Boolean.getBoolean("java.lang.invoke.MethodHandle.DUMP_CLASS_FILES");
+ values[2] = Boolean.getBoolean("java.lang.invoke.MethodHandle.TRACE_INTERPRETER");
+ values[3] = Boolean.getBoolean("java.lang.invoke.MethodHandle.TRACE_METHOD_LINKAGE");
+ values[4] = Integer.getInteger("java.lang.invoke.MethodHandle.COMPILE_THRESHOLD", 0);
+ values[5] = Integer.getInteger("java.lang.invoke.MethodHandle.DONT_INLINE_THRESHOLD", 30);
+ values[6] = Integer.getInteger("java.lang.invoke.MethodHandle.PROFILE_LEVEL", 0);
+ values[7] = Boolean.parseBoolean(System.getProperty("java.lang.invoke.MethodHandle.PROFILE_GWT", "true"));
+ values[8] = Integer.getInteger("java.lang.invoke.MethodHandle.CUSTOMIZE_THRESHOLD", 127);
+ return null;
+ }
+ });
+ DEBUG_METHOD_HANDLE_NAMES = (Boolean) values[0];
+ DUMP_CLASS_FILES = (Boolean) values[1];
+ TRACE_INTERPRETER = (Boolean) values[2];
+ TRACE_METHOD_LINKAGE = (Boolean) values[3];
+ COMPILE_THRESHOLD = (Integer) values[4];
+ DONT_INLINE_THRESHOLD = (Integer) values[5];
+ PROFILE_LEVEL = (Integer) values[6];
+ PROFILE_GWT = (Boolean) values[7];
+ CUSTOMIZE_THRESHOLD = (Integer) values[8];
+
+ if (CUSTOMIZE_THRESHOLD < -1 || CUSTOMIZE_THRESHOLD > 127) {
+ throw newInternalError("CUSTOMIZE_THRESHOLD should be in [-1...127] range");
+ }
+ }
+
+ /** Tell if any of the debugging switches are turned on.
+ * If this is the case, it is reasonable to perform extra checks or save extra information.
+ *
+ /*non-public* static boolean debugEnabled() {
+ return (DEBUG_METHOD_HANDLE_NAMES |
+ DUMP_CLASS_FILES |
+ TRACE_INTERPRETER |
+ TRACE_METHOD_LINKAGE);
+ }
+ */
+
+ // Android-removed: Methods operating on MethodHandles that are currently unused on Android.
+ /*
+ /*non-public* static String getNameString(MethodHandle target, MethodType type) {
+ if (type == null)
+ type = target.type();
+ MemberName name = null;
+ if (target != null)
+ name = target.internalMemberName();
+ if (name == null)
+ return "invoke" + type;
+ return name.getName() + type;
+ }
+
+ /*non-public* static String getNameString(MethodHandle target, MethodHandle typeHolder) {
+ return getNameString(target, typeHolder == null ? (MethodType) null : typeHolder.type());
+ }
+
+ /*non-public* static String getNameString(MethodHandle target) {
+ return getNameString(target, (MethodType) null);
+ }
+
+ /*non-public* static String addTypeString(Object obj, MethodHandle target) {
+ String str = String.valueOf(obj);
+ if (target == null) return str;
+ int paren = str.indexOf('(');
+ if (paren >= 0) str = str.substring(0, paren);
+ return str + target.type();
+ }
+ */
+
+ // handy shared exception makers (they simplify the common case code)
+ /*non-public*/ static InternalError newInternalError(String message) {
+ return new InternalError(message);
+ }
+ /*non-public*/ static InternalError newInternalError(String message, Throwable cause) {
+ return new InternalError(message, cause);
+ }
+ /*non-public*/ static InternalError newInternalError(Throwable cause) {
+ return new InternalError(cause);
+ }
+ /*non-public*/ static RuntimeException newIllegalStateException(String message) {
+ return new IllegalStateException(message);
+ }
+ /*non-public*/ static RuntimeException newIllegalStateException(String message, Object obj) {
+ return new IllegalStateException(message(message, obj));
+ }
+ /*non-public*/ static RuntimeException newIllegalArgumentException(String message) {
+ return new IllegalArgumentException(message);
+ }
+ /*non-public*/ static RuntimeException newIllegalArgumentException(String message, Object obj) {
+ return new IllegalArgumentException(message(message, obj));
+ }
+ /*non-public*/ static RuntimeException newIllegalArgumentException(String message, Object obj, Object obj2) {
+ return new IllegalArgumentException(message(message, obj, obj2));
+ }
+ /** Propagate unchecked exceptions and errors, but wrap anything checked and throw that instead. */
+ /*non-public*/ static Error uncaughtException(Throwable ex) {
+ if (ex instanceof Error) throw (Error) ex;
+ if (ex instanceof RuntimeException) throw (RuntimeException) ex;
+ throw newInternalError("uncaught exception", ex);
+ }
+ static Error NYI() {
+ throw new AssertionError("NYI");
+ }
+ private static String message(String message, Object obj) {
+ if (obj != null) message = message + ": " + obj;
+ return message;
+ }
+ private static String message(String message, Object obj, Object obj2) {
+ if (obj != null || obj2 != null) message = message + ": " + obj + ", " + obj2;
+ return message;
+ }
+}
diff --git a/java/lang/invoke/MethodHandles.java b/java/lang/invoke/MethodHandles.java
new file mode 100644
index 0000000..1188ac6
--- /dev/null
+++ b/java/lang/invoke/MethodHandles.java
@@ -0,0 +1,3521 @@
+/*
+ * Copyright (c) 2008, 2017, 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.lang.reflect.*;
+import java.nio.ByteOrder;
+import java.util.List;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.NoSuchElementException;
+
+import sun.invoke.util.VerifyAccess;
+import sun.invoke.util.Wrapper;
+import sun.reflect.Reflection;
+
+import static java.lang.invoke.MethodHandleStatics.*;
+
+/**
+ * This class consists exclusively of static methods that operate on or return
+ * method handles. They fall into several categories:
+ * <ul>
+ * <li>Lookup methods which help create method handles for methods and fields.
+ * <li>Combinator methods, which combine or transform pre-existing method handles into new ones.
+ * <li>Other factory methods to create method handles that emulate other common JVM operations or control flow patterns.
+ * </ul>
+ * <p>
+ * @author John Rose, JSR 292 EG
+ * @since 1.7
+ */
+public class MethodHandles {
+
+ private MethodHandles() { } // do not instantiate
+
+ // Android-changed: We do not use MemberName / MethodHandleImpl.
+ //
+ // private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory();
+ // static { MethodHandleImpl.initStatics(); }
+ // See IMPL_LOOKUP below.
+
+ //// Method handle creation from ordinary methods.
+
+ /**
+ * Returns a {@link Lookup lookup object} with
+ * full capabilities to emulate all supported bytecode behaviors of the caller.
+ * These capabilities include <a href="MethodHandles.Lookup.html#privacc">private access</a> to the caller.
+ * Factory methods on the lookup object can create
+ * <a href="MethodHandleInfo.html#directmh">direct method handles</a>
+ * for any member that the caller has access to via bytecodes,
+ * including protected and private fields and methods.
+ * This lookup object is a <em>capability</em> which may be delegated to trusted agents.
+ * Do not store it in place where untrusted code can access it.
+ * <p>
+ * This method is caller sensitive, which means that it may return different
+ * values to different callers.
+ * <p>
+ * For any given caller class {@code C}, the lookup object returned by this call
+ * has equivalent capabilities to any lookup object
+ * supplied by the JVM to the bootstrap method of an
+ * <a href="package-summary.html#indyinsn">invokedynamic instruction</a>
+ * executing in the same caller class {@code C}.
+ * @return a lookup object for the caller of this method, with private access
+ */
+ // Android-changed: Remove caller sensitive.
+ // @CallerSensitive
+ public static Lookup lookup() {
+ return new Lookup(Reflection.getCallerClass());
+ }
+
+ /**
+ * Returns a {@link Lookup lookup object} which is trusted minimally.
+ * It can only be used to create method handles to
+ * publicly accessible fields and methods.
+ * <p>
+ * As a matter of pure convention, the {@linkplain Lookup#lookupClass lookup class}
+ * of this lookup object will be {@link java.lang.Object}.
+ *
+ * <p style="font-size:smaller;">
+ * <em>Discussion:</em>
+ * The lookup class can be changed to any other class {@code C} using an expression of the form
+ * {@link Lookup#in publicLookup().in(C.class)}.
+ * Since all classes have equal access to public names,
+ * such a change would confer no new access rights.
+ * A public lookup object is always subject to
+ * <a href="MethodHandles.Lookup.html#secmgr">security manager checks</a>.
+ * Also, it cannot access
+ * <a href="MethodHandles.Lookup.html#callsens">caller sensitive methods</a>.
+ * @return a lookup object which is trusted minimally
+ */
+ public static Lookup publicLookup() {
+ return Lookup.PUBLIC_LOOKUP;
+ }
+
+ /**
+ * Performs an unchecked "crack" of a
+ * <a href="MethodHandleInfo.html#directmh">direct method handle</a>.
+ * The result is as if the user had obtained a lookup object capable enough
+ * to crack the target method handle, called
+ * {@link java.lang.invoke.MethodHandles.Lookup#revealDirect Lookup.revealDirect}
+ * on the target to obtain its symbolic reference, and then called
+ * {@link java.lang.invoke.MethodHandleInfo#reflectAs MethodHandleInfo.reflectAs}
+ * to resolve the symbolic reference to a member.
+ * <p>
+ * If there is a security manager, its {@code checkPermission} method
+ * is called with a {@code ReflectPermission("suppressAccessChecks")} permission.
+ * @param <T> the desired type of the result, either {@link Member} or a subtype
+ * @param target a direct method handle to crack into symbolic reference components
+ * @param expected a class object representing the desired result type {@code T}
+ * @return a reference to the method, constructor, or field object
+ * @exception SecurityException if the caller is not privileged to call {@code setAccessible}
+ * @exception NullPointerException if either argument is {@code null}
+ * @exception IllegalArgumentException if the target is not a direct method handle
+ * @exception ClassCastException if the member is not of the expected type
+ * @since 1.8
+ */
+ public static <T extends Member> T
+ reflectAs(Class<T> expected, MethodHandle target) {
+ MethodHandleImpl directTarget = getMethodHandleImpl(target);
+ // Given that this is specified to be an "unchecked" crack, we can directly allocate
+ // a member from the underlying ArtField / Method and bypass all associated access checks.
+ return expected.cast(directTarget.getMemberInternal());
+ }
+
+ /**
+ * A <em>lookup object</em> is a factory for creating method handles,
+ * when the creation requires access checking.
+ * Method handles do not perform
+ * access checks when they are called, but rather when they are created.
+ * Therefore, method handle access
+ * restrictions must be enforced when a method handle is created.
+ * The caller class against which those restrictions are enforced
+ * is known as the {@linkplain #lookupClass lookup class}.
+ * <p>
+ * A lookup class which needs to create method handles will call
+ * {@link #lookup MethodHandles.lookup} to create a factory for itself.
+ * When the {@code Lookup} factory object is created, the identity of the lookup class is
+ * determined, and securely stored in the {@code Lookup} object.
+ * The lookup class (or its delegates) may then use factory methods
+ * on the {@code Lookup} object to create method handles for access-checked members.
+ * This includes all methods, constructors, and fields which are allowed to the lookup class,
+ * even private ones.
+ *
+ * <h1><a name="lookups"></a>Lookup Factory Methods</h1>
+ * The factory methods on a {@code Lookup} object correspond to all major
+ * use cases for methods, constructors, and fields.
+ * Each method handle created by a factory method is the functional
+ * equivalent of a particular <em>bytecode behavior</em>.
+ * (Bytecode behaviors are described in section 5.4.3.5 of the Java Virtual Machine Specification.)
+ * Here is a summary of the correspondence between these factory methods and
+ * the behavior the resulting method handles:
+ * <table border=1 cellpadding=5 summary="lookup method behaviors">
+ * <tr>
+ * <th><a name="equiv"></a>lookup expression</th>
+ * <th>member</th>
+ * <th>bytecode behavior</th>
+ * </tr>
+ * <tr>
+ * <td>{@link java.lang.invoke.MethodHandles.Lookup#findGetter lookup.findGetter(C.class,"f",FT.class)}</td>
+ * <td>{@code FT f;}</td><td>{@code (T) this.f;}</td>
+ * </tr>
+ * <tr>
+ * <td>{@link java.lang.invoke.MethodHandles.Lookup#findStaticGetter lookup.findStaticGetter(C.class,"f",FT.class)}</td>
+ * <td>{@code static}<br>{@code FT f;}</td><td>{@code (T) C.f;}</td>
+ * </tr>
+ * <tr>
+ * <td>{@link java.lang.invoke.MethodHandles.Lookup#findSetter lookup.findSetter(C.class,"f",FT.class)}</td>
+ * <td>{@code FT f;}</td><td>{@code this.f = x;}</td>
+ * </tr>
+ * <tr>
+ * <td>{@link java.lang.invoke.MethodHandles.Lookup#findStaticSetter lookup.findStaticSetter(C.class,"f",FT.class)}</td>
+ * <td>{@code static}<br>{@code FT f;}</td><td>{@code C.f = arg;}</td>
+ * </tr>
+ * <tr>
+ * <td>{@link java.lang.invoke.MethodHandles.Lookup#findVirtual lookup.findVirtual(C.class,"m",MT)}</td>
+ * <td>{@code T m(A*);}</td><td>{@code (T) this.m(arg*);}</td>
+ * </tr>
+ * <tr>
+ * <td>{@link java.lang.invoke.MethodHandles.Lookup#findStatic lookup.findStatic(C.class,"m",MT)}</td>
+ * <td>{@code static}<br>{@code T m(A*);}</td><td>{@code (T) C.m(arg*);}</td>
+ * </tr>
+ * <tr>
+ * <td>{@link java.lang.invoke.MethodHandles.Lookup#findSpecial lookup.findSpecial(C.class,"m",MT,this.class)}</td>
+ * <td>{@code T m(A*);}</td><td>{@code (T) super.m(arg*);}</td>
+ * </tr>
+ * <tr>
+ * <td>{@link java.lang.invoke.MethodHandles.Lookup#findConstructor lookup.findConstructor(C.class,MT)}</td>
+ * <td>{@code C(A*);}</td><td>{@code new C(arg*);}</td>
+ * </tr>
+ * <tr>
+ * <td>{@link java.lang.invoke.MethodHandles.Lookup#unreflectGetter lookup.unreflectGetter(aField)}</td>
+ * <td>({@code static})?<br>{@code FT f;}</td><td>{@code (FT) aField.get(thisOrNull);}</td>
+ * </tr>
+ * <tr>
+ * <td>{@link java.lang.invoke.MethodHandles.Lookup#unreflectSetter lookup.unreflectSetter(aField)}</td>
+ * <td>({@code static})?<br>{@code FT f;}</td><td>{@code aField.set(thisOrNull, arg);}</td>
+ * </tr>
+ * <tr>
+ * <td>{@link java.lang.invoke.MethodHandles.Lookup#unreflect lookup.unreflect(aMethod)}</td>
+ * <td>({@code static})?<br>{@code T m(A*);}</td><td>{@code (T) aMethod.invoke(thisOrNull, arg*);}</td>
+ * </tr>
+ * <tr>
+ * <td>{@link java.lang.invoke.MethodHandles.Lookup#unreflectConstructor lookup.unreflectConstructor(aConstructor)}</td>
+ * <td>{@code C(A*);}</td><td>{@code (C) aConstructor.newInstance(arg*);}</td>
+ * </tr>
+ * <tr>
+ * <td>{@link java.lang.invoke.MethodHandles.Lookup#unreflect lookup.unreflect(aMethod)}</td>
+ * <td>({@code static})?<br>{@code T m(A*);}</td><td>{@code (T) aMethod.invoke(thisOrNull, arg*);}</td>
+ * </tr>
+ * </table>
+ *
+ * Here, the type {@code C} is the class or interface being searched for a member,
+ * documented as a parameter named {@code refc} in the lookup methods.
+ * The method type {@code MT} is composed from the return type {@code T}
+ * and the sequence of argument types {@code A*}.
+ * The constructor also has a sequence of argument types {@code A*} and
+ * is deemed to return the newly-created object of type {@code C}.
+ * Both {@code MT} and the field type {@code FT} are documented as a parameter named {@code type}.
+ * The formal parameter {@code this} stands for the self-reference of type {@code C};
+ * if it is present, it is always the leading argument to the method handle invocation.
+ * (In the case of some {@code protected} members, {@code this} may be
+ * restricted in type to the lookup class; see below.)
+ * The name {@code arg} stands for all the other method handle arguments.
+ * In the code examples for the Core Reflection API, the name {@code thisOrNull}
+ * stands for a null reference if the accessed method or field is static,
+ * and {@code this} otherwise.
+ * The names {@code aMethod}, {@code aField}, and {@code aConstructor} stand
+ * for reflective objects corresponding to the given members.
+ * <p>
+ * In cases where the given member is of variable arity (i.e., a method or constructor)
+ * the returned method handle will also be of {@linkplain MethodHandle#asVarargsCollector variable arity}.
+ * In all other cases, the returned method handle will be of fixed arity.
+ * <p style="font-size:smaller;">
+ * <em>Discussion:</em>
+ * The equivalence between looked-up method handles and underlying
+ * class members and bytecode behaviors
+ * can break down in a few ways:
+ * <ul style="font-size:smaller;">
+ * <li>If {@code C} is not symbolically accessible from the lookup class's loader,
+ * the lookup can still succeed, even when there is no equivalent
+ * Java expression or bytecoded constant.
+ * <li>Likewise, if {@code T} or {@code MT}
+ * is not symbolically accessible from the lookup class's loader,
+ * the lookup can still succeed.
+ * For example, lookups for {@code MethodHandle.invokeExact} and
+ * {@code MethodHandle.invoke} will always succeed, regardless of requested type.
+ * <li>If there is a security manager installed, it can forbid the lookup
+ * on various grounds (<a href="MethodHandles.Lookup.html#secmgr">see below</a>).
+ * By contrast, the {@code ldc} instruction on a {@code CONSTANT_MethodHandle}
+ * constant is not subject to security manager checks.
+ * <li>If the looked-up method has a
+ * <a href="MethodHandle.html#maxarity">very large arity</a>,
+ * the method handle creation may fail, due to the method handle
+ * type having too many parameters.
+ * </ul>
+ *
+ * <h1><a name="access"></a>Access checking</h1>
+ * Access checks are applied in the factory methods of {@code Lookup},
+ * when a method handle is created.
+ * This is a key difference from the Core Reflection API, since
+ * {@link java.lang.reflect.Method#invoke java.lang.reflect.Method.invoke}
+ * performs access checking against every caller, on every call.
+ * <p>
+ * All access checks start from a {@code Lookup} object, which
+ * compares its recorded lookup class against all requests to
+ * create method handles.
+ * A single {@code Lookup} object can be used to create any number
+ * of access-checked method handles, all checked against a single
+ * lookup class.
+ * <p>
+ * A {@code Lookup} object can be shared with other trusted code,
+ * such as a metaobject protocol.
+ * A shared {@code Lookup} object delegates the capability
+ * to create method handles on private members of the lookup class.
+ * Even if privileged code uses the {@code Lookup} object,
+ * the access checking is confined to the privileges of the
+ * original lookup class.
+ * <p>
+ * A lookup can fail, because
+ * the containing class is not accessible to the lookup class, or
+ * because the desired class member is missing, or because the
+ * desired class member is not accessible to the lookup class, or
+ * because the lookup object is not trusted enough to access the member.
+ * In any of these cases, a {@code ReflectiveOperationException} will be
+ * thrown from the attempted lookup. The exact class will be one of
+ * the following:
+ * <ul>
+ * <li>NoSuchMethodException — if a method is requested but does not exist
+ * <li>NoSuchFieldException — if a field is requested but does not exist
+ * <li>IllegalAccessException — if the member exists but an access check fails
+ * </ul>
+ * <p>
+ * In general, the conditions under which a method handle may be
+ * looked up for a method {@code M} are no more restrictive than the conditions
+ * under which the lookup class could have compiled, verified, and resolved a call to {@code M}.
+ * Where the JVM would raise exceptions like {@code NoSuchMethodError},
+ * a method handle lookup will generally raise a corresponding
+ * checked exception, such as {@code NoSuchMethodException}.
+ * And the effect of invoking the method handle resulting from the lookup
+ * is <a href="MethodHandles.Lookup.html#equiv">exactly equivalent</a>
+ * to executing the compiled, verified, and resolved call to {@code M}.
+ * The same point is true of fields and constructors.
+ * <p style="font-size:smaller;">
+ * <em>Discussion:</em>
+ * Access checks only apply to named and reflected methods,
+ * constructors, and fields.
+ * Other method handle creation methods, such as
+ * {@link MethodHandle#asType MethodHandle.asType},
+ * do not require any access checks, and are used
+ * independently of any {@code Lookup} object.
+ * <p>
+ * If the desired member is {@code protected}, the usual JVM rules apply,
+ * including the requirement that the lookup class must be either be in the
+ * same package as the desired member, or must inherit that member.
+ * (See the Java Virtual Machine Specification, sections 4.9.2, 5.4.3.5, and 6.4.)
+ * In addition, if the desired member is a non-static field or method
+ * in a different package, the resulting method handle may only be applied
+ * to objects of the lookup class or one of its subclasses.
+ * This requirement is enforced by narrowing the type of the leading
+ * {@code this} parameter from {@code C}
+ * (which will necessarily be a superclass of the lookup class)
+ * to the lookup class itself.
+ * <p>
+ * The JVM imposes a similar requirement on {@code invokespecial} instruction,
+ * that the receiver argument must match both the resolved method <em>and</em>
+ * the current class. Again, this requirement is enforced by narrowing the
+ * type of the leading parameter to the resulting method handle.
+ * (See the Java Virtual Machine Specification, section 4.10.1.9.)
+ * <p>
+ * The JVM represents constructors and static initializer blocks as internal methods
+ * with special names ({@code "<init>"} and {@code "<clinit>"}).
+ * The internal syntax of invocation instructions allows them to refer to such internal
+ * methods as if they were normal methods, but the JVM bytecode verifier rejects them.
+ * A lookup of such an internal method will produce a {@code NoSuchMethodException}.
+ * <p>
+ * In some cases, access between nested classes is obtained by the Java compiler by creating
+ * an wrapper method to access a private method of another class
+ * in the same top-level declaration.
+ * For example, a nested class {@code C.D}
+ * can access private members within other related classes such as
+ * {@code C}, {@code C.D.E}, or {@code C.B},
+ * but the Java compiler may need to generate wrapper methods in
+ * those related classes. In such cases, a {@code Lookup} object on
+ * {@code C.E} would be unable to those private members.
+ * A workaround for this limitation is the {@link Lookup#in Lookup.in} method,
+ * which can transform a lookup on {@code C.E} into one on any of those other
+ * classes, without special elevation of privilege.
+ * <p>
+ * The accesses permitted to a given lookup object may be limited,
+ * according to its set of {@link #lookupModes lookupModes},
+ * to a subset of members normally accessible to the lookup class.
+ * For example, the {@link #publicLookup publicLookup}
+ * method produces a lookup object which is only allowed to access
+ * public members in public classes.
+ * The caller sensitive method {@link #lookup lookup}
+ * produces a lookup object with full capabilities relative to
+ * its caller class, to emulate all supported bytecode behaviors.
+ * Also, the {@link Lookup#in Lookup.in} method may produce a lookup object
+ * with fewer access modes than the original lookup object.
+ *
+ * <p style="font-size:smaller;">
+ * <a name="privacc"></a>
+ * <em>Discussion of private access:</em>
+ * We say that a lookup has <em>private access</em>
+ * if its {@linkplain #lookupModes lookup modes}
+ * include the possibility of accessing {@code private} members.
+ * As documented in the relevant methods elsewhere,
+ * only lookups with private access possess the following capabilities:
+ * <ul style="font-size:smaller;">
+ * <li>access private fields, methods, and constructors of the lookup class
+ * <li>create method handles which invoke <a href="MethodHandles.Lookup.html#callsens">caller sensitive</a> methods,
+ * such as {@code Class.forName}
+ * <li>create method handles which {@link Lookup#findSpecial emulate invokespecial} instructions
+ * <li>avoid <a href="MethodHandles.Lookup.html#secmgr">package access checks</a>
+ * for classes accessible to the lookup class
+ * <li>create {@link Lookup#in delegated lookup objects} which have private access to other classes
+ * within the same package member
+ * </ul>
+ * <p style="font-size:smaller;">
+ * Each of these permissions is a consequence of the fact that a lookup object
+ * with private access can be securely traced back to an originating class,
+ * whose <a href="MethodHandles.Lookup.html#equiv">bytecode behaviors</a> and Java language access permissions
+ * can be reliably determined and emulated by method handles.
+ *
+ * <h1><a name="secmgr"></a>Security manager interactions</h1>
+ * Although bytecode instructions can only refer to classes in
+ * a related class loader, this API can search for methods in any
+ * class, as long as a reference to its {@code Class} object is
+ * available. Such cross-loader references are also possible with the
+ * Core Reflection API, and are impossible to bytecode instructions
+ * such as {@code invokestatic} or {@code getfield}.
+ * There is a {@linkplain java.lang.SecurityManager security manager API}
+ * to allow applications to check such cross-loader references.
+ * These checks apply to both the {@code MethodHandles.Lookup} API
+ * and the Core Reflection API
+ * (as found on {@link java.lang.Class Class}).
+ * <p>
+ * If a security manager is present, member lookups are subject to
+ * additional checks.
+ * From one to three calls are made to the security manager.
+ * Any of these calls can refuse access by throwing a
+ * {@link java.lang.SecurityException SecurityException}.
+ * Define {@code smgr} as the security manager,
+ * {@code lookc} as the lookup class of the current lookup object,
+ * {@code refc} as the containing class in which the member
+ * is being sought, and {@code defc} as the class in which the
+ * member is actually defined.
+ * The value {@code lookc} is defined as <em>not present</em>
+ * if the current lookup object does not have
+ * <a href="MethodHandles.Lookup.html#privacc">private access</a>.
+ * The calls are made according to the following rules:
+ * <ul>
+ * <li><b>Step 1:</b>
+ * If {@code lookc} is not present, or if its class loader is not
+ * the same as or an ancestor of the class loader of {@code refc},
+ * then {@link SecurityManager#checkPackageAccess
+ * smgr.checkPackageAccess(refcPkg)} is called,
+ * where {@code refcPkg} is the package of {@code refc}.
+ * <li><b>Step 2:</b>
+ * If the retrieved member is not public and
+ * {@code lookc} is not present, then
+ * {@link SecurityManager#checkPermission smgr.checkPermission}
+ * with {@code RuntimePermission("accessDeclaredMembers")} is called.
+ * <li><b>Step 3:</b>
+ * If the retrieved member is not public,
+ * and if {@code lookc} is not present,
+ * and if {@code defc} and {@code refc} are different,
+ * then {@link SecurityManager#checkPackageAccess
+ * smgr.checkPackageAccess(defcPkg)} is called,
+ * where {@code defcPkg} is the package of {@code defc}.
+ * </ul>
+ * Security checks are performed after other access checks have passed.
+ * Therefore, the above rules presuppose a member that is public,
+ * or else that is being accessed from a lookup class that has
+ * rights to access the member.
+ *
+ * <h1><a name="callsens"></a>Caller sensitive methods</h1>
+ * A small number of Java methods have a special property called caller sensitivity.
+ * A <em>caller-sensitive</em> method can behave differently depending on the
+ * identity of its immediate caller.
+ * <p>
+ * If a method handle for a caller-sensitive method is requested,
+ * the general rules for <a href="MethodHandles.Lookup.html#equiv">bytecode behaviors</a> apply,
+ * but they take account of the lookup class in a special way.
+ * The resulting method handle behaves as if it were called
+ * from an instruction contained in the lookup class,
+ * so that the caller-sensitive method detects the lookup class.
+ * (By contrast, the invoker of the method handle is disregarded.)
+ * Thus, in the case of caller-sensitive methods,
+ * different lookup classes may give rise to
+ * differently behaving method handles.
+ * <p>
+ * In cases where the lookup object is
+ * {@link #publicLookup publicLookup()},
+ * or some other lookup object without
+ * <a href="MethodHandles.Lookup.html#privacc">private access</a>,
+ * the lookup class is disregarded.
+ * In such cases, no caller-sensitive method handle can be created,
+ * access is forbidden, and the lookup fails with an
+ * {@code IllegalAccessException}.
+ * <p style="font-size:smaller;">
+ * <em>Discussion:</em>
+ * For example, the caller-sensitive method
+ * {@link java.lang.Class#forName(String) Class.forName(x)}
+ * can return varying classes or throw varying exceptions,
+ * depending on the class loader of the class that calls it.
+ * A public lookup of {@code Class.forName} will fail, because
+ * there is no reasonable way to determine its bytecode behavior.
+ * <p style="font-size:smaller;">
+ * If an application caches method handles for broad sharing,
+ * it should use {@code publicLookup()} to create them.
+ * If there is a lookup of {@code Class.forName}, it will fail,
+ * and the application must take appropriate action in that case.
+ * It may be that a later lookup, perhaps during the invocation of a
+ * bootstrap method, can incorporate the specific identity
+ * of the caller, making the method accessible.
+ * <p style="font-size:smaller;">
+ * The function {@code MethodHandles.lookup} is caller sensitive
+ * so that there can be a secure foundation for lookups.
+ * Nearly all other methods in the JSR 292 API rely on lookup
+ * objects to check access requests.
+ */
+ // Android-changed: Change link targets from MethodHandles#[public]Lookup to
+ // #[public]Lookup to work around complaints from javadoc.
+ public static final
+ class Lookup {
+ /** The class on behalf of whom the lookup is being performed. */
+ /* @NonNull */ private final Class<?> lookupClass;
+
+ /** The allowed sorts of members which may be looked up (PUBLIC, etc.). */
+ private final int allowedModes;
+
+ /** A single-bit mask representing {@code public} access,
+ * which may contribute to the result of {@link #lookupModes lookupModes}.
+ * The value, {@code 0x01}, happens to be the same as the value of the
+ * {@code public} {@linkplain java.lang.reflect.Modifier#PUBLIC modifier bit}.
+ */
+ public static final int PUBLIC = Modifier.PUBLIC;
+
+ /** A single-bit mask representing {@code private} access,
+ * which may contribute to the result of {@link #lookupModes lookupModes}.
+ * The value, {@code 0x02}, happens to be the same as the value of the
+ * {@code private} {@linkplain java.lang.reflect.Modifier#PRIVATE modifier bit}.
+ */
+ public static final int PRIVATE = Modifier.PRIVATE;
+
+ /** A single-bit mask representing {@code protected} access,
+ * which may contribute to the result of {@link #lookupModes lookupModes}.
+ * The value, {@code 0x04}, happens to be the same as the value of the
+ * {@code protected} {@linkplain java.lang.reflect.Modifier#PROTECTED modifier bit}.
+ */
+ public static final int PROTECTED = Modifier.PROTECTED;
+
+ /** A single-bit mask representing {@code package} access (default access),
+ * which may contribute to the result of {@link #lookupModes lookupModes}.
+ * The value is {@code 0x08}, which does not correspond meaningfully to
+ * any particular {@linkplain java.lang.reflect.Modifier modifier bit}.
+ */
+ public static final int PACKAGE = Modifier.STATIC;
+
+ private static final int ALL_MODES = (PUBLIC | PRIVATE | PROTECTED | PACKAGE);
+
+ // Android-note: Android has no notion of a trusted lookup. If required, such lookups
+ // are performed by the runtime. As a result, we always use lookupClass, which will always
+ // be non-null in our implementation.
+ //
+ // private static final int TRUSTED = -1;
+
+ private static int fixmods(int mods) {
+ mods &= (ALL_MODES - PACKAGE);
+ return (mods != 0) ? mods : PACKAGE;
+ }
+
+ /** Tells which class is performing the lookup. It is this class against
+ * which checks are performed for visibility and access permissions.
+ * <p>
+ * The class implies a maximum level of access permission,
+ * but the permissions may be additionally limited by the bitmask
+ * {@link #lookupModes lookupModes}, which controls whether non-public members
+ * can be accessed.
+ * @return the lookup class, on behalf of which this lookup object finds members
+ */
+ public Class<?> lookupClass() {
+ return lookupClass;
+ }
+
+ /** Tells which access-protection classes of members this lookup object can produce.
+ * The result is a bit-mask of the bits
+ * {@linkplain #PUBLIC PUBLIC (0x01)},
+ * {@linkplain #PRIVATE PRIVATE (0x02)},
+ * {@linkplain #PROTECTED PROTECTED (0x04)},
+ * and {@linkplain #PACKAGE PACKAGE (0x08)}.
+ * <p>
+ * A freshly-created lookup object
+ * on the {@linkplain java.lang.invoke.MethodHandles#lookup() caller's class}
+ * has all possible bits set, since the caller class can access all its own members.
+ * A lookup object on a new lookup class
+ * {@linkplain java.lang.invoke.MethodHandles.Lookup#in created from a previous lookup object}
+ * may have some mode bits set to zero.
+ * The purpose of this is to restrict access via the new lookup object,
+ * so that it can access only names which can be reached by the original
+ * lookup object, and also by the new lookup class.
+ * @return the lookup modes, which limit the kinds of access performed by this lookup object
+ */
+ public int lookupModes() {
+ return allowedModes & ALL_MODES;
+ }
+
+ /** Embody the current class (the lookupClass) as a lookup class
+ * for method handle creation.
+ * Must be called by from a method in this package,
+ * which in turn is called by a method not in this package.
+ */
+ Lookup(Class<?> lookupClass) {
+ this(lookupClass, ALL_MODES);
+ // make sure we haven't accidentally picked up a privileged class:
+ checkUnprivilegedlookupClass(lookupClass, ALL_MODES);
+ }
+
+ private Lookup(Class<?> lookupClass, int allowedModes) {
+ this.lookupClass = lookupClass;
+ this.allowedModes = allowedModes;
+ }
+
+ /**
+ * Creates a lookup on the specified new lookup class.
+ * The resulting object will report the specified
+ * class as its own {@link #lookupClass lookupClass}.
+ * <p>
+ * However, the resulting {@code Lookup} object is guaranteed
+ * to have no more access capabilities than the original.
+ * In particular, access capabilities can be lost as follows:<ul>
+ * <li>If the new lookup class differs from the old one,
+ * protected members will not be accessible by virtue of inheritance.
+ * (Protected members may continue to be accessible because of package sharing.)
+ * <li>If the new lookup class is in a different package
+ * than the old one, protected and default (package) members will not be accessible.
+ * <li>If the new lookup class is not within the same package member
+ * as the old one, private members will not be accessible.
+ * <li>If the new lookup class is not accessible to the old lookup class,
+ * then no members, not even public members, will be accessible.
+ * (In all other cases, public members will continue to be accessible.)
+ * </ul>
+ *
+ * @param requestedLookupClass the desired lookup class for the new lookup object
+ * @return a lookup object which reports the desired lookup class
+ * @throws NullPointerException if the argument is null
+ */
+ public Lookup in(Class<?> requestedLookupClass) {
+ requestedLookupClass.getClass(); // null check
+ // Android-changed: There's no notion of a trusted lookup.
+ // if (allowedModes == TRUSTED) // IMPL_LOOKUP can make any lookup at all
+ // return new Lookup(requestedLookupClass, ALL_MODES);
+
+ if (requestedLookupClass == this.lookupClass)
+ return this; // keep same capabilities
+ int newModes = (allowedModes & (ALL_MODES & ~PROTECTED));
+ if ((newModes & PACKAGE) != 0
+ && !VerifyAccess.isSamePackage(this.lookupClass, requestedLookupClass)) {
+ newModes &= ~(PACKAGE|PRIVATE);
+ }
+ // Allow nestmate lookups to be created without special privilege:
+ if ((newModes & PRIVATE) != 0
+ && !VerifyAccess.isSamePackageMember(this.lookupClass, requestedLookupClass)) {
+ newModes &= ~PRIVATE;
+ }
+ if ((newModes & PUBLIC) != 0
+ && !VerifyAccess.isClassAccessible(requestedLookupClass, this.lookupClass, allowedModes)) {
+ // The requested class it not accessible from the lookup class.
+ // No permissions.
+ newModes = 0;
+ }
+ checkUnprivilegedlookupClass(requestedLookupClass, newModes);
+ return new Lookup(requestedLookupClass, newModes);
+ }
+
+ // Make sure outer class is initialized first.
+ //
+ // Android-changed: Removed unnecessary reference to IMPL_NAMES.
+ // static { IMPL_NAMES.getClass(); }
+
+ /** Version of lookup which is trusted minimally.
+ * It can only be used to create method handles to
+ * publicly accessible members.
+ */
+ static final Lookup PUBLIC_LOOKUP = new Lookup(Object.class, PUBLIC);
+
+ /** Package-private version of lookup which is trusted. */
+ static final Lookup IMPL_LOOKUP = new Lookup(Object.class, ALL_MODES);
+
+ private static void checkUnprivilegedlookupClass(Class<?> lookupClass, int allowedModes) {
+ String name = lookupClass.getName();
+ if (name.startsWith("java.lang.invoke."))
+ throw newIllegalArgumentException("illegal lookupClass: "+lookupClass);
+
+ // For caller-sensitive MethodHandles.lookup()
+ // disallow lookup more restricted packages
+ //
+ // Android-changed: The bootstrap classloader isn't null.
+ if (allowedModes == ALL_MODES &&
+ lookupClass.getClassLoader() == Object.class.getClassLoader()) {
+ if (name.startsWith("java.") ||
+ (name.startsWith("sun.")
+ && !name.startsWith("sun.invoke.")
+ && !name.equals("sun.reflect.ReflectionFactory"))) {
+ throw newIllegalArgumentException("illegal lookupClass: " + lookupClass);
+ }
+ }
+ }
+
+ /**
+ * Displays the name of the class from which lookups are to be made.
+ * (The name is the one reported by {@link java.lang.Class#getName() Class.getName}.)
+ * If there are restrictions on the access permitted to this lookup,
+ * this is indicated by adding a suffix to the class name, consisting
+ * of a slash and a keyword. The keyword represents the strongest
+ * allowed access, and is chosen as follows:
+ * <ul>
+ * <li>If no access is allowed, the suffix is "/noaccess".
+ * <li>If only public access is allowed, the suffix is "/public".
+ * <li>If only public and package access are allowed, the suffix is "/package".
+ * <li>If only public, package, and private access are allowed, the suffix is "/private".
+ * </ul>
+ * If none of the above cases apply, it is the case that full
+ * access (public, package, private, and protected) is allowed.
+ * In this case, no suffix is added.
+ * This is true only of an object obtained originally from
+ * {@link java.lang.invoke.MethodHandles#lookup MethodHandles.lookup}.
+ * Objects created by {@link java.lang.invoke.MethodHandles.Lookup#in Lookup.in}
+ * always have restricted access, and will display a suffix.
+ * <p>
+ * (It may seem strange that protected access should be
+ * stronger than private access. Viewed independently from
+ * package access, protected access is the first to be lost,
+ * because it requires a direct subclass relationship between
+ * caller and callee.)
+ * @see #in
+ */
+ @Override
+ public String toString() {
+ String cname = lookupClass.getName();
+ switch (allowedModes) {
+ case 0: // no privileges
+ return cname + "/noaccess";
+ case PUBLIC:
+ return cname + "/public";
+ case PUBLIC|PACKAGE:
+ return cname + "/package";
+ case ALL_MODES & ~PROTECTED:
+ return cname + "/private";
+ case ALL_MODES:
+ return cname;
+ // Android-changed: No support for TRUSTED callers.
+ // case TRUSTED:
+ // return "/trusted"; // internal only; not exported
+ default: // Should not happen, but it's a bitfield...
+ cname = cname + "/" + Integer.toHexString(allowedModes);
+ assert(false) : cname;
+ return cname;
+ }
+ }
+
+ /**
+ * Produces a method handle for a static method.
+ * The type of the method handle will be that of the method.
+ * (Since static methods do not take receivers, there is no
+ * additional receiver argument inserted into the method handle type,
+ * as there would be with {@link #findVirtual findVirtual} or {@link #findSpecial findSpecial}.)
+ * The method and all its argument types must be accessible to the lookup object.
+ * <p>
+ * The returned method handle will have
+ * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
+ * the method's variable arity modifier bit ({@code 0x0080}) is set.
+ * <p>
+ * If the returned method handle is invoked, the method's class will
+ * be initialized, if it has not already been initialized.
+ * <p><b>Example:</b>
+ * <blockquote><pre>{@code
+import static java.lang.invoke.MethodHandles.*;
+import static java.lang.invoke.MethodType.*;
+...
+MethodHandle MH_asList = publicLookup().findStatic(Arrays.class,
+ "asList", methodType(List.class, Object[].class));
+assertEquals("[x, y]", MH_asList.invoke("x", "y").toString());
+ * }</pre></blockquote>
+ * @param refc the class from which the method is accessed
+ * @param name the name of the method
+ * @param type the type of the method
+ * @return the desired method handle
+ * @throws NoSuchMethodException if the method does not exist
+ * @throws IllegalAccessException if access checking fails,
+ * or if the method is not {@code static},
+ * or if the method's variable arity modifier bit
+ * is set and {@code asVarargsCollector} fails
+ * @exception SecurityException if a security manager is present and it
+ * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
+ * @throws NullPointerException if any argument is null
+ */
+ public
+ MethodHandle findStatic(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
+ Method method = refc.getDeclaredMethod(name, type.ptypes());
+ final int modifiers = method.getModifiers();
+ if (!Modifier.isStatic(modifiers)) {
+ throw new IllegalAccessException("Method" + method + " is not static");
+ }
+ checkReturnType(method, type);
+ checkAccess(refc, method.getDeclaringClass(), modifiers, method.getName());
+ return createMethodHandle(method, MethodHandle.INVOKE_STATIC, type);
+ }
+
+ private MethodHandle findVirtualForMH(String name, MethodType type) {
+ // these names require special lookups because of the implicit MethodType argument
+ if ("invoke".equals(name))
+ return invoker(type);
+ if ("invokeExact".equals(name))
+ return exactInvoker(type);
+ return null;
+ }
+
+ private MethodHandle findVirtualForVH(String name, MethodType type) {
+ VarHandle.AccessMode accessMode;
+ try {
+ accessMode = VarHandle.AccessMode.valueFromMethodName(name);
+ } catch (IllegalArgumentException e) {
+ return null;
+ }
+ return varHandleInvoker(accessMode, type);
+ }
+
+ private static MethodHandle createMethodHandle(Method method, int handleKind,
+ MethodType methodType) {
+ MethodHandle mh = new MethodHandleImpl(method.getArtMethod(), handleKind, methodType);
+ if (method.isVarArgs()) {
+ return new Transformers.VarargsCollector(mh);
+ } else {
+ return mh;
+ }
+ }
+
+ /**
+ * Produces a method handle for a virtual method.
+ * The type of the method handle will be that of the method,
+ * with the receiver type (usually {@code refc}) prepended.
+ * The method and all its argument types must be accessible to the lookup object.
+ * <p>
+ * When called, the handle will treat the first argument as a receiver
+ * and dispatch on the receiver's type to determine which method
+ * implementation to enter.
+ * (The dispatching action is identical with that performed by an
+ * {@code invokevirtual} or {@code invokeinterface} instruction.)
+ * <p>
+ * The first argument will be of type {@code refc} if the lookup
+ * class has full privileges to access the member. Otherwise
+ * the member must be {@code protected} and the first argument
+ * will be restricted in type to the lookup class.
+ * <p>
+ * The returned method handle will have
+ * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
+ * the method's variable arity modifier bit ({@code 0x0080}) is set.
+ * <p>
+ * Because of the general <a href="MethodHandles.Lookup.html#equiv">equivalence</a> between {@code invokevirtual}
+ * instructions and method handles produced by {@code findVirtual},
+ * if the class is {@code MethodHandle} and the name string is
+ * {@code invokeExact} or {@code invoke}, the resulting
+ * method handle is equivalent to one produced by
+ * {@link java.lang.invoke.MethodHandles#exactInvoker MethodHandles.exactInvoker} or
+ * {@link java.lang.invoke.MethodHandles#invoker MethodHandles.invoker}
+ * with the same {@code type} argument.
+ *
+ * <b>Example:</b>
+ * <blockquote><pre>{@code
+import static java.lang.invoke.MethodHandles.*;
+import static java.lang.invoke.MethodType.*;
+...
+MethodHandle MH_concat = publicLookup().findVirtual(String.class,
+ "concat", methodType(String.class, String.class));
+MethodHandle MH_hashCode = publicLookup().findVirtual(Object.class,
+ "hashCode", methodType(int.class));
+MethodHandle MH_hashCode_String = publicLookup().findVirtual(String.class,
+ "hashCode", methodType(int.class));
+assertEquals("xy", (String) MH_concat.invokeExact("x", "y"));
+assertEquals("xy".hashCode(), (int) MH_hashCode.invokeExact((Object)"xy"));
+assertEquals("xy".hashCode(), (int) MH_hashCode_String.invokeExact("xy"));
+// interface method:
+MethodHandle MH_subSequence = publicLookup().findVirtual(CharSequence.class,
+ "subSequence", methodType(CharSequence.class, int.class, int.class));
+assertEquals("def", MH_subSequence.invoke("abcdefghi", 3, 6).toString());
+// constructor "internal method" must be accessed differently:
+MethodType MT_newString = methodType(void.class); //()V for new String()
+try { assertEquals("impossible", lookup()
+ .findVirtual(String.class, "<init>", MT_newString));
+ } catch (NoSuchMethodException ex) { } // OK
+MethodHandle MH_newString = publicLookup()
+ .findConstructor(String.class, MT_newString);
+assertEquals("", (String) MH_newString.invokeExact());
+ * }</pre></blockquote>
+ *
+ * @param refc the class or interface from which the method is accessed
+ * @param name the name of the method
+ * @param type the type of the method, with the receiver argument omitted
+ * @return the desired method handle
+ * @throws NoSuchMethodException if the method does not exist
+ * @throws IllegalAccessException if access checking fails,
+ * or if the method is {@code static}
+ * or if the method's variable arity modifier bit
+ * is set and {@code asVarargsCollector} fails
+ * @exception SecurityException if a security manager is present and it
+ * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
+ * @throws NullPointerException if any argument is null
+ */
+ public MethodHandle findVirtual(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
+ // Special case : when we're looking up a virtual method on the MethodHandles class
+ // itself, we can return one of our specialized invokers.
+ if (refc == MethodHandle.class) {
+ MethodHandle mh = findVirtualForMH(name, type);
+ if (mh != null) {
+ return mh;
+ }
+ } else if (refc == VarHandle.class) {
+ // Returns an non-exact invoker.
+ MethodHandle mh = findVirtualForVH(name, type);
+ if (mh != null) {
+ return mh;
+ }
+ }
+
+ Method method = refc.getInstanceMethod(name, type.ptypes());
+ if (method == null) {
+ // This is pretty ugly and a consequence of the MethodHandles API. We have to throw
+ // an IAE and not an NSME if the method exists but is static (even though the RI's
+ // IAE has a message that says "no such method"). We confine the ugliness and
+ // slowness to the failure case, and allow getInstanceMethod to remain fairly
+ // general.
+ try {
+ Method m = refc.getDeclaredMethod(name, type.ptypes());
+ if (Modifier.isStatic(m.getModifiers())) {
+ throw new IllegalAccessException("Method" + m + " is static");
+ }
+ } catch (NoSuchMethodException ignored) {
+ }
+
+ throw new NoSuchMethodException(name + " " + Arrays.toString(type.ptypes()));
+ }
+ checkReturnType(method, type);
+
+ // We have a valid method, perform access checks.
+ checkAccess(refc, method.getDeclaringClass(), method.getModifiers(), method.getName());
+
+ // Insert the leading reference parameter.
+ MethodType handleType = type.insertParameterTypes(0, refc);
+ return createMethodHandle(method, MethodHandle.INVOKE_VIRTUAL, handleType);
+ }
+
+ /**
+ * Produces a method handle which creates an object and initializes it, using
+ * the constructor of the specified type.
+ * The parameter types of the method handle will be those of the constructor,
+ * while the return type will be a reference to the constructor's class.
+ * The constructor and all its argument types must be accessible to the lookup object.
+ * <p>
+ * The requested type must have a return type of {@code void}.
+ * (This is consistent with the JVM's treatment of constructor type descriptors.)
+ * <p>
+ * The returned method handle will have
+ * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
+ * the constructor's variable arity modifier bit ({@code 0x0080}) is set.
+ * <p>
+ * If the returned method handle is invoked, the constructor's class will
+ * be initialized, if it has not already been initialized.
+ * <p><b>Example:</b>
+ * <blockquote><pre>{@code
+import static java.lang.invoke.MethodHandles.*;
+import static java.lang.invoke.MethodType.*;
+...
+MethodHandle MH_newArrayList = publicLookup().findConstructor(
+ ArrayList.class, methodType(void.class, Collection.class));
+Collection orig = Arrays.asList("x", "y");
+Collection copy = (ArrayList) MH_newArrayList.invokeExact(orig);
+assert(orig != copy);
+assertEquals(orig, copy);
+// a variable-arity constructor:
+MethodHandle MH_newProcessBuilder = publicLookup().findConstructor(
+ ProcessBuilder.class, methodType(void.class, String[].class));
+ProcessBuilder pb = (ProcessBuilder)
+ MH_newProcessBuilder.invoke("x", "y", "z");
+assertEquals("[x, y, z]", pb.command().toString());
+ * }</pre></blockquote>
+ * @param refc the class or interface from which the method is accessed
+ * @param type the type of the method, with the receiver argument omitted, and a void return type
+ * @return the desired method handle
+ * @throws NoSuchMethodException if the constructor does not exist
+ * @throws IllegalAccessException if access checking fails
+ * or if the method's variable arity modifier bit
+ * is set and {@code asVarargsCollector} fails
+ * @exception SecurityException if a security manager is present and it
+ * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
+ * @throws NullPointerException if any argument is null
+ */
+ public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
+ if (refc.isArray()) {
+ throw new NoSuchMethodException("no constructor for array class: " + refc.getName());
+ }
+ // The queried |type| is (PT1,PT2,..)V
+ Constructor constructor = refc.getDeclaredConstructor(type.ptypes());
+ if (constructor == null) {
+ throw new NoSuchMethodException(
+ "No constructor for " + constructor.getDeclaringClass() + " matching " + type);
+ }
+ checkAccess(refc, constructor.getDeclaringClass(), constructor.getModifiers(),
+ constructor.getName());
+
+ return createMethodHandleForConstructor(constructor);
+ }
+
+ private MethodHandle createMethodHandleForConstructor(Constructor constructor) {
+ Class<?> refc = constructor.getDeclaringClass();
+ MethodType constructorType =
+ MethodType.methodType(refc, constructor.getParameterTypes());
+ MethodHandle mh;
+ if (refc == String.class) {
+ // String constructors have optimized StringFactory methods
+ // that matches returned type. These factory methods combine the
+ // memory allocation and initialization calls for String objects.
+ mh = new MethodHandleImpl(constructor.getArtMethod(), MethodHandle.INVOKE_DIRECT,
+ constructorType);
+ } else {
+ // Constructors for all other classes use a Construct transformer to perform
+ // their memory allocation and call to <init>.
+ MethodType initType = initMethodType(constructorType);
+ MethodHandle initHandle = new MethodHandleImpl(
+ constructor.getArtMethod(), MethodHandle.INVOKE_DIRECT, initType);
+ mh = new Transformers.Construct(initHandle, constructorType);
+ }
+
+ if (constructor.isVarArgs()) {
+ mh = new Transformers.VarargsCollector(mh);
+ }
+ return mh;
+ }
+
+ private static MethodType initMethodType(MethodType constructorType) {
+ // Returns a MethodType appropriate for class <init>
+ // methods. Constructor MethodTypes have the form
+ // (PT1,PT2,...)C and class <init> MethodTypes have the
+ // form (C,PT1,PT2,...)V.
+ assert constructorType.rtype() != void.class;
+
+ // Insert constructorType C as the first parameter type in
+ // the MethodType for <init>.
+ Class<?> [] initPtypes = new Class<?> [constructorType.ptypes().length + 1];
+ initPtypes[0] = constructorType.rtype();
+ System.arraycopy(constructorType.ptypes(), 0, initPtypes, 1,
+ constructorType.ptypes().length);
+
+ // Set the return type for the <init> MethodType to be void.
+ return MethodType.methodType(void.class, initPtypes);
+ }
+
+ /**
+ * Produces an early-bound method handle for a virtual method.
+ * It will bypass checks for overriding methods on the receiver,
+ * <a href="MethodHandles.Lookup.html#equiv">as if called</a> from an {@code invokespecial}
+ * instruction from within the explicitly specified {@code specialCaller}.
+ * The type of the method handle will be that of the method,
+ * with a suitably restricted receiver type prepended.
+ * (The receiver type will be {@code specialCaller} or a subtype.)
+ * The method and all its argument types must be accessible
+ * to the lookup object.
+ * <p>
+ * Before method resolution,
+ * if the explicitly specified caller class is not identical with the
+ * lookup class, or if this lookup object does not have
+ * <a href="MethodHandles.Lookup.html#privacc">private access</a>
+ * privileges, the access fails.
+ * <p>
+ * The returned method handle will have
+ * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
+ * the method's variable arity modifier bit ({@code 0x0080}) is set.
+ * <p style="font-size:smaller;">
+ * <em>(Note: JVM internal methods named {@code "<init>"} are not visible to this API,
+ * even though the {@code invokespecial} instruction can refer to them
+ * in special circumstances. Use {@link #findConstructor findConstructor}
+ * to access instance initialization methods in a safe manner.)</em>
+ * <p><b>Example:</b>
+ * <blockquote><pre>{@code
+import static java.lang.invoke.MethodHandles.*;
+import static java.lang.invoke.MethodType.*;
+...
+static class Listie extends ArrayList {
+ public String toString() { return "[wee Listie]"; }
+ static Lookup lookup() { return MethodHandles.lookup(); }
+}
+...
+// no access to constructor via invokeSpecial:
+MethodHandle MH_newListie = Listie.lookup()
+ .findConstructor(Listie.class, methodType(void.class));
+Listie l = (Listie) MH_newListie.invokeExact();
+try { assertEquals("impossible", Listie.lookup().findSpecial(
+ Listie.class, "<init>", methodType(void.class), Listie.class));
+ } catch (NoSuchMethodException ex) { } // OK
+// access to super and self methods via invokeSpecial:
+MethodHandle MH_super = Listie.lookup().findSpecial(
+ ArrayList.class, "toString" , methodType(String.class), Listie.class);
+MethodHandle MH_this = Listie.lookup().findSpecial(
+ Listie.class, "toString" , methodType(String.class), Listie.class);
+MethodHandle MH_duper = Listie.lookup().findSpecial(
+ Object.class, "toString" , methodType(String.class), Listie.class);
+assertEquals("[]", (String) MH_super.invokeExact(l));
+assertEquals(""+l, (String) MH_this.invokeExact(l));
+assertEquals("[]", (String) MH_duper.invokeExact(l)); // ArrayList method
+try { assertEquals("inaccessible", Listie.lookup().findSpecial(
+ String.class, "toString", methodType(String.class), Listie.class));
+ } catch (IllegalAccessException ex) { } // OK
+Listie subl = new Listie() { public String toString() { return "[subclass]"; } };
+assertEquals(""+l, (String) MH_this.invokeExact(subl)); // Listie method
+ * }</pre></blockquote>
+ *
+ * @param refc the class or interface from which the method is accessed
+ * @param name the name of the method (which must not be "<init>")
+ * @param type the type of the method, with the receiver argument omitted
+ * @param specialCaller the proposed calling class to perform the {@code invokespecial}
+ * @return the desired method handle
+ * @throws NoSuchMethodException if the method does not exist
+ * @throws IllegalAccessException if access checking fails
+ * or if the method's variable arity modifier bit
+ * is set and {@code asVarargsCollector} fails
+ * @exception SecurityException if a security manager is present and it
+ * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
+ * @throws NullPointerException if any argument is null
+ */
+ public MethodHandle findSpecial(Class<?> refc, String name, MethodType type,
+ Class<?> specialCaller) throws NoSuchMethodException, IllegalAccessException {
+ if (specialCaller == null) {
+ throw new NullPointerException("specialCaller == null");
+ }
+
+ if (type == null) {
+ throw new NullPointerException("type == null");
+ }
+
+ if (name == null) {
+ throw new NullPointerException("name == null");
+ }
+
+ if (refc == null) {
+ throw new NullPointerException("ref == null");
+ }
+
+ // Make sure that the special caller is identical to the lookup class or that we have
+ // private access.
+ // Android-changed: Also allow access to any interface methods.
+ checkSpecialCaller(specialCaller, refc);
+
+ // Even though constructors are invoked using a "special" invoke, handles to them can't
+ // be created using findSpecial. Callers must use findConstructor instead. Similarly,
+ // there is no path for calling static class initializers.
+ if (name.startsWith("<")) {
+ throw new NoSuchMethodException(name + " is not a valid method name.");
+ }
+
+ Method method = refc.getDeclaredMethod(name, type.ptypes());
+ checkReturnType(method, type);
+ return findSpecial(method, type, refc, specialCaller);
+ }
+
+ private MethodHandle findSpecial(Method method, MethodType type,
+ Class<?> refc, Class<?> specialCaller)
+ throws IllegalAccessException {
+ if (Modifier.isStatic(method.getModifiers())) {
+ throw new IllegalAccessException("expected a non-static method:" + method);
+ }
+
+ if (Modifier.isPrivate(method.getModifiers())) {
+ // Since this is a private method, we'll need to also make sure that the
+ // lookup class is the same as the refering class. We've already checked that
+ // the specialCaller is the same as the special lookup class, both of these must
+ // be the same as the declaring class(*) in order to access the private method.
+ //
+ // (*) Well, this isn't true for nested classes but OpenJDK doesn't support those
+ // either.
+ if (refc != lookupClass()) {
+ throw new IllegalAccessException("no private access for invokespecial : "
+ + refc + ", from" + this);
+ }
+
+ // This is a private method, so there's nothing special to do.
+ MethodType handleType = type.insertParameterTypes(0, refc);
+ return createMethodHandle(method, MethodHandle.INVOKE_DIRECT, handleType);
+ }
+
+ // This is a public, protected or package-private method, which means we're expecting
+ // invoke-super semantics. We'll have to restrict the receiver type appropriately on the
+ // handle once we check that there really is a "super" relationship between them.
+ if (!method.getDeclaringClass().isAssignableFrom(specialCaller)) {
+ throw new IllegalAccessException(refc + "is not assignable from " + specialCaller);
+ }
+
+ // Note that we restrict the receiver to "specialCaller" instances.
+ MethodType handleType = type.insertParameterTypes(0, specialCaller);
+ return createMethodHandle(method, MethodHandle.INVOKE_SUPER, handleType);
+ }
+
+ /**
+ * Produces a method handle giving read access to a non-static field.
+ * The type of the method handle will have a return type of the field's
+ * value type.
+ * The method handle's single argument will be the instance containing
+ * the field.
+ * Access checking is performed immediately on behalf of the lookup class.
+ * @param refc the class or interface from which the method is accessed
+ * @param name the field's name
+ * @param type the field's type
+ * @return a method handle which can load values from the field
+ * @throws NoSuchFieldException if the field does not exist
+ * @throws IllegalAccessException if access checking fails, or if the field is {@code static}
+ * @exception SecurityException if a security manager is present and it
+ * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
+ * @throws NullPointerException if any argument is null
+ */
+ public MethodHandle findGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
+ return findAccessor(refc, name, type, MethodHandle.IGET);
+ }
+
+ private MethodHandle findAccessor(Class<?> refc, String name, Class<?> type, int kind)
+ throws NoSuchFieldException, IllegalAccessException {
+ final Field field = findFieldOfType(refc, name, type);
+ return findAccessor(field, refc, type, kind, true /* performAccessChecks */);
+ }
+
+ private MethodHandle findAccessor(Field field, Class<?> refc, Class<?> type, int kind,
+ boolean performAccessChecks)
+ throws IllegalAccessException {
+ final boolean isSetterKind = kind == MethodHandle.IPUT || kind == MethodHandle.SPUT;
+ final boolean isStaticKind = kind == MethodHandle.SGET || kind == MethodHandle.SPUT;
+ commonFieldChecks(field, refc, type, isStaticKind, performAccessChecks);
+ if (performAccessChecks) {
+ final int modifiers = field.getModifiers();
+ if (isSetterKind && Modifier.isFinal(modifiers)) {
+ throw new IllegalAccessException("Field " + field + " is final");
+ }
+ }
+
+ final MethodType methodType;
+ switch (kind) {
+ case MethodHandle.SGET:
+ methodType = MethodType.methodType(type);
+ break;
+ case MethodHandle.SPUT:
+ methodType = MethodType.methodType(void.class, type);
+ break;
+ case MethodHandle.IGET:
+ methodType = MethodType.methodType(type, refc);
+ break;
+ case MethodHandle.IPUT:
+ methodType = MethodType.methodType(void.class, refc, type);
+ break;
+ default:
+ throw new IllegalArgumentException("Invalid kind " + kind);
+ }
+ return new MethodHandleImpl(field.getArtField(), kind, methodType);
+ }
+
+ /**
+ * Produces a method handle giving write access to a non-static field.
+ * The type of the method handle will have a void return type.
+ * The method handle will take two arguments, the instance containing
+ * the field, and the value to be stored.
+ * The second argument will be of the field's value type.
+ * Access checking is performed immediately on behalf of the lookup class.
+ * @param refc the class or interface from which the method is accessed
+ * @param name the field's name
+ * @param type the field's type
+ * @return a method handle which can store values into the field
+ * @throws NoSuchFieldException if the field does not exist
+ * @throws IllegalAccessException if access checking fails, or if the field is {@code static}
+ * @exception SecurityException if a security manager is present and it
+ * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
+ * @throws NullPointerException if any argument is null
+ */
+ public MethodHandle findSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
+ return findAccessor(refc, name, type, MethodHandle.IPUT);
+ }
+
+ // BEGIN Android-changed: OpenJDK 9+181 VarHandle API factory method.
+ /**
+ * Produces a VarHandle giving access to a non-static field {@code name}
+ * of type {@code type} declared in a class of type {@code recv}.
+ * The VarHandle's variable type is {@code type} and it has one
+ * coordinate type, {@code recv}.
+ * <p>
+ * Access checking is performed immediately on behalf of the lookup
+ * class.
+ * <p>
+ * Certain access modes of the returned VarHandle are unsupported under
+ * the following conditions:
+ * <ul>
+ * <li>if the field is declared {@code final}, then the write, atomic
+ * update, numeric atomic update, and bitwise atomic update access
+ * modes are unsupported.
+ * <li>if the field type is anything other than {@code byte},
+ * {@code short}, {@code char}, {@code int}, {@code long},
+ * {@code float}, or {@code double} then numeric atomic update
+ * access modes are unsupported.
+ * <li>if the field type is anything other than {@code boolean},
+ * {@code byte}, {@code short}, {@code char}, {@code int} or
+ * {@code long} then bitwise atomic update access modes are
+ * unsupported.
+ * </ul>
+ * <p>
+ * If the field is declared {@code volatile} then the returned VarHandle
+ * will override access to the field (effectively ignore the
+ * {@code volatile} declaration) in accordance to its specified
+ * access modes.
+ * <p>
+ * If the field type is {@code float} or {@code double} then numeric
+ * and atomic update access modes compare values using their bitwise
+ * representation (see {@link Float#floatToRawIntBits} and
+ * {@link Double#doubleToRawLongBits}, respectively).
+ * @apiNote
+ * Bitwise comparison of {@code float} values or {@code double} values,
+ * as performed by the numeric and atomic update access modes, differ
+ * from the primitive {@code ==} operator and the {@link Float#equals}
+ * and {@link Double#equals} methods, specifically with respect to
+ * comparing NaN values or comparing {@code -0.0} with {@code +0.0}.
+ * Care should be taken when performing a compare and set or a compare
+ * and exchange operation with such values since the operation may
+ * unexpectedly fail.
+ * There are many possible NaN values that are considered to be
+ * {@code NaN} in Java, although no IEEE 754 floating-point operation
+ * provided by Java can distinguish between them. Operation failure can
+ * occur if the expected or witness value is a NaN value and it is
+ * transformed (perhaps in a platform specific manner) into another NaN
+ * value, and thus has a different bitwise representation (see
+ * {@link Float#intBitsToFloat} or {@link Double#longBitsToDouble} for more
+ * details).
+ * The values {@code -0.0} and {@code +0.0} have different bitwise
+ * representations but are considered equal when using the primitive
+ * {@code ==} operator. Operation failure can occur if, for example, a
+ * numeric algorithm computes an expected value to be say {@code -0.0}
+ * and previously computed the witness value to be say {@code +0.0}.
+ * @param recv the receiver class, of type {@code R}, that declares the
+ * non-static field
+ * @param name the field's name
+ * @param type the field's type, of type {@code T}
+ * @return a VarHandle giving access to non-static fields.
+ * @throws NoSuchFieldException if the field does not exist
+ * @throws IllegalAccessException if access checking fails, or if the field is {@code static}
+ * @exception SecurityException if a security manager is present and it
+ * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
+ * @throws NullPointerException if any argument is null
+ * @since 9
+ * @hide
+ */
+ public VarHandle findVarHandle(Class<?> recv, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
+ final Field field = findFieldOfType(recv, name, type);
+ final boolean isStatic = false;
+ final boolean performAccessChecks = true;
+ commonFieldChecks(field, recv, type, isStatic, performAccessChecks);
+ return FieldVarHandle.create(field);
+ }
+ // END Android-changed: OpenJDK 9+181 VarHandle API factory method.
+
+ // BEGIN Android-added: Common field resolution and access check methods.
+ private Field findFieldOfType(final Class<?> refc, String name, Class<?> type)
+ throws NoSuchFieldException {
+ Field field = null;
+
+ // Search refc and super classes for the field.
+ for (Class<?> cls = refc; cls != null; cls = cls.getSuperclass()) {
+ try {
+ field = cls.getDeclaredField(name);
+ break;
+ } catch (NoSuchFieldException e) {
+ }
+ }
+
+ if (field == null) {
+ // Force failure citing refc.
+ field = refc.getDeclaredField(name);
+ }
+
+ final Class<?> fieldType = field.getType();
+ if (fieldType != type) {
+ throw new NoSuchFieldException(name);
+ }
+ return field;
+ }
+
+ private void commonFieldChecks(Field field, Class<?> refc, Class<?> type,
+ boolean isStatic, boolean performAccessChecks)
+ throws IllegalAccessException {
+ final int modifiers = field.getModifiers();
+ if (performAccessChecks) {
+ checkAccess(refc, field.getDeclaringClass(), modifiers, field.getName());
+ }
+ if (Modifier.isStatic(modifiers) != isStatic) {
+ String reason = "Field " + field + " is " +
+ (isStatic ? "not " : "") + "static";
+ throw new IllegalAccessException(reason);
+ }
+ }
+ // END Android-added: Common field resolution and access check methods.
+
+ /**
+ * Produces a method handle giving read access to a static field.
+ * The type of the method handle will have a return type of the field's
+ * value type.
+ * The method handle will take no arguments.
+ * Access checking is performed immediately on behalf of the lookup class.
+ * <p>
+ * If the returned method handle is invoked, the field's class will
+ * be initialized, if it has not already been initialized.
+ * @param refc the class or interface from which the method is accessed
+ * @param name the field's name
+ * @param type the field's type
+ * @return a method handle which can load values from the field
+ * @throws NoSuchFieldException if the field does not exist
+ * @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
+ * @exception SecurityException if a security manager is present and it
+ * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
+ * @throws NullPointerException if any argument is null
+ */
+ public MethodHandle findStaticGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
+ return findAccessor(refc, name, type, MethodHandle.SGET);
+ }
+
+ /**
+ * Produces a method handle giving write access to a static field.
+ * The type of the method handle will have a void return type.
+ * The method handle will take a single
+ * argument, of the field's value type, the value to be stored.
+ * Access checking is performed immediately on behalf of the lookup class.
+ * <p>
+ * If the returned method handle is invoked, the field's class will
+ * be initialized, if it has not already been initialized.
+ * @param refc the class or interface from which the method is accessed
+ * @param name the field's name
+ * @param type the field's type
+ * @return a method handle which can store values into the field
+ * @throws NoSuchFieldException if the field does not exist
+ * @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
+ * @exception SecurityException if a security manager is present and it
+ * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
+ * @throws NullPointerException if any argument is null
+ */
+ public MethodHandle findStaticSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
+ return findAccessor(refc, name, type, MethodHandle.SPUT);
+ }
+
+ // BEGIN Android-changed: OpenJDK 9+181 VarHandle API factory method.
+ /**
+ * Produces a VarHandle giving access to a static field {@code name} of
+ * type {@code type} declared in a class of type {@code decl}.
+ * The VarHandle's variable type is {@code type} and it has no
+ * coordinate types.
+ * <p>
+ * Access checking is performed immediately on behalf of the lookup
+ * class.
+ * <p>
+ * If the returned VarHandle is operated on, the declaring class will be
+ * initialized, if it has not already been initialized.
+ * <p>
+ * Certain access modes of the returned VarHandle are unsupported under
+ * the following conditions:
+ * <ul>
+ * <li>if the field is declared {@code final}, then the write, atomic
+ * update, numeric atomic update, and bitwise atomic update access
+ * modes are unsupported.
+ * <li>if the field type is anything other than {@code byte},
+ * {@code short}, {@code char}, {@code int}, {@code long},
+ * {@code float}, or {@code double}, then numeric atomic update
+ * access modes are unsupported.
+ * <li>if the field type is anything other than {@code boolean},
+ * {@code byte}, {@code short}, {@code char}, {@code int} or
+ * {@code long} then bitwise atomic update access modes are
+ * unsupported.
+ * </ul>
+ * <p>
+ * If the field is declared {@code volatile} then the returned VarHandle
+ * will override access to the field (effectively ignore the
+ * {@code volatile} declaration) in accordance to its specified
+ * access modes.
+ * <p>
+ * If the field type is {@code float} or {@code double} then numeric
+ * and atomic update access modes compare values using their bitwise
+ * representation (see {@link Float#floatToRawIntBits} and
+ * {@link Double#doubleToRawLongBits}, respectively).
+ * @apiNote
+ * Bitwise comparison of {@code float} values or {@code double} values,
+ * as performed by the numeric and atomic update access modes, differ
+ * from the primitive {@code ==} operator and the {@link Float#equals}
+ * and {@link Double#equals} methods, specifically with respect to
+ * comparing NaN values or comparing {@code -0.0} with {@code +0.0}.
+ * Care should be taken when performing a compare and set or a compare
+ * and exchange operation with such values since the operation may
+ * unexpectedly fail.
+ * There are many possible NaN values that are considered to be
+ * {@code NaN} in Java, although no IEEE 754 floating-point operation
+ * provided by Java can distinguish between them. Operation failure can
+ * occur if the expected or witness value is a NaN value and it is
+ * transformed (perhaps in a platform specific manner) into another NaN
+ * value, and thus has a different bitwise representation (see
+ * {@link Float#intBitsToFloat} or {@link Double#longBitsToDouble} for more
+ * details).
+ * The values {@code -0.0} and {@code +0.0} have different bitwise
+ * representations but are considered equal when using the primitive
+ * {@code ==} operator. Operation failure can occur if, for example, a
+ * numeric algorithm computes an expected value to be say {@code -0.0}
+ * and previously computed the witness value to be say {@code +0.0}.
+ * @param decl the class that declares the static field
+ * @param name the field's name
+ * @param type the field's type, of type {@code T}
+ * @return a VarHandle giving access to a static field
+ * @throws NoSuchFieldException if the field does not exist
+ * @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
+ * @exception SecurityException if a security manager is present and it
+ * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
+ * @throws NullPointerException if any argument is null
+ * @since 9
+ * @hide
+ */
+ public VarHandle findStaticVarHandle(Class<?> decl, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
+ final Field field = findFieldOfType(decl, name, type);
+ final boolean isStatic = true;
+ final boolean performAccessChecks = true;
+ commonFieldChecks(field, decl, type, isStatic, performAccessChecks);
+ return FieldVarHandle.create(field);
+ }
+ // END Android-changed: OpenJDK 9+181 VarHandle API factory method.
+
+ /**
+ * Produces an early-bound method handle for a non-static method.
+ * The receiver must have a supertype {@code defc} in which a method
+ * of the given name and type is accessible to the lookup class.
+ * The method and all its argument types must be accessible to the lookup object.
+ * The type of the method handle will be that of the method,
+ * without any insertion of an additional receiver parameter.
+ * The given receiver will be bound into the method handle,
+ * so that every call to the method handle will invoke the
+ * requested method on the given receiver.
+ * <p>
+ * The returned method handle will have
+ * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
+ * the method's variable arity modifier bit ({@code 0x0080}) is set
+ * <em>and</em> the trailing array argument is not the only argument.
+ * (If the trailing array argument is the only argument,
+ * the given receiver value will be bound to it.)
+ * <p>
+ * This is equivalent to the following code:
+ * <blockquote><pre>{@code
+import static java.lang.invoke.MethodHandles.*;
+import static java.lang.invoke.MethodType.*;
+...
+MethodHandle mh0 = lookup().findVirtual(defc, name, type);
+MethodHandle mh1 = mh0.bindTo(receiver);
+MethodType mt1 = mh1.type();
+if (mh0.isVarargsCollector())
+ mh1 = mh1.asVarargsCollector(mt1.parameterType(mt1.parameterCount()-1));
+return mh1;
+ * }</pre></blockquote>
+ * where {@code defc} is either {@code receiver.getClass()} or a super
+ * type of that class, in which the requested method is accessible
+ * to the lookup class.
+ * (Note that {@code bindTo} does not preserve variable arity.)
+ * @param receiver the object from which the method is accessed
+ * @param name the name of the method
+ * @param type the type of the method, with the receiver argument omitted
+ * @return the desired method handle
+ * @throws NoSuchMethodException if the method does not exist
+ * @throws IllegalAccessException if access checking fails
+ * or if the method's variable arity modifier bit
+ * is set and {@code asVarargsCollector} fails
+ * @exception SecurityException if a security manager is present and it
+ * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
+ * @throws NullPointerException if any argument is null
+ * @see MethodHandle#bindTo
+ * @see #findVirtual
+ */
+ public MethodHandle bind(Object receiver, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
+ MethodHandle handle = findVirtual(receiver.getClass(), name, type);
+ MethodHandle adapter = handle.bindTo(receiver);
+ MethodType adapterType = adapter.type();
+ if (handle.isVarargsCollector()) {
+ adapter = adapter.asVarargsCollector(
+ adapterType.parameterType(adapterType.parameterCount() - 1));
+ }
+
+ return adapter;
+ }
+
+ /**
+ * Makes a <a href="MethodHandleInfo.html#directmh">direct method handle</a>
+ * to <i>m</i>, if the lookup class has permission.
+ * If <i>m</i> is non-static, the receiver argument is treated as an initial argument.
+ * If <i>m</i> is virtual, overriding is respected on every call.
+ * Unlike the Core Reflection API, exceptions are <em>not</em> wrapped.
+ * The type of the method handle will be that of the method,
+ * with the receiver type prepended (but only if it is non-static).
+ * If the method's {@code accessible} flag is not set,
+ * access checking is performed immediately on behalf of the lookup class.
+ * If <i>m</i> is not public, do not share the resulting handle with untrusted parties.
+ * <p>
+ * The returned method handle will have
+ * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
+ * the method's variable arity modifier bit ({@code 0x0080}) is set.
+ * <p>
+ * If <i>m</i> is static, and
+ * if the returned method handle is invoked, the method's class will
+ * be initialized, if it has not already been initialized.
+ * @param m the reflected method
+ * @return a method handle which can invoke the reflected method
+ * @throws IllegalAccessException if access checking fails
+ * or if the method's variable arity modifier bit
+ * is set and {@code asVarargsCollector} fails
+ * @throws NullPointerException if the argument is null
+ */
+ public MethodHandle unreflect(Method m) throws IllegalAccessException {
+ if (m == null) {
+ throw new NullPointerException("m == null");
+ }
+
+ MethodType methodType = MethodType.methodType(m.getReturnType(),
+ m.getParameterTypes());
+
+ // We should only perform access checks if setAccessible hasn't been called yet.
+ if (!m.isAccessible()) {
+ checkAccess(m.getDeclaringClass(), m.getDeclaringClass(), m.getModifiers(),
+ m.getName());
+ }
+
+ if (Modifier.isStatic(m.getModifiers())) {
+ return createMethodHandle(m, MethodHandle.INVOKE_STATIC, methodType);
+ } else {
+ methodType = methodType.insertParameterTypes(0, m.getDeclaringClass());
+ return createMethodHandle(m, MethodHandle.INVOKE_VIRTUAL, methodType);
+ }
+ }
+
+ /**
+ * Produces a method handle for a reflected method.
+ * It will bypass checks for overriding methods on the receiver,
+ * <a href="MethodHandles.Lookup.html#equiv">as if called</a> from an {@code invokespecial}
+ * instruction from within the explicitly specified {@code specialCaller}.
+ * The type of the method handle will be that of the method,
+ * with a suitably restricted receiver type prepended.
+ * (The receiver type will be {@code specialCaller} or a subtype.)
+ * If the method's {@code accessible} flag is not set,
+ * access checking is performed immediately on behalf of the lookup class,
+ * as if {@code invokespecial} instruction were being linked.
+ * <p>
+ * Before method resolution,
+ * if the explicitly specified caller class is not identical with the
+ * lookup class, or if this lookup object does not have
+ * <a href="MethodHandles.Lookup.html#privacc">private access</a>
+ * privileges, the access fails.
+ * <p>
+ * The returned method handle will have
+ * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
+ * the method's variable arity modifier bit ({@code 0x0080}) is set.
+ * @param m the reflected method
+ * @param specialCaller the class nominally calling the method
+ * @return a method handle which can invoke the reflected method
+ * @throws IllegalAccessException if access checking fails
+ * or if the method's variable arity modifier bit
+ * is set and {@code asVarargsCollector} fails
+ * @throws NullPointerException if any argument is null
+ */
+ public MethodHandle unreflectSpecial(Method m, Class<?> specialCaller) throws IllegalAccessException {
+ if (m == null) {
+ throw new NullPointerException("m == null");
+ }
+
+ if (specialCaller == null) {
+ throw new NullPointerException("specialCaller == null");
+ }
+
+ if (!m.isAccessible()) {
+ // Android-changed: Match Java language 9 behavior where unreflectSpecial continues
+ // to require exact caller lookupClass match.
+ checkSpecialCaller(specialCaller, null);
+ }
+
+ final MethodType methodType = MethodType.methodType(m.getReturnType(),
+ m.getParameterTypes());
+ return findSpecial(m, methodType, m.getDeclaringClass() /* refc */, specialCaller);
+ }
+
+ /**
+ * Produces a method handle for a reflected constructor.
+ * The type of the method handle will be that of the constructor,
+ * with the return type changed to the declaring class.
+ * The method handle will perform a {@code newInstance} operation,
+ * creating a new instance of the constructor's class on the
+ * arguments passed to the method handle.
+ * <p>
+ * If the constructor's {@code accessible} flag is not set,
+ * access checking is performed immediately on behalf of the lookup class.
+ * <p>
+ * The returned method handle will have
+ * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
+ * the constructor's variable arity modifier bit ({@code 0x0080}) is set.
+ * <p>
+ * If the returned method handle is invoked, the constructor's class will
+ * be initialized, if it has not already been initialized.
+ * @param c the reflected constructor
+ * @return a method handle which can invoke the reflected constructor
+ * @throws IllegalAccessException if access checking fails
+ * or if the method's variable arity modifier bit
+ * is set and {@code asVarargsCollector} fails
+ * @throws NullPointerException if the argument is null
+ */
+ public MethodHandle unreflectConstructor(Constructor<?> c) throws IllegalAccessException {
+ if (c == null) {
+ throw new NullPointerException("c == null");
+ }
+
+ if (!c.isAccessible()) {
+ checkAccess(c.getDeclaringClass(), c.getDeclaringClass(), c.getModifiers(),
+ c.getName());
+ }
+
+ return createMethodHandleForConstructor(c);
+ }
+
+ /**
+ * Produces a method handle giving read access to a reflected field.
+ * The type of the method handle will have a return type of the field's
+ * value type.
+ * If the field is static, the method handle will take no arguments.
+ * Otherwise, its single argument will be the instance containing
+ * the field.
+ * If the field's {@code accessible} flag is not set,
+ * access checking is performed immediately on behalf of the lookup class.
+ * <p>
+ * If the field is static, and
+ * if the returned method handle is invoked, the field's class will
+ * be initialized, if it has not already been initialized.
+ * @param f the reflected field
+ * @return a method handle which can load values from the reflected field
+ * @throws IllegalAccessException if access checking fails
+ * @throws NullPointerException if the argument is null
+ */
+ public MethodHandle unreflectGetter(Field f) throws IllegalAccessException {
+ return findAccessor(f, f.getDeclaringClass(), f.getType(),
+ Modifier.isStatic(f.getModifiers()) ? MethodHandle.SGET : MethodHandle.IGET,
+ !f.isAccessible() /* performAccessChecks */);
+ }
+
+ /**
+ * Produces a method handle giving write access to a reflected field.
+ * The type of the method handle will have a void return type.
+ * If the field is static, the method handle will take a single
+ * argument, of the field's value type, the value to be stored.
+ * Otherwise, the two arguments will be the instance containing
+ * the field, and the value to be stored.
+ * If the field's {@code accessible} flag is not set,
+ * access checking is performed immediately on behalf of the lookup class.
+ * <p>
+ * If the field is static, and
+ * if the returned method handle is invoked, the field's class will
+ * be initialized, if it has not already been initialized.
+ * @param f the reflected field
+ * @return a method handle which can store values into the reflected field
+ * @throws IllegalAccessException if access checking fails
+ * @throws NullPointerException if the argument is null
+ */
+ public MethodHandle unreflectSetter(Field f) throws IllegalAccessException {
+ return findAccessor(f, f.getDeclaringClass(), f.getType(),
+ Modifier.isStatic(f.getModifiers()) ? MethodHandle.SPUT : MethodHandle.IPUT,
+ !f.isAccessible() /* performAccessChecks */);
+ }
+
+ // BEGIN Android-changed: OpenJDK 9+181 VarHandle API factory method.
+ /**
+ * Produces a VarHandle giving access to a reflected field {@code f}
+ * of type {@code T} declared in a class of type {@code R}.
+ * The VarHandle's variable type is {@code T}.
+ * If the field is non-static the VarHandle has one coordinate type,
+ * {@code R}. Otherwise, the field is static, and the VarHandle has no
+ * coordinate types.
+ * <p>
+ * Access checking is performed immediately on behalf of the lookup
+ * class, regardless of the value of the field's {@code accessible}
+ * flag.
+ * <p>
+ * If the field is static, and if the returned VarHandle is operated
+ * on, the field's declaring class will be initialized, if it has not
+ * already been initialized.
+ * <p>
+ * Certain access modes of the returned VarHandle are unsupported under
+ * the following conditions:
+ * <ul>
+ * <li>if the field is declared {@code final}, then the write, atomic
+ * update, numeric atomic update, and bitwise atomic update access
+ * modes are unsupported.
+ * <li>if the field type is anything other than {@code byte},
+ * {@code short}, {@code char}, {@code int}, {@code long},
+ * {@code float}, or {@code double} then numeric atomic update
+ * access modes are unsupported.
+ * <li>if the field type is anything other than {@code boolean},
+ * {@code byte}, {@code short}, {@code char}, {@code int} or
+ * {@code long} then bitwise atomic update access modes are
+ * unsupported.
+ * </ul>
+ * <p>
+ * If the field is declared {@code volatile} then the returned VarHandle
+ * will override access to the field (effectively ignore the
+ * {@code volatile} declaration) in accordance to its specified
+ * access modes.
+ * <p>
+ * If the field type is {@code float} or {@code double} then numeric
+ * and atomic update access modes compare values using their bitwise
+ * representation (see {@link Float#floatToRawIntBits} and
+ * {@link Double#doubleToRawLongBits}, respectively).
+ * @apiNote
+ * Bitwise comparison of {@code float} values or {@code double} values,
+ * as performed by the numeric and atomic update access modes, differ
+ * from the primitive {@code ==} operator and the {@link Float#equals}
+ * and {@link Double#equals} methods, specifically with respect to
+ * comparing NaN values or comparing {@code -0.0} with {@code +0.0}.
+ * Care should be taken when performing a compare and set or a compare
+ * and exchange operation with such values since the operation may
+ * unexpectedly fail.
+ * There are many possible NaN values that are considered to be
+ * {@code NaN} in Java, although no IEEE 754 floating-point operation
+ * provided by Java can distinguish between them. Operation failure can
+ * occur if the expected or witness value is a NaN value and it is
+ * transformed (perhaps in a platform specific manner) into another NaN
+ * value, and thus has a different bitwise representation (see
+ * {@link Float#intBitsToFloat} or {@link Double#longBitsToDouble} for more
+ * details).
+ * The values {@code -0.0} and {@code +0.0} have different bitwise
+ * representations but are considered equal when using the primitive
+ * {@code ==} operator. Operation failure can occur if, for example, a
+ * numeric algorithm computes an expected value to be say {@code -0.0}
+ * and previously computed the witness value to be say {@code +0.0}.
+ * @param f the reflected field, with a field of type {@code T}, and
+ * a declaring class of type {@code R}
+ * @return a VarHandle giving access to non-static fields or a static
+ * field
+ * @throws IllegalAccessException if access checking fails
+ * @throws NullPointerException if the argument is null
+ * @since 9
+ * @hide
+ */
+ public VarHandle unreflectVarHandle(Field f) throws IllegalAccessException {
+ final boolean isStatic = Modifier.isStatic(f.getModifiers());
+ final boolean performAccessChecks = true;
+ commonFieldChecks(f, f.getDeclaringClass(), f.getType(), isStatic, performAccessChecks);
+ return FieldVarHandle.create(f);
+ }
+ // END Android-changed: OpenJDK 9+181 VarHandle API factory method.
+
+ /**
+ * Cracks a <a href="MethodHandleInfo.html#directmh">direct method handle</a>
+ * created by this lookup object or a similar one.
+ * Security and access checks are performed to ensure that this lookup object
+ * is capable of reproducing the target method handle.
+ * This means that the cracking may fail if target is a direct method handle
+ * but was created by an unrelated lookup object.
+ * This can happen if the method handle is <a href="MethodHandles.Lookup.html#callsens">caller sensitive</a>
+ * and was created by a lookup object for a different class.
+ * @param target a direct method handle to crack into symbolic reference components
+ * @return a symbolic reference which can be used to reconstruct this method handle from this lookup object
+ * @exception SecurityException if a security manager is present and it
+ * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
+ * @throws IllegalArgumentException if the target is not a direct method handle or if access checking fails
+ * @exception NullPointerException if the target is {@code null}
+ * @see MethodHandleInfo
+ * @since 1.8
+ */
+ public MethodHandleInfo revealDirect(MethodHandle target) {
+ MethodHandleImpl directTarget = getMethodHandleImpl(target);
+ MethodHandleInfo info = directTarget.reveal();
+
+ try {
+ checkAccess(lookupClass(), info.getDeclaringClass(), info.getModifiers(),
+ info.getName());
+ } catch (IllegalAccessException exception) {
+ throw new IllegalArgumentException("Unable to access memeber.", exception);
+ }
+
+ return info;
+ }
+
+ private boolean hasPrivateAccess() {
+ return (allowedModes & PRIVATE) != 0;
+ }
+
+ /** Check public/protected/private bits on the symbolic reference class and its member. */
+ void checkAccess(Class<?> refc, Class<?> defc, int mods, String methName)
+ throws IllegalAccessException {
+ int allowedModes = this.allowedModes;
+
+ if (Modifier.isProtected(mods) &&
+ defc == Object.class &&
+ "clone".equals(methName) &&
+ refc.isArray()) {
+ // The JVM does this hack also.
+ // (See ClassVerifier::verify_invoke_instructions
+ // and LinkResolver::check_method_accessability.)
+ // Because the JVM does not allow separate methods on array types,
+ // there is no separate method for int[].clone.
+ // All arrays simply inherit Object.clone.
+ // But for access checking logic, we make Object.clone
+ // (normally protected) appear to be public.
+ // Later on, when the DirectMethodHandle is created,
+ // its leading argument will be restricted to the
+ // requested array type.
+ // N.B. The return type is not adjusted, because
+ // that is *not* the bytecode behavior.
+ mods ^= Modifier.PROTECTED | Modifier.PUBLIC;
+ }
+
+ if (Modifier.isProtected(mods) && Modifier.isConstructor(mods)) {
+ // cannot "new" a protected ctor in a different package
+ mods ^= Modifier.PROTECTED;
+ }
+
+ if (Modifier.isPublic(mods) && Modifier.isPublic(refc.getModifiers()) && allowedModes != 0)
+ return; // common case
+ int requestedModes = fixmods(mods); // adjust 0 => PACKAGE
+ if ((requestedModes & allowedModes) != 0) {
+ if (VerifyAccess.isMemberAccessible(refc, defc, mods, lookupClass(), allowedModes))
+ return;
+ } else {
+ // Protected members can also be checked as if they were package-private.
+ if ((requestedModes & PROTECTED) != 0 && (allowedModes & PACKAGE) != 0
+ && VerifyAccess.isSamePackage(defc, lookupClass()))
+ return;
+ }
+
+ throwMakeAccessException(accessFailedMessage(refc, defc, mods), this);
+ }
+
+ String accessFailedMessage(Class<?> refc, Class<?> defc, int mods) {
+ // check the class first:
+ boolean classOK = (Modifier.isPublic(defc.getModifiers()) &&
+ (defc == refc ||
+ Modifier.isPublic(refc.getModifiers())));
+ if (!classOK && (allowedModes & PACKAGE) != 0) {
+ classOK = (VerifyAccess.isClassAccessible(defc, lookupClass(), ALL_MODES) &&
+ (defc == refc ||
+ VerifyAccess.isClassAccessible(refc, lookupClass(), ALL_MODES)));
+ }
+ if (!classOK)
+ return "class is not public";
+ if (Modifier.isPublic(mods))
+ return "access to public member failed"; // (how?)
+ if (Modifier.isPrivate(mods))
+ return "member is private";
+ if (Modifier.isProtected(mods))
+ return "member is protected";
+ return "member is private to package";
+ }
+
+ // Android-changed: checkSpecialCaller assumes that ALLOW_NESTMATE_ACCESS = false,
+ // as in upstream OpenJDK.
+ //
+ // private static final boolean ALLOW_NESTMATE_ACCESS = false;
+
+ // Android-changed: Match java language 9 behavior allowing special access if the reflected
+ // class (called 'refc', the class from which the method is being accessed) is an interface
+ // and is implemented by the caller.
+ private void checkSpecialCaller(Class<?> specialCaller, Class<?> refc) throws IllegalAccessException {
+ // Android-changed: No support for TRUSTED lookups. Also construct the
+ // IllegalAccessException by hand because the upstream code implicitly assumes
+ // that the lookupClass == specialCaller.
+ //
+ // if (allowedModes == TRUSTED) return;
+ boolean isInterfaceLookup = (refc != null &&
+ refc.isInterface() &&
+ refc.isAssignableFrom(specialCaller));
+ if (!hasPrivateAccess() || (specialCaller != lookupClass() && !isInterfaceLookup)) {
+ throw new IllegalAccessException("no private access for invokespecial : "
+ + specialCaller + ", from" + this);
+ }
+ }
+
+ private void throwMakeAccessException(String message, Object from) throws
+ IllegalAccessException{
+ message = message + ": "+ toString();
+ if (from != null) message += ", from " + from;
+ throw new IllegalAccessException(message);
+ }
+
+ private void checkReturnType(Method method, MethodType methodType)
+ throws NoSuchMethodException {
+ if (method.getReturnType() != methodType.rtype()) {
+ throw new NoSuchMethodException(method.getName() + methodType);
+ }
+ }
+ }
+
+ /**
+ * "Cracks" {@code target} to reveal the underlying {@code MethodHandleImpl}.
+ */
+ private static MethodHandleImpl getMethodHandleImpl(MethodHandle target) {
+ // Special case : We implement handles to constructors as transformers,
+ // so we must extract the underlying handle from the transformer.
+ if (target instanceof Transformers.Construct) {
+ target = ((Transformers.Construct) target).getConstructorHandle();
+ }
+
+ // Special case: Var-args methods are also implemented as Transformers,
+ // so we should get the underlying handle in that case as well.
+ if (target instanceof Transformers.VarargsCollector) {
+ target = target.asFixedArity();
+ }
+
+ if (target instanceof MethodHandleImpl) {
+ return (MethodHandleImpl) target;
+ }
+
+ throw new IllegalArgumentException(target + " is not a direct handle");
+ }
+
+ // BEGIN Android-added: method to check if a class is an array.
+ private static void checkClassIsArray(Class<?> c) {
+ if (!c.isArray()) {
+ throw new IllegalArgumentException("Not an array type: " + c);
+ }
+ }
+
+ private static void checkTypeIsViewable(Class<?> componentType) {
+ if (componentType == short.class ||
+ componentType == char.class ||
+ componentType == int.class ||
+ componentType == long.class ||
+ componentType == float.class ||
+ componentType == double.class) {
+ return;
+ }
+ throw new UnsupportedOperationException("Component type not supported: " + componentType);
+ }
+ // END Android-added: method to check if a class is an array.
+
+ /**
+ * Produces a method handle giving read access to elements of an array.
+ * The type of the method handle will have a return type of the array's
+ * element type. Its first argument will be the array type,
+ * and the second will be {@code int}.
+ * @param arrayClass an array type
+ * @return a method handle which can load values from the given array type
+ * @throws NullPointerException if the argument is null
+ * @throws IllegalArgumentException if arrayClass is not an array type
+ */
+ public static
+ MethodHandle arrayElementGetter(Class<?> arrayClass) throws IllegalArgumentException {
+ checkClassIsArray(arrayClass);
+ final Class<?> componentType = arrayClass.getComponentType();
+ if (componentType.isPrimitive()) {
+ try {
+ return Lookup.PUBLIC_LOOKUP.findStatic(MethodHandles.class,
+ "arrayElementGetter",
+ MethodType.methodType(componentType, arrayClass, int.class));
+ } catch (NoSuchMethodException | IllegalAccessException exception) {
+ throw new AssertionError(exception);
+ }
+ }
+
+ return new Transformers.ReferenceArrayElementGetter(arrayClass);
+ }
+
+ /** @hide */ public static byte arrayElementGetter(byte[] array, int i) { return array[i]; }
+ /** @hide */ public static boolean arrayElementGetter(boolean[] array, int i) { return array[i]; }
+ /** @hide */ public static char arrayElementGetter(char[] array, int i) { return array[i]; }
+ /** @hide */ public static short arrayElementGetter(short[] array, int i) { return array[i]; }
+ /** @hide */ public static int arrayElementGetter(int[] array, int i) { return array[i]; }
+ /** @hide */ public static long arrayElementGetter(long[] array, int i) { return array[i]; }
+ /** @hide */ public static float arrayElementGetter(float[] array, int i) { return array[i]; }
+ /** @hide */ public static double arrayElementGetter(double[] array, int i) { return array[i]; }
+
+ /**
+ * Produces a method handle giving write access to elements of an array.
+ * The type of the method handle will have a void return type.
+ * Its last argument will be the array's element type.
+ * The first and second arguments will be the array type and int.
+ * @param arrayClass the class of an array
+ * @return a method handle which can store values into the array type
+ * @throws NullPointerException if the argument is null
+ * @throws IllegalArgumentException if arrayClass is not an array type
+ */
+ public static
+ MethodHandle arrayElementSetter(Class<?> arrayClass) throws IllegalArgumentException {
+ checkClassIsArray(arrayClass);
+ final Class<?> componentType = arrayClass.getComponentType();
+ if (componentType.isPrimitive()) {
+ try {
+ return Lookup.PUBLIC_LOOKUP.findStatic(MethodHandles.class,
+ "arrayElementSetter",
+ MethodType.methodType(void.class, arrayClass, int.class, componentType));
+ } catch (NoSuchMethodException | IllegalAccessException exception) {
+ throw new AssertionError(exception);
+ }
+ }
+
+ return new Transformers.ReferenceArrayElementSetter(arrayClass);
+ }
+
+ /** @hide */
+ public static void arrayElementSetter(byte[] array, int i, byte val) { array[i] = val; }
+ /** @hide */
+ public static void arrayElementSetter(boolean[] array, int i, boolean val) { array[i] = val; }
+ /** @hide */
+ public static void arrayElementSetter(char[] array, int i, char val) { array[i] = val; }
+ /** @hide */
+ public static void arrayElementSetter(short[] array, int i, short val) { array[i] = val; }
+ /** @hide */
+ public static void arrayElementSetter(int[] array, int i, int val) { array[i] = val; }
+ /** @hide */
+ public static void arrayElementSetter(long[] array, int i, long val) { array[i] = val; }
+ /** @hide */
+ public static void arrayElementSetter(float[] array, int i, float val) { array[i] = val; }
+ /** @hide */
+ public static void arrayElementSetter(double[] array, int i, double val) { array[i] = val; }
+
+ // BEGIN Android-changed: OpenJDK 9+181 VarHandle API factory methods.
+ /**
+ * Produces a VarHandle giving access to elements of an array of type
+ * {@code arrayClass}. The VarHandle's variable type is the component type
+ * of {@code arrayClass} and the list of coordinate types is
+ * {@code (arrayClass, int)}, where the {@code int} coordinate type
+ * corresponds to an argument that is an index into an array.
+ * <p>
+ * Certain access modes of the returned VarHandle are unsupported under
+ * the following conditions:
+ * <ul>
+ * <li>if the component type is anything other than {@code byte},
+ * {@code short}, {@code char}, {@code int}, {@code long},
+ * {@code float}, or {@code double} then numeric atomic update access
+ * modes are unsupported.
+ * <li>if the field type is anything other than {@code boolean},
+ * {@code byte}, {@code short}, {@code char}, {@code int} or
+ * {@code long} then bitwise atomic update access modes are
+ * unsupported.
+ * </ul>
+ * <p>
+ * If the component type is {@code float} or {@code double} then numeric
+ * and atomic update access modes compare values using their bitwise
+ * representation (see {@link Float#floatToRawIntBits} and
+ * {@link Double#doubleToRawLongBits}, respectively).
+ * @apiNote
+ * Bitwise comparison of {@code float} values or {@code double} values,
+ * as performed by the numeric and atomic update access modes, differ
+ * from the primitive {@code ==} operator and the {@link Float#equals}
+ * and {@link Double#equals} methods, specifically with respect to
+ * comparing NaN values or comparing {@code -0.0} with {@code +0.0}.
+ * Care should be taken when performing a compare and set or a compare
+ * and exchange operation with such values since the operation may
+ * unexpectedly fail.
+ * There are many possible NaN values that are considered to be
+ * {@code NaN} in Java, although no IEEE 754 floating-point operation
+ * provided by Java can distinguish between them. Operation failure can
+ * occur if the expected or witness value is a NaN value and it is
+ * transformed (perhaps in a platform specific manner) into another NaN
+ * value, and thus has a different bitwise representation (see
+ * {@link Float#intBitsToFloat} or {@link Double#longBitsToDouble} for more
+ * details).
+ * The values {@code -0.0} and {@code +0.0} have different bitwise
+ * representations but are considered equal when using the primitive
+ * {@code ==} operator. Operation failure can occur if, for example, a
+ * numeric algorithm computes an expected value to be say {@code -0.0}
+ * and previously computed the witness value to be say {@code +0.0}.
+ * @param arrayClass the class of an array, of type {@code T[]}
+ * @return a VarHandle giving access to elements of an array
+ * @throws NullPointerException if the arrayClass is null
+ * @throws IllegalArgumentException if arrayClass is not an array type
+ * @since 9
+ * @hide
+ */
+ public static
+ VarHandle arrayElementVarHandle(Class<?> arrayClass) throws IllegalArgumentException {
+ checkClassIsArray(arrayClass);
+ return ArrayElementVarHandle.create(arrayClass);
+ }
+
+ /**
+ * Produces a VarHandle giving access to elements of a {@code byte[]} array
+ * viewed as if it were a different primitive array type, such as
+ * {@code int[]} or {@code long[]}.
+ * The VarHandle's variable type is the component type of
+ * {@code viewArrayClass} and the list of coordinate types is
+ * {@code (byte[], int)}, where the {@code int} coordinate type
+ * corresponds to an argument that is an index into a {@code byte[]} array.
+ * The returned VarHandle accesses bytes at an index in a {@code byte[]}
+ * array, composing bytes to or from a value of the component type of
+ * {@code viewArrayClass} according to the given endianness.
+ * <p>
+ * The supported component types (variables types) are {@code short},
+ * {@code char}, {@code int}, {@code long}, {@code float} and
+ * {@code double}.
+ * <p>
+ * Access of bytes at a given index will result in an
+ * {@code IndexOutOfBoundsException} if the index is less than {@code 0}
+ * or greater than the {@code byte[]} array length minus the size (in bytes)
+ * of {@code T}.
+ * <p>
+ * Access of bytes at an index may be aligned or misaligned for {@code T},
+ * with respect to the underlying memory address, {@code A} say, associated
+ * with the array and index.
+ * If access is misaligned then access for anything other than the
+ * {@code get} and {@code set} access modes will result in an
+ * {@code IllegalStateException}. In such cases atomic access is only
+ * guaranteed with respect to the largest power of two that divides the GCD
+ * of {@code A} and the size (in bytes) of {@code T}.
+ * If access is aligned then following access modes are supported and are
+ * guaranteed to support atomic access:
+ * <ul>
+ * <li>read write access modes for all {@code T}, with the exception of
+ * access modes {@code get} and {@code set} for {@code long} and
+ * {@code double} on 32-bit platforms.
+ * <li>atomic update access modes for {@code int}, {@code long},
+ * {@code float} or {@code double}.
+ * (Future major platform releases of the JDK may support additional
+ * types for certain currently unsupported access modes.)
+ * <li>numeric atomic update access modes for {@code int} and {@code long}.
+ * (Future major platform releases of the JDK may support additional
+ * numeric types for certain currently unsupported access modes.)
+ * <li>bitwise atomic update access modes for {@code int} and {@code long}.
+ * (Future major platform releases of the JDK may support additional
+ * numeric types for certain currently unsupported access modes.)
+ * </ul>
+ * <p>
+ * Misaligned access, and therefore atomicity guarantees, may be determined
+ * for {@code byte[]} arrays without operating on a specific array. Given
+ * an {@code index}, {@code T} and it's corresponding boxed type,
+ * {@code T_BOX}, misalignment may be determined as follows:
+ * <pre>{@code
+ * int sizeOfT = T_BOX.BYTES; // size in bytes of T
+ * int misalignedAtZeroIndex = ByteBuffer.wrap(new byte[0]).
+ * alignmentOffset(0, sizeOfT);
+ * int misalignedAtIndex = (misalignedAtZeroIndex + index) % sizeOfT;
+ * boolean isMisaligned = misalignedAtIndex != 0;
+ * }</pre>
+ * <p>
+ * If the variable type is {@code float} or {@code double} then atomic
+ * update access modes compare values using their bitwise representation
+ * (see {@link Float#floatToRawIntBits} and
+ * {@link Double#doubleToRawLongBits}, respectively).
+ * @param viewArrayClass the view array class, with a component type of
+ * type {@code T}
+ * @param byteOrder the endianness of the view array elements, as
+ * stored in the underlying {@code byte} array
+ * @return a VarHandle giving access to elements of a {@code byte[]} array
+ * viewed as if elements corresponding to the components type of the view
+ * array class
+ * @throws NullPointerException if viewArrayClass or byteOrder is null
+ * @throws IllegalArgumentException if viewArrayClass is not an array type
+ * @throws UnsupportedOperationException if the component type of
+ * viewArrayClass is not supported as a variable type
+ * @since 9
+ * @hide
+ */
+ public static
+ VarHandle byteArrayViewVarHandle(Class<?> viewArrayClass,
+ ByteOrder byteOrder) throws IllegalArgumentException {
+ checkClassIsArray(viewArrayClass);
+ checkTypeIsViewable(viewArrayClass.getComponentType());
+ return ByteArrayViewVarHandle.create(viewArrayClass, byteOrder);
+ }
+
+ /**
+ * Produces a VarHandle giving access to elements of a {@code ByteBuffer}
+ * viewed as if it were an array of elements of a different primitive
+ * component type to that of {@code byte}, such as {@code int[]} or
+ * {@code long[]}.
+ * The VarHandle's variable type is the component type of
+ * {@code viewArrayClass} and the list of coordinate types is
+ * {@code (ByteBuffer, int)}, where the {@code int} coordinate type
+ * corresponds to an argument that is an index into a {@code byte[]} array.
+ * The returned VarHandle accesses bytes at an index in a
+ * {@code ByteBuffer}, composing bytes to or from a value of the component
+ * type of {@code viewArrayClass} according to the given endianness.
+ * <p>
+ * The supported component types (variables types) are {@code short},
+ * {@code char}, {@code int}, {@code long}, {@code float} and
+ * {@code double}.
+ * <p>
+ * Access will result in a {@code ReadOnlyBufferException} for anything
+ * other than the read access modes if the {@code ByteBuffer} is read-only.
+ * <p>
+ * Access of bytes at a given index will result in an
+ * {@code IndexOutOfBoundsException} if the index is less than {@code 0}
+ * or greater than the {@code ByteBuffer} limit minus the size (in bytes) of
+ * {@code T}.
+ * <p>
+ * Access of bytes at an index may be aligned or misaligned for {@code T},
+ * with respect to the underlying memory address, {@code A} say, associated
+ * with the {@code ByteBuffer} and index.
+ * If access is misaligned then access for anything other than the
+ * {@code get} and {@code set} access modes will result in an
+ * {@code IllegalStateException}. In such cases atomic access is only
+ * guaranteed with respect to the largest power of two that divides the GCD
+ * of {@code A} and the size (in bytes) of {@code T}.
+ * If access is aligned then following access modes are supported and are
+ * guaranteed to support atomic access:
+ * <ul>
+ * <li>read write access modes for all {@code T}, with the exception of
+ * access modes {@code get} and {@code set} for {@code long} and
+ * {@code double} on 32-bit platforms.
+ * <li>atomic update access modes for {@code int}, {@code long},
+ * {@code float} or {@code double}.
+ * (Future major platform releases of the JDK may support additional
+ * types for certain currently unsupported access modes.)
+ * <li>numeric atomic update access modes for {@code int} and {@code long}.
+ * (Future major platform releases of the JDK may support additional
+ * numeric types for certain currently unsupported access modes.)
+ * <li>bitwise atomic update access modes for {@code int} and {@code long}.
+ * (Future major platform releases of the JDK may support additional
+ * numeric types for certain currently unsupported access modes.)
+ * </ul>
+ * <p>
+ * Misaligned access, and therefore atomicity guarantees, may be determined
+ * for a {@code ByteBuffer}, {@code bb} (direct or otherwise), an
+ * {@code index}, {@code T} and it's corresponding boxed type,
+ * {@code T_BOX}, as follows:
+ * <pre>{@code
+ * int sizeOfT = T_BOX.BYTES; // size in bytes of T
+ * ByteBuffer bb = ...
+ * int misalignedAtIndex = bb.alignmentOffset(index, sizeOfT);
+ * boolean isMisaligned = misalignedAtIndex != 0;
+ * }</pre>
+ * <p>
+ * If the variable type is {@code float} or {@code double} then atomic
+ * update access modes compare values using their bitwise representation
+ * (see {@link Float#floatToRawIntBits} and
+ * {@link Double#doubleToRawLongBits}, respectively).
+ * @param viewArrayClass the view array class, with a component type of
+ * type {@code T}
+ * @param byteOrder the endianness of the view array elements, as
+ * stored in the underlying {@code ByteBuffer} (Note this overrides the
+ * endianness of a {@code ByteBuffer})
+ * @return a VarHandle giving access to elements of a {@code ByteBuffer}
+ * viewed as if elements corresponding to the components type of the view
+ * array class
+ * @throws NullPointerException if viewArrayClass or byteOrder is null
+ * @throws IllegalArgumentException if viewArrayClass is not an array type
+ * @throws UnsupportedOperationException if the component type of
+ * viewArrayClass is not supported as a variable type
+ * @since 9
+ * @hide
+ */
+ public static
+ VarHandle byteBufferViewVarHandle(Class<?> viewArrayClass,
+ ByteOrder byteOrder) throws IllegalArgumentException {
+ checkClassIsArray(viewArrayClass);
+ checkTypeIsViewable(viewArrayClass.getComponentType());
+ return ByteBufferViewVarHandle.create(viewArrayClass, byteOrder);
+ }
+ // END Android-changed: OpenJDK 9+181 VarHandle API factory methods.
+
+ /// method handle invocation (reflective style)
+
+ /**
+ * Produces a method handle which will invoke any method handle of the
+ * given {@code type}, with a given number of trailing arguments replaced by
+ * a single trailing {@code Object[]} array.
+ * The resulting invoker will be a method handle with the following
+ * arguments:
+ * <ul>
+ * <li>a single {@code MethodHandle} target
+ * <li>zero or more leading values (counted by {@code leadingArgCount})
+ * <li>an {@code Object[]} array containing trailing arguments
+ * </ul>
+ * <p>
+ * The invoker will invoke its target like a call to {@link MethodHandle#invoke invoke} with
+ * the indicated {@code type}.
+ * That is, if the target is exactly of the given {@code type}, it will behave
+ * like {@code invokeExact}; otherwise it behave as if {@link MethodHandle#asType asType}
+ * is used to convert the target to the required {@code type}.
+ * <p>
+ * The type of the returned invoker will not be the given {@code type}, but rather
+ * will have all parameters except the first {@code leadingArgCount}
+ * replaced by a single array of type {@code Object[]}, which will be
+ * the final parameter.
+ * <p>
+ * Before invoking its target, the invoker will spread the final array, apply
+ * reference casts as necessary, and unbox and widen primitive arguments.
+ * If, when the invoker is called, the supplied array argument does
+ * not have the correct number of elements, the invoker will throw
+ * an {@link IllegalArgumentException} instead of invoking the target.
+ * <p>
+ * This method is equivalent to the following code (though it may be more efficient):
+ * <blockquote><pre>{@code
+MethodHandle invoker = MethodHandles.invoker(type);
+int spreadArgCount = type.parameterCount() - leadingArgCount;
+invoker = invoker.asSpreader(Object[].class, spreadArgCount);
+return invoker;
+ * }</pre></blockquote>
+ * This method throws no reflective or security exceptions.
+ * @param type the desired target type
+ * @param leadingArgCount number of fixed arguments, to be passed unchanged to the target
+ * @return a method handle suitable for invoking any method handle of the given type
+ * @throws NullPointerException if {@code type} is null
+ * @throws IllegalArgumentException if {@code leadingArgCount} is not in
+ * the range from 0 to {@code type.parameterCount()} inclusive,
+ * or if the resulting method handle's type would have
+ * <a href="MethodHandle.html#maxarity">too many parameters</a>
+ */
+ static public
+ MethodHandle spreadInvoker(MethodType type, int leadingArgCount) {
+ if (leadingArgCount < 0 || leadingArgCount > type.parameterCount())
+ throw newIllegalArgumentException("bad argument count", leadingArgCount);
+
+ MethodHandle invoker = MethodHandles.invoker(type);
+ int spreadArgCount = type.parameterCount() - leadingArgCount;
+ invoker = invoker.asSpreader(Object[].class, spreadArgCount);
+ return invoker;
+ }
+
+ /**
+ * Produces a special <em>invoker method handle</em> which can be used to
+ * invoke any method handle of the given type, as if by {@link MethodHandle#invokeExact invokeExact}.
+ * The resulting invoker will have a type which is
+ * exactly equal to the desired type, except that it will accept
+ * an additional leading argument of type {@code MethodHandle}.
+ * <p>
+ * This method is equivalent to the following code (though it may be more efficient):
+ * {@code publicLookup().findVirtual(MethodHandle.class, "invokeExact", type)}
+ *
+ * <p style="font-size:smaller;">
+ * <em>Discussion:</em>
+ * Invoker method handles can be useful when working with variable method handles
+ * of unknown types.
+ * For example, to emulate an {@code invokeExact} call to a variable method
+ * handle {@code M}, extract its type {@code T},
+ * look up the invoker method {@code X} for {@code T},
+ * and call the invoker method, as {@code X.invoke(T, A...)}.
+ * (It would not work to call {@code X.invokeExact}, since the type {@code T}
+ * is unknown.)
+ * If spreading, collecting, or other argument transformations are required,
+ * they can be applied once to the invoker {@code X} and reused on many {@code M}
+ * method handle values, as long as they are compatible with the type of {@code X}.
+ * <p style="font-size:smaller;">
+ * <em>(Note: The invoker method is not available via the Core Reflection API.
+ * An attempt to call {@linkplain java.lang.reflect.Method#invoke java.lang.reflect.Method.invoke}
+ * on the declared {@code invokeExact} or {@code invoke} method will raise an
+ * {@link java.lang.UnsupportedOperationException UnsupportedOperationException}.)</em>
+ * <p>
+ * This method throws no reflective or security exceptions.
+ * @param type the desired target type
+ * @return a method handle suitable for invoking any method handle of the given type
+ * @throws IllegalArgumentException if the resulting method handle's type would have
+ * <a href="MethodHandle.html#maxarity">too many parameters</a>
+ */
+ static public
+ MethodHandle exactInvoker(MethodType type) {
+ return new Transformers.Invoker(type, true /* isExactInvoker */);
+ }
+
+ /**
+ * Produces a special <em>invoker method handle</em> which can be used to
+ * invoke any method handle compatible with the given type, as if by {@link MethodHandle#invoke invoke}.
+ * The resulting invoker will have a type which is
+ * exactly equal to the desired type, except that it will accept
+ * an additional leading argument of type {@code MethodHandle}.
+ * <p>
+ * Before invoking its target, if the target differs from the expected type,
+ * the invoker will apply reference casts as
+ * necessary and box, unbox, or widen primitive values, as if by {@link MethodHandle#asType asType}.
+ * Similarly, the return value will be converted as necessary.
+ * If the target is a {@linkplain MethodHandle#asVarargsCollector variable arity method handle},
+ * the required arity conversion will be made, again as if by {@link MethodHandle#asType asType}.
+ * <p>
+ * This method is equivalent to the following code (though it may be more efficient):
+ * {@code publicLookup().findVirtual(MethodHandle.class, "invoke", type)}
+ * <p style="font-size:smaller;">
+ * <em>Discussion:</em>
+ * A {@linkplain MethodType#genericMethodType general method type} is one which
+ * mentions only {@code Object} arguments and return values.
+ * An invoker for such a type is capable of calling any method handle
+ * of the same arity as the general type.
+ * <p style="font-size:smaller;">
+ * <em>(Note: The invoker method is not available via the Core Reflection API.
+ * An attempt to call {@linkplain java.lang.reflect.Method#invoke java.lang.reflect.Method.invoke}
+ * on the declared {@code invokeExact} or {@code invoke} method will raise an
+ * {@link java.lang.UnsupportedOperationException UnsupportedOperationException}.)</em>
+ * <p>
+ * This method throws no reflective or security exceptions.
+ * @param type the desired target type
+ * @return a method handle suitable for invoking any method handle convertible to the given type
+ * @throws IllegalArgumentException if the resulting method handle's type would have
+ * <a href="MethodHandle.html#maxarity">too many parameters</a>
+ */
+ static public
+ MethodHandle invoker(MethodType type) {
+ return new Transformers.Invoker(type, false /* isExactInvoker */);
+ }
+
+ // BEGIN Android-added: resolver for VarHandle accessor methods.
+ static private MethodHandle methodHandleForVarHandleAccessor(VarHandle.AccessMode accessMode,
+ MethodType type,
+ boolean isExactInvoker) {
+ Class<?> refc = VarHandle.class;
+ Method method;
+ try {
+ method = refc.getDeclaredMethod(accessMode.methodName(), Object[].class);
+ } catch (NoSuchMethodException e) {
+ throw new InternalError("No method for AccessMode " + accessMode, e);
+ }
+ MethodType methodType = type.insertParameterTypes(0, VarHandle.class);
+ int kind = isExactInvoker ? MethodHandle.INVOKE_VAR_HANDLE_EXACT
+ : MethodHandle.INVOKE_VAR_HANDLE;
+ return new MethodHandleImpl(method.getArtMethod(), kind, methodType);
+ }
+ // END Android-added: resolver for VarHandle accessor methods.
+
+ /**
+ * Produces a special <em>invoker method handle</em> which can be used to
+ * invoke a signature-polymorphic access mode method on any VarHandle whose
+ * associated access mode type is compatible with the given type.
+ * The resulting invoker will have a type which is exactly equal to the
+ * desired given type, except that it will accept an additional leading
+ * argument of type {@code VarHandle}.
+ *
+ * @param accessMode the VarHandle access mode
+ * @param type the desired target type
+ * @return a method handle suitable for invoking an access mode method of
+ * any VarHandle whose access mode type is of the given type.
+ * @since 9
+ * @hide
+ */
+ static public
+ MethodHandle varHandleExactInvoker(VarHandle.AccessMode accessMode, MethodType type) {
+ return methodHandleForVarHandleAccessor(accessMode, type, true /* isExactInvoker */);
+ }
+
+ /**
+ * Produces a special <em>invoker method handle</em> which can be used to
+ * invoke a signature-polymorphic access mode method on any VarHandle whose
+ * associated access mode type is compatible with the given type.
+ * The resulting invoker will have a type which is exactly equal to the
+ * desired given type, except that it will accept an additional leading
+ * argument of type {@code VarHandle}.
+ * <p>
+ * Before invoking its target, if the access mode type differs from the
+ * desired given type, the invoker will apply reference casts as necessary
+ * and box, unbox, or widen primitive values, as if by
+ * {@link MethodHandle#asType asType}. Similarly, the return value will be
+ * converted as necessary.
+ * <p>
+ * This method is equivalent to the following code (though it may be more
+ * efficient): {@code publicLookup().findVirtual(VarHandle.class, accessMode.name(), type)}
+ *
+ * @param accessMode the VarHandle access mode
+ * @param type the desired target type
+ * @return a method handle suitable for invoking an access mode method of
+ * any VarHandle whose access mode type is convertible to the given
+ * type.
+ * @since 9
+ * @hide
+ */
+ static public
+ MethodHandle varHandleInvoker(VarHandle.AccessMode accessMode, MethodType type) {
+ return methodHandleForVarHandleAccessor(accessMode, type, false /* isExactInvoker */);
+ }
+
+ // Android-changed: Basic invokers are not supported.
+ //
+ // static /*non-public*/
+ // MethodHandle basicInvoker(MethodType type) {
+ // return type.invokers().basicInvoker();
+ // }
+
+ /// method handle modification (creation from other method handles)
+
+ /**
+ * Produces a method handle which adapts the type of the
+ * given method handle to a new type by pairwise argument and return type conversion.
+ * The original type and new type must have the same number of arguments.
+ * The resulting method handle is guaranteed to report a type
+ * which is equal to the desired new type.
+ * <p>
+ * If the original type and new type are equal, returns target.
+ * <p>
+ * The same conversions are allowed as for {@link MethodHandle#asType MethodHandle.asType},
+ * and some additional conversions are also applied if those conversions fail.
+ * Given types <em>T0</em>, <em>T1</em>, one of the following conversions is applied
+ * if possible, before or instead of any conversions done by {@code asType}:
+ * <ul>
+ * <li>If <em>T0</em> and <em>T1</em> are references, and <em>T1</em> is an interface type,
+ * then the value of type <em>T0</em> is passed as a <em>T1</em> without a cast.
+ * (This treatment of interfaces follows the usage of the bytecode verifier.)
+ * <li>If <em>T0</em> is boolean and <em>T1</em> is another primitive,
+ * the boolean is converted to a byte value, 1 for true, 0 for false.
+ * (This treatment follows the usage of the bytecode verifier.)
+ * <li>If <em>T1</em> is boolean and <em>T0</em> is another primitive,
+ * <em>T0</em> is converted to byte via Java casting conversion (JLS 5.5),
+ * and the low order bit of the result is tested, as if by {@code (x & 1) != 0}.
+ * <li>If <em>T0</em> and <em>T1</em> are primitives other than boolean,
+ * then a Java casting conversion (JLS 5.5) is applied.
+ * (Specifically, <em>T0</em> will convert to <em>T1</em> by
+ * widening and/or narrowing.)
+ * <li>If <em>T0</em> is a reference and <em>T1</em> a primitive, an unboxing
+ * conversion will be applied at runtime, possibly followed
+ * by a Java casting conversion (JLS 5.5) on the primitive value,
+ * possibly followed by a conversion from byte to boolean by testing
+ * the low-order bit.
+ * <li>If <em>T0</em> is a reference and <em>T1</em> a primitive,
+ * and if the reference is null at runtime, a zero value is introduced.
+ * </ul>
+ * @param target the method handle to invoke after arguments are retyped
+ * @param newType the expected type of the new method handle
+ * @return a method handle which delegates to the target after performing
+ * any necessary argument conversions, and arranges for any
+ * necessary return value conversions
+ * @throws NullPointerException if either argument is null
+ * @throws WrongMethodTypeException if the conversion cannot be made
+ * @see MethodHandle#asType
+ */
+ public static
+ MethodHandle explicitCastArguments(MethodHandle target, MethodType newType) {
+ explicitCastArgumentsChecks(target, newType);
+ // use the asTypeCache when possible:
+ MethodType oldType = target.type();
+ if (oldType == newType) return target;
+ if (oldType.explicitCastEquivalentToAsType(newType)) {
+ if (Transformers.Transformer.class.isAssignableFrom(target.getClass())) {
+ // The StackFrameReader and StackFrameWriter used to perform transforms on
+ // EmulatedStackFrames (in Transformers.java) do not how to perform asType()
+ // conversions, but we know here that an explicit cast transform is the same as
+ // having called asType() on the method handle.
+ return new Transformers.ExplicitCastArguments(target.asFixedArity(), newType);
+ } else {
+ // Runtime will perform asType() conversion during invocation.
+ return target.asFixedArity().asType(newType);
+ }
+ }
+ return new Transformers.ExplicitCastArguments(target, newType);
+ }
+
+ private static void explicitCastArgumentsChecks(MethodHandle target, MethodType newType) {
+ if (target.type().parameterCount() != newType.parameterCount()) {
+ throw new WrongMethodTypeException("cannot explicitly cast " + target +
+ " to " + newType);
+ }
+ }
+
+ /**
+ * Produces a method handle which adapts the calling sequence of the
+ * given method handle to a new type, by reordering the arguments.
+ * The resulting method handle is guaranteed to report a type
+ * which is equal to the desired new type.
+ * <p>
+ * The given array controls the reordering.
+ * Call {@code #I} the number of incoming parameters (the value
+ * {@code newType.parameterCount()}, and call {@code #O} the number
+ * of outgoing parameters (the value {@code target.type().parameterCount()}).
+ * Then the length of the reordering array must be {@code #O},
+ * and each element must be a non-negative number less than {@code #I}.
+ * For every {@code N} less than {@code #O}, the {@code N}-th
+ * outgoing argument will be taken from the {@code I}-th incoming
+ * argument, where {@code I} is {@code reorder[N]}.
+ * <p>
+ * No argument or return value conversions are applied.
+ * The type of each incoming argument, as determined by {@code newType},
+ * must be identical to the type of the corresponding outgoing parameter
+ * or parameters in the target method handle.
+ * The return type of {@code newType} must be identical to the return
+ * type of the original target.
+ * <p>
+ * The reordering array need not specify an actual permutation.
+ * An incoming argument will be duplicated if its index appears
+ * more than once in the array, and an incoming argument will be dropped
+ * if its index does not appear in the array.
+ * As in the case of {@link #dropArguments(MethodHandle,int,List) dropArguments},
+ * incoming arguments which are not mentioned in the reordering array
+ * are may be any type, as determined only by {@code newType}.
+ * <blockquote><pre>{@code
+import static java.lang.invoke.MethodHandles.*;
+import static java.lang.invoke.MethodType.*;
+...
+MethodType intfn1 = methodType(int.class, int.class);
+MethodType intfn2 = methodType(int.class, int.class, int.class);
+MethodHandle sub = ... (int x, int y) -> (x-y) ...;
+assert(sub.type().equals(intfn2));
+MethodHandle sub1 = permuteArguments(sub, intfn2, 0, 1);
+MethodHandle rsub = permuteArguments(sub, intfn2, 1, 0);
+assert((int)rsub.invokeExact(1, 100) == 99);
+MethodHandle add = ... (int x, int y) -> (x+y) ...;
+assert(add.type().equals(intfn2));
+MethodHandle twice = permuteArguments(add, intfn1, 0, 0);
+assert(twice.type().equals(intfn1));
+assert((int)twice.invokeExact(21) == 42);
+ * }</pre></blockquote>
+ * @param target the method handle to invoke after arguments are reordered
+ * @param newType the expected type of the new method handle
+ * @param reorder an index array which controls the reordering
+ * @return a method handle which delegates to the target after it
+ * drops unused arguments and moves and/or duplicates the other arguments
+ * @throws NullPointerException if any argument is null
+ * @throws IllegalArgumentException if the index array length is not equal to
+ * the arity of the target, or if any index array element
+ * not a valid index for a parameter of {@code newType},
+ * or if two corresponding parameter types in
+ * {@code target.type()} and {@code newType} are not identical,
+ */
+ public static
+ MethodHandle permuteArguments(MethodHandle target, MethodType newType, int... reorder) {
+ reorder = reorder.clone(); // get a private copy
+ MethodType oldType = target.type();
+ permuteArgumentChecks(reorder, newType, oldType);
+
+ return new Transformers.PermuteArguments(newType, target, reorder);
+ }
+
+ // Android-changed: findFirstDupOrDrop is unused and removed.
+ // private static int findFirstDupOrDrop(int[] reorder, int newArity);
+
+ private static boolean permuteArgumentChecks(int[] reorder, MethodType newType, MethodType oldType) {
+ if (newType.returnType() != oldType.returnType())
+ throw newIllegalArgumentException("return types do not match",
+ oldType, newType);
+ if (reorder.length == oldType.parameterCount()) {
+ int limit = newType.parameterCount();
+ boolean bad = false;
+ for (int j = 0; j < reorder.length; j++) {
+ int i = reorder[j];
+ if (i < 0 || i >= limit) {
+ bad = true; break;
+ }
+ Class<?> src = newType.parameterType(i);
+ Class<?> dst = oldType.parameterType(j);
+ if (src != dst)
+ throw newIllegalArgumentException("parameter types do not match after reorder",
+ oldType, newType);
+ }
+ if (!bad) return true;
+ }
+ throw newIllegalArgumentException("bad reorder array: "+Arrays.toString(reorder));
+ }
+
+ /**
+ * Produces a method handle of the requested return type which returns the given
+ * constant value every time it is invoked.
+ * <p>
+ * Before the method handle is returned, the passed-in value is converted to the requested type.
+ * If the requested type is primitive, widening primitive conversions are attempted,
+ * else reference conversions are attempted.
+ * <p>The returned method handle is equivalent to {@code identity(type).bindTo(value)}.
+ * @param type the return type of the desired method handle
+ * @param value the value to return
+ * @return a method handle of the given return type and no arguments, which always returns the given value
+ * @throws NullPointerException if the {@code type} argument is null
+ * @throws ClassCastException if the value cannot be converted to the required return type
+ * @throws IllegalArgumentException if the given type is {@code void.class}
+ */
+ public static
+ MethodHandle constant(Class<?> type, Object value) {
+ if (type.isPrimitive()) {
+ if (type == void.class)
+ throw newIllegalArgumentException("void type");
+ Wrapper w = Wrapper.forPrimitiveType(type);
+ value = w.convert(value, type);
+ }
+
+ return new Transformers.Constant(type, value);
+ }
+
+ /**
+ * Produces a method handle which returns its sole argument when invoked.
+ * @param type the type of the sole parameter and return value of the desired method handle
+ * @return a unary method handle which accepts and returns the given type
+ * @throws NullPointerException if the argument is null
+ * @throws IllegalArgumentException if the given type is {@code void.class}
+ */
+ public static
+ MethodHandle identity(Class<?> type) {
+ if (type == null) {
+ throw new NullPointerException("type == null");
+ }
+
+ if (type.isPrimitive()) {
+ try {
+ return Lookup.PUBLIC_LOOKUP.findStatic(MethodHandles.class, "identity",
+ MethodType.methodType(type, type));
+ } catch (NoSuchMethodException | IllegalAccessException e) {
+ throw new AssertionError(e);
+ }
+ }
+
+ return new Transformers.ReferenceIdentity(type);
+ }
+
+ /** @hide */ public static byte identity(byte val) { return val; }
+ /** @hide */ public static boolean identity(boolean val) { return val; }
+ /** @hide */ public static char identity(char val) { return val; }
+ /** @hide */ public static short identity(short val) { return val; }
+ /** @hide */ public static int identity(int val) { return val; }
+ /** @hide */ public static long identity(long val) { return val; }
+ /** @hide */ public static float identity(float val) { return val; }
+ /** @hide */ public static double identity(double val) { return val; }
+
+ /**
+ * Provides a target method handle with one or more <em>bound arguments</em>
+ * in advance of the method handle's invocation.
+ * The formal parameters to the target corresponding to the bound
+ * arguments are called <em>bound parameters</em>.
+ * Returns a new method handle which saves away the bound arguments.
+ * When it is invoked, it receives arguments for any non-bound parameters,
+ * binds the saved arguments to their corresponding parameters,
+ * and calls the original target.
+ * <p>
+ * The type of the new method handle will drop the types for the bound
+ * parameters from the original target type, since the new method handle
+ * will no longer require those arguments to be supplied by its callers.
+ * <p>
+ * Each given argument object must match the corresponding bound parameter type.
+ * If a bound parameter type is a primitive, the argument object
+ * must be a wrapper, and will be unboxed to produce the primitive value.
+ * <p>
+ * The {@code pos} argument selects which parameters are to be bound.
+ * It may range between zero and <i>N-L</i> (inclusively),
+ * where <i>N</i> is the arity of the target method handle
+ * and <i>L</i> is the length of the values array.
+ * @param target the method handle to invoke after the argument is inserted
+ * @param pos where to insert the argument (zero for the first)
+ * @param values the series of arguments to insert
+ * @return a method handle which inserts an additional argument,
+ * before calling the original method handle
+ * @throws NullPointerException if the target or the {@code values} array is null
+ * @see MethodHandle#bindTo
+ */
+ public static
+ MethodHandle insertArguments(MethodHandle target, int pos, Object... values) {
+ int insCount = values.length;
+ Class<?>[] ptypes = insertArgumentsChecks(target, insCount, pos);
+ if (insCount == 0) {
+ return target;
+ }
+
+ // Throw ClassCastExceptions early if we can't cast any of the provided values
+ // to the required type.
+ for (int i = 0; i < insCount; i++) {
+ final Class<?> ptype = ptypes[pos + i];
+ if (!ptype.isPrimitive()) {
+ ptypes[pos + i].cast(values[i]);
+ } else {
+ // Will throw a ClassCastException if something terrible happens.
+ values[i] = Wrapper.forPrimitiveType(ptype).convert(values[i], ptype);
+ }
+ }
+
+ return new Transformers.InsertArguments(target, pos, values);
+ }
+
+ // Android-changed: insertArgumentPrimitive is unused.
+ //
+ // private static BoundMethodHandle insertArgumentPrimitive(BoundMethodHandle result, int pos,
+ // Class<?> ptype, Object value) {
+ // Wrapper w = Wrapper.forPrimitiveType(ptype);
+ // // perform unboxing and/or primitive conversion
+ // value = w.convert(value, ptype);
+ // switch (w) {
+ // case INT: return result.bindArgumentI(pos, (int)value);
+ // case LONG: return result.bindArgumentJ(pos, (long)value);
+ // case FLOAT: return result.bindArgumentF(pos, (float)value);
+ // case DOUBLE: return result.bindArgumentD(pos, (double)value);
+ // default: return result.bindArgumentI(pos, ValueConversions.widenSubword(value));
+ // }
+ // }
+
+ private static Class<?>[] insertArgumentsChecks(MethodHandle target, int insCount, int pos) throws RuntimeException {
+ MethodType oldType = target.type();
+ int outargs = oldType.parameterCount();
+ int inargs = outargs - insCount;
+ if (inargs < 0)
+ throw newIllegalArgumentException("too many values to insert");
+ if (pos < 0 || pos > inargs)
+ throw newIllegalArgumentException("no argument type to append");
+ return oldType.ptypes();
+ }
+
+ /**
+ * Produces a method handle which will discard some dummy arguments
+ * before calling some other specified <i>target</i> method handle.
+ * The type of the new method handle will be the same as the target's type,
+ * except it will also include the dummy argument types,
+ * at some given position.
+ * <p>
+ * The {@code pos} argument may range between zero and <i>N</i>,
+ * where <i>N</i> is the arity of the target.
+ * If {@code pos} is zero, the dummy arguments will precede
+ * the target's real arguments; if {@code pos} is <i>N</i>
+ * they will come after.
+ * <p>
+ * <b>Example:</b>
+ * <blockquote><pre>{@code
+import static java.lang.invoke.MethodHandles.*;
+import static java.lang.invoke.MethodType.*;
+...
+MethodHandle cat = lookup().findVirtual(String.class,
+ "concat", methodType(String.class, String.class));
+assertEquals("xy", (String) cat.invokeExact("x", "y"));
+MethodType bigType = cat.type().insertParameterTypes(0, int.class, String.class);
+MethodHandle d0 = dropArguments(cat, 0, bigType.parameterList().subList(0,2));
+assertEquals(bigType, d0.type());
+assertEquals("yz", (String) d0.invokeExact(123, "x", "y", "z"));
+ * }</pre></blockquote>
+ * <p>
+ * This method is also equivalent to the following code:
+ * <blockquote><pre>
+ * {@link #dropArguments(MethodHandle,int,Class...) dropArguments}{@code (target, pos, valueTypes.toArray(new Class[0]))}
+ * </pre></blockquote>
+ * @param target the method handle to invoke after the arguments are dropped
+ * @param valueTypes the type(s) of the argument(s) to drop
+ * @param pos position of first argument to drop (zero for the leftmost)
+ * @return a method handle which drops arguments of the given types,
+ * before calling the original method handle
+ * @throws NullPointerException if the target is null,
+ * or if the {@code valueTypes} list or any of its elements is null
+ * @throws IllegalArgumentException if any element of {@code valueTypes} is {@code void.class},
+ * or if {@code pos} is negative or greater than the arity of the target,
+ * or if the new method handle's type would have too many parameters
+ */
+ public static
+ MethodHandle dropArguments(MethodHandle target, int pos, List<Class<?>> valueTypes) {
+ valueTypes = copyTypes(valueTypes);
+ MethodType oldType = target.type(); // get NPE
+ int dropped = dropArgumentChecks(oldType, pos, valueTypes);
+
+ MethodType newType = oldType.insertParameterTypes(pos, valueTypes);
+ if (dropped == 0) {
+ return target;
+ }
+
+ return new Transformers.DropArguments(newType, target, pos, valueTypes.size());
+ }
+
+ private static List<Class<?>> copyTypes(List<Class<?>> types) {
+ Object[] a = types.toArray();
+ return Arrays.asList(Arrays.copyOf(a, a.length, Class[].class));
+ }
+
+ private static int dropArgumentChecks(MethodType oldType, int pos, List<Class<?>> valueTypes) {
+ int dropped = valueTypes.size();
+ MethodType.checkSlotCount(dropped);
+ int outargs = oldType.parameterCount();
+ int inargs = outargs + dropped;
+ if (pos < 0 || pos > outargs)
+ throw newIllegalArgumentException("no argument type to remove"
+ + Arrays.asList(oldType, pos, valueTypes, inargs, outargs)
+ );
+ return dropped;
+ }
+
+ /**
+ * Produces a method handle which will discard some dummy arguments
+ * before calling some other specified <i>target</i> method handle.
+ * The type of the new method handle will be the same as the target's type,
+ * except it will also include the dummy argument types,
+ * at some given position.
+ * <p>
+ * The {@code pos} argument may range between zero and <i>N</i>,
+ * where <i>N</i> is the arity of the target.
+ * If {@code pos} is zero, the dummy arguments will precede
+ * the target's real arguments; if {@code pos} is <i>N</i>
+ * they will come after.
+ * <p>
+ * <b>Example:</b>
+ * <blockquote><pre>{@code
+import static java.lang.invoke.MethodHandles.*;
+import static java.lang.invoke.MethodType.*;
+...
+MethodHandle cat = lookup().findVirtual(String.class,
+ "concat", methodType(String.class, String.class));
+assertEquals("xy", (String) cat.invokeExact("x", "y"));
+MethodHandle d0 = dropArguments(cat, 0, String.class);
+assertEquals("yz", (String) d0.invokeExact("x", "y", "z"));
+MethodHandle d1 = dropArguments(cat, 1, String.class);
+assertEquals("xz", (String) d1.invokeExact("x", "y", "z"));
+MethodHandle d2 = dropArguments(cat, 2, String.class);
+assertEquals("xy", (String) d2.invokeExact("x", "y", "z"));
+MethodHandle d12 = dropArguments(cat, 1, int.class, boolean.class);
+assertEquals("xz", (String) d12.invokeExact("x", 12, true, "z"));
+ * }</pre></blockquote>
+ * <p>
+ * This method is also equivalent to the following code:
+ * <blockquote><pre>
+ * {@link #dropArguments(MethodHandle,int,List) dropArguments}{@code (target, pos, Arrays.asList(valueTypes))}
+ * </pre></blockquote>
+ * @param target the method handle to invoke after the arguments are dropped
+ * @param valueTypes the type(s) of the argument(s) to drop
+ * @param pos position of first argument to drop (zero for the leftmost)
+ * @return a method handle which drops arguments of the given types,
+ * before calling the original method handle
+ * @throws NullPointerException if the target is null,
+ * or if the {@code valueTypes} array or any of its elements is null
+ * @throws IllegalArgumentException if any element of {@code valueTypes} is {@code void.class},
+ * or if {@code pos} is negative or greater than the arity of the target,
+ * or if the new method handle's type would have
+ * <a href="MethodHandle.html#maxarity">too many parameters</a>
+ */
+ public static
+ MethodHandle dropArguments(MethodHandle target, int pos, Class<?>... valueTypes) {
+ return dropArguments(target, pos, Arrays.asList(valueTypes));
+ }
+
+ /**
+ * Adapts a target method handle by pre-processing
+ * one or more of its arguments, each with its own unary filter function,
+ * and then calling the target with each pre-processed argument
+ * replaced by the result of its corresponding filter function.
+ * <p>
+ * The pre-processing is performed by one or more method handles,
+ * specified in the elements of the {@code filters} array.
+ * The first element of the filter array corresponds to the {@code pos}
+ * argument of the target, and so on in sequence.
+ * <p>
+ * Null arguments in the array are treated as identity functions,
+ * and the corresponding arguments left unchanged.
+ * (If there are no non-null elements in the array, the original target is returned.)
+ * Each filter is applied to the corresponding argument of the adapter.
+ * <p>
+ * If a filter {@code F} applies to the {@code N}th argument of
+ * the target, then {@code F} must be a method handle which
+ * takes exactly one argument. The type of {@code F}'s sole argument
+ * replaces the corresponding argument type of the target
+ * in the resulting adapted method handle.
+ * The return type of {@code F} must be identical to the corresponding
+ * parameter type of the target.
+ * <p>
+ * It is an error if there are elements of {@code filters}
+ * (null or not)
+ * which do not correspond to argument positions in the target.
+ * <p><b>Example:</b>
+ * <blockquote><pre>{@code
+import static java.lang.invoke.MethodHandles.*;
+import static java.lang.invoke.MethodType.*;
+...
+MethodHandle cat = lookup().findVirtual(String.class,
+ "concat", methodType(String.class, String.class));
+MethodHandle upcase = lookup().findVirtual(String.class,
+ "toUpperCase", methodType(String.class));
+assertEquals("xy", (String) cat.invokeExact("x", "y"));
+MethodHandle f0 = filterArguments(cat, 0, upcase);
+assertEquals("Xy", (String) f0.invokeExact("x", "y")); // Xy
+MethodHandle f1 = filterArguments(cat, 1, upcase);
+assertEquals("xY", (String) f1.invokeExact("x", "y")); // xY
+MethodHandle f2 = filterArguments(cat, 0, upcase, upcase);
+assertEquals("XY", (String) f2.invokeExact("x", "y")); // XY
+ * }</pre></blockquote>
+ * <p> Here is pseudocode for the resulting adapter:
+ * <blockquote><pre>{@code
+ * V target(P... p, A[i]... a[i], B... b);
+ * A[i] filter[i](V[i]);
+ * T adapter(P... p, V[i]... v[i], B... b) {
+ * return target(p..., f[i](v[i])..., b...);
+ * }
+ * }</pre></blockquote>
+ *
+ * @param target the method handle to invoke after arguments are filtered
+ * @param pos the position of the first argument to filter
+ * @param filters method handles to call initially on filtered arguments
+ * @return method handle which incorporates the specified argument filtering logic
+ * @throws NullPointerException if the target is null
+ * or if the {@code filters} array is null
+ * @throws IllegalArgumentException if a non-null element of {@code filters}
+ * does not match a corresponding argument type of target as described above,
+ * or if the {@code pos+filters.length} is greater than {@code target.type().parameterCount()},
+ * or if the resulting method handle's type would have
+ * <a href="MethodHandle.html#maxarity">too many parameters</a>
+ */
+ public static
+ MethodHandle filterArguments(MethodHandle target, int pos, MethodHandle... filters) {
+ filterArgumentsCheckArity(target, pos, filters);
+
+ for (int i = 0; i < filters.length; ++i) {
+ filterArgumentChecks(target, i + pos, filters[i]);
+ }
+
+ return new Transformers.FilterArguments(target, pos, filters);
+ }
+
+ private static void filterArgumentsCheckArity(MethodHandle target, int pos, MethodHandle[] filters) {
+ MethodType targetType = target.type();
+ int maxPos = targetType.parameterCount();
+ if (pos + filters.length > maxPos)
+ throw newIllegalArgumentException("too many filters");
+ }
+
+ private static void filterArgumentChecks(MethodHandle target, int pos, MethodHandle filter) throws RuntimeException {
+ MethodType targetType = target.type();
+ MethodType filterType = filter.type();
+ if (filterType.parameterCount() != 1
+ || filterType.returnType() != targetType.parameterType(pos))
+ throw newIllegalArgumentException("target and filter types do not match", targetType, filterType);
+ }
+
+ /**
+ * Adapts a target method handle by pre-processing
+ * a sub-sequence of its arguments with a filter (another method handle).
+ * The pre-processed arguments are replaced by the result (if any) of the
+ * filter function.
+ * The target is then called on the modified (usually shortened) argument list.
+ * <p>
+ * If the filter returns a value, the target must accept that value as
+ * its argument in position {@code pos}, preceded and/or followed by
+ * any arguments not passed to the filter.
+ * If the filter returns void, the target must accept all arguments
+ * not passed to the filter.
+ * No arguments are reordered, and a result returned from the filter
+ * replaces (in order) the whole subsequence of arguments originally
+ * passed to the adapter.
+ * <p>
+ * The argument types (if any) of the filter
+ * replace zero or one argument types of the target, at position {@code pos},
+ * in the resulting adapted method handle.
+ * The return type of the filter (if any) must be identical to the
+ * argument type of the target at position {@code pos}, and that target argument
+ * is supplied by the return value of the filter.
+ * <p>
+ * In all cases, {@code pos} must be greater than or equal to zero, and
+ * {@code pos} must also be less than or equal to the target's arity.
+ * <p><b>Example:</b>
+ * <blockquote><pre>{@code
+import static java.lang.invoke.MethodHandles.*;
+import static java.lang.invoke.MethodType.*;
+...
+MethodHandle deepToString = publicLookup()
+ .findStatic(Arrays.class, "deepToString", methodType(String.class, Object[].class));
+
+MethodHandle ts1 = deepToString.asCollector(String[].class, 1);
+assertEquals("[strange]", (String) ts1.invokeExact("strange"));
+
+MethodHandle ts2 = deepToString.asCollector(String[].class, 2);
+assertEquals("[up, down]", (String) ts2.invokeExact("up", "down"));
+
+MethodHandle ts3 = deepToString.asCollector(String[].class, 3);
+MethodHandle ts3_ts2 = collectArguments(ts3, 1, ts2);
+assertEquals("[top, [up, down], strange]",
+ (String) ts3_ts2.invokeExact("top", "up", "down", "strange"));
+
+MethodHandle ts3_ts2_ts1 = collectArguments(ts3_ts2, 3, ts1);
+assertEquals("[top, [up, down], [strange]]",
+ (String) ts3_ts2_ts1.invokeExact("top", "up", "down", "strange"));
+
+MethodHandle ts3_ts2_ts3 = collectArguments(ts3_ts2, 1, ts3);
+assertEquals("[top, [[up, down, strange], charm], bottom]",
+ (String) ts3_ts2_ts3.invokeExact("top", "up", "down", "strange", "charm", "bottom"));
+ * }</pre></blockquote>
+ * <p> Here is pseudocode for the resulting adapter:
+ * <blockquote><pre>{@code
+ * T target(A...,V,C...);
+ * V filter(B...);
+ * T adapter(A... a,B... b,C... c) {
+ * V v = filter(b...);
+ * return target(a...,v,c...);
+ * }
+ * // and if the filter has no arguments:
+ * T target2(A...,V,C...);
+ * V filter2();
+ * T adapter2(A... a,C... c) {
+ * V v = filter2();
+ * return target2(a...,v,c...);
+ * }
+ * // and if the filter has a void return:
+ * T target3(A...,C...);
+ * void filter3(B...);
+ * void adapter3(A... a,B... b,C... c) {
+ * filter3(b...);
+ * return target3(a...,c...);
+ * }
+ * }</pre></blockquote>
+ * <p>
+ * A collection adapter {@code collectArguments(mh, 0, coll)} is equivalent to
+ * one which first "folds" the affected arguments, and then drops them, in separate
+ * steps as follows:
+ * <blockquote><pre>{@code
+ * mh = MethodHandles.dropArguments(mh, 1, coll.type().parameterList()); //step 2
+ * mh = MethodHandles.foldArguments(mh, coll); //step 1
+ * }</pre></blockquote>
+ * If the target method handle consumes no arguments besides than the result
+ * (if any) of the filter {@code coll}, then {@code collectArguments(mh, 0, coll)}
+ * is equivalent to {@code filterReturnValue(coll, mh)}.
+ * If the filter method handle {@code coll} consumes one argument and produces
+ * a non-void result, then {@code collectArguments(mh, N, coll)}
+ * is equivalent to {@code filterArguments(mh, N, coll)}.
+ * Other equivalences are possible but would require argument permutation.
+ *
+ * @param target the method handle to invoke after filtering the subsequence of arguments
+ * @param pos the position of the first adapter argument to pass to the filter,
+ * and/or the target argument which receives the result of the filter
+ * @param filter method handle to call on the subsequence of arguments
+ * @return method handle which incorporates the specified argument subsequence filtering logic
+ * @throws NullPointerException if either argument is null
+ * @throws IllegalArgumentException if the return type of {@code filter}
+ * is non-void and is not the same as the {@code pos} argument of the target,
+ * or if {@code pos} is not between 0 and the target's arity, inclusive,
+ * or if the resulting method handle's type would have
+ * <a href="MethodHandle.html#maxarity">too many parameters</a>
+ * @see MethodHandles#foldArguments
+ * @see MethodHandles#filterArguments
+ * @see MethodHandles#filterReturnValue
+ */
+ public static
+ MethodHandle collectArguments(MethodHandle target, int pos, MethodHandle filter) {
+ MethodType newType = collectArgumentsChecks(target, pos, filter);
+ return new Transformers.CollectArguments(target, filter, pos, newType);
+ }
+
+ private static MethodType collectArgumentsChecks(MethodHandle target, int pos, MethodHandle filter) throws RuntimeException {
+ MethodType targetType = target.type();
+ MethodType filterType = filter.type();
+ Class<?> rtype = filterType.returnType();
+ List<Class<?>> filterArgs = filterType.parameterList();
+ if (rtype == void.class) {
+ return targetType.insertParameterTypes(pos, filterArgs);
+ }
+ if (rtype != targetType.parameterType(pos)) {
+ throw newIllegalArgumentException("target and filter types do not match", targetType, filterType);
+ }
+ return targetType.dropParameterTypes(pos, pos+1).insertParameterTypes(pos, filterArgs);
+ }
+
+ /**
+ * Adapts a target method handle by post-processing
+ * its return value (if any) with a filter (another method handle).
+ * The result of the filter is returned from the adapter.
+ * <p>
+ * If the target returns a value, the filter must accept that value as
+ * its only argument.
+ * If the target returns void, the filter must accept no arguments.
+ * <p>
+ * The return type of the filter
+ * replaces the return type of the target
+ * in the resulting adapted method handle.
+ * The argument type of the filter (if any) must be identical to the
+ * return type of the target.
+ * <p><b>Example:</b>
+ * <blockquote><pre>{@code
+import static java.lang.invoke.MethodHandles.*;
+import static java.lang.invoke.MethodType.*;
+...
+MethodHandle cat = lookup().findVirtual(String.class,
+ "concat", methodType(String.class, String.class));
+MethodHandle length = lookup().findVirtual(String.class,
+ "length", methodType(int.class));
+System.out.println((String) cat.invokeExact("x", "y")); // xy
+MethodHandle f0 = filterReturnValue(cat, length);
+System.out.println((int) f0.invokeExact("x", "y")); // 2
+ * }</pre></blockquote>
+ * <p> Here is pseudocode for the resulting adapter:
+ * <blockquote><pre>{@code
+ * V target(A...);
+ * T filter(V);
+ * T adapter(A... a) {
+ * V v = target(a...);
+ * return filter(v);
+ * }
+ * // and if the target has a void return:
+ * void target2(A...);
+ * T filter2();
+ * T adapter2(A... a) {
+ * target2(a...);
+ * return filter2();
+ * }
+ * // and if the filter has a void return:
+ * V target3(A...);
+ * void filter3(V);
+ * void adapter3(A... a) {
+ * V v = target3(a...);
+ * filter3(v);
+ * }
+ * }</pre></blockquote>
+ * @param target the method handle to invoke before filtering the return value
+ * @param filter method handle to call on the return value
+ * @return method handle which incorporates the specified return value filtering logic
+ * @throws NullPointerException if either argument is null
+ * @throws IllegalArgumentException if the argument list of {@code filter}
+ * does not match the return type of target as described above
+ */
+ public static
+ MethodHandle filterReturnValue(MethodHandle target, MethodHandle filter) {
+ MethodType targetType = target.type();
+ MethodType filterType = filter.type();
+ filterReturnValueChecks(targetType, filterType);
+
+ return new Transformers.FilterReturnValue(target, filter);
+ }
+
+ private static void filterReturnValueChecks(MethodType targetType, MethodType filterType) throws RuntimeException {
+ Class<?> rtype = targetType.returnType();
+ int filterValues = filterType.parameterCount();
+ if (filterValues == 0
+ ? (rtype != void.class)
+ : (rtype != filterType.parameterType(0) || filterValues != 1))
+ throw newIllegalArgumentException("target and filter types do not match", targetType, filterType);
+ }
+
+ /**
+ * Adapts a target method handle by pre-processing
+ * some of its arguments, and then calling the target with
+ * the result of the pre-processing, inserted into the original
+ * sequence of arguments.
+ * <p>
+ * The pre-processing is performed by {@code combiner}, a second method handle.
+ * Of the arguments passed to the adapter, the first {@code N} arguments
+ * are copied to the combiner, which is then called.
+ * (Here, {@code N} is defined as the parameter count of the combiner.)
+ * After this, control passes to the target, with any result
+ * from the combiner inserted before the original {@code N} incoming
+ * arguments.
+ * <p>
+ * If the combiner returns a value, the first parameter type of the target
+ * must be identical with the return type of the combiner, and the next
+ * {@code N} parameter types of the target must exactly match the parameters
+ * of the combiner.
+ * <p>
+ * If the combiner has a void return, no result will be inserted,
+ * and the first {@code N} parameter types of the target
+ * must exactly match the parameters of the combiner.
+ * <p>
+ * The resulting adapter is the same type as the target, except that the
+ * first parameter type is dropped,
+ * if it corresponds to the result of the combiner.
+ * <p>
+ * (Note that {@link #dropArguments(MethodHandle,int,List) dropArguments} can be used to remove any arguments
+ * that either the combiner or the target does not wish to receive.
+ * If some of the incoming arguments are destined only for the combiner,
+ * consider using {@link MethodHandle#asCollector asCollector} instead, since those
+ * arguments will not need to be live on the stack on entry to the
+ * target.)
+ * <p><b>Example:</b>
+ * <blockquote><pre>{@code
+import static java.lang.invoke.MethodHandles.*;
+import static java.lang.invoke.MethodType.*;
+...
+MethodHandle trace = publicLookup().findVirtual(java.io.PrintStream.class,
+ "println", methodType(void.class, String.class))
+ .bindTo(System.out);
+MethodHandle cat = lookup().findVirtual(String.class,
+ "concat", methodType(String.class, String.class));
+assertEquals("boojum", (String) cat.invokeExact("boo", "jum"));
+MethodHandle catTrace = foldArguments(cat, trace);
+// also prints "boo":
+assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
+ * }</pre></blockquote>
+ * <p> Here is pseudocode for the resulting adapter:
+ * <blockquote><pre>{@code
+ * // there are N arguments in A...
+ * T target(V, A[N]..., B...);
+ * V combiner(A...);
+ * T adapter(A... a, B... b) {
+ * V v = combiner(a...);
+ * return target(v, a..., b...);
+ * }
+ * // and if the combiner has a void return:
+ * T target2(A[N]..., B...);
+ * void combiner2(A...);
+ * T adapter2(A... a, B... b) {
+ * combiner2(a...);
+ * return target2(a..., b...);
+ * }
+ * }</pre></blockquote>
+ * @param target the method handle to invoke after arguments are combined
+ * @param combiner method handle to call initially on the incoming arguments
+ * @return method handle which incorporates the specified argument folding logic
+ * @throws NullPointerException if either argument is null
+ * @throws IllegalArgumentException if {@code combiner}'s return type
+ * is non-void and not the same as the first argument type of
+ * the target, or if the initial {@code N} argument types
+ * of the target
+ * (skipping one matching the {@code combiner}'s return type)
+ * are not identical with the argument types of {@code combiner}
+ */
+ public static
+ MethodHandle foldArguments(MethodHandle target, MethodHandle combiner) {
+ int foldPos = 0;
+ MethodType targetType = target.type();
+ MethodType combinerType = combiner.type();
+ Class<?> rtype = foldArgumentChecks(foldPos, targetType, combinerType);
+
+ return new Transformers.FoldArguments(target, combiner);
+ }
+
+ private static Class<?> foldArgumentChecks(int foldPos, MethodType targetType, MethodType combinerType) {
+ int foldArgs = combinerType.parameterCount();
+ Class<?> rtype = combinerType.returnType();
+ int foldVals = rtype == void.class ? 0 : 1;
+ int afterInsertPos = foldPos + foldVals;
+ boolean ok = (targetType.parameterCount() >= afterInsertPos + foldArgs);
+ if (ok && !(combinerType.parameterList()
+ .equals(targetType.parameterList().subList(afterInsertPos,
+ afterInsertPos + foldArgs))))
+ ok = false;
+ if (ok && foldVals != 0 && combinerType.returnType() != targetType.parameterType(0))
+ ok = false;
+ if (!ok)
+ throw misMatchedTypes("target and combiner types", targetType, combinerType);
+ return rtype;
+ }
+
+ /**
+ * Makes a method handle which adapts a target method handle,
+ * by guarding it with a test, a boolean-valued method handle.
+ * If the guard fails, a fallback handle is called instead.
+ * All three method handles must have the same corresponding
+ * argument and return types, except that the return type
+ * of the test must be boolean, and the test is allowed
+ * to have fewer arguments than the other two method handles.
+ * <p> Here is pseudocode for the resulting adapter:
+ * <blockquote><pre>{@code
+ * boolean test(A...);
+ * T target(A...,B...);
+ * T fallback(A...,B...);
+ * T adapter(A... a,B... b) {
+ * if (test(a...))
+ * return target(a..., b...);
+ * else
+ * return fallback(a..., b...);
+ * }
+ * }</pre></blockquote>
+ * Note that the test arguments ({@code a...} in the pseudocode) cannot
+ * be modified by execution of the test, and so are passed unchanged
+ * from the caller to the target or fallback as appropriate.
+ * @param test method handle used for test, must return boolean
+ * @param target method handle to call if test passes
+ * @param fallback method handle to call if test fails
+ * @return method handle which incorporates the specified if/then/else logic
+ * @throws NullPointerException if any argument is null
+ * @throws IllegalArgumentException if {@code test} does not return boolean,
+ * or if all three method types do not match (with the return
+ * type of {@code test} changed to match that of the target).
+ */
+ public static
+ MethodHandle guardWithTest(MethodHandle test,
+ MethodHandle target,
+ MethodHandle fallback) {
+ MethodType gtype = test.type();
+ MethodType ttype = target.type();
+ MethodType ftype = fallback.type();
+ if (!ttype.equals(ftype))
+ throw misMatchedTypes("target and fallback types", ttype, ftype);
+ if (gtype.returnType() != boolean.class)
+ throw newIllegalArgumentException("guard type is not a predicate "+gtype);
+ List<Class<?>> targs = ttype.parameterList();
+ List<Class<?>> gargs = gtype.parameterList();
+ if (!targs.equals(gargs)) {
+ int gpc = gargs.size(), tpc = targs.size();
+ if (gpc >= tpc || !targs.subList(0, gpc).equals(gargs))
+ throw misMatchedTypes("target and test types", ttype, gtype);
+ test = dropArguments(test, gpc, targs.subList(gpc, tpc));
+ gtype = test.type();
+ }
+
+ return new Transformers.GuardWithTest(test, target, fallback);
+ }
+
+ static RuntimeException misMatchedTypes(String what, MethodType t1, MethodType t2) {
+ return newIllegalArgumentException(what + " must match: " + t1 + " != " + t2);
+ }
+
+ /**
+ * Makes a method handle which adapts a target method handle,
+ * by running it inside an exception handler.
+ * If the target returns normally, the adapter returns that value.
+ * If an exception matching the specified type is thrown, the fallback
+ * handle is called instead on the exception, plus the original arguments.
+ * <p>
+ * The target and handler must have the same corresponding
+ * argument and return types, except that handler may omit trailing arguments
+ * (similarly to the predicate in {@link #guardWithTest guardWithTest}).
+ * Also, the handler must have an extra leading parameter of {@code exType} or a supertype.
+ * <p> Here is pseudocode for the resulting adapter:
+ * <blockquote><pre>{@code
+ * T target(A..., B...);
+ * T handler(ExType, A...);
+ * T adapter(A... a, B... b) {
+ * try {
+ * return target(a..., b...);
+ * } catch (ExType ex) {
+ * return handler(ex, a...);
+ * }
+ * }
+ * }</pre></blockquote>
+ * Note that the saved arguments ({@code a...} in the pseudocode) cannot
+ * be modified by execution of the target, and so are passed unchanged
+ * from the caller to the handler, if the handler is invoked.
+ * <p>
+ * The target and handler must return the same type, even if the handler
+ * always throws. (This might happen, for instance, because the handler
+ * is simulating a {@code finally} clause).
+ * To create such a throwing handler, compose the handler creation logic
+ * with {@link #throwException throwException},
+ * in order to create a method handle of the correct return type.
+ * @param target method handle to call
+ * @param exType the type of exception which the handler will catch
+ * @param handler method handle to call if a matching exception is thrown
+ * @return method handle which incorporates the specified try/catch logic
+ * @throws NullPointerException if any argument is null
+ * @throws IllegalArgumentException if {@code handler} does not accept
+ * the given exception type, or if the method handle types do
+ * not match in their return types and their
+ * corresponding parameters
+ */
+ public static
+ MethodHandle catchException(MethodHandle target,
+ Class<? extends Throwable> exType,
+ MethodHandle handler) {
+ MethodType ttype = target.type();
+ MethodType htype = handler.type();
+ if (htype.parameterCount() < 1 ||
+ !htype.parameterType(0).isAssignableFrom(exType))
+ throw newIllegalArgumentException("handler does not accept exception type "+exType);
+ if (htype.returnType() != ttype.returnType())
+ throw misMatchedTypes("target and handler return types", ttype, htype);
+ List<Class<?>> targs = ttype.parameterList();
+ List<Class<?>> hargs = htype.parameterList();
+ hargs = hargs.subList(1, hargs.size()); // omit leading parameter from handler
+ if (!targs.equals(hargs)) {
+ int hpc = hargs.size(), tpc = targs.size();
+ if (hpc >= tpc || !targs.subList(0, hpc).equals(hargs))
+ throw misMatchedTypes("target and handler types", ttype, htype);
+ }
+
+ return new Transformers.CatchException(target, handler, exType);
+ }
+
+ /**
+ * Produces a method handle which will throw exceptions of the given {@code exType}.
+ * The method handle will accept a single argument of {@code exType},
+ * and immediately throw it as an exception.
+ * The method type will nominally specify a return of {@code returnType}.
+ * The return type may be anything convenient: It doesn't matter to the
+ * method handle's behavior, since it will never return normally.
+ * @param returnType the return type of the desired method handle
+ * @param exType the parameter type of the desired method handle
+ * @return method handle which can throw the given exceptions
+ * @throws NullPointerException if either argument is null
+ */
+ public static
+ MethodHandle throwException(Class<?> returnType, Class<? extends Throwable> exType) {
+ if (!Throwable.class.isAssignableFrom(exType))
+ throw new ClassCastException(exType.getName());
+
+ return new Transformers.AlwaysThrow(returnType, exType);
+ }
+}
diff --git a/java/lang/invoke/MethodType.java b/java/lang/invoke/MethodType.java
new file mode 100644
index 0000000..4652c93
--- /dev/null
+++ b/java/lang/invoke/MethodType.java
@@ -0,0 +1,1328 @@
+/*
+ * Copyright (c) 2008, 2013, 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 sun.invoke.util.Wrapper;
+import java.lang.ref.WeakReference;
+import java.lang.ref.Reference;
+import java.lang.ref.ReferenceQueue;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ConcurrentHashMap;
+import sun.invoke.util.BytecodeDescriptor;
+import static java.lang.invoke.MethodHandleStatics.*;
+
+/**
+ * A method type represents the arguments and return type accepted and
+ * returned by a method handle, or the arguments and return type passed
+ * and expected by a method handle caller. Method types must be properly
+ * matched between a method handle and all its callers,
+ * and the JVM's operations enforce this matching at, specifically
+ * during calls to {@link MethodHandle#invokeExact MethodHandle.invokeExact}
+ * and {@link MethodHandle#invoke MethodHandle.invoke}, and during execution
+ * of {@code invokedynamic} instructions.
+ * <p>
+ * The structure is a return type accompanied by any number of parameter types.
+ * The types (primitive, {@code void}, and reference) are represented by {@link Class} objects.
+ * (For ease of exposition, we treat {@code void} as if it were a type.
+ * In fact, it denotes the absence of a return type.)
+ * <p>
+ * All instances of {@code MethodType} are immutable.
+ * Two instances are completely interchangeable if they compare equal.
+ * Equality depends on pairwise correspondence of the return and parameter types and on nothing else.
+ * <p>
+ * This type can be created only by factory methods.
+ * All factory methods may cache values, though caching is not guaranteed.
+ * Some factory methods are static, while others are virtual methods which
+ * modify precursor method types, e.g., by changing a selected parameter.
+ * <p>
+ * Factory methods which operate on groups of parameter types
+ * are systematically presented in two versions, so that both Java arrays and
+ * Java lists can be used to work with groups of parameter types.
+ * The query methods {@code parameterArray} and {@code parameterList}
+ * also provide a choice between arrays and lists.
+ * <p>
+ * {@code MethodType} objects are sometimes derived from bytecode instructions
+ * such as {@code invokedynamic}, specifically from the type descriptor strings associated
+ * with the instructions in a class file's constant pool.
+ * <p>
+ * Like classes and strings, method types can also be represented directly
+ * in a class file's constant pool as constants.
+ * A method type may be loaded by an {@code ldc} instruction which refers
+ * to a suitable {@code CONSTANT_MethodType} constant pool entry.
+ * The entry refers to a {@code CONSTANT_Utf8} spelling for the descriptor string.
+ * (For full details on method type constants,
+ * see sections 4.4.8 and 5.4.3.5 of the Java Virtual Machine Specification.)
+ * <p>
+ * When the JVM materializes a {@code MethodType} from a descriptor string,
+ * all classes named in the descriptor must be accessible, and will be loaded.
+ * (But the classes need not be initialized, as is the case with a {@code CONSTANT_Class}.)
+ * This loading may occur at any time before the {@code MethodType} object is first derived.
+ * @author John Rose, JSR 292 EG
+ */
+public final
+class MethodType implements java.io.Serializable {
+ private static final long serialVersionUID = 292L; // {rtype, {ptype...}}
+
+ // The rtype and ptypes fields define the structural identity of the method type:
+ private final Class<?> rtype;
+ private final Class<?>[] ptypes;
+
+ // The remaining fields are caches of various sorts:
+ private @Stable MethodTypeForm form; // erased form, plus cached data about primitives
+ private @Stable MethodType wrapAlt; // alternative wrapped/unwrapped version
+ // Android-removed: Cache of higher order adapters.
+ // We're not dynamically generating any adapters at this point.
+ // private @Stable Invokers invokers; // cache of handy higher-order adapters
+ private @Stable String methodDescriptor; // cache for toMethodDescriptorString
+
+ /**
+ * Check the given parameters for validity and store them into the final fields.
+ */
+ private MethodType(Class<?> rtype, Class<?>[] ptypes, boolean trusted) {
+ checkRtype(rtype);
+ checkPtypes(ptypes);
+ this.rtype = rtype;
+ // defensively copy the array passed in by the user
+ this.ptypes = trusted ? ptypes : Arrays.copyOf(ptypes, ptypes.length);
+ }
+
+ /**
+ * Construct a temporary unchecked instance of MethodType for use only as a key to the intern table.
+ * Does not check the given parameters for validity, and must be discarded after it is used as a searching key.
+ * The parameters are reversed for this constructor, so that is is not accidentally used.
+ */
+ private MethodType(Class<?>[] ptypes, Class<?> rtype) {
+ this.rtype = rtype;
+ this.ptypes = ptypes;
+ }
+
+ /*trusted*/ MethodTypeForm form() { return form; }
+ // Android-changed: Make rtype()/ptypes() public @hide for implementation use.
+ // /*trusted*/ Class<?> rtype() { return rtype; }
+ // /*trusted*/ Class<?>[] ptypes() { return ptypes; }
+ /*trusted*/ /** @hide */ public Class<?> rtype() { return rtype; }
+ /*trusted*/ /** @hide */ public Class<?>[] ptypes() { return ptypes; }
+
+ // Android-removed: Implementation methods unused on Android.
+ // void setForm(MethodTypeForm f) { form = f; }
+
+ /** This number, mandated by the JVM spec as 255,
+ * is the maximum number of <em>slots</em>
+ * that any Java method can receive in its argument list.
+ * It limits both JVM signatures and method type objects.
+ * The longest possible invocation will look like
+ * {@code staticMethod(arg1, arg2, ..., arg255)} or
+ * {@code x.virtualMethod(arg1, arg2, ..., arg254)}.
+ */
+ /*non-public*/ static final int MAX_JVM_ARITY = 255; // this is mandated by the JVM spec.
+
+ /** This number is the maximum arity of a method handle, 254.
+ * It is derived from the absolute JVM-imposed arity by subtracting one,
+ * which is the slot occupied by the method handle itself at the
+ * beginning of the argument list used to invoke the method handle.
+ * The longest possible invocation will look like
+ * {@code mh.invoke(arg1, arg2, ..., arg254)}.
+ */
+ // Issue: Should we allow MH.invokeWithArguments to go to the full 255?
+ /*non-public*/ static final int MAX_MH_ARITY = MAX_JVM_ARITY-1; // deduct one for mh receiver
+
+ /** This number is the maximum arity of a method handle invoker, 253.
+ * It is derived from the absolute JVM-imposed arity by subtracting two,
+ * which are the slots occupied by invoke method handle, and the
+ * target method handle, which are both at the beginning of the argument
+ * list used to invoke the target method handle.
+ * The longest possible invocation will look like
+ * {@code invokermh.invoke(targetmh, arg1, arg2, ..., arg253)}.
+ */
+ /*non-public*/ static final int MAX_MH_INVOKER_ARITY = MAX_MH_ARITY-1; // deduct one more for invoker
+
+ private static void checkRtype(Class<?> rtype) {
+ Objects.requireNonNull(rtype);
+ }
+ private static void checkPtype(Class<?> ptype) {
+ Objects.requireNonNull(ptype);
+ if (ptype == void.class)
+ throw newIllegalArgumentException("parameter type cannot be void");
+ }
+ /** Return number of extra slots (count of long/double args). */
+ private static int checkPtypes(Class<?>[] ptypes) {
+ int slots = 0;
+ for (Class<?> ptype : ptypes) {
+ checkPtype(ptype);
+ if (ptype == double.class || ptype == long.class) {
+ slots++;
+ }
+ }
+ checkSlotCount(ptypes.length + slots);
+ return slots;
+ }
+ static void checkSlotCount(int count) {
+ assert((MAX_JVM_ARITY & (MAX_JVM_ARITY+1)) == 0);
+ // MAX_JVM_ARITY must be power of 2 minus 1 for following code trick to work:
+ if ((count & MAX_JVM_ARITY) != count)
+ throw newIllegalArgumentException("bad parameter count "+count);
+ }
+ private static IndexOutOfBoundsException newIndexOutOfBoundsException(Object num) {
+ if (num instanceof Integer) num = "bad index: "+num;
+ return new IndexOutOfBoundsException(num.toString());
+ }
+
+ static final ConcurrentWeakInternSet<MethodType> internTable = new ConcurrentWeakInternSet<>();
+
+ static final Class<?>[] NO_PTYPES = {};
+
+ /**
+ * Finds or creates an instance of the given method type.
+ * @param rtype the return type
+ * @param ptypes the parameter types
+ * @return a method type with the given components
+ * @throws NullPointerException if {@code rtype} or {@code ptypes} or any element of {@code ptypes} is null
+ * @throws IllegalArgumentException if any element of {@code ptypes} is {@code void.class}
+ */
+ public static
+ MethodType methodType(Class<?> rtype, Class<?>[] ptypes) {
+ return makeImpl(rtype, ptypes, false);
+ }
+
+ /**
+ * Finds or creates a method type with the given components.
+ * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+ * @param rtype the return type
+ * @param ptypes the parameter types
+ * @return a method type with the given components
+ * @throws NullPointerException if {@code rtype} or {@code ptypes} or any element of {@code ptypes} is null
+ * @throws IllegalArgumentException if any element of {@code ptypes} is {@code void.class}
+ */
+ public static
+ MethodType methodType(Class<?> rtype, List<Class<?>> ptypes) {
+ boolean notrust = false; // random List impl. could return evil ptypes array
+ return makeImpl(rtype, listToArray(ptypes), notrust);
+ }
+
+ private static Class<?>[] listToArray(List<Class<?>> ptypes) {
+ // sanity check the size before the toArray call, since size might be huge
+ checkSlotCount(ptypes.size());
+ return ptypes.toArray(NO_PTYPES);
+ }
+
+ /**
+ * Finds or creates a method type with the given components.
+ * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+ * The leading parameter type is prepended to the remaining array.
+ * @param rtype the return type
+ * @param ptype0 the first parameter type
+ * @param ptypes the remaining parameter types
+ * @return a method type with the given components
+ * @throws NullPointerException if {@code rtype} or {@code ptype0} or {@code ptypes} or any element of {@code ptypes} is null
+ * @throws IllegalArgumentException if {@code ptype0} or {@code ptypes} or any element of {@code ptypes} is {@code void.class}
+ */
+ public static
+ MethodType methodType(Class<?> rtype, Class<?> ptype0, Class<?>... ptypes) {
+ Class<?>[] ptypes1 = new Class<?>[1+ptypes.length];
+ ptypes1[0] = ptype0;
+ System.arraycopy(ptypes, 0, ptypes1, 1, ptypes.length);
+ return makeImpl(rtype, ptypes1, true);
+ }
+
+ /**
+ * Finds or creates a method type with the given components.
+ * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+ * The resulting method has no parameter types.
+ * @param rtype the return type
+ * @return a method type with the given return value
+ * @throws NullPointerException if {@code rtype} is null
+ */
+ public static
+ MethodType methodType(Class<?> rtype) {
+ return makeImpl(rtype, NO_PTYPES, true);
+ }
+
+ /**
+ * Finds or creates a method type with the given components.
+ * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+ * The resulting method has the single given parameter type.
+ * @param rtype the return type
+ * @param ptype0 the parameter type
+ * @return a method type with the given return value and parameter type
+ * @throws NullPointerException if {@code rtype} or {@code ptype0} is null
+ * @throws IllegalArgumentException if {@code ptype0} is {@code void.class}
+ */
+ public static
+ MethodType methodType(Class<?> rtype, Class<?> ptype0) {
+ return makeImpl(rtype, new Class<?>[]{ ptype0 }, true);
+ }
+
+ /**
+ * Finds or creates a method type with the given components.
+ * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+ * The resulting method has the same parameter types as {@code ptypes},
+ * and the specified return type.
+ * @param rtype the return type
+ * @param ptypes the method type which supplies the parameter types
+ * @return a method type with the given components
+ * @throws NullPointerException if {@code rtype} or {@code ptypes} is null
+ */
+ public static
+ MethodType methodType(Class<?> rtype, MethodType ptypes) {
+ return makeImpl(rtype, ptypes.ptypes, true);
+ }
+
+ /**
+ * Sole factory method to find or create an interned method type.
+ * @param rtype desired return type
+ * @param ptypes desired parameter types
+ * @param trusted whether the ptypes can be used without cloning
+ * @return the unique method type of the desired structure
+ */
+ /*trusted*/ static
+ MethodType makeImpl(Class<?> rtype, Class<?>[] ptypes, boolean trusted) {
+ MethodType mt = internTable.get(new MethodType(ptypes, rtype));
+ if (mt != null)
+ return mt;
+ if (ptypes.length == 0) {
+ ptypes = NO_PTYPES; trusted = true;
+ }
+ mt = new MethodType(rtype, ptypes, trusted);
+ // promote the object to the Real Thing, and reprobe
+ mt.form = MethodTypeForm.findForm(mt);
+ return internTable.add(mt);
+ }
+ private static final MethodType[] objectOnlyTypes = new MethodType[20];
+
+ /**
+ * Finds or creates a method type whose components are {@code Object} with an optional trailing {@code Object[]} array.
+ * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+ * All parameters and the return type will be {@code Object},
+ * except the final array parameter if any, which will be {@code Object[]}.
+ * @param objectArgCount number of parameters (excluding the final array parameter if any)
+ * @param finalArray whether there will be a trailing array parameter, of type {@code Object[]}
+ * @return a generally applicable method type, for all calls of the given fixed argument count and a collected array of further arguments
+ * @throws IllegalArgumentException if {@code objectArgCount} is negative or greater than 255 (or 254, if {@code finalArray} is true)
+ * @see #genericMethodType(int)
+ */
+ public static
+ MethodType genericMethodType(int objectArgCount, boolean finalArray) {
+ MethodType mt;
+ checkSlotCount(objectArgCount);
+ int ivarargs = (!finalArray ? 0 : 1);
+ int ootIndex = objectArgCount*2 + ivarargs;
+ if (ootIndex < objectOnlyTypes.length) {
+ mt = objectOnlyTypes[ootIndex];
+ if (mt != null) return mt;
+ }
+ Class<?>[] ptypes = new Class<?>[objectArgCount + ivarargs];
+ Arrays.fill(ptypes, Object.class);
+ if (ivarargs != 0) ptypes[objectArgCount] = Object[].class;
+ mt = makeImpl(Object.class, ptypes, true);
+ if (ootIndex < objectOnlyTypes.length) {
+ objectOnlyTypes[ootIndex] = mt; // cache it here also!
+ }
+ return mt;
+ }
+
+ /**
+ * Finds or creates a method type whose components are all {@code Object}.
+ * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+ * All parameters and the return type will be Object.
+ * @param objectArgCount number of parameters
+ * @return a generally applicable method type, for all calls of the given argument count
+ * @throws IllegalArgumentException if {@code objectArgCount} is negative or greater than 255
+ * @see #genericMethodType(int, boolean)
+ */
+ public static
+ MethodType genericMethodType(int objectArgCount) {
+ return genericMethodType(objectArgCount, false);
+ }
+
+ /**
+ * Finds or creates a method type with a single different parameter type.
+ * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+ * @param num the index (zero-based) of the parameter type to change
+ * @param nptype a new parameter type to replace the old one with
+ * @return the same type, except with the selected parameter changed
+ * @throws IndexOutOfBoundsException if {@code num} is not a valid index into {@code parameterArray()}
+ * @throws IllegalArgumentException if {@code nptype} is {@code void.class}
+ * @throws NullPointerException if {@code nptype} is null
+ */
+ public MethodType changeParameterType(int num, Class<?> nptype) {
+ if (parameterType(num) == nptype) return this;
+ checkPtype(nptype);
+ Class<?>[] nptypes = ptypes.clone();
+ nptypes[num] = nptype;
+ return makeImpl(rtype, nptypes, true);
+ }
+
+ /**
+ * Finds or creates a method type with additional parameter types.
+ * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+ * @param num the position (zero-based) of the inserted parameter type(s)
+ * @param ptypesToInsert zero or more new parameter types to insert into the parameter list
+ * @return the same type, except with the selected parameter(s) inserted
+ * @throws IndexOutOfBoundsException if {@code num} is negative or greater than {@code parameterCount()}
+ * @throws IllegalArgumentException if any element of {@code ptypesToInsert} is {@code void.class}
+ * or if the resulting method type would have more than 255 parameter slots
+ * @throws NullPointerException if {@code ptypesToInsert} or any of its elements is null
+ */
+ public MethodType insertParameterTypes(int num, Class<?>... ptypesToInsert) {
+ int len = ptypes.length;
+ if (num < 0 || num > len)
+ throw newIndexOutOfBoundsException(num);
+ int ins = checkPtypes(ptypesToInsert);
+ checkSlotCount(parameterSlotCount() + ptypesToInsert.length + ins);
+ int ilen = ptypesToInsert.length;
+ if (ilen == 0) return this;
+ Class<?>[] nptypes = Arrays.copyOfRange(ptypes, 0, len+ilen);
+ System.arraycopy(nptypes, num, nptypes, num+ilen, len-num);
+ System.arraycopy(ptypesToInsert, 0, nptypes, num, ilen);
+ return makeImpl(rtype, nptypes, true);
+ }
+
+ /**
+ * Finds or creates a method type with additional parameter types.
+ * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+ * @param ptypesToInsert zero or more new parameter types to insert after the end of the parameter list
+ * @return the same type, except with the selected parameter(s) appended
+ * @throws IllegalArgumentException if any element of {@code ptypesToInsert} is {@code void.class}
+ * or if the resulting method type would have more than 255 parameter slots
+ * @throws NullPointerException if {@code ptypesToInsert} or any of its elements is null
+ */
+ public MethodType appendParameterTypes(Class<?>... ptypesToInsert) {
+ return insertParameterTypes(parameterCount(), ptypesToInsert);
+ }
+
+ /**
+ * Finds or creates a method type with additional parameter types.
+ * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+ * @param num the position (zero-based) of the inserted parameter type(s)
+ * @param ptypesToInsert zero or more new parameter types to insert into the parameter list
+ * @return the same type, except with the selected parameter(s) inserted
+ * @throws IndexOutOfBoundsException if {@code num} is negative or greater than {@code parameterCount()}
+ * @throws IllegalArgumentException if any element of {@code ptypesToInsert} is {@code void.class}
+ * or if the resulting method type would have more than 255 parameter slots
+ * @throws NullPointerException if {@code ptypesToInsert} or any of its elements is null
+ */
+ public MethodType insertParameterTypes(int num, List<Class<?>> ptypesToInsert) {
+ return insertParameterTypes(num, listToArray(ptypesToInsert));
+ }
+
+ /**
+ * Finds or creates a method type with additional parameter types.
+ * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+ * @param ptypesToInsert zero or more new parameter types to insert after the end of the parameter list
+ * @return the same type, except with the selected parameter(s) appended
+ * @throws IllegalArgumentException if any element of {@code ptypesToInsert} is {@code void.class}
+ * or if the resulting method type would have more than 255 parameter slots
+ * @throws NullPointerException if {@code ptypesToInsert} or any of its elements is null
+ */
+ public MethodType appendParameterTypes(List<Class<?>> ptypesToInsert) {
+ return insertParameterTypes(parameterCount(), ptypesToInsert);
+ }
+
+ /**
+ * Finds or creates a method type with modified parameter types.
+ * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+ * @param start the position (zero-based) of the first replaced parameter type(s)
+ * @param end the position (zero-based) after the last replaced parameter type(s)
+ * @param ptypesToInsert zero or more new parameter types to insert into the parameter list
+ * @return the same type, except with the selected parameter(s) replaced
+ * @throws IndexOutOfBoundsException if {@code start} is negative or greater than {@code parameterCount()}
+ * or if {@code end} is negative or greater than {@code parameterCount()}
+ * or if {@code start} is greater than {@code end}
+ * @throws IllegalArgumentException if any element of {@code ptypesToInsert} is {@code void.class}
+ * or if the resulting method type would have more than 255 parameter slots
+ * @throws NullPointerException if {@code ptypesToInsert} or any of its elements is null
+ */
+ /*non-public*/ MethodType replaceParameterTypes(int start, int end, Class<?>... ptypesToInsert) {
+ if (start == end)
+ return insertParameterTypes(start, ptypesToInsert);
+ int len = ptypes.length;
+ if (!(0 <= start && start <= end && end <= len))
+ throw newIndexOutOfBoundsException("start="+start+" end="+end);
+ int ilen = ptypesToInsert.length;
+ if (ilen == 0)
+ return dropParameterTypes(start, end);
+ return dropParameterTypes(start, end).insertParameterTypes(start, ptypesToInsert);
+ }
+
+ /** Replace the last arrayLength parameter types with the component type of arrayType.
+ * @param arrayType any array type
+ * @param arrayLength the number of parameter types to change
+ * @return the resulting type
+ */
+ /*non-public*/ MethodType asSpreaderType(Class<?> arrayType, int arrayLength) {
+ assert(parameterCount() >= arrayLength);
+ int spreadPos = ptypes.length - arrayLength;
+ if (arrayLength == 0) return this; // nothing to change
+ if (arrayType == Object[].class) {
+ if (isGeneric()) return this; // nothing to change
+ if (spreadPos == 0) {
+ // no leading arguments to preserve; go generic
+ MethodType res = genericMethodType(arrayLength);
+ if (rtype != Object.class) {
+ res = res.changeReturnType(rtype);
+ }
+ return res;
+ }
+ }
+ Class<?> elemType = arrayType.getComponentType();
+ assert(elemType != null);
+ for (int i = spreadPos; i < ptypes.length; i++) {
+ if (ptypes[i] != elemType) {
+ Class<?>[] fixedPtypes = ptypes.clone();
+ Arrays.fill(fixedPtypes, i, ptypes.length, elemType);
+ return methodType(rtype, fixedPtypes);
+ }
+ }
+ return this; // arguments check out; no change
+ }
+
+ /** Return the leading parameter type, which must exist and be a reference.
+ * @return the leading parameter type, after error checks
+ */
+ /*non-public*/ Class<?> leadingReferenceParameter() {
+ Class<?> ptype;
+ if (ptypes.length == 0 ||
+ (ptype = ptypes[0]).isPrimitive())
+ throw newIllegalArgumentException("no leading reference parameter");
+ return ptype;
+ }
+
+ /** Delete the last parameter type and replace it with arrayLength copies of the component type of arrayType.
+ * @param arrayType any array type
+ * @param arrayLength the number of parameter types to insert
+ * @return the resulting type
+ */
+ /*non-public*/ MethodType asCollectorType(Class<?> arrayType, int arrayLength) {
+ assert(parameterCount() >= 1);
+ assert(lastParameterType().isAssignableFrom(arrayType));
+ MethodType res;
+ if (arrayType == Object[].class) {
+ res = genericMethodType(arrayLength);
+ if (rtype != Object.class) {
+ res = res.changeReturnType(rtype);
+ }
+ } else {
+ Class<?> elemType = arrayType.getComponentType();
+ assert(elemType != null);
+ res = methodType(rtype, Collections.nCopies(arrayLength, elemType));
+ }
+ if (ptypes.length == 1) {
+ return res;
+ } else {
+ return res.insertParameterTypes(0, parameterList().subList(0, ptypes.length-1));
+ }
+ }
+
+ /**
+ * Finds or creates a method type with some parameter types omitted.
+ * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+ * @param start the index (zero-based) of the first parameter type to remove
+ * @param end the index (greater than {@code start}) of the first parameter type after not to remove
+ * @return the same type, except with the selected parameter(s) removed
+ * @throws IndexOutOfBoundsException if {@code start} is negative or greater than {@code parameterCount()}
+ * or if {@code end} is negative or greater than {@code parameterCount()}
+ * or if {@code start} is greater than {@code end}
+ */
+ public MethodType dropParameterTypes(int start, int end) {
+ int len = ptypes.length;
+ if (!(0 <= start && start <= end && end <= len))
+ throw newIndexOutOfBoundsException("start="+start+" end="+end);
+ if (start == end) return this;
+ Class<?>[] nptypes;
+ if (start == 0) {
+ if (end == len) {
+ // drop all parameters
+ nptypes = NO_PTYPES;
+ } else {
+ // drop initial parameter(s)
+ nptypes = Arrays.copyOfRange(ptypes, end, len);
+ }
+ } else {
+ if (end == len) {
+ // drop trailing parameter(s)
+ nptypes = Arrays.copyOfRange(ptypes, 0, start);
+ } else {
+ int tail = len - end;
+ nptypes = Arrays.copyOfRange(ptypes, 0, start + tail);
+ System.arraycopy(ptypes, end, nptypes, start, tail);
+ }
+ }
+ return makeImpl(rtype, nptypes, true);
+ }
+
+ /**
+ * Finds or creates a method type with a different return type.
+ * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+ * @param nrtype a return parameter type to replace the old one with
+ * @return the same type, except with the return type change
+ * @throws NullPointerException if {@code nrtype} is null
+ */
+ public MethodType changeReturnType(Class<?> nrtype) {
+ if (returnType() == nrtype) return this;
+ return makeImpl(nrtype, ptypes, true);
+ }
+
+ /**
+ * Reports if this type contains a primitive argument or return value.
+ * The return type {@code void} counts as a primitive.
+ * @return true if any of the types are primitives
+ */
+ public boolean hasPrimitives() {
+ return form.hasPrimitives();
+ }
+
+ /**
+ * Reports if this type contains a wrapper argument or return value.
+ * Wrappers are types which box primitive values, such as {@link Integer}.
+ * The reference type {@code java.lang.Void} counts as a wrapper,
+ * if it occurs as a return type.
+ * @return true if any of the types are wrappers
+ */
+ public boolean hasWrappers() {
+ return unwrap() != this;
+ }
+
+ /**
+ * Erases all reference types to {@code Object}.
+ * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+ * All primitive types (including {@code void}) will remain unchanged.
+ * @return a version of the original type with all reference types replaced
+ */
+ public MethodType erase() {
+ return form.erasedType();
+ }
+
+ // BEGIN Android-removed: Implementation methods unused on Android.
+ /*
+ /**
+ * Erases all reference types to {@code Object}, and all subword types to {@code int}.
+ * This is the reduced type polymorphism used by private methods
+ * such as {@link MethodHandle#invokeBasic invokeBasic}.
+ * @return a version of the original type with all reference and subword types replaced
+ *
+ /*non-public* MethodType basicType() {
+ return form.basicType();
+ }
+
+ /**
+ * @return a version of the original type with MethodHandle prepended as the first argument
+ *
+ /*non-public* MethodType invokerType() {
+ return insertParameterTypes(0, MethodHandle.class);
+ }
+ */
+ // END Android-removed: Implementation methods unused on Android.
+
+ /**
+ * Converts all types, both reference and primitive, to {@code Object}.
+ * Convenience method for {@link #genericMethodType(int) genericMethodType}.
+ * The expression {@code type.wrap().erase()} produces the same value
+ * as {@code type.generic()}.
+ * @return a version of the original type with all types replaced
+ */
+ public MethodType generic() {
+ return genericMethodType(parameterCount());
+ }
+
+ /*non-public*/ boolean isGeneric() {
+ return this == erase() && !hasPrimitives();
+ }
+
+ /**
+ * Converts all primitive types to their corresponding wrapper types.
+ * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+ * All reference types (including wrapper types) will remain unchanged.
+ * A {@code void} return type is changed to the type {@code java.lang.Void}.
+ * The expression {@code type.wrap().erase()} produces the same value
+ * as {@code type.generic()}.
+ * @return a version of the original type with all primitive types replaced
+ */
+ public MethodType wrap() {
+ return hasPrimitives() ? wrapWithPrims(this) : this;
+ }
+
+ /**
+ * Converts all wrapper types to their corresponding primitive types.
+ * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+ * All primitive types (including {@code void}) will remain unchanged.
+ * A return type of {@code java.lang.Void} is changed to {@code void}.
+ * @return a version of the original type with all wrapper types replaced
+ */
+ public MethodType unwrap() {
+ MethodType noprims = !hasPrimitives() ? this : wrapWithPrims(this);
+ return unwrapWithNoPrims(noprims);
+ }
+
+ private static MethodType wrapWithPrims(MethodType pt) {
+ assert(pt.hasPrimitives());
+ MethodType wt = pt.wrapAlt;
+ if (wt == null) {
+ // fill in lazily
+ wt = MethodTypeForm.canonicalize(pt, MethodTypeForm.WRAP, MethodTypeForm.WRAP);
+ assert(wt != null);
+ pt.wrapAlt = wt;
+ }
+ return wt;
+ }
+
+ private static MethodType unwrapWithNoPrims(MethodType wt) {
+ assert(!wt.hasPrimitives());
+ MethodType uwt = wt.wrapAlt;
+ if (uwt == null) {
+ // fill in lazily
+ uwt = MethodTypeForm.canonicalize(wt, MethodTypeForm.UNWRAP, MethodTypeForm.UNWRAP);
+ if (uwt == null)
+ uwt = wt; // type has no wrappers or prims at all
+ wt.wrapAlt = uwt;
+ }
+ return uwt;
+ }
+
+ /**
+ * Returns the parameter type at the specified index, within this method type.
+ * @param num the index (zero-based) of the desired parameter type
+ * @return the selected parameter type
+ * @throws IndexOutOfBoundsException if {@code num} is not a valid index into {@code parameterArray()}
+ */
+ public Class<?> parameterType(int num) {
+ return ptypes[num];
+ }
+ /**
+ * Returns the number of parameter types in this method type.
+ * @return the number of parameter types
+ */
+ public int parameterCount() {
+ return ptypes.length;
+ }
+ /**
+ * Returns the return type of this method type.
+ * @return the return type
+ */
+ public Class<?> returnType() {
+ return rtype;
+ }
+
+ /**
+ * Presents the parameter types as a list (a convenience method).
+ * The list will be immutable.
+ * @return the parameter types (as an immutable list)
+ */
+ public List<Class<?>> parameterList() {
+ return Collections.unmodifiableList(Arrays.asList(ptypes.clone()));
+ }
+
+ /*non-public*/ Class<?> lastParameterType() {
+ int len = ptypes.length;
+ return len == 0 ? void.class : ptypes[len-1];
+ }
+
+ /**
+ * Presents the parameter types as an array (a convenience method).
+ * Changes to the array will not result in changes to the type.
+ * @return the parameter types (as a fresh copy if necessary)
+ */
+ public Class<?>[] parameterArray() {
+ return ptypes.clone();
+ }
+
+ /**
+ * Compares the specified object with this type for equality.
+ * That is, it returns <tt>true</tt> if and only if the specified object
+ * is also a method type with exactly the same parameters and return type.
+ * @param x object to compare
+ * @see Object#equals(Object)
+ */
+ @Override
+ public boolean equals(Object x) {
+ return this == x || x instanceof MethodType && equals((MethodType)x);
+ }
+
+ private boolean equals(MethodType that) {
+ return this.rtype == that.rtype
+ && Arrays.equals(this.ptypes, that.ptypes);
+ }
+
+ /**
+ * Returns the hash code value for this method type.
+ * It is defined to be the same as the hashcode of a List
+ * whose elements are the return type followed by the
+ * parameter types.
+ * @return the hash code value for this method type
+ * @see Object#hashCode()
+ * @see #equals(Object)
+ * @see List#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ int hashCode = 31 + rtype.hashCode();
+ for (Class<?> ptype : ptypes)
+ hashCode = 31*hashCode + ptype.hashCode();
+ return hashCode;
+ }
+
+ /**
+ * Returns a string representation of the method type,
+ * of the form {@code "(PT0,PT1...)RT"}.
+ * The string representation of a method type is a
+ * parenthesis enclosed, comma separated list of type names,
+ * followed immediately by the return type.
+ * <p>
+ * Each type is represented by its
+ * {@link java.lang.Class#getSimpleName simple name}.
+ */
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("(");
+ for (int i = 0; i < ptypes.length; i++) {
+ if (i > 0) sb.append(",");
+ sb.append(ptypes[i].getSimpleName());
+ }
+ sb.append(")");
+ sb.append(rtype.getSimpleName());
+ return sb.toString();
+ }
+
+ // BEGIN Android-removed: Implementation methods unused on Android.
+ /*
+ /** True if the old return type can always be viewed (w/o casting) under new return type,
+ * and the new parameters can be viewed (w/o casting) under the old parameter types.
+ *
+ /*non-public*
+ boolean isViewableAs(MethodType newType, boolean keepInterfaces) {
+ if (!VerifyType.isNullConversion(returnType(), newType.returnType(), keepInterfaces))
+ return false;
+ return parametersAreViewableAs(newType, keepInterfaces);
+ }
+ /** True if the new parameters can be viewed (w/o casting) under the old parameter types. *
+ /*non-public*
+ boolean parametersAreViewableAs(MethodType newType, boolean keepInterfaces) {
+ if (form == newType.form && form.erasedType == this)
+ return true; // my reference parameters are all Object
+ if (ptypes == newType.ptypes)
+ return true;
+ int argc = parameterCount();
+ if (argc != newType.parameterCount())
+ return false;
+ for (int i = 0; i < argc; i++) {
+ if (!VerifyType.isNullConversion(newType.parameterType(i), parameterType(i), keepInterfaces))
+ return false;
+ }
+ return true;
+ }
+ */
+ // END Android-removed: Implementation methods unused on Android.
+
+ /*non-public*/
+ boolean isConvertibleTo(MethodType newType) {
+ MethodTypeForm oldForm = this.form();
+ MethodTypeForm newForm = newType.form();
+ if (oldForm == newForm)
+ // same parameter count, same primitive/object mix
+ return true;
+ if (!canConvert(returnType(), newType.returnType()))
+ return false;
+ Class<?>[] srcTypes = newType.ptypes;
+ Class<?>[] dstTypes = ptypes;
+ if (srcTypes == dstTypes)
+ return true;
+ int argc;
+ if ((argc = srcTypes.length) != dstTypes.length)
+ return false;
+ if (argc <= 1) {
+ if (argc == 1 && !canConvert(srcTypes[0], dstTypes[0]))
+ return false;
+ return true;
+ }
+ if ((oldForm.primitiveParameterCount() == 0 && oldForm.erasedType == this) ||
+ (newForm.primitiveParameterCount() == 0 && newForm.erasedType == newType)) {
+ // Somewhat complicated test to avoid a loop of 2 or more trips.
+ // If either type has only Object parameters, we know we can convert.
+ assert(canConvertParameters(srcTypes, dstTypes));
+ return true;
+ }
+ return canConvertParameters(srcTypes, dstTypes);
+ }
+
+ /** Returns true if MHs.explicitCastArguments produces the same result as MH.asType.
+ * If the type conversion is impossible for either, the result should be false.
+ */
+ /*non-public*/
+ boolean explicitCastEquivalentToAsType(MethodType newType) {
+ if (this == newType) return true;
+ if (!explicitCastEquivalentToAsType(rtype, newType.rtype)) {
+ return false;
+ }
+ Class<?>[] srcTypes = newType.ptypes;
+ Class<?>[] dstTypes = ptypes;
+ if (dstTypes == srcTypes) {
+ return true;
+ }
+ assert(dstTypes.length == srcTypes.length);
+ for (int i = 0; i < dstTypes.length; i++) {
+ if (!explicitCastEquivalentToAsType(srcTypes[i], dstTypes[i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /** Reports true if the src can be converted to the dst, by both asType and MHs.eCE,
+ * and with the same effect.
+ * MHs.eCA has the following "upgrades" to MH.asType:
+ * 1. interfaces are unchecked (that is, treated as if aliased to Object)
+ * Therefore, {@code Object->CharSequence} is possible in both cases but has different semantics
+ * 2a. the full matrix of primitive-to-primitive conversions is supported
+ * Narrowing like {@code long->byte} and basic-typing like {@code boolean->int}
+ * are not supported by asType, but anything supported by asType is equivalent
+ * with MHs.eCE.
+ * 2b. conversion of void->primitive means explicit cast has to insert zero/false/null.
+ * 3a. unboxing conversions can be followed by the full matrix of primitive conversions
+ * 3b. unboxing of null is permitted (creates a zero primitive value)
+ * Other than interfaces, reference-to-reference conversions are the same.
+ * Boxing primitives to references is the same for both operators.
+ */
+ private static boolean explicitCastEquivalentToAsType(Class<?> src, Class<?> dst) {
+ if (src == dst || dst == Object.class || dst == void.class) return true;
+ if (src.isPrimitive()) {
+ // Could be a prim/prim conversion, where casting is a strict superset.
+ // Or a boxing conversion, which is always to an exact wrapper class.
+ return canConvert(src, dst);
+ } else if (dst.isPrimitive()) {
+ // Unboxing behavior is different between MHs.eCA & MH.asType (see 3b).
+ return false;
+ } else {
+ // R->R always works, but we have to avoid a check-cast to an interface.
+ return !dst.isInterface() || dst.isAssignableFrom(src);
+ }
+ }
+
+ private boolean canConvertParameters(Class<?>[] srcTypes, Class<?>[] dstTypes) {
+ for (int i = 0; i < srcTypes.length; i++) {
+ if (!canConvert(srcTypes[i], dstTypes[i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /*non-public*/
+ static boolean canConvert(Class<?> src, Class<?> dst) {
+ // short-circuit a few cases:
+ if (src == dst || src == Object.class || dst == Object.class) return true;
+ // the remainder of this logic is documented in MethodHandle.asType
+ if (src.isPrimitive()) {
+ // can force void to an explicit null, a la reflect.Method.invoke
+ // can also force void to a primitive zero, by analogy
+ if (src == void.class) return true; //or !dst.isPrimitive()?
+ Wrapper sw = Wrapper.forPrimitiveType(src);
+ if (dst.isPrimitive()) {
+ // P->P must widen
+ return Wrapper.forPrimitiveType(dst).isConvertibleFrom(sw);
+ } else {
+ // P->R must box and widen
+ return dst.isAssignableFrom(sw.wrapperType());
+ }
+ } else if (dst.isPrimitive()) {
+ // any value can be dropped
+ if (dst == void.class) return true;
+ Wrapper dw = Wrapper.forPrimitiveType(dst);
+ // R->P must be able to unbox (from a dynamically chosen type) and widen
+ // For example:
+ // Byte/Number/Comparable/Object -> dw:Byte -> byte.
+ // Character/Comparable/Object -> dw:Character -> char
+ // Boolean/Comparable/Object -> dw:Boolean -> boolean
+ // This means that dw must be cast-compatible with src.
+ if (src.isAssignableFrom(dw.wrapperType())) {
+ return true;
+ }
+ // The above does not work if the source reference is strongly typed
+ // to a wrapper whose primitive must be widened. For example:
+ // Byte -> unbox:byte -> short/int/long/float/double
+ // Character -> unbox:char -> int/long/float/double
+ if (Wrapper.isWrapperType(src) &&
+ dw.isConvertibleFrom(Wrapper.forWrapperType(src))) {
+ // can unbox from src and then widen to dst
+ return true;
+ }
+ // We have already covered cases which arise due to runtime unboxing
+ // of a reference type which covers several wrapper types:
+ // Object -> cast:Integer -> unbox:int -> long/float/double
+ // Serializable -> cast:Byte -> unbox:byte -> byte/short/int/long/float/double
+ // An marginal case is Number -> dw:Character -> char, which would be OK if there were a
+ // subclass of Number which wraps a value that can convert to char.
+ // Since there is none, we don't need an extra check here to cover char or boolean.
+ return false;
+ } else {
+ // R->R always works, since null is always valid dynamically
+ return true;
+ }
+ }
+
+ /// Queries which have to do with the bytecode architecture
+
+ /** Reports the number of JVM stack slots required to invoke a method
+ * of this type. Note that (for historical reasons) the JVM requires
+ * a second stack slot to pass long and double arguments.
+ * So this method returns {@link #parameterCount() parameterCount} plus the
+ * number of long and double parameters (if any).
+ * <p>
+ * This method is included for the benefit of applications that must
+ * generate bytecodes that process method handles and invokedynamic.
+ * @return the number of JVM stack slots for this type's parameters
+ */
+ /*non-public*/ int parameterSlotCount() {
+ return form.parameterSlotCount();
+ }
+
+ // BEGIN Android-removed: Cache of higher order adapters.
+ /*
+ /*non-public* Invokers invokers() {
+ Invokers inv = invokers;
+ if (inv != null) return inv;
+ invokers = inv = new Invokers(this);
+ return inv;
+ }
+ */
+ // END Android-removed: Cache of higher order adapters.
+
+ // BEGIN Android-removed: Implementation methods unused on Android.
+ /*
+ /** Reports the number of JVM stack slots which carry all parameters including and after
+ * the given position, which must be in the range of 0 to
+ * {@code parameterCount} inclusive. Successive parameters are
+ * more shallowly stacked, and parameters are indexed in the bytecodes
+ * according to their trailing edge. Thus, to obtain the depth
+ * in the outgoing call stack of parameter {@code N}, obtain
+ * the {@code parameterSlotDepth} of its trailing edge
+ * at position {@code N+1}.
+ * <p>
+ * Parameters of type {@code long} and {@code double} occupy
+ * two stack slots (for historical reasons) and all others occupy one.
+ * Therefore, the number returned is the number of arguments
+ * <em>including</em> and <em>after</em> the given parameter,
+ * <em>plus</em> the number of long or double arguments
+ * at or after after the argument for the given parameter.
+ * <p>
+ * This method is included for the benefit of applications that must
+ * generate bytecodes that process method handles and invokedynamic.
+ * @param num an index (zero-based, inclusive) within the parameter types
+ * @return the index of the (shallowest) JVM stack slot transmitting the
+ * given parameter
+ * @throws IllegalArgumentException if {@code num} is negative or greater than {@code parameterCount()}
+ *
+ /*non-public* int parameterSlotDepth(int num) {
+ if (num < 0 || num > ptypes.length)
+ parameterType(num); // force a range check
+ return form.parameterToArgSlot(num-1);
+ }
+
+ /** Reports the number of JVM stack slots required to receive a return value
+ * from a method of this type.
+ * If the {@link #returnType() return type} is void, it will be zero,
+ * else if the return type is long or double, it will be two, else one.
+ * <p>
+ * This method is included for the benefit of applications that must
+ * generate bytecodes that process method handles and invokedynamic.
+ * @return the number of JVM stack slots (0, 1, or 2) for this type's return value
+ * Will be removed for PFD.
+ *
+ /*non-public* int returnSlotCount() {
+ return form.returnSlotCount();
+ }
+ */
+ // END Android-removed: Implementation methods unused on Android.
+
+ /**
+ * Finds or creates an instance of a method type, given the spelling of its bytecode descriptor.
+ * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+ * Any class or interface name embedded in the descriptor string
+ * will be resolved by calling {@link ClassLoader#loadClass(java.lang.String)}
+ * on the given loader (or if it is null, on the system class loader).
+ * <p>
+ * Note that it is possible to encounter method types which cannot be
+ * constructed by this method, because their component types are
+ * not all reachable from a common class loader.
+ * <p>
+ * This method is included for the benefit of applications that must
+ * generate bytecodes that process method handles and {@code invokedynamic}.
+ * @param descriptor a bytecode-level type descriptor string "(T...)T"
+ * @param loader the class loader in which to look up the types
+ * @return a method type matching the bytecode-level type descriptor
+ * @throws NullPointerException if the string is null
+ * @throws IllegalArgumentException if the string is not well-formed
+ * @throws TypeNotPresentException if a named type cannot be found
+ */
+ public static MethodType fromMethodDescriptorString(String descriptor, ClassLoader loader)
+ throws IllegalArgumentException, TypeNotPresentException
+ {
+ if (!descriptor.startsWith("(") || // also generates NPE if needed
+ descriptor.indexOf(')') < 0 ||
+ descriptor.indexOf('.') >= 0)
+ throw newIllegalArgumentException("not a method descriptor: "+descriptor);
+ List<Class<?>> types = BytecodeDescriptor.parseMethod(descriptor, loader);
+ Class<?> rtype = types.remove(types.size() - 1);
+ checkSlotCount(types.size());
+ Class<?>[] ptypes = listToArray(types);
+ return makeImpl(rtype, ptypes, true);
+ }
+
+ /**
+ * Produces a bytecode descriptor representation of the method type.
+ * <p>
+ * Note that this is not a strict inverse of {@link #fromMethodDescriptorString fromMethodDescriptorString}.
+ * Two distinct classes which share a common name but have different class loaders
+ * will appear identical when viewed within descriptor strings.
+ * <p>
+ * This method is included for the benefit of applications that must
+ * generate bytecodes that process method handles and {@code invokedynamic}.
+ * {@link #fromMethodDescriptorString(java.lang.String, java.lang.ClassLoader) fromMethodDescriptorString},
+ * because the latter requires a suitable class loader argument.
+ * @return the bytecode type descriptor representation
+ */
+ public String toMethodDescriptorString() {
+ String desc = methodDescriptor;
+ if (desc == null) {
+ desc = BytecodeDescriptor.unparse(this);
+ methodDescriptor = desc;
+ }
+ return desc;
+ }
+
+ /*non-public*/ static String toFieldDescriptorString(Class<?> cls) {
+ return BytecodeDescriptor.unparse(cls);
+ }
+
+ /// Serialization.
+
+ /**
+ * There are no serializable fields for {@code MethodType}.
+ */
+ private static final java.io.ObjectStreamField[] serialPersistentFields = { };
+
+ /**
+ * Save the {@code MethodType} instance to a stream.
+ *
+ * @serialData
+ * For portability, the serialized format does not refer to named fields.
+ * Instead, the return type and parameter type arrays are written directly
+ * from the {@code writeObject} method, using two calls to {@code s.writeObject}
+ * as follows:
+ * <blockquote><pre>{@code
+s.writeObject(this.returnType());
+s.writeObject(this.parameterArray());
+ * }</pre></blockquote>
+ * <p>
+ * The deserialized field values are checked as if they were
+ * provided to the factory method {@link #methodType(Class,Class[]) methodType}.
+ * For example, null values, or {@code void} parameter types,
+ * will lead to exceptions during deserialization.
+ * @param s the stream to write the object to
+ * @throws java.io.IOException if there is a problem writing the object
+ */
+ private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
+ s.defaultWriteObject(); // requires serialPersistentFields to be an empty array
+ s.writeObject(returnType());
+ s.writeObject(parameterArray());
+ }
+
+ /**
+ * Reconstitute the {@code MethodType} instance from a stream (that is,
+ * deserialize it).
+ * This instance is a scratch object with bogus final fields.
+ * It provides the parameters to the factory method called by
+ * {@link #readResolve readResolve}.
+ * After that call it is discarded.
+ * @param s the stream to read the object from
+ * @throws java.io.IOException if there is a problem reading the object
+ * @throws ClassNotFoundException if one of the component classes cannot be resolved
+ * @see #MethodType()
+ * @see #readResolve
+ * @see #writeObject
+ */
+ private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException {
+ s.defaultReadObject(); // requires serialPersistentFields to be an empty array
+
+ Class<?> returnType = (Class<?>) s.readObject();
+ Class<?>[] parameterArray = (Class<?>[]) s.readObject();
+
+ // Probably this object will never escape, but let's check
+ // the field values now, just to be sure.
+ checkRtype(returnType);
+ checkPtypes(parameterArray);
+
+ parameterArray = parameterArray.clone(); // make sure it is unshared
+ MethodType_init(returnType, parameterArray);
+ }
+
+ /**
+ * For serialization only.
+ * Sets the final fields to null, pending {@code Unsafe.putObject}.
+ */
+ private MethodType() {
+ this.rtype = null;
+ this.ptypes = null;
+ }
+ private void MethodType_init(Class<?> rtype, Class<?>[] ptypes) {
+ // In order to communicate these values to readResolve, we must
+ // store them into the implementation-specific final fields.
+ checkRtype(rtype);
+ checkPtypes(ptypes);
+ UNSAFE.putObject(this, rtypeOffset, rtype);
+ UNSAFE.putObject(this, ptypesOffset, ptypes);
+ }
+
+ // Support for resetting final fields while deserializing
+ private static final long rtypeOffset, ptypesOffset;
+ static {
+ try {
+ rtypeOffset = UNSAFE.objectFieldOffset
+ (MethodType.class.getDeclaredField("rtype"));
+ ptypesOffset = UNSAFE.objectFieldOffset
+ (MethodType.class.getDeclaredField("ptypes"));
+ } catch (Exception ex) {
+ throw new Error(ex);
+ }
+ }
+
+ /**
+ * Resolves and initializes a {@code MethodType} object
+ * after serialization.
+ * @return the fully initialized {@code MethodType} object
+ */
+ private Object readResolve() {
+ // Do not use a trusted path for deserialization:
+ //return makeImpl(rtype, ptypes, true);
+ // Verify all operands, and make sure ptypes is unshared:
+ return methodType(rtype, ptypes);
+ }
+
+ /**
+ * Simple implementation of weak concurrent intern set.
+ *
+ * @param <T> interned type
+ */
+ private static class ConcurrentWeakInternSet<T> {
+
+ private final ConcurrentMap<WeakEntry<T>, WeakEntry<T>> map;
+ private final ReferenceQueue<T> stale;
+
+ public ConcurrentWeakInternSet() {
+ this.map = new ConcurrentHashMap<>();
+ this.stale = new ReferenceQueue<>();
+ }
+
+ /**
+ * Get the existing interned element.
+ * This method returns null if no element is interned.
+ *
+ * @param elem element to look up
+ * @return the interned element
+ */
+ public T get(T elem) {
+ if (elem == null) throw new NullPointerException();
+ expungeStaleElements();
+
+ WeakEntry<T> value = map.get(new WeakEntry<>(elem));
+ if (value != null) {
+ T res = value.get();
+ if (res != null) {
+ return res;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Interns the element.
+ * Always returns non-null element, matching the one in the intern set.
+ * Under the race against another add(), it can return <i>different</i>
+ * element, if another thread beats us to interning it.
+ *
+ * @param elem element to add
+ * @return element that was actually added
+ */
+ public T add(T elem) {
+ if (elem == null) throw new NullPointerException();
+
+ // Playing double race here, and so spinloop is required.
+ // First race is with two concurrent updaters.
+ // Second race is with GC purging weak ref under our feet.
+ // Hopefully, we almost always end up with a single pass.
+ T interned;
+ WeakEntry<T> e = new WeakEntry<>(elem, stale);
+ do {
+ expungeStaleElements();
+ WeakEntry<T> exist = map.putIfAbsent(e, e);
+ interned = (exist == null) ? elem : exist.get();
+ } while (interned == null);
+ return interned;
+ }
+
+ private void expungeStaleElements() {
+ Reference<? extends T> reference;
+ while ((reference = stale.poll()) != null) {
+ map.remove(reference);
+ }
+ }
+
+ private static class WeakEntry<T> extends WeakReference<T> {
+
+ public final int hashcode;
+
+ public WeakEntry(T key, ReferenceQueue<T> queue) {
+ super(key, queue);
+ hashcode = key.hashCode();
+ }
+
+ public WeakEntry(T key) {
+ super(key);
+ hashcode = key.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof WeakEntry) {
+ Object that = ((WeakEntry) obj).get();
+ Object mine = get();
+ return (that == null || mine == null) ? (this == obj) : mine.equals(that);
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return hashcode;
+ }
+
+ }
+ }
+
+}
diff --git a/java/lang/invoke/MethodTypeForm.java b/java/lang/invoke/MethodTypeForm.java
new file mode 100644
index 0000000..6f6c2a8
--- /dev/null
+++ b/java/lang/invoke/MethodTypeForm.java
@@ -0,0 +1,439 @@
+/*
+ * Copyright (c) 2008, 2013, 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 sun.invoke.util.Wrapper;
+import java.lang.ref.SoftReference;
+import static java.lang.invoke.MethodHandleStatics.*;
+
+/**
+ * Shared information for a group of method types, which differ
+ * only by reference types, and therefore share a common erasure
+ * and wrapping.
+ * <p>
+ * For an empirical discussion of the structure of method types,
+ * see <a href="http://groups.google.com/group/jvm-languages/browse_thread/thread/ac9308ae74da9b7e/">
+ * the thread "Avoiding Boxing" on jvm-languages</a>.
+ * There are approximately 2000 distinct erased method types in the JDK.
+ * There are a little over 10 times that number of unerased types.
+ * No more than half of these are likely to be loaded at once.
+ * @author John Rose
+ */
+final class MethodTypeForm {
+ final int[] argToSlotTable, slotToArgTable;
+ final long argCounts; // packed slot & value counts
+ final long primCounts; // packed prim & double counts
+ final MethodType erasedType; // the canonical erasure
+ final MethodType basicType; // the canonical erasure, with primitives simplified
+
+ // BEGIN Android-removed: Cached adaptors / lambda forms.
+ // The upstream caching mechanism will not work on Android because of fundamental differences
+ // in the Android runtime/implementation of MethodHandle. LambdaForm is not supported on
+ // Android for similar reasons.
+ /*
+ // Cached adapter information:
+ @Stable final SoftReference<MethodHandle>[] methodHandles;
+ // Indexes into methodHandles:
+ static final int
+ MH_BASIC_INV = 0, // cached instance of MH.invokeBasic
+ MH_NF_INV = 1, // cached helper for LF.NamedFunction
+ MH_UNINIT_CS = 2, // uninitialized call site
+ MH_LIMIT = 3;
+
+ // Cached lambda form information, for basic types only:
+ final @Stable SoftReference<LambdaForm>[] lambdaForms;
+ // Indexes into lambdaForms:
+ static final int
+ LF_INVVIRTUAL = 0, // DMH invokeVirtual
+ LF_INVSTATIC = 1,
+ LF_INVSPECIAL = 2,
+ LF_NEWINVSPECIAL = 3,
+ LF_INVINTERFACE = 4,
+ LF_INVSTATIC_INIT = 5, // DMH invokeStatic with <clinit> barrier
+ LF_INTERPRET = 6, // LF interpreter
+ LF_REBIND = 7, // BoundMethodHandle
+ LF_DELEGATE = 8, // DelegatingMethodHandle
+ LF_DELEGATE_BLOCK_INLINING = 9, // Counting DelegatingMethodHandle w/ @DontInline
+ LF_EX_LINKER = 10, // invokeExact_MT (for invokehandle)
+ LF_EX_INVOKER = 11, // MHs.invokeExact
+ LF_GEN_LINKER = 12, // generic invoke_MT (for invokehandle)
+ LF_GEN_INVOKER = 13, // generic MHs.invoke
+ LF_CS_LINKER = 14, // linkToCallSite_CS
+ LF_MH_LINKER = 15, // linkToCallSite_MH
+ LF_GWC = 16, // guardWithCatch (catchException)
+ LF_GWT = 17, // guardWithTest
+ LF_LIMIT = 18;
+ */
+ // END Android-removed: Cached adaptors / lambda forms.
+
+ /** Return the type corresponding uniquely (1-1) to this MT-form.
+ * It might have any primitive returns or arguments, but will have no references except Object.
+ */
+ public MethodType erasedType() {
+ return erasedType;
+ }
+
+ /** Return the basic type derived from the erased type of this MT-form.
+ * A basic type is erased (all references Object) and also has all primitive
+ * types (except int, long, float, double, void) normalized to int.
+ * Such basic types correspond to low-level JVM calling sequences.
+ */
+ public MethodType basicType() {
+ return basicType;
+ }
+
+ private boolean assertIsBasicType() {
+ // primitives must be flattened also
+ assert(erasedType == basicType)
+ : "erasedType: " + erasedType + " != basicType: " + basicType;
+ return true;
+ }
+
+ // BEGIN Android-removed: Cached adaptors / lambda forms.
+ /*
+ public MethodHandle cachedMethodHandle(int which) {
+ assert(assertIsBasicType());
+ SoftReference<MethodHandle> entry = methodHandles[which];
+ return (entry != null) ? entry.get() : null;
+ }
+
+ synchronized public MethodHandle setCachedMethodHandle(int which, MethodHandle mh) {
+ // Simulate a CAS, to avoid racy duplication of results.
+ SoftReference<MethodHandle> entry = methodHandles[which];
+ if (entry != null) {
+ MethodHandle prev = entry.get();
+ if (prev != null) {
+ return prev;
+ }
+ }
+ methodHandles[which] = new SoftReference<>(mh);
+ return mh;
+ }
+
+ public LambdaForm cachedLambdaForm(int which) {
+ assert(assertIsBasicType());
+ SoftReference<LambdaForm> entry = lambdaForms[which];
+ return (entry != null) ? entry.get() : null;
+ }
+
+ synchronized public LambdaForm setCachedLambdaForm(int which, LambdaForm form) {
+ // Simulate a CAS, to avoid racy duplication of results.
+ SoftReference<LambdaForm> entry = lambdaForms[which];
+ if (entry != null) {
+ LambdaForm prev = entry.get();
+ if (prev != null) {
+ return prev;
+ }
+ }
+ lambdaForms[which] = new SoftReference<>(form);
+ return form;
+ }
+ */
+ // END Android-removed: Cached adaptors / lambda forms.
+
+ /**
+ * Build an MTF for a given type, which must have all references erased to Object.
+ * This MTF will stand for that type and all un-erased variations.
+ * Eagerly compute some basic properties of the type, common to all variations.
+ */
+ @SuppressWarnings({"rawtypes", "unchecked"})
+ protected MethodTypeForm(MethodType erasedType) {
+ this.erasedType = erasedType;
+
+ Class<?>[] ptypes = erasedType.ptypes();
+ int ptypeCount = ptypes.length;
+ int pslotCount = ptypeCount; // temp. estimate
+ int rtypeCount = 1; // temp. estimate
+ int rslotCount = 1; // temp. estimate
+
+ int[] argToSlotTab = null, slotToArgTab = null;
+
+ // Walk the argument types, looking for primitives.
+ int pac = 0, lac = 0, prc = 0, lrc = 0;
+ Class<?>[] epts = ptypes;
+ Class<?>[] bpts = epts;
+ for (int i = 0; i < epts.length; i++) {
+ Class<?> pt = epts[i];
+ if (pt != Object.class) {
+ ++pac;
+ Wrapper w = Wrapper.forPrimitiveType(pt);
+ if (w.isDoubleWord()) ++lac;
+ if (w.isSubwordOrInt() && pt != int.class) {
+ if (bpts == epts)
+ bpts = bpts.clone();
+ bpts[i] = int.class;
+ }
+ }
+ }
+ pslotCount += lac; // #slots = #args + #longs
+ Class<?> rt = erasedType.returnType();
+ Class<?> bt = rt;
+ if (rt != Object.class) {
+ ++prc; // even void.class counts as a prim here
+ Wrapper w = Wrapper.forPrimitiveType(rt);
+ if (w.isDoubleWord()) ++lrc;
+ if (w.isSubwordOrInt() && rt != int.class)
+ bt = int.class;
+ // adjust #slots, #args
+ if (rt == void.class)
+ rtypeCount = rslotCount = 0;
+ else
+ rslotCount += lrc;
+ }
+ if (epts == bpts && bt == rt) {
+ this.basicType = erasedType;
+ } else {
+ this.basicType = MethodType.makeImpl(bt, bpts, true);
+ // fill in rest of data from the basic type:
+ MethodTypeForm that = this.basicType.form();
+ assert(this != that);
+ this.primCounts = that.primCounts;
+ this.argCounts = that.argCounts;
+ this.argToSlotTable = that.argToSlotTable;
+ this.slotToArgTable = that.slotToArgTable;
+ // Android-removed: Cached adaptors / lambda forms.
+ // this.methodHandles = null;
+ // this.lambdaForms = null;
+ return;
+ }
+ if (lac != 0) {
+ int slot = ptypeCount + lac;
+ slotToArgTab = new int[slot+1];
+ argToSlotTab = new int[1+ptypeCount];
+ argToSlotTab[0] = slot; // argument "-1" is past end of slots
+ for (int i = 0; i < epts.length; i++) {
+ Class<?> pt = epts[i];
+ Wrapper w = Wrapper.forBasicType(pt);
+ if (w.isDoubleWord()) --slot;
+ --slot;
+ slotToArgTab[slot] = i+1; // "+1" see argSlotToParameter note
+ argToSlotTab[1+i] = slot;
+ }
+ assert(slot == 0); // filled the table
+ } else if (pac != 0) {
+ // have primitives but no long primitives; share slot counts with generic
+ assert(ptypeCount == pslotCount);
+ MethodTypeForm that = MethodType.genericMethodType(ptypeCount).form();
+ assert(this != that);
+ slotToArgTab = that.slotToArgTable;
+ argToSlotTab = that.argToSlotTable;
+ } else {
+ int slot = ptypeCount; // first arg is deepest in stack
+ slotToArgTab = new int[slot+1];
+ argToSlotTab = new int[1+ptypeCount];
+ argToSlotTab[0] = slot; // argument "-1" is past end of slots
+ for (int i = 0; i < ptypeCount; i++) {
+ --slot;
+ slotToArgTab[slot] = i+1; // "+1" see argSlotToParameter note
+ argToSlotTab[1+i] = slot;
+ }
+ }
+ this.primCounts = pack(lrc, prc, lac, pac);
+ this.argCounts = pack(rslotCount, rtypeCount, pslotCount, ptypeCount);
+ this.argToSlotTable = argToSlotTab;
+ this.slotToArgTable = slotToArgTab;
+
+ if (pslotCount >= 256) throw newIllegalArgumentException("too many arguments");
+
+ // Initialize caches, but only for basic types
+ assert(basicType == erasedType);
+ // Android-removed: Cached adaptors / lambda forms.
+ // this.lambdaForms = new SoftReference[LF_LIMIT];
+ // this.methodHandles = new SoftReference[MH_LIMIT];
+ }
+
+ private static long pack(int a, int b, int c, int d) {
+ assert(((a|b|c|d) & ~0xFFFF) == 0);
+ long hw = ((a << 16) | b), lw = ((c << 16) | d);
+ return (hw << 32) | lw;
+ }
+ private static char unpack(long packed, int word) { // word==0 => return a, ==3 => return d
+ assert(word <= 3);
+ return (char)(packed >> ((3-word) * 16));
+ }
+
+ public int parameterCount() { // # outgoing values
+ return unpack(argCounts, 3);
+ }
+ public int parameterSlotCount() { // # outgoing interpreter slots
+ return unpack(argCounts, 2);
+ }
+ public int returnCount() { // = 0 (V), or 1
+ return unpack(argCounts, 1);
+ }
+ public int returnSlotCount() { // = 0 (V), 2 (J/D), or 1
+ return unpack(argCounts, 0);
+ }
+ public int primitiveParameterCount() {
+ return unpack(primCounts, 3);
+ }
+ public int longPrimitiveParameterCount() {
+ return unpack(primCounts, 2);
+ }
+ public int primitiveReturnCount() { // = 0 (obj), or 1
+ return unpack(primCounts, 1);
+ }
+ public int longPrimitiveReturnCount() { // = 1 (J/D), or 0
+ return unpack(primCounts, 0);
+ }
+ public boolean hasPrimitives() {
+ return primCounts != 0;
+ }
+ public boolean hasNonVoidPrimitives() {
+ if (primCounts == 0) return false;
+ if (primitiveParameterCount() != 0) return true;
+ return (primitiveReturnCount() != 0 && returnCount() != 0);
+ }
+ public boolean hasLongPrimitives() {
+ return (longPrimitiveParameterCount() | longPrimitiveReturnCount()) != 0;
+ }
+ public int parameterToArgSlot(int i) {
+ return argToSlotTable[1+i];
+ }
+ public int argSlotToParameter(int argSlot) {
+ // Note: Empty slots are represented by zero in this table.
+ // Valid arguments slots contain incremented entries, so as to be non-zero.
+ // We return -1 the caller to mean an empty slot.
+ return slotToArgTable[argSlot] - 1;
+ }
+
+ static MethodTypeForm findForm(MethodType mt) {
+ MethodType erased = canonicalize(mt, ERASE, ERASE);
+ if (erased == null) {
+ // It is already erased. Make a new MethodTypeForm.
+ return new MethodTypeForm(mt);
+ } else {
+ // Share the MethodTypeForm with the erased version.
+ return erased.form();
+ }
+ }
+
+ /** Codes for {@link #canonicalize(java.lang.Class, int)}.
+ * ERASE means change every reference to {@code Object}.
+ * WRAP means convert primitives (including {@code void} to their
+ * corresponding wrapper types. UNWRAP means the reverse of WRAP.
+ * INTS means convert all non-void primitive types to int or long,
+ * according to size. LONGS means convert all non-void primitives
+ * to long, regardless of size. RAW_RETURN means convert a type
+ * (assumed to be a return type) to int if it is smaller than an int,
+ * or if it is void.
+ */
+ public static final int NO_CHANGE = 0, ERASE = 1, WRAP = 2, UNWRAP = 3, INTS = 4, LONGS = 5, RAW_RETURN = 6;
+
+ /** Canonicalize the types in the given method type.
+ * If any types change, intern the new type, and return it.
+ * Otherwise return null.
+ */
+ public static MethodType canonicalize(MethodType mt, int howRet, int howArgs) {
+ Class<?>[] ptypes = mt.ptypes();
+ Class<?>[] ptc = MethodTypeForm.canonicalizeAll(ptypes, howArgs);
+ Class<?> rtype = mt.returnType();
+ Class<?> rtc = MethodTypeForm.canonicalize(rtype, howRet);
+ if (ptc == null && rtc == null) {
+ // It is already canonical.
+ return null;
+ }
+ // Find the erased version of the method type:
+ if (rtc == null) rtc = rtype;
+ if (ptc == null) ptc = ptypes;
+ return MethodType.makeImpl(rtc, ptc, true);
+ }
+
+ /** Canonicalize the given return or param type.
+ * Return null if the type is already canonicalized.
+ */
+ static Class<?> canonicalize(Class<?> t, int how) {
+ Class<?> ct;
+ if (t == Object.class) {
+ // no change, ever
+ } else if (!t.isPrimitive()) {
+ switch (how) {
+ case UNWRAP:
+ ct = Wrapper.asPrimitiveType(t);
+ if (ct != t) return ct;
+ break;
+ case RAW_RETURN:
+ case ERASE:
+ return Object.class;
+ }
+ } else if (t == void.class) {
+ // no change, usually
+ switch (how) {
+ case RAW_RETURN:
+ return int.class;
+ case WRAP:
+ return Void.class;
+ }
+ } else {
+ // non-void primitive
+ switch (how) {
+ case WRAP:
+ return Wrapper.asWrapperType(t);
+ case INTS:
+ if (t == int.class || t == long.class)
+ return null; // no change
+ if (t == double.class)
+ return long.class;
+ return int.class;
+ case LONGS:
+ if (t == long.class)
+ return null; // no change
+ return long.class;
+ case RAW_RETURN:
+ if (t == int.class || t == long.class ||
+ t == float.class || t == double.class)
+ return null; // no change
+ // everything else returns as an int
+ return int.class;
+ }
+ }
+ // no change; return null to signify
+ return null;
+ }
+
+ /** Canonicalize each param type in the given array.
+ * Return null if all types are already canonicalized.
+ */
+ static Class<?>[] canonicalizeAll(Class<?>[] ts, int how) {
+ Class<?>[] cs = null;
+ for (int imax = ts.length, i = 0; i < imax; i++) {
+ Class<?> c = canonicalize(ts[i], how);
+ if (c == void.class)
+ c = null; // a Void parameter was unwrapped to void; ignore
+ if (c != null) {
+ if (cs == null)
+ cs = ts.clone();
+ cs[i] = c;
+ }
+ }
+ return cs;
+ }
+
+ @Override
+ public String toString() {
+ return "Form"+erasedType;
+ }
+}
diff --git a/java/lang/invoke/MutableCallSite.java b/java/lang/invoke/MutableCallSite.java
new file mode 100644
index 0000000..305579f
--- /dev/null
+++ b/java/lang/invoke/MutableCallSite.java
@@ -0,0 +1,282 @@
+/*
+ * Copyright (c) 2008, 2013, 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;
+
+// Android-changed: removed references to MutableCallSite.syncAll().
+/**
+ * A {@code MutableCallSite} is a {@link CallSite} whose target variable
+ * behaves like an ordinary field.
+ * An {@code invokedynamic} instruction linked to a {@code MutableCallSite} delegates
+ * all calls to the site's current target.
+ * The {@linkplain CallSite#dynamicInvoker dynamic invoker} of a mutable call site
+ * also delegates each call to the site's current target.
+ * <p>
+ * Here is an example of a mutable call site which introduces a
+ * state variable into a method handle chain.
+ * <!-- JavaDocExamplesTest.testMutableCallSite -->
+ * <blockquote><pre>{@code
+MutableCallSite name = new MutableCallSite(MethodType.methodType(String.class));
+MethodHandle MH_name = name.dynamicInvoker();
+MethodType MT_str1 = MethodType.methodType(String.class);
+MethodHandle MH_upcase = MethodHandles.lookup()
+ .findVirtual(String.class, "toUpperCase", MT_str1);
+MethodHandle worker1 = MethodHandles.filterReturnValue(MH_name, MH_upcase);
+name.setTarget(MethodHandles.constant(String.class, "Rocky"));
+assertEquals("ROCKY", (String) worker1.invokeExact());
+name.setTarget(MethodHandles.constant(String.class, "Fred"));
+assertEquals("FRED", (String) worker1.invokeExact());
+// (mutation can be continued indefinitely)
+ * }</pre></blockquote>
+ * <p>
+ * The same call site may be used in several places at once.
+ * <blockquote><pre>{@code
+MethodType MT_str2 = MethodType.methodType(String.class, String.class);
+MethodHandle MH_cat = lookup().findVirtual(String.class,
+ "concat", methodType(String.class, String.class));
+MethodHandle MH_dear = MethodHandles.insertArguments(MH_cat, 1, ", dear?");
+MethodHandle worker2 = MethodHandles.filterReturnValue(MH_name, MH_dear);
+assertEquals("Fred, dear?", (String) worker2.invokeExact());
+name.setTarget(MethodHandles.constant(String.class, "Wilma"));
+assertEquals("WILMA", (String) worker1.invokeExact());
+assertEquals("Wilma, dear?", (String) worker2.invokeExact());
+ * }</pre></blockquote>
+ * <p>
+ * <em>Non-synchronization of target values:</em>
+ * A write to a mutable call site's target does not force other threads
+ * to become aware of the updated value. Threads which do not perform
+ * suitable synchronization actions relative to the updated call site
+ * may cache the old target value and delay their use of the new target
+ * value indefinitely.
+ * (This is a normal consequence of the Java Memory Model as applied
+ * to object fields.)
+ * <p>
+ * For target values which will be frequently updated, consider using
+ * a {@linkplain VolatileCallSite volatile call site} instead.
+ * @author John Rose, JSR 292 EG
+ */
+public class MutableCallSite extends CallSite {
+ /**
+ * Creates a blank call site object with the given method type.
+ * The initial target is set to a method handle of the given type
+ * which will throw an {@link IllegalStateException} if called.
+ * <p>
+ * The type of the call site is permanently set to the given type.
+ * <p>
+ * Before this {@code CallSite} object is returned from a bootstrap method,
+ * or invoked in some other manner,
+ * it is usually provided with a more useful target method,
+ * via a call to {@link CallSite#setTarget(MethodHandle) setTarget}.
+ * @param type the method type that this call site will have
+ * @throws NullPointerException if the proposed type is null
+ */
+ public MutableCallSite(MethodType type) {
+ super(type);
+ }
+
+ /**
+ * Creates a call site object with an initial target method handle.
+ * The type of the call site is permanently set to the initial target's type.
+ * @param target the method handle that will be the initial target of the call site
+ * @throws NullPointerException if the proposed target is null
+ */
+ public MutableCallSite(MethodHandle target) {
+ super(target);
+ }
+
+ /**
+ * Returns the target method of the call site, which behaves
+ * like a normal field of the {@code MutableCallSite}.
+ * <p>
+ * The interactions of {@code getTarget} with memory are the same
+ * as of a read from an ordinary variable, such as an array element or a
+ * non-volatile, non-final field.
+ * <p>
+ * In particular, the current thread may choose to reuse the result
+ * of a previous read of the target from memory, and may fail to see
+ * a recent update to the target by another thread.
+ *
+ * @return the linkage state of this call site, a method handle which can change over time
+ * @see #setTarget
+ */
+ @Override public final MethodHandle getTarget() {
+ return target;
+ }
+
+ /**
+ * Updates the target method of this call site, as a normal variable.
+ * The type of the new target must agree with the type of the old target.
+ * <p>
+ * The interactions with memory are the same
+ * as of a write to an ordinary variable, such as an array element or a
+ * non-volatile, non-final field.
+ * <p>
+ * In particular, unrelated threads may fail to see the updated target
+ * until they perform a read from memory.
+ * Stronger guarantees can be created by putting appropriate operations
+ * into the bootstrap method and/or the target methods used
+ * at any given call site.
+ *
+ * @param newTarget the new target
+ * @throws NullPointerException if the proposed new target is null
+ * @throws WrongMethodTypeException if the proposed new target
+ * has a method type that differs from the previous target
+ * @see #getTarget
+ */
+ @Override public void setTarget(MethodHandle newTarget) {
+ checkTargetChange(this.target, newTarget);
+ setTargetNormal(newTarget);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public final MethodHandle dynamicInvoker() {
+ return makeDynamicInvoker();
+ }
+
+ // BEGIN Android-removed: syncAll() implementation is incomplete.
+ /**
+ * Performs a synchronization operation on each call site in the given array,
+ * forcing all other threads to throw away any cached values previously
+ * loaded from the target of any of the call sites.
+ * <p>
+ * This operation does not reverse any calls that have already started
+ * on an old target value.
+ * (Java supports {@linkplain java.lang.Object#wait() forward time travel} only.)
+ * <p>
+ * The overall effect is to force all future readers of each call site's target
+ * to accept the most recently stored value.
+ * ("Most recently" is reckoned relative to the {@code syncAll} itself.)
+ * Conversely, the {@code syncAll} call may block until all readers have
+ * (somehow) decached all previous versions of each call site's target.
+ * <p>
+ * To avoid race conditions, calls to {@code setTarget} and {@code syncAll}
+ * should generally be performed under some sort of mutual exclusion.
+ * Note that reader threads may observe an updated target as early
+ * as the {@code setTarget} call that install the value
+ * (and before the {@code syncAll} that confirms the value).
+ * On the other hand, reader threads may observe previous versions of
+ * the target until the {@code syncAll} call returns
+ * (and after the {@code setTarget} that attempts to convey the updated version).
+ * <p>
+ * This operation is likely to be expensive and should be used sparingly.
+ * If possible, it should be buffered for batch processing on sets of call sites.
+ * <p>
+ * If {@code sites} contains a null element,
+ * a {@code NullPointerException} will be raised.
+ * In this case, some non-null elements in the array may be
+ * processed before the method returns abnormally.
+ * Which elements these are (if any) is implementation-dependent.
+ *
+ * <h1>Java Memory Model details</h1>
+ * In terms of the Java Memory Model, this operation performs a synchronization
+ * action which is comparable in effect to the writing of a volatile variable
+ * by the current thread, and an eventual volatile read by every other thread
+ * that may access one of the affected call sites.
+ * <p>
+ * The following effects are apparent, for each individual call site {@code S}:
+ * <ul>
+ * <li>A new volatile variable {@code V} is created, and written by the current thread.
+ * As defined by the JMM, this write is a global synchronization event.
+ * <li>As is normal with thread-local ordering of write events,
+ * every action already performed by the current thread is
+ * taken to happen before the volatile write to {@code V}.
+ * (In some implementations, this means that the current thread
+ * performs a global release operation.)
+ * <li>Specifically, the write to the current target of {@code S} is
+ * taken to happen before the volatile write to {@code V}.
+ * <li>The volatile write to {@code V} is placed
+ * (in an implementation specific manner)
+ * in the global synchronization order.
+ * <li>Consider an arbitrary thread {@code T} (other than the current thread).
+ * If {@code T} executes a synchronization action {@code A}
+ * after the volatile write to {@code V} (in the global synchronization order),
+ * it is therefore required to see either the current target
+ * of {@code S}, or a later write to that target,
+ * if it executes a read on the target of {@code S}.
+ * (This constraint is called "synchronization-order consistency".)
+ * <li>The JMM specifically allows optimizing compilers to elide
+ * reads or writes of variables that are known to be useless.
+ * Such elided reads and writes have no effect on the happens-before
+ * relation. Regardless of this fact, the volatile {@code V}
+ * will not be elided, even though its written value is
+ * indeterminate and its read value is not used.
+ * </ul>
+ * Because of the last point, the implementation behaves as if a
+ * volatile read of {@code V} were performed by {@code T}
+ * immediately after its action {@code A}. In the local ordering
+ * of actions in {@code T}, this read happens before any future
+ * read of the target of {@code S}. It is as if the
+ * implementation arbitrarily picked a read of {@code S}'s target
+ * by {@code T}, and forced a read of {@code V} to precede it,
+ * thereby ensuring communication of the new target value.
+ * <p>
+ * As long as the constraints of the Java Memory Model are obeyed,
+ * implementations may delay the completion of a {@code syncAll}
+ * operation while other threads ({@code T} above) continue to
+ * use previous values of {@code S}'s target.
+ * However, implementations are (as always) encouraged to avoid
+ * livelock, and to eventually require all threads to take account
+ * of the updated target.
+ *
+ * <p style="font-size:smaller;">
+ * <em>Discussion:</em>
+ * For performance reasons, {@code syncAll} is not a virtual method
+ * on a single call site, but rather applies to a set of call sites.
+ * Some implementations may incur a large fixed overhead cost
+ * for processing one or more synchronization operations,
+ * but a small incremental cost for each additional call site.
+ * In any case, this operation is likely to be costly, since
+ * other threads may have to be somehow interrupted
+ * in order to make them notice the updated target value.
+ * However, it may be observed that a single call to synchronize
+ * several sites has the same formal effect as many calls,
+ * each on just one of the sites.
+ *
+ * <p style="font-size:smaller;">
+ * <em>Implementation Note:</em>
+ * Simple implementations of {@code MutableCallSite} may use
+ * a volatile variable for the target of a mutable call site.
+ * In such an implementation, the {@code syncAll} method can be a no-op,
+ * and yet it will conform to the JMM behavior documented above.
+ *
+ * @param sites an array of call sites to be synchronized
+ * @throws NullPointerException if the {@code sites} array reference is null
+ * or the array contains a null
+ *
+ public static void syncAll(MutableCallSite[] sites) {
+ if (sites.length == 0) return;
+ STORE_BARRIER.lazySet(0);
+ for (int i = 0; i < sites.length; i++) {
+ sites[i].getClass(); // trigger NPE on first null
+ }
+ // FIXME: NYI
+ }
+ private static final AtomicInteger STORE_BARRIER = new AtomicInteger();
+ */
+ // END Android-removed: syncAll() implementation is incomplete.
+}
diff --git a/java/lang/invoke/SerializedLambda.java b/java/lang/invoke/SerializedLambda.java
new file mode 100644
index 0000000..55ec670
--- /dev/null
+++ b/java/lang/invoke/SerializedLambda.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2012, 2013, 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.io.Serializable;
+
+public final class SerializedLambda implements Serializable {
+
+ public SerializedLambda(Class<?> capturingClass,
+ String functionalInterfaceClass,
+ String functionalInterfaceMethodName,
+ String functionalInterfaceMethodSignature,
+ int implMethodKind,
+ String implClass,
+ String implMethodName,
+ String implMethodSignature,
+ String instantiatedMethodType,
+ Object[] capturedArgs) { }
+
+ public String getCapturingClass() { return null; }
+
+ public String getFunctionalInterfaceClass() {
+ return null;
+ }
+
+ public String getFunctionalInterfaceMethodName() {
+ return null;
+ }
+
+ public String getFunctionalInterfaceMethodSignature() { return null; }
+
+ public String getImplClass() {
+ return null;
+ }
+
+ public String getImplMethodName() {
+ return null;
+ }
+
+ public String getImplMethodSignature() {
+ return null;
+ }
+
+ public int getImplMethodKind() {
+ return 0;
+ }
+
+ public final String getInstantiatedMethodType() {
+ return null;
+ }
+
+ public int getCapturedArgCount() {
+ return 0;
+ }
+
+ public Object getCapturedArg(int i) {
+ return null;
+ }
+
+}
diff --git a/java/lang/invoke/Stable.java b/java/lang/invoke/Stable.java
new file mode 100644
index 0000000..a0a413e
--- /dev/null
+++ b/java/lang/invoke/Stable.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2012, 2013, 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.lang.annotation.*;
+
+/**
+ * A field may be annotated as stable if all of its component variables
+ * changes value at most once.
+ * A field's value counts as its component value.
+ * If the field is typed as an array, then all the non-null components
+ * of the array, of depth up to the rank of the field's array type,
+ * also count as component values.
+ * By extension, any variable (either array or field) which has annotated
+ * as stable is called a stable variable, and its non-null or non-zero
+ * value is called a stable value.
+ * <p>
+ * Since all fields begin with a default value of null for references
+ * (resp., zero for primitives), it follows that this annotation indicates
+ * that the first non-null (resp., non-zero) value stored in the field
+ * will never be changed.
+ * <p>
+ * If the field is not of an array type, there are no array elements,
+ * then the value indicated as stable is simply the value of the field.
+ * If the dynamic type of the field value is an array but the static type
+ * is not, the components of the array are <em>not</em> regarded as stable.
+ * <p>
+ * If the field is an array type, then both the field value and
+ * all the components of the field value (if the field value is non-null)
+ * are indicated to be stable.
+ * If the field type is an array type with rank {@code N > 1},
+ * then each component of the field value (if the field value is non-null),
+ * is regarded as a stable array of rank {@code N-1}.
+ * <p>
+ * Fields which are declared {@code final} may also be annotated as stable.
+ * Since final fields already behave as stable values, such an annotation
+ * indicates no additional information, unless the type of the field is
+ * an array type.
+ * <p>
+ * It is (currently) undefined what happens if a field annotated as stable
+ * is given a third value. In practice, if the JVM relies on this annotation
+ * to promote a field reference to a constant, it may be that the Java memory
+ * model would appear to be broken, if such a constant (the second value of the field)
+ * is used as the value of the field even after the field value has changed.
+ */
+/* package-private */
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+@interface Stable {
+}
diff --git a/java/lang/invoke/Transformers.java b/java/lang/invoke/Transformers.java
new file mode 100644
index 0000000..15546a8
--- /dev/null
+++ b/java/lang/invoke/Transformers.java
@@ -0,0 +1,2307 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * 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. The Android Open Source
+ * Project designates this particular file as subject to the "Classpath"
+ * exception as provided by The Android Open Source Project 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.
+ */
+
+package java.lang.invoke;
+
+import dalvik.system.EmulatedStackFrame;
+import dalvik.system.EmulatedStackFrame.Range;
+import dalvik.system.EmulatedStackFrame.StackFrameAccessor;
+import dalvik.system.EmulatedStackFrame.StackFrameReader;
+import dalvik.system.EmulatedStackFrame.StackFrameWriter;
+import java.lang.reflect.Array;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import sun.invoke.util.Wrapper;
+import sun.misc.Unsafe;
+import static dalvik.system.EmulatedStackFrame.StackFrameAccessor.copyNext;
+
+/**
+ * @hide Public for testing only.
+ */
+public class Transformers {
+ private Transformers() {}
+
+ static {
+ try {
+ TRANSFORM_INTERNAL = MethodHandle.class.getDeclaredMethod("transformInternal",
+ EmulatedStackFrame.class);
+ } catch (NoSuchMethodException nsme) {
+ throw new AssertionError();
+ }
+ }
+
+ /**
+ * Method reference to the private {@code MethodHandle.transformInternal} method. This is
+ * cached here because it's the point of entry for all transformers.
+ */
+ private static final Method TRANSFORM_INTERNAL;
+
+ /** @hide */
+ public static abstract class Transformer extends MethodHandle implements Cloneable {
+ protected Transformer(MethodType type) {
+ super(TRANSFORM_INTERNAL.getArtMethod(), MethodHandle.INVOKE_TRANSFORM, type);
+ }
+
+ protected Transformer(MethodType type, int invokeKind) {
+ super(TRANSFORM_INTERNAL.getArtMethod(), invokeKind, type);
+ }
+
+ @Override
+ public Object clone() throws CloneNotSupportedException {
+ return super.clone();
+ }
+ }
+
+ /**
+ * A method handle that always throws an exception of a specified type.
+ *
+ * The handle declares a nominal return type, which is immaterial to the execution
+ * of the handle because it never returns.
+ *
+ * @hide
+ */
+ public static class AlwaysThrow extends Transformer {
+ private final Class<? extends Throwable> exceptionType;
+
+ public AlwaysThrow(Class<?> nominalReturnType, Class<? extends Throwable> exType) {
+ super(MethodType.methodType(nominalReturnType, exType));
+ this.exceptionType = exType;
+ }
+
+ @Override
+ public void transform(EmulatedStackFrame emulatedStackFrame) throws Throwable {
+ throw emulatedStackFrame.getReference(0, exceptionType);
+ }
+ }
+
+ /**
+ * Implements {@code MethodHandles.dropArguments}.
+ */
+ public static class DropArguments extends Transformer {
+ private final MethodHandle delegate;
+
+ private final EmulatedStackFrame.Range range1;
+
+ /**
+ * Note that {@code range2} will be null if the arguments that are being dropped
+ * are the last {@code n}.
+ */
+ /* @Nullable */ private final EmulatedStackFrame.Range range2;
+
+ public DropArguments(MethodType type, MethodHandle delegate,
+ int startPos, int numDropped) {
+ super(type);
+
+ this.delegate = delegate;
+
+ // We pre-calculate the ranges of values we have to copy through to the delegate
+ // handle at the time of instantiation so that the actual invoke is performant.
+ this.range1 = EmulatedStackFrame.Range.of(type, 0, startPos);
+ final int numArgs = type.ptypes().length;
+ if (startPos + numDropped < numArgs) {
+ this.range2 = EmulatedStackFrame.Range.of(type, startPos + numDropped, numArgs);
+ } else {
+ this.range2 = null;
+ }
+ }
+
+ @Override
+ public void transform(EmulatedStackFrame emulatedStackFrame) throws Throwable {
+ EmulatedStackFrame calleeFrame = EmulatedStackFrame.create(delegate.type());
+
+ emulatedStackFrame.copyRangeTo(calleeFrame, range1,
+ 0 /* referencesStart */, 0 /* stackFrameStart */);
+
+ if (range2 != null) {
+ final int referencesStart = range1.numReferences;
+ final int stackFrameStart = range1.numBytes;
+
+ emulatedStackFrame.copyRangeTo(calleeFrame, range2,
+ referencesStart, stackFrameStart);
+ }
+
+ delegate.invoke(calleeFrame);
+ calleeFrame.copyReturnValueTo(emulatedStackFrame);
+ }
+ }
+
+ /**
+ * Implements {@code MethodHandles.catchException}.
+ */
+ public static class CatchException extends Transformer {
+ private final MethodHandle target;
+ private final MethodHandle handler;
+ private final Class<?> exType;
+
+ private final EmulatedStackFrame.Range handlerArgsRange;
+
+ public CatchException(MethodHandle target, MethodHandle handler, Class<?> exType) {
+ super(target.type());
+
+ this.target = target;
+ this.handler = handler;
+ this.exType = exType;
+
+ // We only copy the first "count" args, dropping others if required. Note that
+ // we subtract one because the first handler arg is the exception thrown by the
+ // target.
+ handlerArgsRange = EmulatedStackFrame.Range.of(target.type(), 0,
+ (handler.type().parameterCount() - 1));
+ }
+
+ @Override
+ public void transform(EmulatedStackFrame emulatedStackFrame) throws Throwable {
+ try {
+ target.invoke(emulatedStackFrame);
+ } catch (Throwable th) {
+ if (th.getClass() == exType) {
+ // We've gotten an exception of the appropriate type, so we need to call
+ // the handler. Create a new frame of the appropriate size.
+ EmulatedStackFrame fallback = EmulatedStackFrame.create(handler.type());
+
+ // The first argument to the handler is the actual exception.
+ fallback.setReference(0, th);
+
+ // We then copy other arguments that need to be passed through to the handler.
+ // Note that we might drop arguments at the end, if needed. Note that
+ // referencesStart == 1 because the first argument is the exception type.
+ emulatedStackFrame.copyRangeTo(fallback, handlerArgsRange,
+ 1 /* referencesStart */, 0 /* stackFrameStart */);
+
+ // Perform the invoke and return the appropriate value.
+ handler.invoke(fallback);
+ fallback.copyReturnValueTo(emulatedStackFrame);
+ } else {
+ // The exception is not of the expected type, we throw it.
+ throw th;
+ }
+ }
+ }
+ }
+
+ /**
+ * Implements {@code MethodHandles.GuardWithTest}.
+ */
+ public static class GuardWithTest extends Transformer {
+ private final MethodHandle test;
+ private final MethodHandle target;
+ private final MethodHandle fallback;
+
+ private final EmulatedStackFrame.Range testArgsRange;
+
+ public GuardWithTest(MethodHandle test, MethodHandle target, MethodHandle fallback) {
+ super(target.type());
+
+ this.test = test;
+ this.target = target;
+ this.fallback = fallback;
+
+ // The test method might have a subset of the arguments of the handle / target.
+ testArgsRange = EmulatedStackFrame.Range.of(target.type(), 0, test.type().parameterCount());
+ }
+
+ @Override
+ public void transform(EmulatedStackFrame emulatedStackFrame) throws Throwable {
+ EmulatedStackFrame testFrame = EmulatedStackFrame.create(test.type());
+ emulatedStackFrame.copyRangeTo(testFrame, testArgsRange, 0, 0);
+
+ // We know that the return value for test is going to be boolean.class, so we don't have
+ // to do the copyReturnValue dance.
+ final boolean value = (boolean) test.invoke(testFrame);
+ if (value) {
+ target.invoke(emulatedStackFrame);
+ } else {
+ fallback.invoke(emulatedStackFrame);
+ }
+ }
+ }
+
+ /**
+ * Implementation of MethodHandles.arrayElementGetter for reference types.
+ */
+ public static class ReferenceArrayElementGetter extends Transformer {
+ private final Class<?> arrayClass;
+
+ public ReferenceArrayElementGetter(Class<?> arrayClass) {
+ super(MethodType.methodType(arrayClass.getComponentType(),
+ new Class<?>[]{arrayClass, int.class}));
+ this.arrayClass = arrayClass;
+ }
+
+ @Override
+ public void transform(EmulatedStackFrame emulatedStackFrame) throws Throwable {
+ final StackFrameReader reader = new StackFrameReader();
+ reader.attach(emulatedStackFrame);
+
+ // Read the array object and the index from the stack frame.
+ final Object[] array = (Object[]) reader.nextReference(arrayClass);
+ final int index = reader.nextInt();
+
+ // Write the array element back to the stack frame.
+ final StackFrameWriter writer = new StackFrameWriter();
+ writer.attach(emulatedStackFrame);
+ writer.makeReturnValueAccessor();
+ writer.putNextReference(array[index], arrayClass.getComponentType());
+ }
+ }
+
+ /**
+ * Implementation of MethodHandles.arrayElementSetter for reference types.
+ */
+ public static class ReferenceArrayElementSetter extends Transformer {
+ private final Class<?> arrayClass;
+
+ public ReferenceArrayElementSetter(Class<?> arrayClass) {
+ super(MethodType.methodType(void.class,
+ new Class<?>[] { arrayClass, int.class, arrayClass.getComponentType() }));
+ this.arrayClass = arrayClass;
+ }
+
+ @Override
+ public void transform(EmulatedStackFrame emulatedStackFrame) throws Throwable {
+ final StackFrameReader reader = new StackFrameReader();
+ reader.attach(emulatedStackFrame);
+
+ // Read the array object, index and the value to write from the stack frame.
+ final Object[] array = (Object[]) reader.nextReference(arrayClass);
+ final int index = reader.nextInt();
+ final Object value = reader.nextReference(arrayClass.getComponentType());
+
+ array[index] = value;
+ }
+ }
+
+ /**
+ * Implementation of MethodHandles.identity() for reference types.
+ */
+ public static class ReferenceIdentity extends Transformer {
+ private final Class<?> type;
+
+ public ReferenceIdentity(Class<?> type) {
+ super(MethodType.methodType(type, type));
+ this.type = type;
+ }
+
+ @Override
+ public void transform(EmulatedStackFrame emulatedStackFrame) throws Throwable {
+ final StackFrameReader reader = new StackFrameReader();
+ reader.attach(emulatedStackFrame);
+
+ final StackFrameWriter writer = new StackFrameWriter();
+ writer.attach(emulatedStackFrame);
+ writer.makeReturnValueAccessor();
+ writer.putNextReference(reader.nextReference(type), type);
+ }
+ }
+
+ /**
+ * Implementation of MethodHandles.constant.
+ */
+ public static class Constant extends Transformer {
+ private final Class<?> type;
+
+ // NOTE: This implementation turned out to be more awkward than expected becuase
+ // of the type system. We could simplify this considerably at the cost of making
+ // the emulated stack frame API uglier or by transitioning into JNI.
+ //
+ // We could consider implementing this in terms of bind() once that's implemented.
+ // This would then just become : MethodHandles.identity(type).bind(value).
+ private int asInt;
+ private long asLong;
+ private float asFloat;
+ private double asDouble;
+ private Object asReference;
+
+ private char typeChar;
+
+ public Constant(Class<?> type, Object value) {
+ super(MethodType.methodType(type));
+ this.type = type;
+
+ if (!type.isPrimitive()) {
+ asReference = value;
+ typeChar = 'L';
+ } else if (type == int.class) {
+ asInt = (int) value;
+ typeChar = 'I';
+ } else if (type == char.class) {
+ asInt = (int) (char) value;
+ typeChar = 'C';
+ } else if (type == short.class) {
+ asInt = (int) (short) value;
+ typeChar = 'S';
+ } else if (type == byte.class) {
+ asInt = (int) (byte) value;
+ typeChar = 'B';
+ } else if (type == boolean.class) {
+ asInt = ((boolean) value) ? 1 : 0;
+ typeChar = 'Z';
+ } else if (type == long.class) {
+ asLong = (long) value;
+ typeChar = 'J';
+ } else if (type == float.class) {
+ asFloat = (float) value;
+ typeChar = 'F';
+ } else if (type == double.class) {
+ asDouble = (double) value;
+ typeChar = 'D';
+ } else {
+ throw new AssertionError("unknown type: " + typeChar);
+ }
+ }
+
+ @Override
+ public void transform(EmulatedStackFrame emulatedStackFrame) throws Throwable {
+ final StackFrameWriter writer = new StackFrameWriter();
+ writer.attach(emulatedStackFrame);
+ writer.makeReturnValueAccessor();
+
+ switch (typeChar) {
+ case 'L' : { writer.putNextReference(asReference, type); break; }
+ case 'I' : { writer.putNextInt(asInt); break; }
+ case 'C' : { writer.putNextChar((char) asInt); break; }
+ case 'S' : { writer.putNextShort((short) asInt); break; }
+ case 'B' : { writer.putNextByte((byte) asInt); break; }
+ case 'Z' : { writer.putNextBoolean(asInt == 1); break; }
+ case 'J' : { writer.putNextLong(asLong); break; }
+ case 'F' : { writer.putNextFloat(asFloat); break; }
+ case 'D' : { writer.putNextDouble(asDouble); break; }
+ default:
+ throw new AssertionError("Unexpected typeChar: " + typeChar);
+ }
+ }
+ }
+
+ /*package*/ static class Construct extends Transformer {
+ private final MethodHandle constructorHandle;
+ private final EmulatedStackFrame.Range callerRange;
+
+ /*package*/ Construct(MethodHandle constructorHandle, MethodType returnedType) {
+ super(returnedType);
+ this.constructorHandle = constructorHandle;
+ this.callerRange = EmulatedStackFrame.Range.all(type());
+ }
+
+ MethodHandle getConstructorHandle() {
+ return constructorHandle;
+ }
+
+ private static boolean isAbstract(Class<?> klass) {
+ return (klass.getModifiers() & Modifier.ABSTRACT) == Modifier.ABSTRACT;
+ }
+
+ private static void checkInstantiable(Class<?> klass) throws InstantiationException {
+ if (isAbstract(klass)) {
+ String s = klass.isInterface() ? "interface " : "abstract class ";
+ throw new InstantiationException("Can't instantiate " + s + klass);
+ }
+ }
+
+ @Override
+ public void transform(EmulatedStackFrame emulatedStackFrame) throws Throwable {
+ final Class<?> receiverType = constructorHandle.type().parameterType(0);
+ checkInstantiable(receiverType);
+
+ // Allocate memory for receiver.
+ Object receiver = Unsafe.getUnsafe().allocateInstance(receiverType);
+
+ // The MethodHandle type for the caller has the form of
+ // {rtype=T,ptypes=A1..An}. The constructor MethodHandle is of
+ // the form {rtype=void,ptypes=T,A1...An}. So the frame for
+ // the constructor needs to have a slot with the receiver
+ // in position 0.
+ EmulatedStackFrame constructorFrame =
+ EmulatedStackFrame.create(constructorHandle.type());
+ constructorFrame.setReference(0, receiver);
+ emulatedStackFrame.copyRangeTo(constructorFrame, callerRange, 1, 0);
+ constructorHandle.invoke(constructorFrame);
+
+ // Set return result for caller.
+ emulatedStackFrame.setReturnValueTo(receiver);
+ }
+ }
+
+ /**
+ * Implements MethodHandle.bindTo.
+ *
+ * @hide
+ */
+ public static class BindTo extends Transformer {
+ private final MethodHandle delegate;
+ private final Object receiver;
+
+ private final EmulatedStackFrame.Range range;
+
+ public BindTo(MethodHandle delegate, Object receiver) {
+ super(delegate.type().dropParameterTypes(0, 1));
+
+ this.delegate = delegate;
+ this.receiver = receiver;
+
+ this.range = EmulatedStackFrame.Range.all(this.type());
+ }
+
+ @Override
+ public void transform(EmulatedStackFrame emulatedStackFrame) throws Throwable {
+ // Create a new emulated stack frame with the full type (including the leading
+ // receiver reference).
+ EmulatedStackFrame stackFrame = EmulatedStackFrame.create(delegate.type());
+
+ // The first reference argument must be the receiver.
+ stackFrame.setReference(0, receiver);
+ // Copy all other arguments.
+ emulatedStackFrame.copyRangeTo(stackFrame, range,
+ 1 /* referencesStart */, 0 /* stackFrameStart */);
+
+ // Perform the invoke.
+ delegate.invoke(stackFrame);
+ stackFrame.copyReturnValueTo(emulatedStackFrame);
+ }
+ }
+
+ /**
+ * Implements MethodHandle.filterReturnValue.
+ */
+ public static class FilterReturnValue extends Transformer {
+ private final MethodHandle target;
+ private final MethodHandle filter;
+
+ private final EmulatedStackFrame.Range allArgs;
+
+ public FilterReturnValue(MethodHandle target, MethodHandle filter) {
+ super(MethodType.methodType(filter.type().rtype(), target.type().ptypes()));
+
+ this.target = target;
+ this.filter = filter;
+
+ allArgs = EmulatedStackFrame.Range.all(type());
+ }
+
+ @Override
+ public void transform(EmulatedStackFrame emulatedStackFrame) throws Throwable {
+ // Create a new frame with the target's type and copy all arguments over.
+ // This frame differs in return type with |emulatedStackFrame| but will have
+ // the same parameter shapes.
+ EmulatedStackFrame targetFrame = EmulatedStackFrame.create(target.type());
+ emulatedStackFrame.copyRangeTo(targetFrame, allArgs, 0, 0);
+ target.invoke(targetFrame);
+
+ // Perform the invoke.
+ final StackFrameReader returnValueReader = new StackFrameReader();
+ returnValueReader.attach(targetFrame);
+ returnValueReader.makeReturnValueAccessor();
+
+ // Create an emulated frame for the filter and copy all its arguments across.
+ EmulatedStackFrame filterFrame = EmulatedStackFrame.create(filter.type());
+ final StackFrameWriter filterWriter = new StackFrameWriter();
+ filterWriter.attach(filterFrame);
+
+ final Class<?> returnType = target.type().rtype();
+ if (!returnType.isPrimitive()) {
+ filterWriter.putNextReference(returnValueReader.nextReference(returnType),
+ returnType);
+ } else if (returnType == boolean.class) {
+ filterWriter.putNextBoolean(returnValueReader.nextBoolean());
+ } else if (returnType == byte.class) {
+ filterWriter.putNextByte(returnValueReader.nextByte());
+ } else if (returnType == char.class) {
+ filterWriter.putNextChar(returnValueReader.nextChar());
+ } else if (returnType == short.class) {
+ filterWriter.putNextShort(returnValueReader.nextShort());
+ } else if (returnType == int.class) {
+ filterWriter.putNextInt(returnValueReader.nextInt());
+ } else if (returnType == long.class) {
+ filterWriter.putNextLong(returnValueReader.nextLong());
+ } else if (returnType == float.class) {
+ filterWriter.putNextFloat(returnValueReader.nextFloat());
+ } else if (returnType == double.class) {
+ filterWriter.putNextDouble(returnValueReader.nextDouble());
+ }
+
+ // Invoke the filter and copy its return value back to the original frame.
+ filter.invoke(filterFrame);
+ filterFrame.copyReturnValueTo(emulatedStackFrame);
+ }
+ }
+
+ /*
+ * Implements MethodHandles.permuteArguments.
+ *
+ * @hide
+ */
+ public static class PermuteArguments extends Transformer {
+ private final MethodHandle target;
+ private final int[] reorder;
+
+ public PermuteArguments(MethodType type, MethodHandle target, int[] reorder) {
+ super(type);
+
+ this.target = target;
+ this.reorder = reorder;
+ }
+
+ @Override
+ public void transform(EmulatedStackFrame emulatedStackFrame) throws Throwable {
+ final StackFrameReader reader = new StackFrameReader();
+ reader.attach(emulatedStackFrame);
+
+ // In the interests of simplicity, we box / unbox arguments while performing
+ // the permutation. We first iterate through the incoming stack frame and box
+ // each argument. We then unbox and write out the argument to the target frame
+ // according to the specified reordering.
+ Object[] arguments = new Object[reorder.length];
+ final Class<?>[] ptypes = type().ptypes();
+ for (int i = 0; i < ptypes.length; ++i) {
+ final Class<?> ptype = ptypes[i];
+ if (!ptype.isPrimitive()) {
+ arguments[i] = reader.nextReference(ptype);
+ } else if (ptype == boolean.class) {
+ arguments[i] = reader.nextBoolean();
+ } else if (ptype == byte.class) {
+ arguments[i] = reader.nextByte();
+ } else if (ptype == char.class) {
+ arguments[i] = reader.nextChar();
+ } else if (ptype == short.class) {
+ arguments[i] = reader.nextShort();
+ } else if (ptype == int.class) {
+ arguments[i] = reader.nextInt();
+ } else if (ptype == long.class) {
+ arguments[i] = reader.nextLong();
+ } else if (ptype == float.class) {
+ arguments[i] = reader.nextFloat();
+ } else if (ptype == double.class) {
+ arguments[i] = reader.nextDouble();
+ } else {
+ throw new AssertionError("Unexpected type: " + ptype);
+ }
+ }
+
+ EmulatedStackFrame calleeFrame = EmulatedStackFrame.create(target.type());
+ final StackFrameWriter writer = new StackFrameWriter();
+ writer.attach(calleeFrame);
+
+ for (int i = 0; i < ptypes.length; ++i) {
+ int idx = reorder[i];
+ final Class<?> ptype = ptypes[idx];
+ final Object argument = arguments[idx];
+
+ if (!ptype.isPrimitive()) {
+ writer.putNextReference(argument, ptype);
+ } else if (ptype == boolean.class) {
+ writer.putNextBoolean((boolean) argument);
+ } else if (ptype == byte.class) {
+ writer.putNextByte((byte) argument);
+ } else if (ptype == char.class) {
+ writer.putNextChar((char) argument);
+ } else if (ptype == short.class) {
+ writer.putNextShort((short) argument);
+ } else if (ptype == int.class) {
+ writer.putNextInt((int) argument);
+ } else if (ptype == long.class) {
+ writer.putNextLong((long) argument);
+ } else if (ptype == float.class) {
+ writer.putNextFloat((float) argument);
+ } else if (ptype == double.class) {
+ writer.putNextDouble((double) argument);
+ } else {
+ throw new AssertionError("Unexpected type: " + ptype);
+ }
+ }
+
+ target.invoke(calleeFrame);
+ calleeFrame.copyReturnValueTo(emulatedStackFrame);
+ }
+ }
+
+ /**
+ * Converts methods with a trailing array argument to variable arity
+ * methods. So (A,B,C[])R can be invoked with any number of convertible
+ * arguments after B, e.g. (A,B)R or (A, B, C0)R or (A, B, C0...Cn)R.
+ *
+ * @hide
+ */
+ /*package*/ static class VarargsCollector extends Transformer {
+ final MethodHandle target;
+
+ /*package*/ VarargsCollector(MethodHandle target) {
+ super(target.type(), MethodHandle.INVOKE_CALLSITE_TRANSFORM);
+ if (!lastParameterTypeIsAnArray(target.type().ptypes())) {
+ throw new IllegalArgumentException("target does not have array as last parameter");
+ }
+ this.target = target;
+ }
+
+ private static boolean lastParameterTypeIsAnArray(Class<?>[] parameterTypes) {
+ if (parameterTypes.length == 0) return false;
+ return parameterTypes[parameterTypes.length - 1].isArray();
+ }
+
+ @Override
+ public boolean isVarargsCollector() { return true; }
+
+ @Override
+ public MethodHandle asFixedArity() { return target; }
+
+ @Override
+ public void transform(EmulatedStackFrame callerFrame) throws Throwable {
+ MethodType callerFrameType = callerFrame.getMethodType();
+ Class<?>[] callerPTypes = callerFrameType.ptypes();
+ Class<?>[] targetPTypes = type().ptypes();
+
+ int lastTargetIndex = targetPTypes.length - 1;
+ if (callerPTypes.length == targetPTypes.length &&
+ targetPTypes[lastTargetIndex].isAssignableFrom(callerPTypes[lastTargetIndex])) {
+ // Caller frame matches target frame in the arity array parameter. Invoke
+ // immediately, and let the invoke() dispatch perform any necessary conversions
+ // on the other parameters present.
+ target.invoke(callerFrame);
+ return;
+ }
+
+ if (callerPTypes.length < targetPTypes.length - 1) {
+ // Too few arguments to be compatible with variable arity invocation.
+ throwWrongMethodTypeException(callerFrameType, type());
+ }
+
+ if (!MethodType.canConvert(type().rtype(), callerFrameType.rtype())) {
+ // Incompatible return type.
+ throwWrongMethodTypeException(callerFrameType, type());
+ }
+
+ Class<?> elementType = targetPTypes[lastTargetIndex].getComponentType();
+ if (!arityArgumentsConvertible(callerPTypes, lastTargetIndex, elementType)) {
+ // Wrong types to be compatible with variable arity invocation.
+ throwWrongMethodTypeException(callerFrameType, type());
+ }
+
+ // Allocate targetFrame.
+ MethodType targetFrameType = makeTargetFrameType(callerFrameType, type());
+ EmulatedStackFrame targetFrame = EmulatedStackFrame.create(targetFrameType);
+ prepareFrame(callerFrame, targetFrame);
+
+ // Invoke target.
+ target.invoke(targetFrame);
+
+ // Copy return value to the caller's frame.
+ targetFrame.copyReturnValueTo(callerFrame);
+ }
+
+ private static void throwWrongMethodTypeException(MethodType from, MethodType to) {
+ throw new WrongMethodTypeException("Cannot convert " + from + " to " + to);
+ }
+
+ private static boolean arityArgumentsConvertible(Class<?>[] ptypes, int arityStart,
+ Class<?> elementType) {
+ if (ptypes.length - 1 == arityStart) {
+ if (ptypes[arityStart].isArray() &&
+ ptypes[arityStart].getComponentType() == elementType) {
+ // The last ptype is in the same position as the arity
+ // array and has the same type.
+ return true;
+ }
+ }
+
+ for (int i = arityStart; i < ptypes.length; ++i) {
+ if (!MethodType.canConvert(ptypes[i], elementType)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private static Object referenceArray(StackFrameReader reader, Class<?>[] ptypes,
+ Class<?> elementType, int offset, int length) {
+ Object arityArray = Array.newInstance(elementType, length);
+ for (int i = 0; i < length; ++i) {
+ Class<?> argumentType = ptypes[i + offset];
+ Object o = null;
+ switch (Wrapper.basicTypeChar(argumentType)) {
+ case 'L': { o = reader.nextReference(argumentType); break; }
+ case 'I': { o = reader.nextInt(); break; }
+ case 'J': { o = reader.nextLong(); break; }
+ case 'B': { o = reader.nextByte(); break; }
+ case 'S': { o = reader.nextShort(); break; }
+ case 'C': { o = reader.nextChar(); break; }
+ case 'Z': { o = reader.nextBoolean(); break; }
+ case 'F': { o = reader.nextFloat(); break; }
+ case 'D': { o = reader.nextDouble(); break; }
+ }
+ Array.set(arityArray, i, elementType.cast(o));
+ }
+ return arityArray;
+ }
+
+ private static Object intArray(StackFrameReader reader, Class<?> ptypes[],
+ int offset, int length) {
+ int[] arityArray = new int[length];
+ for (int i = 0; i < length; ++i) {
+ Class<?> argumentType = ptypes[i + offset];
+ switch (Wrapper.basicTypeChar(argumentType)) {
+ case 'I': { arityArray[i] = reader.nextInt(); break; }
+ case 'S': { arityArray[i] = reader.nextShort(); break; }
+ case 'B': { arityArray[i] = reader.nextByte(); break; }
+ default: {
+ arityArray[i] = (Integer) reader.nextReference(argumentType);
+ break;
+ }
+ }
+ }
+ return arityArray;
+ }
+
+ private static Object longArray(StackFrameReader reader, Class<?> ptypes[],
+ int offset, int length) {
+ long[] arityArray = new long[length];
+ for (int i = 0; i < length; ++i) {
+ Class<?> argumentType = ptypes[i + offset];
+ switch (Wrapper.basicTypeChar(argumentType)) {
+ case 'J': { arityArray[i] = reader.nextLong(); break; }
+ case 'I': { arityArray[i] = reader.nextInt(); break; }
+ case 'S': { arityArray[i] = reader.nextShort(); break; }
+ case 'B': { arityArray[i] = reader.nextByte(); break; }
+ default: { arityArray[i] = (Long) reader.nextReference(argumentType); break; }
+ }
+ }
+ return arityArray;
+ }
+
+ private static Object byteArray(StackFrameReader reader, Class<?> ptypes[],
+ int offset, int length) {
+ byte[] arityArray = new byte[length];
+ for (int i = 0; i < length; ++i) {
+ Class<?> argumentType = ptypes[i + offset];
+ switch (Wrapper.basicTypeChar(argumentType)) {
+ case 'B': { arityArray[i] = reader.nextByte(); break; }
+ default: { arityArray[i] = (Byte) reader.nextReference(argumentType); break; }
+ }
+ }
+ return arityArray;
+ }
+
+ private static Object shortArray(StackFrameReader reader, Class<?> ptypes[],
+ int offset, int length) {
+ short[] arityArray = new short[length];
+ for (int i = 0; i < length; ++i) {
+ Class<?> argumentType = ptypes[i + offset];
+ switch (Wrapper.basicTypeChar(argumentType)) {
+ case 'S': { arityArray[i] = reader.nextShort(); break; }
+ case 'B': { arityArray[i] = reader.nextByte(); break; }
+ default: { arityArray[i] = (Short) reader.nextReference(argumentType); break; }
+ }
+ }
+ return arityArray;
+ }
+
+ private static Object charArray(StackFrameReader reader, Class<?> ptypes[],
+ int offset, int length) {
+ char[] arityArray = new char[length];
+ for (int i = 0; i < length; ++i) {
+ Class<?> argumentType = ptypes[i + offset];
+ switch (Wrapper.basicTypeChar(argumentType)) {
+ case 'C': { arityArray[i] = reader.nextChar(); break; }
+ default: {
+ arityArray[i] = (Character) reader.nextReference(argumentType);
+ break;
+ }
+ }
+ }
+ return arityArray;
+ }
+
+ private static Object booleanArray(StackFrameReader reader, Class<?> ptypes[],
+ int offset, int length) {
+ boolean[] arityArray = new boolean[length];
+ for (int i = 0; i < length; ++i) {
+ Class<?> argumentType = ptypes[i + offset];
+ switch (Wrapper.basicTypeChar(argumentType)) {
+ case 'Z': { arityArray[i] = reader.nextBoolean(); break; }
+ default:
+ arityArray[i] = (Boolean) reader.nextReference(argumentType);
+ break;
+ }
+ }
+ return arityArray;
+ }
+
+ private static Object floatArray(StackFrameReader reader, Class<?> ptypes[],
+ int offset, int length) {
+ float[] arityArray = new float[length];
+ for (int i = 0; i < length; ++i) {
+ Class<?> argumentType = ptypes[i + offset];
+ switch (Wrapper.basicTypeChar(argumentType)) {
+ case 'F': { arityArray[i] = reader.nextFloat(); break; }
+ case 'J': { arityArray[i] = reader.nextLong(); break; }
+ case 'I': { arityArray[i] = reader.nextInt(); break; }
+ case 'S': { arityArray[i] = reader.nextShort(); break; }
+ case 'B': { arityArray[i] = reader.nextByte(); break; }
+ default: {
+ arityArray[i] = (Float) reader.nextReference(argumentType);
+ break;
+ }
+ }
+ }
+ return arityArray;
+ }
+
+ private static Object doubleArray(StackFrameReader reader, Class<?> ptypes[],
+ int offset, int length) {
+ double[] arityArray = new double[length];
+ for (int i = 0; i < length; ++i) {
+ Class<?> argumentType = ptypes[i + offset];
+ switch (Wrapper.basicTypeChar(argumentType)) {
+ case 'D': { arityArray[i] = reader.nextDouble(); break; }
+ case 'F': { arityArray[i] = reader.nextFloat(); break; }
+ case 'J': { arityArray[i] = reader.nextLong(); break; }
+ case 'I': { arityArray[i] = reader.nextInt(); break; }
+ case 'S': { arityArray[i] = reader.nextShort(); break; }
+ case 'B': { arityArray[i] = reader.nextByte(); break; }
+ default: {
+ arityArray[i] = (Double) reader.nextReference(argumentType);
+ break;
+ }
+ }
+ }
+ return arityArray;
+ }
+
+ private static Object makeArityArray(MethodType callerFrameType,
+ StackFrameReader callerFrameReader,
+ int indexOfArityArray,
+ Class<?> arityArrayType) {
+ int arityArrayLength = callerFrameType.ptypes().length - indexOfArityArray;
+ Class<?> elementType = arityArrayType.getComponentType();
+ Class<?>[] callerPTypes = callerFrameType.ptypes();
+
+ char elementBasicType = Wrapper.basicTypeChar(elementType);
+ switch (elementBasicType) {
+ case 'L': return referenceArray(callerFrameReader, callerPTypes, elementType,
+ indexOfArityArray, arityArrayLength);
+ case 'I': return intArray(callerFrameReader, callerPTypes,
+ indexOfArityArray, arityArrayLength);
+ case 'J': return longArray(callerFrameReader, callerPTypes,
+ indexOfArityArray, arityArrayLength);
+ case 'B': return byteArray(callerFrameReader, callerPTypes,
+ indexOfArityArray, arityArrayLength);
+ case 'S': return shortArray(callerFrameReader, callerPTypes,
+ indexOfArityArray, arityArrayLength);
+ case 'C': return charArray(callerFrameReader, callerPTypes,
+ indexOfArityArray, arityArrayLength);
+ case 'Z': return booleanArray(callerFrameReader, callerPTypes,
+ indexOfArityArray, arityArrayLength);
+ case 'F': return floatArray(callerFrameReader, callerPTypes,
+ indexOfArityArray, arityArrayLength);
+ case 'D': return doubleArray(callerFrameReader, callerPTypes,
+ indexOfArityArray, arityArrayLength);
+ }
+ throw new InternalError("Unexpected type: " + elementType);
+ }
+
+ public static Object collectArguments(char basicComponentType, Class<?> componentType,
+ StackFrameReader reader, Class<?>[] types,
+ int startIdx, int length) {
+ switch (basicComponentType) {
+ case 'L': return referenceArray(reader, types, componentType, startIdx, length);
+ case 'I': return intArray(reader, types, startIdx, length);
+ case 'J': return longArray(reader, types, startIdx, length);
+ case 'B': return byteArray(reader, types, startIdx, length);
+ case 'S': return shortArray(reader, types, startIdx, length);
+ case 'C': return charArray(reader, types, startIdx, length);
+ case 'Z': return booleanArray(reader, types, startIdx, length);
+ case 'F': return floatArray(reader, types, startIdx, length);
+ case 'D': return doubleArray(reader, types, startIdx, length);
+ }
+ throw new InternalError("Unexpected type: " + basicComponentType);
+ }
+
+ private static void copyParameter(StackFrameReader reader, StackFrameWriter writer,
+ Class<?> ptype) {
+ switch (Wrapper.basicTypeChar(ptype)) {
+ case 'L': { writer.putNextReference(reader.nextReference(ptype), ptype); break; }
+ case 'I': { writer.putNextInt(reader.nextInt()); break; }
+ case 'J': { writer.putNextLong(reader.nextLong()); break; }
+ case 'B': { writer.putNextByte(reader.nextByte()); break; }
+ case 'S': { writer.putNextShort(reader.nextShort()); break; }
+ case 'C': { writer.putNextChar(reader.nextChar()); break; }
+ case 'Z': { writer.putNextBoolean(reader.nextBoolean()); break; }
+ case 'F': { writer.putNextFloat(reader.nextFloat()); break; }
+ case 'D': { writer.putNextDouble(reader.nextDouble()); break; }
+ default: throw new InternalError("Unexpected type: " + ptype);
+ }
+ }
+
+ private static void prepareFrame(EmulatedStackFrame callerFrame,
+ EmulatedStackFrame targetFrame) {
+ StackFrameWriter targetWriter = new StackFrameWriter();
+ targetWriter.attach(targetFrame);
+ StackFrameReader callerReader = new StackFrameReader();
+ callerReader.attach(callerFrame);
+
+ // Copy parameters from |callerFrame| to |targetFrame| leaving room for arity array.
+ MethodType targetMethodType = targetFrame.getMethodType();
+ int indexOfArityArray = targetMethodType.ptypes().length - 1;
+ for (int i = 0; i < indexOfArityArray; ++i) {
+ Class<?> ptype = targetMethodType.ptypes()[i];
+ copyParameter(callerReader, targetWriter, ptype);
+ }
+
+ // Add arity array as last parameter in |targetFrame|.
+ Class<?> arityArrayType = targetMethodType.ptypes()[indexOfArityArray];
+ Object arityArray = makeArityArray(callerFrame.getMethodType(), callerReader,
+ indexOfArityArray, arityArrayType);
+ targetWriter.putNextReference(arityArray, arityArrayType);
+ }
+
+ /**
+ * Computes the frame type to invoke the target method handle with. This
+ * is the same as the caller frame type, but with the trailing argument
+ * being the array type that is the trailing argument in the target method
+ * handle.
+ *
+ * Suppose the targetType is (T0, T1, T2[])RT and the callerType is (C0, C1, C2, C3)RC
+ * then the constructed type is (C0, C1, T2[])RC.
+ */
+ private static MethodType makeTargetFrameType(MethodType callerType,
+ MethodType targetType) {
+ final int ptypesLength = targetType.ptypes().length;
+ final Class<?>[] ptypes = new Class<?>[ptypesLength];
+ // Copy types from caller types to new methodType.
+ System.arraycopy(callerType.ptypes(), 0, ptypes, 0, ptypesLength - 1);
+ // Set the last element in the type array to be the
+ // varargs array of the target.
+ ptypes[ptypesLength - 1] = targetType.ptypes()[ptypesLength - 1];
+ return MethodType.methodType(callerType.rtype(), ptypes);
+ }
+ }
+
+ /**
+ * Implements MethodHandles.invoker & MethodHandles.exactInvoker.
+ */
+ static class Invoker extends Transformer {
+ private final MethodType targetType;
+ private final boolean isExactInvoker;
+ private final EmulatedStackFrame.Range copyRange;
+
+ Invoker(MethodType targetType, boolean isExactInvoker) {
+ super(targetType.insertParameterTypes(0, MethodHandle.class));
+ this.targetType = targetType;
+ this.isExactInvoker = isExactInvoker;
+ copyRange = EmulatedStackFrame.Range.of(type(), 1, type().parameterCount());
+ }
+
+ @Override
+ public void transform(EmulatedStackFrame emulatedStackFrame) throws Throwable {
+ // We need to artifically throw a WrongMethodTypeException here because we
+ // can't call invokeExact on the target inside the transformer.
+ if (isExactInvoker) {
+ // TODO: We should do the comparison by hand if this new type creation
+ // on every invoke proves too expensive.
+ MethodType callType = emulatedStackFrame.getCallsiteType().dropParameterTypes(0, 1);
+ if (!targetType.equals(callType)) {
+ throw new WrongMethodTypeException("Wrong type, Expected: " + targetType
+ + " was: " + callType);
+ }
+ }
+
+ // The first argument to the stack frame is the handle that needs to be invoked.
+ MethodHandle target = emulatedStackFrame.getReference(0, MethodHandle.class);
+
+ // All other arguments must be copied to the target frame.
+ EmulatedStackFrame targetFrame = EmulatedStackFrame.create(targetType);
+ emulatedStackFrame.copyRangeTo(targetFrame, copyRange, 0, 0);
+
+ // Finally, invoke the handle and copy the return value.
+ target.invoke(targetFrame);
+ targetFrame.copyReturnValueTo(emulatedStackFrame);
+ }
+ }
+
+ /**
+ * Implements MethodHandle.asSpreader / MethodHandles.spreadInvoker.
+ */
+ static class Spreader extends Transformer {
+ /** The method handle we're delegating to. */
+ private final MethodHandle target;
+
+ /**
+ * The offset of the trailing array argument in the list of arguments to
+ * this transformer. The array argument is always the last argument.
+ */
+ private final int arrayOffset;
+
+ /**
+ * The type char of the component type of the array.
+ */
+ private final char arrayTypeChar;
+
+ /**
+ * The number of input arguments that will be present in the array. In other words,
+ * this is the expected array length.
+ */
+ private final int numArrayArgs;
+
+ /**
+ * Range of arguments to copy verbatim from the input frame, This will cover all
+ * arguments that aren't a part of the trailing array.
+ */
+ private final Range copyRange;
+
+ Spreader(MethodHandle target, MethodType spreaderType, int numArrayArgs) {
+ super(spreaderType);
+ this.target = target;
+ // Copy all arguments except the last argument (which is the trailing array argument
+ // that needs to be spread).
+ arrayOffset = spreaderType.parameterCount() - 1;
+
+ // Get and cache the component type of the input array.
+ final Class<?> componentType = spreaderType.ptypes()[arrayOffset].getComponentType();
+ if (componentType == null) {
+ throw new AssertionError("Trailing argument must be an array.");
+ }
+ arrayTypeChar = Wrapper.basicTypeChar(componentType);
+
+ this.numArrayArgs = numArrayArgs;
+ // Copy all args except for the last argument.
+ this.copyRange = EmulatedStackFrame.Range.of(spreaderType, 0, arrayOffset);
+ }
+
+ @Override
+ public void transform(EmulatedStackFrame callerFrame) throws Throwable {
+ // Create a new stack frame for the callee.
+ EmulatedStackFrame targetFrame = EmulatedStackFrame.create(target.type());
+
+ // Copy all arguments except for the trailing array argument.
+ callerFrame.copyRangeTo(targetFrame, copyRange, 0, 0);
+
+ // Attach the writer, prepare to spread the trailing array arguments into
+ // the callee frame.
+ StackFrameWriter writer = new StackFrameWriter();
+ writer.attach(targetFrame,
+ arrayOffset,
+ copyRange.numReferences,
+ copyRange.numBytes);
+
+ // Get the array reference and check that its length is as expected.
+ Object arrayObj = callerFrame.getReference(
+ copyRange.numReferences, this.type().ptypes()[arrayOffset]);
+ final int arrayLength = Array.getLength(arrayObj);
+ if (arrayLength != numArrayArgs) {
+ throw new IllegalArgumentException("Invalid array length: " + arrayLength);
+ }
+
+ final MethodType type = target.type();
+ switch (arrayTypeChar) {
+ case 'L':
+ spreadArray((Object[]) arrayObj, writer, type, numArrayArgs, arrayOffset);
+ break;
+ case 'I':
+ spreadArray((int[]) arrayObj, writer, type, numArrayArgs, arrayOffset);
+ break;
+ case 'J':
+ spreadArray((long[]) arrayObj, writer, type, numArrayArgs, arrayOffset);
+ break;
+ case 'B':
+ spreadArray((byte[]) arrayObj, writer, type, numArrayArgs, arrayOffset);
+ break;
+ case 'S':
+ spreadArray((short[]) arrayObj, writer, type, numArrayArgs, arrayOffset);
+ break;
+ case 'C':
+ spreadArray((char[]) arrayObj, writer, type, numArrayArgs, arrayOffset);
+ break;
+ case 'Z':
+ spreadArray((boolean[]) arrayObj, writer, type, numArrayArgs, arrayOffset);
+ break;
+ case 'F':
+ spreadArray((float[]) arrayObj, writer, type, numArrayArgs, arrayOffset);
+ break;
+ case 'D':
+ spreadArray((double[]) arrayObj, writer, type, numArrayArgs, arrayOffset);
+ break;
+
+ }
+
+ target.invoke(targetFrame);
+ targetFrame.copyReturnValueTo(callerFrame);
+ }
+
+ public static void spreadArray(Object[] array, StackFrameWriter writer, MethodType type,
+ int numArgs, int offset) {
+ final Class<?>[] ptypes = type.ptypes();
+ for (int i = 0; i < numArgs; ++i) {
+ Class<?> argumentType = ptypes[i + offset];
+ Object o = array[i];
+ switch (Wrapper.basicTypeChar(argumentType)) {
+ case 'L': { writer.putNextReference(o, argumentType); break; }
+ case 'I': { writer.putNextInt((int) o); break; }
+ case 'J': { writer.putNextLong((long) o); break; }
+ case 'B': { writer.putNextByte((byte) o); break; }
+ case 'S': { writer.putNextShort((short) o); break; }
+ case 'C': { writer.putNextChar((char) o); break; }
+ case 'Z': { writer.putNextBoolean((boolean) o); break; }
+ case 'F': { writer.putNextFloat((float) o); break; }
+ case 'D': { writer.putNextDouble((double) o); break; }
+ }
+ }
+ }
+
+ public static void spreadArray(int[] array, StackFrameWriter writer, MethodType type,
+ int numArgs, int offset) {
+ final Class<?>[] ptypes = type.ptypes();
+ for (int i = 0; i < numArgs; ++i) {
+ Class<?> argumentType = ptypes[i + offset];
+ int j = array[i];
+ switch (Wrapper.basicTypeChar(argumentType)) {
+ case 'L': { writer.putNextReference(j, argumentType); break; }
+ case 'I': { writer.putNextInt(j); break; }
+ case 'J': { writer.putNextLong(j); break; }
+ case 'F': { writer.putNextFloat(j); break; }
+ case 'D': { writer.putNextDouble(j); break; }
+ default : { throw new AssertionError(); }
+ }
+ }
+ }
+
+ public static void spreadArray(long[] array, StackFrameWriter writer, MethodType type,
+ int numArgs, int offset) {
+ final Class<?>[] ptypes = type.ptypes();
+ for (int i = 0; i < numArgs; ++i) {
+ Class<?> argumentType = ptypes[i + offset];
+ long l = array[i];
+ switch (Wrapper.basicTypeChar(argumentType)) {
+ case 'L': { writer.putNextReference(l, argumentType); break; }
+ case 'J': { writer.putNextLong(l); break; }
+ case 'F': { writer.putNextFloat((float) l); break; }
+ case 'D': { writer.putNextDouble((double) l); break; }
+ default : { throw new AssertionError(); }
+ }
+ }
+ }
+
+ public static void spreadArray(byte[] array,
+ StackFrameWriter writer, MethodType type,
+ int numArgs, int offset) {
+ final Class<?>[] ptypes = type.ptypes();
+ for (int i = 0; i < numArgs; ++i) {
+ Class<?> argumentType = ptypes[i + offset];
+ byte b = array[i];
+ switch (Wrapper.basicTypeChar(argumentType)) {
+ case 'L': { writer.putNextReference(b, argumentType); break; }
+ case 'I': { writer.putNextInt(b); break; }
+ case 'J': { writer.putNextLong(b); break; }
+ case 'B': { writer.putNextByte(b); break; }
+ case 'S': { writer.putNextShort(b); break; }
+ case 'F': { writer.putNextFloat(b); break; }
+ case 'D': { writer.putNextDouble(b); break; }
+ default : { throw new AssertionError(); }
+ }
+ }
+ }
+
+ public static void spreadArray(short[] array,
+ StackFrameWriter writer, MethodType type,
+ int numArgs, int offset) {
+ final Class<?>[] ptypes = type.ptypes();
+ for (int i = 0; i < numArgs; ++i) {
+ Class<?> argumentType = ptypes[i + offset];
+ short s = array[i];
+ switch (Wrapper.basicTypeChar(argumentType)) {
+ case 'L': { writer.putNextReference(s, argumentType); break; }
+ case 'I': { writer.putNextInt(s); break; }
+ case 'J': { writer.putNextLong(s); break; }
+ case 'S': { writer.putNextShort(s); break; }
+ case 'F': { writer.putNextFloat(s); break; }
+ case 'D': { writer.putNextDouble(s); break; }
+ default : { throw new AssertionError(); }
+ }
+ }
+ }
+
+ public static void spreadArray(char[] array,
+ StackFrameWriter writer, MethodType type,
+ int numArgs, int offset) {
+ final Class<?>[] ptypes = type.ptypes();
+ for (int i = 0; i < numArgs; ++i) {
+ Class<?> argumentType = ptypes[i + offset];
+ char c = array[i];
+ switch (Wrapper.basicTypeChar(argumentType)) {
+ case 'L': { writer.putNextReference(c, argumentType); break; }
+ case 'I': { writer.putNextInt(c); break; }
+ case 'J': { writer.putNextLong(c); break; }
+ case 'C': { writer.putNextChar(c); break; }
+ case 'F': { writer.putNextFloat(c); break; }
+ case 'D': { writer.putNextDouble(c); break; }
+ default : { throw new AssertionError(); }
+ }
+ }
+ }
+
+ public static void spreadArray(boolean[] array,
+ StackFrameWriter writer, MethodType type,
+ int numArgs, int offset) {
+ final Class<?>[] ptypes = type.ptypes();
+ for (int i = 0; i < numArgs; ++i) {
+ Class<?> argumentType = ptypes[i + offset];
+ boolean z = array[i];
+ switch (Wrapper.basicTypeChar(argumentType)) {
+ case 'L': { writer.putNextReference(z, argumentType); break; }
+ case 'Z': { writer.putNextBoolean(z); break; }
+ default : { throw new AssertionError(); }
+ }
+ }
+ }
+
+ public static void spreadArray(double[] array,
+ StackFrameWriter writer, MethodType type,
+ int numArgs, int offset) {
+ final Class<?>[] ptypes = type.ptypes();
+ for (int i = 0; i < numArgs; ++i) {
+ Class<?> argumentType = ptypes[i + offset];
+ double d = array[i];
+ switch (Wrapper.basicTypeChar(argumentType)) {
+ case 'L': { writer.putNextReference(d, argumentType); break; }
+ case 'D': { writer.putNextDouble(d); break; }
+ default : { throw new AssertionError(); }
+ }
+ }
+ }
+
+ public static void spreadArray(float[] array, StackFrameWriter writer, MethodType type,
+ int numArgs, int offset) {
+ final Class<?>[] ptypes = type.ptypes();
+ for (int i = 0; i < numArgs; ++i) {
+ Class<?> argumentType = ptypes[i + offset];
+ float f = array[i];
+ switch (Wrapper.basicTypeChar(argumentType)) {
+ case 'L': { writer.putNextReference(f, argumentType); break; }
+ case 'D': { writer.putNextDouble((double) f); break; }
+ case 'F': { writer.putNextFloat(f); break; }
+ default : { throw new AssertionError(); }
+ }
+ }
+ }
+ }
+
+ /**
+ * Implements MethodHandle.asCollector.
+ */
+ static class Collector extends Transformer {
+ private final MethodHandle target;
+
+ /**
+ * The offset of the trailing array argument in the list of arguments to
+ * this transformer. The array argument is always the last argument.
+ */
+ private final int arrayOffset;
+
+ /**
+ * The number of input arguments that will be present in the array. In other words,
+ * this is the expected array length.
+ */
+ private final int numArrayArgs;
+
+ /**
+ * The type char of the component type of the array.
+ */
+ private final char arrayTypeChar;
+
+ /**
+ * Range of arguments to copy verbatim from the input frame, This will cover all
+ * arguments that aren't a part of the trailing array.
+ */
+ private final Range copyRange;
+
+ Collector(MethodHandle delegate, Class<?> arrayType, int length) {
+ super(delegate.type().asCollectorType(arrayType, length));
+
+ target = delegate;
+ // Copy all arguments except the last argument (which is the trailing array argument
+ // that needs to be spread).
+ arrayOffset = delegate.type().parameterCount() - 1;
+ arrayTypeChar = Wrapper.basicTypeChar(arrayType.getComponentType());
+ numArrayArgs = length;
+
+ // Copy all args except for the last argument.
+ copyRange = EmulatedStackFrame.Range.of(delegate.type(), 0, arrayOffset);
+ }
+
+ @Override
+ public void transform(EmulatedStackFrame callerFrame) throws Throwable {
+ // Create a new stack frame for the callee.
+ EmulatedStackFrame targetFrame = EmulatedStackFrame.create(target.type());
+
+ // Copy all arguments except for the trailing array argument.
+ callerFrame.copyRangeTo(targetFrame, copyRange, 0, 0);
+
+ // Attach the writer, prepare to spread the trailing array arguments into
+ // the callee frame.
+ final StackFrameWriter writer = new StackFrameWriter();
+ writer.attach(targetFrame, arrayOffset, copyRange.numReferences, copyRange.numBytes);
+ final StackFrameReader reader = new StackFrameReader();
+ reader.attach(callerFrame, arrayOffset, copyRange.numReferences, copyRange.numBytes);
+
+ switch (arrayTypeChar) {
+ case 'L': {
+ // Reference arrays are the only case where the component type of the
+ // array we construct might differ from the type of the reference we read
+ // from the stack frame.
+ final Class<?> targetType = target.type().ptypes()[arrayOffset];
+ final Class<?> targetComponentType = targetType.getComponentType();
+ final Class<?> adapterComponentType = type().lastParameterType();
+
+ Object[] arr = (Object[]) Array.newInstance(targetComponentType, numArrayArgs);
+ for (int i = 0; i < numArrayArgs; ++i) {
+ arr[i] = reader.nextReference(adapterComponentType);
+ }
+
+ writer.putNextReference(arr, targetType);
+ break;
+ }
+ case 'I': {
+ int[] array = new int[numArrayArgs];
+ for (int i = 0; i < numArrayArgs; ++i) {
+ array[i] = reader.nextInt();
+ }
+ writer.putNextReference(array, int[].class);
+ break;
+ }
+ case 'J': {
+ long[] array = new long[numArrayArgs];
+ for (int i = 0; i < numArrayArgs; ++i) {
+ array[i] = reader.nextLong();
+ }
+ writer.putNextReference(array, long[].class);
+ break;
+ }
+ case 'B': {
+ byte[] array = new byte[numArrayArgs];
+ for (int i = 0; i < numArrayArgs; ++i) {
+ array[i] = reader.nextByte();
+ }
+ writer.putNextReference(array, byte[].class);
+ break;
+ }
+ case 'S': {
+ short[] array = new short[numArrayArgs];
+ for (int i = 0; i < numArrayArgs; ++i) {
+ array[i] = reader.nextShort();
+ }
+ writer.putNextReference(array, short[].class);
+ break;
+ }
+ case 'C': {
+ char[] array = new char[numArrayArgs];
+ for (int i = 0; i < numArrayArgs; ++i) {
+ array[i] = reader.nextChar();
+ }
+ writer.putNextReference(array, char[].class);
+ break;
+ }
+ case 'Z': {
+ boolean[] array = new boolean[numArrayArgs];
+ for (int i = 0; i < numArrayArgs; ++i) {
+ array[i] = reader.nextBoolean();
+ }
+ writer.putNextReference(array, boolean[].class);
+ break;
+ }
+ case 'F': {
+ float[] array = new float[numArrayArgs];
+ for (int i = 0; i < numArrayArgs; ++i) {
+ array[i] = reader.nextFloat();
+ }
+ writer.putNextReference(array, float[].class);
+ break;
+ }
+ case 'D': {
+ double[] array = new double[numArrayArgs];
+ for (int i = 0; i < numArrayArgs; ++i) {
+ array[i] = reader.nextDouble();
+ }
+ writer.putNextReference(array, double[].class);
+ break;
+ }
+ }
+
+ target.invoke(targetFrame);
+ targetFrame.copyReturnValueTo(callerFrame);
+ }
+ }
+
+ /*
+ * Implements MethodHandles.filterArguments.
+ */
+ static class FilterArguments extends Transformer {
+ /** The target handle. */
+ private final MethodHandle target;
+ /** Index of the first argument to filter */
+ private final int pos;
+ /** The list of filters to apply */
+ private final MethodHandle[] filters;
+
+ FilterArguments(MethodHandle target, int pos, MethodHandle[] filters) {
+ super(deriveType(target, pos, filters));
+
+ this.target = target;
+ this.pos = pos;
+ this.filters = filters;
+
+ }
+
+ private static MethodType deriveType(MethodHandle target, int pos, MethodHandle[] filters) {
+ final Class<?>[] filterArgs = new Class<?>[filters.length];
+ for (int i = 0; i < filters.length; ++i) {
+ filterArgs[i] = filters[i].type().parameterType(0);
+ }
+
+ return target.type().replaceParameterTypes(pos, pos + filters.length, filterArgs);
+ }
+
+ @Override
+ public void transform(EmulatedStackFrame stackFrame) throws Throwable {
+ final StackFrameReader reader = new StackFrameReader();
+ reader.attach(stackFrame);
+
+ EmulatedStackFrame transformedFrame = EmulatedStackFrame.create(target.type());
+ final StackFrameWriter writer = new StackFrameWriter();
+ writer.attach(transformedFrame);
+
+ final Class<?>[] ptypes = target.type().ptypes();
+ for (int i = 0; i < ptypes.length; ++i) {
+ // Check whether the current argument has a filter associated with it.
+ // If it has no filter, no further action need be taken.
+ final Class<?> ptype = ptypes[i];
+ final MethodHandle filter;
+ if (i < pos) {
+ filter = null;
+ } else if (i >= pos + filters.length) {
+ filter = null;
+ } else {
+ filter = filters[i - pos];
+ }
+
+ if (filter != null) {
+ // Note that filter.type() must be (ptype)ptype - this is checked before
+ // this transformer is created.
+ EmulatedStackFrame filterFrame = EmulatedStackFrame.create(filter.type());
+
+ // Copy the next argument from the stack frame to the filter frame.
+ final StackFrameWriter filterWriter = new StackFrameWriter();
+ filterWriter.attach(filterFrame);
+ copyNext(reader, filterWriter, filter.type().ptypes()[0]);
+
+ filter.invoke(filterFrame);
+
+ // Copy the argument back from the filter frame to the stack frame.
+ final StackFrameReader filterReader = new StackFrameReader();
+ filterReader.attach(filterFrame);
+ filterReader.makeReturnValueAccessor();
+ copyNext(filterReader, writer, ptype);
+ } else {
+ // There's no filter associated with this frame, just copy the next argument
+ // over.
+ copyNext(reader, writer, ptype);
+ }
+ }
+
+ target.invoke(transformedFrame);
+ transformedFrame.copyReturnValueTo(stackFrame);
+ }
+ }
+
+ /**
+ * Implements MethodHandles.collectArguments.
+ */
+ static class CollectArguments extends Transformer {
+ private final MethodHandle target;
+ private final MethodHandle collector;
+ private final int pos;
+
+ /** The range of input arguments we copy to the collector. */
+ private final Range collectorRange;
+
+ /**
+ * The first range of arguments we copy to the target. These are arguments
+ * in the range [0, pos). Note that arg[pos] is the return value of the filter.
+ */
+ private final Range range1;
+
+ /**
+ * The second range of arguments we copy to the target. These are arguments in the range
+ * (pos, N], where N is the number of target arguments.
+ */
+ private final Range range2;
+
+ private final int referencesOffset;
+ private final int stackFrameOffset;
+
+ CollectArguments(MethodHandle target, MethodHandle collector, int pos,
+ MethodType adapterType) {
+ super(adapterType);
+
+ this.target = target;
+ this.collector = collector;
+ this.pos = pos;
+
+ final int numFilterArgs = collector.type().parameterCount();
+ final int numAdapterArgs = type().parameterCount();
+ collectorRange = Range.of(type(), pos, pos + numFilterArgs);
+
+ range1 = Range.of(type(), 0, pos);
+ if (pos + numFilterArgs < numAdapterArgs) {
+ this.range2 = Range.of(type(), pos + numFilterArgs, numAdapterArgs);
+ } else {
+ this.range2 = null;
+ }
+
+ // Calculate the number of primitive bytes (or references) we copy to the
+ // target frame based on the return value of the combiner.
+ final Class<?> collectorRType = collector.type().rtype();
+ if (collectorRType == void.class) {
+ stackFrameOffset = 0;
+ referencesOffset = 0;
+ } else if (collectorRType.isPrimitive()) {
+ stackFrameOffset = EmulatedStackFrame.getSize(collectorRType);
+ referencesOffset = 0;
+ } else {
+ stackFrameOffset = 0;
+ referencesOffset = 1;
+ }
+ }
+
+ @Override
+ public void transform(EmulatedStackFrame stackFrame) throws Throwable {
+ // First invoke the collector.
+ EmulatedStackFrame filterFrame = EmulatedStackFrame.create(collector.type());
+ stackFrame.copyRangeTo(filterFrame, collectorRange, 0, 0);
+ collector.invoke(filterFrame);
+
+ // Start constructing the target frame.
+ EmulatedStackFrame targetFrame = EmulatedStackFrame.create(target.type());
+ stackFrame.copyRangeTo(targetFrame, range1, 0, 0);
+
+ // If one of these offsets is not zero, we have a return value to copy.
+ if (referencesOffset != 0 || stackFrameOffset != 0) {
+ final StackFrameReader reader = new StackFrameReader();
+ reader.attach(filterFrame).makeReturnValueAccessor();
+ final StackFrameWriter writer = new StackFrameWriter();
+ writer.attach(targetFrame, pos, range1.numReferences, range1.numBytes);
+ copyNext(reader, writer, target.type().ptypes()[0]);
+ }
+
+ if (range2 != null) {
+ stackFrame.copyRangeTo(targetFrame, range2,
+ range1.numReferences + referencesOffset,
+ range2.numBytes + stackFrameOffset);
+ }
+
+ target.invoke(targetFrame);
+ targetFrame.copyReturnValueTo(stackFrame);
+ }
+ }
+
+ /**
+ * Implements MethodHandles.foldArguments.
+ */
+ static class FoldArguments extends Transformer {
+ private final MethodHandle target;
+ private final MethodHandle combiner;
+
+ private final Range combinerArgs;
+ private final Range targetArgs;
+
+ private final int referencesOffset;
+ private final int stackFrameOffset;
+
+ FoldArguments(MethodHandle target, MethodHandle combiner) {
+ super(deriveType(target, combiner));
+
+ this.target = target;
+ this.combiner = combiner;
+
+ combinerArgs = Range.all(combiner.type());
+ targetArgs = Range.all(type());
+
+ final Class<?> combinerRType = combiner.type().rtype();
+ if (combinerRType == void.class) {
+ stackFrameOffset = 0;
+ referencesOffset = 0;
+ } else if (combinerRType.isPrimitive()) {
+ stackFrameOffset = EmulatedStackFrame.getSize(combinerRType);
+ referencesOffset = 0;
+ } else {
+ stackFrameOffset = 0;
+ referencesOffset = 1;
+ }
+ }
+
+ @Override
+ public void transform(EmulatedStackFrame stackFrame) throws Throwable {
+ // First construct the combiner frame and invoke it.
+ EmulatedStackFrame combinerFrame = EmulatedStackFrame.create(combiner.type());
+ stackFrame.copyRangeTo(combinerFrame, combinerArgs, 0, 0);
+ combiner.invoke(combinerFrame);
+
+ // Create the stack frame for the target.
+ EmulatedStackFrame targetFrame = EmulatedStackFrame.create(target.type());
+
+ // If one of these offsets is not zero, we have a return value to copy.
+ if (referencesOffset != 0 || stackFrameOffset != 0) {
+ final StackFrameReader reader = new StackFrameReader();
+ reader.attach(combinerFrame).makeReturnValueAccessor();
+ final StackFrameWriter writer = new StackFrameWriter();
+ writer.attach(targetFrame);
+ copyNext(reader, writer, target.type().ptypes()[0]);
+ }
+
+ stackFrame.copyRangeTo(targetFrame, targetArgs, referencesOffset, stackFrameOffset);
+ target.invoke(targetFrame);
+
+ targetFrame.copyReturnValueTo(stackFrame);
+ }
+
+ private static MethodType deriveType(MethodHandle target, MethodHandle combiner) {
+ if (combiner.type().rtype() == void.class) {
+ return target.type();
+ }
+
+ return target.type().dropParameterTypes(0, 1);
+ }
+ }
+
+ /**
+ * Implements MethodHandles.insertArguments.
+ */
+ static class InsertArguments extends Transformer {
+ private final MethodHandle target;
+ private final int pos;
+ private final Object[] values;
+
+ private final Range range1;
+ private final Range range2;
+
+ InsertArguments(MethodHandle target, int pos, Object[] values) {
+ super(target.type().dropParameterTypes(pos, pos + values.length));
+ this.target = target;
+ this.pos = pos;
+ this.values = values;
+
+ final MethodType type = type();
+ range1 = EmulatedStackFrame.Range.of(type, 0, pos);
+ range2 = Range.of(type, pos, type.parameterCount());
+ }
+
+ @Override
+ public void transform(EmulatedStackFrame stackFrame) throws Throwable {
+ EmulatedStackFrame calleeFrame = EmulatedStackFrame.create(target.type());
+
+ // Copy all arguments before |pos|.
+ stackFrame.copyRangeTo(calleeFrame, range1, 0, 0);
+
+ // Attach a stack frame writer so that we can copy the next |values.length|
+ // arguments.
+ final StackFrameWriter writer = new StackFrameWriter();
+ writer.attach(calleeFrame, pos, range1.numReferences, range1.numBytes);
+
+ // Copy all the arguments supplied in |values|.
+ int referencesCopied = 0;
+ int bytesCopied = 0;
+ final Class<?>[] ptypes = target.type().ptypes();
+ for (int i = 0; i < values.length; ++i) {
+ final Class<?> ptype = ptypes[i + pos];
+ if (ptype.isPrimitive()) {
+ if (ptype == boolean.class) {
+ writer.putNextBoolean((boolean) values[i]);
+ } else if (ptype == byte.class) {
+ writer.putNextByte((byte) values[i]);
+ } else if (ptype == char.class) {
+ writer.putNextChar((char) values[i]);
+ } else if (ptype == short.class) {
+ writer.putNextShort((short) values[i]);
+ } else if (ptype == int.class) {
+ writer.putNextInt((int) values[i]);
+ } else if (ptype == long.class) {
+ writer.putNextLong((long) values[i]);
+ } else if (ptype == float.class) {
+ writer.putNextFloat((float) values[i]);
+ } else if (ptype == double.class) {
+ writer.putNextDouble((double) values[i]);
+ }
+
+ bytesCopied += EmulatedStackFrame.getSize(ptype);
+ } else {
+ writer.putNextReference(values[i], ptype);
+ referencesCopied++;
+ }
+ }
+
+ // Copy all remaining arguments.
+ if (range2 != null) {
+ stackFrame.copyRangeTo(calleeFrame, range2,
+ range1.numReferences + referencesCopied,
+ range1.numBytes + bytesCopied);
+ }
+
+ target.invoke(calleeFrame);
+ calleeFrame.copyReturnValueTo(stackFrame);
+ }
+ }
+
+
+ /**
+ * Implements {@link java.lang.invokeMethodHandles#explicitCastArguments()}.
+ */
+ public static class ExplicitCastArguments extends Transformer {
+ private final MethodHandle target;
+
+ public ExplicitCastArguments(MethodHandle target, MethodType type) {
+ super(type);
+ this.target = target;
+ }
+
+ @Override
+ public void transform(EmulatedStackFrame callerFrame) throws Throwable {
+ // Create a new stack frame for the target.
+ EmulatedStackFrame targetFrame = EmulatedStackFrame.create(target.type());
+
+ explicitCastArguments(callerFrame, targetFrame);
+ target.invoke(targetFrame);
+ explicitCastReturnValue(callerFrame, targetFrame);
+ }
+
+ private void explicitCastArguments(final EmulatedStackFrame callerFrame,
+ final EmulatedStackFrame targetFrame) {
+ final StackFrameReader reader = new StackFrameReader();
+ reader.attach(callerFrame);
+ final StackFrameWriter writer = new StackFrameWriter();
+ writer.attach(targetFrame);
+
+ final Class<?>[] fromTypes = type().ptypes();
+ final Class<?>[] toTypes = target.type().ptypes();
+ for (int i = 0; i < fromTypes.length; ++i) {
+ explicitCast(reader, fromTypes[i], writer, toTypes[i]);
+ }
+ }
+
+ private void explicitCastReturnValue(final EmulatedStackFrame callerFrame,
+ final EmulatedStackFrame targetFrame) {
+ Class<?> from = target.type().rtype();
+ Class<?> to = type().rtype();
+ if (to != void.class) {
+ final StackFrameWriter writer = new StackFrameWriter();
+ writer.attach(callerFrame);
+ writer.makeReturnValueAccessor();
+ if (from == void.class) {
+ if (to.isPrimitive()) {
+ unboxNull(writer, to);
+ } else {
+ writer.putNextReference(null, to);
+ }
+ } else {
+ final StackFrameReader reader = new StackFrameReader();
+ reader.attach(targetFrame);
+ reader.makeReturnValueAccessor();
+ explicitCast(reader, target.type().rtype(), writer, type().rtype());
+ }
+ }
+ }
+
+ private static void throwUnexpectedType(final Class<?> unexpectedType) {
+ throw new InternalError("Unexpected type: " + unexpectedType);
+ }
+
+ @SuppressWarnings("unchecked")
+ private static void badCast(final Class<?> from, final Class<?> to) {
+ throw new ClassCastException("Cannot cast " + from.getName() + " to " + to.getName());
+ }
+
+ /**
+ * Converts byte value to boolean according to
+ * {@link java.lang.invoke.MethodHandles#explicitCast()}
+ */
+ private static boolean toBoolean(byte value) {
+ return (value & 1) == 1;
+ }
+
+ private static byte readPrimitiveAsByte(final StackFrameReader reader,
+ final Class<?> from) {
+ if (from == byte.class) {
+ return (byte) reader.nextByte();
+ } else if (from == char.class) {
+ return (byte) reader.nextChar();
+ } else if (from == short.class) {
+ return (byte) reader.nextShort();
+ } else if (from == int.class) {
+ return (byte) reader.nextInt();
+ } else if (from == long.class) {
+ return (byte) reader.nextLong();
+ } else if (from == float.class) {
+ return (byte) reader.nextFloat();
+ } else if (from == double.class) {
+ return (byte) reader.nextDouble();
+ } else if (from == boolean.class) {
+ return reader.nextBoolean() ? (byte) 1 : (byte) 0;
+ } else {
+ throwUnexpectedType(from);
+ return 0;
+ }
+ }
+
+ private static char readPrimitiveAsChar(final StackFrameReader reader,
+ final Class<?> from) {
+ if (from == byte.class) {
+ return (char) reader.nextByte();
+ } else if (from == char.class) {
+ return (char) reader.nextChar();
+ } else if (from == short.class) {
+ return (char) reader.nextShort();
+ } else if (from == int.class) {
+ return (char) reader.nextInt();
+ } else if (from == long.class) {
+ return (char) reader.nextLong();
+ } else if (from == float.class) {
+ return (char) reader.nextFloat();
+ } else if (from == double.class) {
+ return (char) reader.nextDouble();
+ } else if (from == boolean.class) {
+ return reader.nextBoolean() ? (char) 1 : (char) 0;
+ } else {
+ throwUnexpectedType(from);
+ return 0;
+ }
+ }
+
+ private static short readPrimitiveAsShort(final StackFrameReader reader,
+ final Class<?> from) {
+ if (from == byte.class) {
+ return (short) reader.nextByte();
+ } else if (from == char.class) {
+ return (short) reader.nextChar();
+ } else if (from == short.class) {
+ return (short) reader.nextShort();
+ } else if (from == int.class) {
+ return (short) reader.nextInt();
+ } else if (from == long.class) {
+ return (short) reader.nextLong();
+ } else if (from == float.class) {
+ return (short) reader.nextFloat();
+ } else if (from == double.class) {
+ return (short) reader.nextDouble();
+ } else if (from == boolean.class) {
+ return reader.nextBoolean() ? (short) 1 : (short) 0;
+ } else {
+ throwUnexpectedType(from);
+ return 0;
+ }
+ }
+
+ private static int readPrimitiveAsInt(final StackFrameReader reader,
+ final Class<?> from) {
+ if (from == byte.class) {
+ return (int) reader.nextByte();
+ } else if (from == char.class) {
+ return (int) reader.nextChar();
+ } else if (from == short.class) {
+ return (int) reader.nextShort();
+ } else if (from == int.class) {
+ return (int) reader.nextInt();
+ } else if (from == long.class) {
+ return (int) reader.nextLong();
+ } else if (from == float.class) {
+ return (int) reader.nextFloat();
+ } else if (from == double.class) {
+ return (int) reader.nextDouble();
+ } else if (from == boolean.class) {
+ return reader.nextBoolean() ? 1 : 0;
+ } else {
+ throwUnexpectedType(from);
+ return 0;
+ }
+ }
+
+ private static long readPrimitiveAsLong(final StackFrameReader reader,
+ final Class<?> from) {
+ if (from == byte.class) {
+ return (long) reader.nextByte();
+ } else if (from == char.class) {
+ return (long) reader.nextChar();
+ } else if (from == short.class) {
+ return (long) reader.nextShort();
+ } else if (from == int.class) {
+ return (long) reader.nextInt();
+ } else if (from == long.class) {
+ return (long) reader.nextLong();
+ } else if (from == float.class) {
+ return (long) reader.nextFloat();
+ } else if (from == double.class) {
+ return (long) reader.nextDouble();
+ } else if (from == boolean.class) {
+ return reader.nextBoolean() ? 1L : 0L;
+ } else {
+ throwUnexpectedType(from);
+ return 0;
+ }
+ }
+
+ private static float readPrimitiveAsFloat(final StackFrameReader reader,
+ final Class<?> from) {
+ if (from == byte.class) {
+ return (float) reader.nextByte();
+ } else if (from == char.class) {
+ return (float) reader.nextChar();
+ } else if (from == short.class) {
+ return (float) reader.nextShort();
+ } else if (from == int.class) {
+ return (float) reader.nextInt();
+ } else if (from == long.class) {
+ return (float) reader.nextLong();
+ } else if (from == float.class) {
+ return (float) reader.nextFloat();
+ } else if (from == double.class) {
+ return (float) reader.nextDouble();
+ } else if (from == boolean.class) {
+ return reader.nextBoolean() ? 1.0f : 0.0f;
+ } else {
+ throwUnexpectedType(from);
+ return 0;
+ }
+ }
+
+ private static double readPrimitiveAsDouble(final StackFrameReader reader,
+ final Class<?> from) {
+ if (from == byte.class) {
+ return (double) reader.nextByte();
+ } else if (from == char.class) {
+ return (double) reader.nextChar();
+ } else if (from == short.class) {
+ return (double) reader.nextShort();
+ } else if (from == int.class) {
+ return (double) reader.nextInt();
+ } else if (from == long.class) {
+ return (double) reader.nextLong();
+ } else if (from == float.class) {
+ return (double) reader.nextFloat();
+ } else if (from == double.class) {
+ return (double) reader.nextDouble();
+ } else if (from == boolean.class) {
+ return reader.nextBoolean() ? 1.0 : 0.0;
+ } else {
+ throwUnexpectedType(from);
+ return 0;
+ }
+ }
+
+ private static void explicitCastPrimitives(final StackFrameReader reader,
+ final Class<?> from,
+ final StackFrameWriter writer,
+ final Class<?> to) {
+ if (to == byte.class) {
+ byte value = readPrimitiveAsByte(reader, from);
+ writer.putNextByte(value);
+ } else if (to == char.class) {
+ char value = readPrimitiveAsChar(reader, from);
+ writer.putNextChar(value);
+ } else if (to == short.class) {
+ short value = readPrimitiveAsShort(reader, from);
+ writer.putNextShort(value);
+ } else if (to == int.class) {
+ int value = readPrimitiveAsInt(reader, from);
+ writer.putNextInt(value);
+ } else if (to == long.class) {
+ long value = readPrimitiveAsLong(reader, from);
+ writer.putNextLong(value);
+ } else if (to == float.class) {
+ float value = readPrimitiveAsFloat(reader, from);
+ writer.putNextFloat(value);
+ } else if (to == double.class) {
+ double value = readPrimitiveAsDouble(reader, from);
+ writer.putNextDouble(value);
+ } else if (to == boolean.class) {
+ byte byteValue = readPrimitiveAsByte(reader, from);
+ writer.putNextBoolean(toBoolean(byteValue));
+ } else {
+ throwUnexpectedType(to);
+ }
+ }
+
+ private static void unboxNull(final StackFrameWriter writer, final Class<?> to) {
+ if (to == boolean.class) {
+ writer.putNextBoolean(false);
+ } else if (to == byte.class) {
+ writer.putNextByte((byte) 0);
+ } else if (to == char.class) {
+ writer.putNextChar((char) 0);
+ } else if (to == short.class) {
+ writer.putNextShort((short) 0);
+ } else if (to == int.class) {
+ writer.putNextInt((int) 0);
+ } else if (to == long.class) {
+ writer.putNextLong((long) 0);
+ } else if (to == float.class) {
+ writer.putNextFloat((float) 0);
+ } else if (to == double.class) {
+ writer.putNextDouble((double) 0);
+ } else {
+ throwUnexpectedType(to);
+ }
+ }
+
+ private static void unboxNonNull(final Object ref, final Class<?> from,
+ final StackFrameWriter writer, final Class<?> to) {
+ if (from == Boolean.class) {
+ boolean z = (boolean) ref;
+ if (to == boolean.class) {
+ writer.putNextBoolean(z);
+ } else if (to == byte.class) {
+ writer.putNextByte(z ? (byte) 1 : (byte) 0);
+ } else if (to == short.class) {
+ writer.putNextShort(z ? (short) 1 : (short) 0);
+ } else if (to == char.class) {
+ writer.putNextChar(z ? (char) 1 : (char) 0);
+ } else if (to == int.class) {
+ writer.putNextInt(z ? 1 : 0);
+ } else if (to == long.class) {
+ writer.putNextLong(z ? 1l : 0l);
+ } else if (to == float.class) {
+ writer.putNextFloat(z ? 1.0f : 0.0f);
+ } else if (to == double.class) {
+ writer.putNextDouble(z ? 1.0 : 0.0);
+ } else {
+ badCast(from, to);
+ }
+ } else if (from == Byte.class) {
+ byte b = (byte) ref;
+ if (to == byte.class) {
+ writer.putNextByte(b);
+ } else if (to == boolean.class) {
+ writer.putNextBoolean(toBoolean(b));
+ } else if (to == short.class) {
+ writer.putNextShort((short) b);
+ } else if (to == char.class) {
+ writer.putNextChar((char) b);
+ } else if (to == int.class) {
+ writer.putNextInt((int) b);
+ } else if (to == long.class) {
+ writer.putNextLong((long) b);
+ } else if (to == float.class) {
+ writer.putNextFloat((float) b);
+ } else if (to == double.class) {
+ writer.putNextDouble((double) b);
+ } else {
+ badCast(from, to);
+ }
+ } else if (from == Short.class) {
+ short s = (short) ref;
+ if (to == boolean.class) {
+ writer.putNextBoolean((s & 1) == 1);
+ } else if (to == byte.class) {
+ writer.putNextByte((byte) s);
+ } else if (to == short.class) {
+ writer.putNextShort(s);
+ } else if (to == char.class) {
+ writer.putNextChar((char) s);
+ } else if (to == int.class) {
+ writer.putNextInt((int) s);
+ } else if (to == long.class) {
+ writer.putNextLong((long) s);
+ } else if (to == float.class) {
+ writer.putNextFloat((float) s);
+ } else if (to == double.class) {
+ writer.putNextDouble((double) s);
+ } else {
+ badCast(from, to);
+ }
+ } else if (from == Character.class) {
+ char c = (char) ref;
+ if (to == boolean.class) {
+ writer.putNextBoolean((c & (char) 1) == (char) 1);
+ } else if (to == byte.class) {
+ writer.putNextByte((byte) c);
+ } else if (to == short.class) {
+ writer.putNextShort((short) c);
+ } else if (to == char.class) {
+ writer.putNextChar(c);
+ } else if (to == int.class) {
+ writer.putNextInt((int) c);
+ } else if (to == long.class) {
+ writer.putNextLong((long) c);
+ } else if (to == float.class) {
+ writer.putNextFloat((float) c);
+ } else if (to == double.class) {
+ writer.putNextDouble((double) c);
+ } else {
+ badCast(from, to);
+ }
+ } else if (from == Integer.class) {
+ int i = (int) ref;
+ if (to == boolean.class) {
+ writer.putNextBoolean((i & 1) == 1);
+ } else if (to == byte.class) {
+ writer.putNextByte((byte) i);
+ } else if (to == short.class) {
+ writer.putNextShort((short) i);
+ } else if (to == char.class) {
+ writer.putNextChar((char) i);
+ } else if (to == int.class) {
+ writer.putNextInt(i);
+ } else if (to == long.class) {
+ writer.putNextLong((long) i);
+ } else if (to == float.class) {
+ writer.putNextFloat((float) i);
+ } else if (to == double.class) {
+ writer.putNextDouble((double) i);
+ } else {
+ badCast(from, to);
+ }
+ } else if (from == Long.class) {
+ long j = (long) ref;
+ if (to == boolean.class) {
+ writer.putNextBoolean((j & 1l) == 1l);
+ } else if (to == byte.class) {
+ writer.putNextByte((byte) j);
+ } else if (to == short.class) {
+ writer.putNextShort((short) j);
+ } else if (to == char.class) {
+ writer.putNextChar((char) j);
+ } else if (to == int.class) {
+ writer.putNextInt((int) j);
+ } else if (to == long.class) {
+ writer.putNextLong(j);
+ } else if (to == float.class) {
+ writer.putNextFloat((float) j);
+ } else if (to == double.class) {
+ writer.putNextDouble((double) j);
+ } else {
+ badCast(from, to);
+ }
+ } else if (from == Float.class) {
+ float f = (float) ref;
+ if (to == boolean.class) {
+ writer.putNextBoolean(((byte) f & 1) != 0);
+ } else if (to == byte.class) {
+ writer.putNextByte((byte) f);
+ } else if (to == short.class) {
+ writer.putNextShort((short) f);
+ } else if (to == char.class) {
+ writer.putNextChar((char) f);
+ } else if (to == int.class) {
+ writer.putNextInt((int) f);
+ } else if (to == long.class) {
+ writer.putNextLong((long) f);
+ } else if (to == float.class) {
+ writer.putNextFloat(f);
+ } else if (to == double.class) {
+ writer.putNextDouble((double) f);
+ } else {
+ badCast(from, to);
+ }
+ } else if (from == Double.class) {
+ double d = (double) ref;
+ if (to == boolean.class) {
+ writer.putNextBoolean(((byte) d & 1) != 0);
+ } else if (to == byte.class) {
+ writer.putNextByte((byte) d);
+ } else if (to == short.class) {
+ writer.putNextShort((short) d);
+ } else if (to == char.class) {
+ writer.putNextChar((char) d);
+ } else if (to == int.class) {
+ writer.putNextInt((int) d);
+ } else if (to == long.class) {
+ writer.putNextLong((long) d);
+ } else if (to == float.class) {
+ writer.putNextFloat((float) d);
+ } else if (to == double.class) {
+ writer.putNextDouble(d);
+ } else {
+ badCast(from, to);
+ }
+ } else {
+ badCast(from, to);
+ }
+ }
+
+ private static void unbox(final Object ref, final Class<?> from,
+ final StackFrameWriter writer, final Class<?> to) {
+ if (ref == null) {
+ unboxNull(writer, to);
+ } else {
+ unboxNonNull(ref, from, writer, to);
+ }
+ }
+
+ private static void box(final StackFrameReader reader, final Class<?> from,
+ final StackFrameWriter writer, final Class<?> to) {
+ Object boxed = null;
+ if (from == boolean.class) {
+ boxed = Boolean.valueOf(reader.nextBoolean());
+ } else if (from == byte.class) {
+ boxed = Byte.valueOf(reader.nextByte());
+ } else if (from == char.class) {
+ boxed = Character.valueOf(reader.nextChar());
+ } else if (from == short.class) {
+ boxed = Short.valueOf(reader.nextShort());
+ } else if (from == int.class) {
+ boxed = Integer.valueOf(reader.nextInt());
+ } else if (from == long.class) {
+ boxed = Long.valueOf(reader.nextLong());
+ } else if (from == float.class) {
+ boxed = Float.valueOf(reader.nextFloat());
+ } else if (from == double.class) {
+ boxed = Double.valueOf(reader.nextDouble());
+ } else {
+ throwUnexpectedType(from);
+ }
+ writer.putNextReference(to.cast(boxed), to);
+ }
+
+ private static void explicitCast(final StackFrameReader reader, final Class<?> from,
+ final StackFrameWriter writer, final Class<?> to) {
+ if (from.equals(to)) {
+ StackFrameAccessor.copyNext(reader, writer, from);
+ return;
+ }
+
+ if (from.isPrimitive()) {
+ if (to.isPrimitive()) {
+ // |from| and |to| are primitive types.
+ explicitCastPrimitives(reader, from, writer, to);
+ } else {
+ // |from| is a primitive type, |to| is a reference type.
+ box(reader, from, writer, to);
+ }
+ } else {
+ // |from| is a reference type.
+ Object ref = reader.nextReference(from);
+ if (to.isPrimitive()) {
+ // |from| is a reference type, |to| is a primitive type,
+ unbox(ref, from, writer, to);
+ } else if (to.isInterface()) {
+ // Pass from without a cast according to description for
+ // {@link java.lang.invoke.MethodHandles#explicitCastArguments()}.
+ writer.putNextReference(ref, to);
+ } else {
+ // |to| and from |from| are reference types, perform class cast check.
+ writer.putNextReference(to.cast(ref), to);
+ }
+ }
+ }
+ }
+}
diff --git a/java/lang/invoke/VarHandle.java b/java/lang/invoke/VarHandle.java
new file mode 100644
index 0000000..7b5ac00
--- /dev/null
+++ b/java/lang/invoke/VarHandle.java
@@ -0,0 +1,2386 @@
+/*
+ * Copyright (c) 2014, 2017, 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 dalvik.system.VMRuntime;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * A VarHandle is a dynamically strongly typed reference to a variable, or to a
+ * parametrically-defined family of variables, including static fields,
+ * non-static fields, array elements, or components of an off-heap data
+ * structure. Access to such variables is supported under various
+ * <em>access modes</em>, including plain read/write access, volatile
+ * read/write access, and compare-and-swap.
+ *
+ * <p>VarHandles are immutable and have no visible state. VarHandles cannot be
+ * subclassed by the user.
+ *
+ * <p>A VarHandle has:
+ * <ul>
+ * <li>a {@link #varType variable type} T, the type of every variable referenced
+ * by this VarHandle; and
+ * <li>a list of {@link #coordinateTypes coordinate types}
+ * {@code CT1, CT2, ..., CTn}, the types of <em>coordinate expressions</em> that
+ * jointly locate a variable referenced by this VarHandle.
+ * </ul>
+ * Variable and coordinate types may be primitive or reference, and are
+ * represented by {@code Class} objects. The list of coordinate types may be
+ * empty.
+ *
+ * <p>Factory methods that produce or {@link java.lang.invoke.MethodHandles.Lookup
+ * lookup} VarHandle instances document the supported variable type and the list
+ * of coordinate types.
+ *
+ * <p>Each access mode is associated with one <em>access mode method</em>, a
+ * <a href="MethodHandle.html#sigpoly">signature polymorphic</a> method named
+ * for the access mode. When an access mode method is invoked on a VarHandle
+ * instance, the initial arguments to the invocation are coordinate expressions
+ * that indicate in precisely which object the variable is to be accessed.
+ * Trailing arguments to the invocation represent values of importance to the
+ * access mode. For example, the various compare-and-set or compare-and-exchange
+ * access modes require two trailing arguments for the variable's expected value
+ * and new value.
+ *
+ * <p>The arity and types of arguments to the invocation of an access mode
+ * method are not checked statically. Instead, each access mode method
+ * specifies an {@link #accessModeType(AccessMode) access mode type},
+ * represented as an instance of {@link MethodType}, that serves as a kind of
+ * method signature against which the arguments are checked dynamically. An
+ * access mode type gives formal parameter types in terms of the coordinate
+ * types of a VarHandle instance and the types for values of importance to the
+ * access mode. An access mode type also gives a return type, often in terms of
+ * the variable type of a VarHandle instance. When an access mode method is
+ * invoked on a VarHandle instance, the symbolic type descriptor at the
+ * call site, the run time types of arguments to the invocation, and the run
+ * time type of the return value, must <a href="#invoke">match</a> the types
+ * given in the access mode type. A runtime exception will be thrown if the
+ * match fails.
+ *
+ * For example, the access mode method {@link #compareAndSet} specifies that if
+ * its receiver is a VarHandle instance with coordinate types
+ * {@code CT1, ..., CTn} and variable type {@code T}, then its access mode type
+ * is {@code (CT1 c1, ..., CTn cn, T expectedValue, T newValue)boolean}.
+ * Suppose that a VarHandle instance can access array elements, and that its
+ * coordinate types are {@code String[]} and {@code int} while its variable type
+ * is {@code String}. The access mode type for {@code compareAndSet} on this
+ * VarHandle instance would be
+ * {@code (String[] c1, int c2, String expectedValue, String newValue)boolean}.
+ * Such a VarHandle instance may produced by the
+ * {@link MethodHandles#arrayElementVarHandle(Class) array factory method} and
+ * access array elements as follows:
+ * <pre> {@code
+ * String[] sa = ...
+ * VarHandle avh = MethodHandles.arrayElementVarHandle(String[].class);
+ * boolean r = avh.compareAndSet(sa, 10, "expected", "new");
+ * }</pre>
+ *
+ * <p>Access modes control atomicity and consistency properties.
+ * <em>Plain</em> read ({@code get}) and write ({@code set})
+ * accesses are guaranteed to be bitwise atomic only for references
+ * and for primitive values of at most 32 bits, and impose no observable
+ * ordering constraints with respect to threads other than the
+ * executing thread. <em>Opaque</em> operations are bitwise atomic and
+ * coherently ordered with respect to accesses to the same variable.
+ * In addition to obeying Opaque properties, <em>Acquire</em> mode
+ * reads and their subsequent accesses are ordered after matching
+ * <em>Release</em> mode writes and their previous accesses. In
+ * addition to obeying Acquire and Release properties, all
+ * <em>Volatile</em> operations are totally ordered with respect to
+ * each other.
+ *
+ * <p>Access modes are grouped into the following categories:
+ * <ul>
+ * <li>read access modes that get the value of a variable under specified
+ * memory ordering effects.
+ * The set of corresponding access mode methods belonging to this group
+ * consists of the methods
+ * {@link #get get},
+ * {@link #getVolatile getVolatile},
+ * {@link #getAcquire getAcquire},
+ * {@link #getOpaque getOpaque}.
+ * <li>write access modes that set the value of a variable under specified
+ * memory ordering effects.
+ * The set of corresponding access mode methods belonging to this group
+ * consists of the methods
+ * {@link #set set},
+ * {@link #setVolatile setVolatile},
+ * {@link #setRelease setRelease},
+ * {@link #setOpaque setOpaque}.
+ * <li>atomic update access modes that, for example, atomically compare and set
+ * the value of a variable under specified memory ordering effects.
+ * The set of corresponding access mode methods belonging to this group
+ * consists of the methods
+ * {@link #compareAndSet compareAndSet},
+ * {@link #weakCompareAndSetPlain weakCompareAndSetPlain},
+ * {@link #weakCompareAndSet weakCompareAndSet},
+ * {@link #weakCompareAndSetAcquire weakCompareAndSetAcquire},
+ * {@link #weakCompareAndSetRelease weakCompareAndSetRelease},
+ * {@link #compareAndExchangeAcquire compareAndExchangeAcquire},
+ * {@link #compareAndExchange compareAndExchange},
+ * {@link #compareAndExchangeRelease compareAndExchangeRelease},
+ * {@link #getAndSet getAndSet},
+ * {@link #getAndSetAcquire getAndSetAcquire},
+ * {@link #getAndSetRelease getAndSetRelease}.
+ * <li>numeric atomic update access modes that, for example, atomically get and
+ * set with addition the value of a variable under specified memory ordering
+ * effects.
+ * The set of corresponding access mode methods belonging to this group
+ * consists of the methods
+ * {@link #getAndAdd getAndAdd},
+ * {@link #getAndAddAcquire getAndAddAcquire},
+ * {@link #getAndAddRelease getAndAddRelease},
+ * <li>bitwise atomic update access modes that, for example, atomically get and
+ * bitwise OR the value of a variable under specified memory ordering
+ * effects.
+ * The set of corresponding access mode methods belonging to this group
+ * consists of the methods
+ * {@link #getAndBitwiseOr getAndBitwiseOr},
+ * {@link #getAndBitwiseOrAcquire getAndBitwiseOrAcquire},
+ * {@link #getAndBitwiseOrRelease getAndBitwiseOrRelease},
+ * {@link #getAndBitwiseAnd getAndBitwiseAnd},
+ * {@link #getAndBitwiseAndAcquire getAndBitwiseAndAcquire},
+ * {@link #getAndBitwiseAndRelease getAndBitwiseAndRelease},
+ * {@link #getAndBitwiseXor getAndBitwiseXor},
+ * {@link #getAndBitwiseXorAcquire getAndBitwiseXorAcquire},
+ * {@link #getAndBitwiseXorRelease getAndBitwiseXorRelease}.
+ * </ul>
+ *
+ * <p>Factory methods that produce or {@link java.lang.invoke.MethodHandles.Lookup
+ * lookup} VarHandle instances document the set of access modes that are
+ * supported, which may also include documenting restrictions based on the
+ * variable type and whether a variable is read-only. If an access mode is not
+ * supported then the corresponding access mode method will on invocation throw
+ * an {@code UnsupportedOperationException}. Factory methods should document
+ * any additional undeclared exceptions that may be thrown by access mode
+ * methods.
+ * The {@link #get get} access mode is supported for all
+ * VarHandle instances and the corresponding method never throws
+ * {@code UnsupportedOperationException}.
+ * If a VarHandle references a read-only variable (for example a {@code final}
+ * field) then write, atomic update, numeric atomic update, and bitwise atomic
+ * update access modes are not supported and corresponding methods throw
+ * {@code UnsupportedOperationException}.
+ * Read/write access modes (if supported), with the exception of
+ * {@code get} and {@code set}, provide atomic access for
+ * reference types and all primitive types.
+ * Unless stated otherwise in the documentation of a factory method, the access
+ * modes {@code get} and {@code set} (if supported) provide atomic access for
+ * reference types and all primitives types, with the exception of {@code long}
+ * and {@code double} on 32-bit platforms.
+ *
+ * <p>Access modes will override any memory ordering effects specified at
+ * the declaration site of a variable. For example, a VarHandle accessing a
+ * a field using the {@code get} access mode will access the field as
+ * specified <em>by its access mode</em> even if that field is declared
+ * {@code volatile}. When mixed access is performed extreme care should be
+ * taken since the Java Memory Model may permit surprising results.
+ *
+ * <p>In addition to supporting access to variables under various access modes,
+ * a set of static methods, referred to as memory fence methods, is also
+ * provided for fine-grained control of memory ordering.
+ *
+ * The Java Language Specification permits other threads to observe operations
+ * as if they were executed in orders different than are apparent in program
+ * source code, subject to constraints arising, for example, from the use of
+ * locks, {@code volatile} fields or VarHandles. The static methods,
+ * {@link #fullFence fullFence}, {@link #acquireFence acquireFence},
+ * {@link #releaseFence releaseFence}, {@link #loadLoadFence loadLoadFence} and
+ * {@link #storeStoreFence storeStoreFence}, can also be used to impose
+ * constraints. Their specifications, as is the case for certain access modes,
+ * are phrased in terms of the lack of "reorderings" -- observable ordering
+ * effects that might otherwise occur if the fence was not present. More
+ * precise phrasing of the specification of access mode methods and memory fence
+ * methods may accompany future updates of the Java Language Specification.
+ *
+ * <h1>Compiling invocation of access mode methods</h1>
+ * A Java method call expression naming an access mode method can invoke a
+ * VarHandle from Java source code. From the viewpoint of source code, these
+ * methods can take any arguments and their polymorphic result (if expressed)
+ * can be cast to any return type. Formally this is accomplished by giving the
+ * access mode methods variable arity {@code Object} arguments and
+ * {@code Object} return types (if the return type is polymorphic), but they
+ * have an additional quality called <em>signature polymorphism</em> which
+ * connects this freedom of invocation directly to the JVM execution stack.
+ * <p>
+ * As is usual with virtual methods, source-level calls to access mode methods
+ * compile to an {@code invokevirtual} instruction. More unusually, the
+ * compiler must record the actual argument types, and may not perform method
+ * invocation conversions on the arguments. Instead, it must generate
+ * instructions to push them on the stack according to their own unconverted
+ * types. The VarHandle object itself will be pushed on the stack before the
+ * arguments. The compiler then generates an {@code invokevirtual} instruction
+ * that invokes the access mode method with a symbolic type descriptor which
+ * describes the argument and return types.
+ * <p>
+ * To issue a complete symbolic type descriptor, the compiler must also
+ * determine the return type (if polymorphic). This is based on a cast on the
+ * method invocation expression, if there is one, or else {@code Object} if the
+ * invocation is an expression, or else {@code void} if the invocation is a
+ * statement. The cast may be to a primitive type (but not {@code void}).
+ * <p>
+ * As a corner case, an uncasted {@code null} argument is given a symbolic type
+ * descriptor of {@code java.lang.Void}. The ambiguity with the type
+ * {@code Void} is harmless, since there are no references of type {@code Void}
+ * except the null reference.
+ *
+ *
+ * <h1><a id="invoke">Performing invocation of access mode methods</a></h1>
+ * The first time an {@code invokevirtual} instruction is executed it is linked
+ * by symbolically resolving the names in the instruction and verifying that
+ * the method call is statically legal. This also holds for calls to access mode
+ * methods. In this case, the symbolic type descriptor emitted by the compiler
+ * is checked for correct syntax, and names it contains are resolved. Thus, an
+ * {@code invokevirtual} instruction which invokes an access mode method will
+ * always link, as long as the symbolic type descriptor is syntactically
+ * well-formed and the types exist.
+ * <p>
+ * When the {@code invokevirtual} is executed after linking, the receiving
+ * VarHandle's access mode type is first checked by the JVM to ensure that it
+ * matches the symbolic type descriptor. If the type
+ * match fails, it means that the access mode method which the caller is
+ * invoking is not present on the individual VarHandle being invoked.
+ *
+ * <p>
+ * Invocation of an access mode method behaves as if an invocation of
+ * {@link MethodHandle#invoke}, where the receiving method handle accepts the
+ * VarHandle instance as the leading argument. More specifically, the
+ * following, where {@code {access-mode}} corresponds to the access mode method
+ * name:
+ * <pre> {@code
+ * VarHandle vh = ..
+ * R r = (R) vh.{access-mode}(p1, p2, ..., pN);
+ * }</pre>
+ * behaves as if:
+ * <pre> {@code
+ * VarHandle vh = ..
+ * VarHandle.AccessMode am = VarHandle.AccessMode.valueFromMethodName("{access-mode}");
+ * MethodHandle mh = MethodHandles.varHandleExactInvoker(
+ * am,
+ * vh.accessModeType(am));
+ *
+ * R r = (R) mh.invoke(vh, p1, p2, ..., pN)
+ * }</pre>
+ * (modulo access mode methods do not declare throwing of {@code Throwable}).
+ * This is equivalent to:
+ * <pre> {@code
+ * MethodHandle mh = MethodHandles.lookup().findVirtual(
+ * VarHandle.class,
+ * "{access-mode}",
+ * MethodType.methodType(R, p1, p2, ..., pN));
+ *
+ * R r = (R) mh.invokeExact(vh, p1, p2, ..., pN)
+ * }</pre>
+ * where the desired method type is the symbolic type descriptor and a
+ * {@link MethodHandle#invokeExact} is performed, since before invocation of the
+ * target, the handle will apply reference casts as necessary and box, unbox, or
+ * widen primitive values, as if by {@link MethodHandle#asType asType} (see also
+ * {@link MethodHandles#varHandleInvoker}).
+ *
+ * More concisely, such behaviour is equivalent to:
+ * <pre> {@code
+ * VarHandle vh = ..
+ * VarHandle.AccessMode am = VarHandle.AccessMode.valueFromMethodName("{access-mode}");
+ * MethodHandle mh = vh.toMethodHandle(am);
+ *
+ * R r = (R) mh.invoke(p1, p2, ..., pN)
+ * }</pre>
+ * Where, in this case, the method handle is bound to the VarHandle instance.
+ *
+ *
+ * <h1>Invocation checking</h1>
+ * In typical programs, VarHandle access mode type matching will usually
+ * succeed. But if a match fails, the JVM will throw a
+ * {@link WrongMethodTypeException}.
+ * <p>
+ * Thus, an access mode type mismatch which might show up as a linkage error
+ * in a statically typed program can show up as a dynamic
+ * {@code WrongMethodTypeException} in a program which uses VarHandles.
+ * <p>
+ * Because access mode types contain "live" {@code Class} objects, method type
+ * matching takes into account both type names and class loaders.
+ * Thus, even if a VarHandle {@code VH} is created in one class loader
+ * {@code L1} and used in another {@code L2}, VarHandle access mode method
+ * calls are type-safe, because the caller's symbolic type descriptor, as
+ * resolved in {@code L2}, is matched against the original callee method's
+ * symbolic type descriptor, as resolved in {@code L1}. The resolution in
+ * {@code L1} happens when {@code VH} is created and its access mode types are
+ * assigned, while the resolution in {@code L2} happens when the
+ * {@code invokevirtual} instruction is linked.
+ * <p>
+ * Apart from type descriptor checks, a VarHandles's capability to
+ * access it's variables is unrestricted.
+ * If a VarHandle is formed on a non-public variable by a class that has access
+ * to that variable, the resulting VarHandle can be used in any place by any
+ * caller who receives a reference to it.
+ * <p>
+ * Unlike with the Core Reflection API, where access is checked every time a
+ * reflective method is invoked, VarHandle access checking is performed
+ * <a href="MethodHandles.Lookup.html#access">when the VarHandle is
+ * created</a>.
+ * Thus, VarHandles to non-public variables, or to variables in non-public
+ * classes, should generally be kept secret. They should not be passed to
+ * untrusted code unless their use from the untrusted code would be harmless.
+ *
+ *
+ * <h1>VarHandle creation</h1>
+ * Java code can create a VarHandle that directly accesses any field that is
+ * accessible to that code. This is done via a reflective, capability-based
+ * API called {@link java.lang.invoke.MethodHandles.Lookup
+ * MethodHandles.Lookup}.
+ * For example, a VarHandle for a non-static field can be obtained
+ * from {@link java.lang.invoke.MethodHandles.Lookup#findVarHandle
+ * Lookup.findVarHandle}.
+ * There is also a conversion method from Core Reflection API objects,
+ * {@link java.lang.invoke.MethodHandles.Lookup#unreflectVarHandle
+ * Lookup.unreflectVarHandle}.
+ * <p>
+ * Access to protected field members is restricted to receivers only of the
+ * accessing class, or one of its subclasses, and the accessing class must in
+ * turn be a subclass (or package sibling) of the protected member's defining
+ * class. If a VarHandle refers to a protected non-static field of a declaring
+ * class outside the current package, the receiver argument will be narrowed to
+ * the type of the accessing class.
+ *
+ * <h1>Interoperation between VarHandles and the Core Reflection API</h1>
+ * Using factory methods in the {@link java.lang.invoke.MethodHandles.Lookup
+ * Lookup} API, any field represented by a Core Reflection API object
+ * can be converted to a behaviorally equivalent VarHandle.
+ * For example, a reflective {@link java.lang.reflect.Field Field} can
+ * be converted to a VarHandle using
+ * {@link java.lang.invoke.MethodHandles.Lookup#unreflectVarHandle
+ * Lookup.unreflectVarHandle}.
+ * The resulting VarHandles generally provide more direct and efficient
+ * access to the underlying fields.
+ * <p>
+ * As a special case, when the Core Reflection API is used to view the
+ * signature polymorphic access mode methods in this class, they appear as
+ * ordinary non-polymorphic methods. Their reflective appearance, as viewed by
+ * {@link java.lang.Class#getDeclaredMethod Class.getDeclaredMethod},
+ * is unaffected by their special status in this API.
+ * For example, {@link java.lang.reflect.Method#getModifiers
+ * Method.getModifiers}
+ * will report exactly those modifier bits required for any similarly
+ * declared method, including in this case {@code native} and {@code varargs}
+ * bits.
+ * <p>
+ * As with any reflected method, these methods (when reflected) may be invoked
+ * directly via {@link java.lang.reflect.Method#invoke java.lang.reflect.Method.invoke},
+ * via JNI, or indirectly via
+ * {@link java.lang.invoke.MethodHandles.Lookup#unreflect Lookup.unreflect}.
+ * However, such reflective calls do not result in access mode method
+ * invocations. Such a call, if passed the required argument (a single one, of
+ * type {@code Object[]}), will ignore the argument and will throw an
+ * {@code UnsupportedOperationException}.
+ * <p>
+ * Since {@code invokevirtual} instructions can natively invoke VarHandle
+ * access mode methods under any symbolic type descriptor, this reflective view
+ * conflicts with the normal presentation of these methods via bytecodes.
+ * Thus, these native methods, when reflectively viewed by
+ * {@code Class.getDeclaredMethod}, may be regarded as placeholders only.
+ * <p>
+ * In order to obtain an invoker method for a particular access mode type,
+ * use {@link java.lang.invoke.MethodHandles#varHandleExactInvoker} or
+ * {@link java.lang.invoke.MethodHandles#varHandleInvoker}. The
+ * {@link java.lang.invoke.MethodHandles.Lookup#findVirtual Lookup.findVirtual}
+ * API is also able to return a method handle to call an access mode method for
+ * any specified access mode type and is equivalent in behaviour to
+ * {@link java.lang.invoke.MethodHandles#varHandleInvoker}.
+ *
+ * <h1>Interoperation between VarHandles and Java generics</h1>
+ * A VarHandle can be obtained for a variable, such as a a field, which is
+ * declared with Java generic types. As with the Core Reflection API, the
+ * VarHandle's variable type will be constructed from the erasure of the
+ * source-level type. When a VarHandle access mode method is invoked, the
+ * types
+ * of its arguments or the return value cast type may be generic types or type
+ * instances. If this occurs, the compiler will replace those types by their
+ * erasures when it constructs the symbolic type descriptor for the
+ * {@code invokevirtual} instruction.
+ *
+ * @see MethodHandle
+ * @see MethodHandles
+ * @see MethodType
+ * @since 9
+ * @hide
+ */
+public abstract class VarHandle {
+ // Android-added: Using sun.misc.Unsafe for fence implementation.
+ private static final sun.misc.Unsafe UNSAFE = sun.misc.Unsafe.getUnsafe();
+
+ // BEGIN Android-removed: No VarForm in Android implementation.
+ /*
+ final VarForm vform;
+
+ VarHandle(VarForm vform) {
+ this.vform = vform;
+ }
+ */
+ // END Android-removed: No VarForm in Android implementation.
+
+ // BEGIN Android-added: fields for common metadata.
+ /** The target type for accesses. */
+ private final Class<?> varType;
+
+ /** This VarHandle's first coordinate, or null if this VarHandle has no coordinates. */
+ private final Class<?> coordinateType0;
+
+ /** This VarHandle's second coordinate, or null if this VarHandle has less than two
+ * coordinates. */
+ private final Class<?> coordinateType1;
+
+ /** BitMask of supported access mode indexed by AccessMode.ordinal(). */
+ private final int accessModesBitMask;
+ // END Android-added: fields for common metadata.
+
+ // Plain accessors
+
+ /**
+ * Returns the value of a variable, with memory semantics of reading as
+ * if the variable was declared non-{@code volatile}. Commonly referred to
+ * as plain read access.
+ *
+ * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn)T}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code get}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.GET)} on this VarHandle.
+ *
+ * <p>This access mode is supported by all VarHandle instances and never
+ * throws {@code UnsupportedOperationException}.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT1 ct1, ..., CTn)}
+ * , statically represented using varargs.
+ * @return the signature-polymorphic result that is the value of the
+ * variable
+ * , statically represented using {@code Object}.
+ * @throws WrongMethodTypeException if the access mode type does not
+ * match the caller's symbolic type descriptor.
+ * @throws ClassCastException if the access mode type matches the caller's
+ * symbolic type descriptor, but a reference cast fails.
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ // Android-removed: unsupported annotation.
+ // @HotSpotIntrinsicCandidate
+ Object get(Object... args);
+
+ /**
+ * Sets the value of a variable to the {@code newValue}, with memory
+ * semantics of setting as if the variable was declared non-{@code volatile}
+ * and non-{@code final}. Commonly referred to as plain write access.
+ *
+ * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T newValue)void}
+ *
+ * <p>The symbolic type descriptor at the call site of {@code set}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.SET)} on this VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT1 ct1, ..., CTn ctn, T newValue)}
+ * , statically represented using varargs.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type does not
+ * match the caller's symbolic type descriptor.
+ * @throws ClassCastException if the access mode type matches the caller's
+ * symbolic type descriptor, but a reference cast fails.
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ // Android-removed: unsupported annotation.
+ // @HotSpotIntrinsicCandidate
+ void set(Object... args);
+
+
+ // Volatile accessors
+
+ /**
+ * Returns the value of a variable, with memory semantics of reading as if
+ * the variable was declared {@code volatile}.
+ *
+ * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn)T}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code getVolatile}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.GET_VOLATILE)} on this
+ * VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT1 ct1, ..., CTn ctn)}
+ * , statically represented using varargs.
+ * @return the signature-polymorphic result that is the value of the
+ * variable
+ * , statically represented using {@code Object}.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type does not
+ * match the caller's symbolic type descriptor.
+ * @throws ClassCastException if the access mode type matches the caller's
+ * symbolic type descriptor, but a reference cast fails.
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ // Android-removed: unsupported annotation.
+ // @HotSpotIntrinsicCandidate
+ Object getVolatile(Object... args);
+
+ /**
+ * Sets the value of a variable to the {@code newValue}, with memory
+ * semantics of setting as if the variable was declared {@code volatile}.
+ *
+ * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T newValue)void}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code setVolatile}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.SET_VOLATILE)} on this
+ * VarHandle.
+ *
+ * @apiNote
+ * Ignoring the many semantic differences from C and C++, this method has
+ * memory ordering effects compatible with {@code memory_order_seq_cst}.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT1 ct1, ..., CTn ctn, T newValue)}
+ * , statically represented using varargs.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type does not
+ * match the caller's symbolic type descriptor.
+ * @throws ClassCastException if the access mode type matches the caller's
+ * symbolic type descriptor, but a reference cast fails.
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ // Android-removed: unsupported annotation.
+ // @HotSpotIntrinsicCandidate
+ void setVolatile(Object... args);
+
+
+ /**
+ * Returns the value of a variable, accessed in program order, but with no
+ * assurance of memory ordering effects with respect to other threads.
+ *
+ * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn)T}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code getOpaque}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.GET_OPAQUE)} on this
+ * VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT1 ct1, ..., CTn ctn)}
+ * , statically represented using varargs.
+ * @return the signature-polymorphic result that is the value of the
+ * variable
+ * , statically represented using {@code Object}.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type does not
+ * match the caller's symbolic type descriptor.
+ * @throws ClassCastException if the access mode type matches the caller's
+ * symbolic type descriptor, but a reference cast fails.
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ // Android-removed: unsupported annotation.
+ // @HotSpotIntrinsicCandidate
+ Object getOpaque(Object... args);
+
+ /**
+ * Sets the value of a variable to the {@code newValue}, in program order,
+ * but with no assurance of memory ordering effects with respect to other
+ * threads.
+ *
+ * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T newValue)void}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code setOpaque}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.SET_OPAQUE)} on this
+ * VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT1 ct1, ..., CTn ctn, T newValue)}
+ * , statically represented using varargs.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type does not
+ * match the caller's symbolic type descriptor.
+ * @throws ClassCastException if the access mode type matches the caller's
+ * symbolic type descriptor, but a reference cast fails.
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ // Android-removed: unsupported annotation.
+ // @HotSpotIntrinsicCandidate
+ void setOpaque(Object... args);
+
+
+ // Lazy accessors
+
+ /**
+ * Returns the value of a variable, and ensures that subsequent loads and
+ * stores are not reordered before this access.
+ *
+ * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn)T}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code getAcquire}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.GET_ACQUIRE)} on this
+ * VarHandle.
+ *
+ * @apiNote
+ * Ignoring the many semantic differences from C and C++, this method has
+ * memory ordering effects compatible with {@code memory_order_acquire}
+ * ordering.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT1 ct1, ..., CTn ctn)}
+ * , statically represented using varargs.
+ * @return the signature-polymorphic result that is the value of the
+ * variable
+ * , statically represented using {@code Object}.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type does not
+ * match the caller's symbolic type descriptor.
+ * @throws ClassCastException if the access mode type matches the caller's
+ * symbolic type descriptor, but a reference cast fails.
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ // Android-removed: unsupported annotation.
+ // @HotSpotIntrinsicCandidate
+ Object getAcquire(Object... args);
+
+ /**
+ * Sets the value of a variable to the {@code newValue}, and ensures that
+ * prior loads and stores are not reordered after this access.
+ *
+ * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T newValue)void}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code setRelease}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.SET_RELEASE)} on this
+ * VarHandle.
+ *
+ * @apiNote
+ * Ignoring the many semantic differences from C and C++, this method has
+ * memory ordering effects compatible with {@code memory_order_release}
+ * ordering.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT1 ct1, ..., CTn ctn, T newValue)}
+ * , statically represented using varargs.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type does not
+ * match the caller's symbolic type descriptor.
+ * @throws ClassCastException if the access mode type matches the caller's
+ * symbolic type descriptor, but a reference cast fails.
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ // Android-removed: unsupported annotation.
+ // @HotSpotIntrinsicCandidate
+ void setRelease(Object... args);
+
+
+ // Compare and set accessors
+
+ /**
+ * Atomically sets the value of a variable to the {@code newValue} with the
+ * memory semantics of {@link #setVolatile} if the variable's current value,
+ * referred to as the <em>witness value</em>, {@code ==} the
+ * {@code expectedValue}, as accessed with the memory semantics of
+ * {@link #getVolatile}.
+ *
+ * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)boolean}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code
+ * compareAndSet} must match the access mode type that is the result of
+ * calling {@code accessModeType(VarHandle.AccessMode.COMPARE_AND_SET)} on
+ * this VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)}
+ * , statically represented using varargs.
+ * @return {@code true} if successful, otherwise {@code false} if the
+ * witness value was not the same as the {@code expectedValue}.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type does not
+ * match the caller's symbolic type descriptor.
+ * @throws ClassCastException if the access mode type matches the caller's
+ * symbolic type descriptor, but a reference cast fails.
+ * @see #setVolatile(Object...)
+ * @see #getVolatile(Object...)
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ // Android-removed: unsupported annotation.
+ // @HotSpotIntrinsicCandidate
+ boolean compareAndSet(Object... args);
+
+ /**
+ * Atomically sets the value of a variable to the {@code newValue} with the
+ * memory semantics of {@link #setVolatile} if the variable's current value,
+ * referred to as the <em>witness value</em>, {@code ==} the
+ * {@code expectedValue}, as accessed with the memory semantics of
+ * {@link #getVolatile}.
+ *
+ * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)T}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code
+ * compareAndExchange}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.COMPARE_AND_EXCHANGE)}
+ * on this VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)}
+ * , statically represented using varargs.
+ * @return the signature-polymorphic result that is the witness value, which
+ * will be the same as the {@code expectedValue} if successful
+ * , statically represented using {@code Object}.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type is not
+ * compatible with the caller's symbolic type descriptor.
+ * @throws ClassCastException if the access mode type is compatible with the
+ * caller's symbolic type descriptor, but a reference cast fails.
+ * @see #setVolatile(Object...)
+ * @see #getVolatile(Object...)
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ // Android-removed: unsupported annotation.
+ // @HotSpotIntrinsicCandidate
+ Object compareAndExchange(Object... args);
+
+ /**
+ * Atomically sets the value of a variable to the {@code newValue} with the
+ * memory semantics of {@link #set} if the variable's current value,
+ * referred to as the <em>witness value</em>, {@code ==} the
+ * {@code expectedValue}, as accessed with the memory semantics of
+ * {@link #getAcquire}.
+ *
+ * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)T}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code
+ * compareAndExchangeAcquire}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE)} on
+ * this VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)}
+ * , statically represented using varargs.
+ * @return the signature-polymorphic result that is the witness value, which
+ * will be the same as the {@code expectedValue} if successful
+ * , statically represented using {@code Object}.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type does not
+ * match the caller's symbolic type descriptor.
+ * @throws ClassCastException if the access mode type matches the caller's
+ * symbolic type descriptor, but a reference cast fails.
+ * @see #set(Object...)
+ * @see #getAcquire(Object...)
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ // Android-removed: unsupported annotation.
+ // @HotSpotIntrinsicCandidate
+ Object compareAndExchangeAcquire(Object... args);
+
+ /**
+ * Atomically sets the value of a variable to the {@code newValue} with the
+ * memory semantics of {@link #setRelease} if the variable's current value,
+ * referred to as the <em>witness value</em>, {@code ==} the
+ * {@code expectedValue}, as accessed with the memory semantics of
+ * {@link #get}.
+ *
+ * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)T}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code
+ * compareAndExchangeRelease}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE)}
+ * on this VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)}
+ * , statically represented using varargs.
+ * @return the signature-polymorphic result that is the witness value, which
+ * will be the same as the {@code expectedValue} if successful
+ * , statically represented using {@code Object}.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type does not
+ * match the caller's symbolic type descriptor.
+ * @throws ClassCastException if the access mode type matches the caller's
+ * symbolic type descriptor, but a reference cast fails.
+ * @see #setRelease(Object...)
+ * @see #get(Object...)
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ // Android-removed: unsupported annotation.
+ // @HotSpotIntrinsicCandidate
+ Object compareAndExchangeRelease(Object... args);
+
+ // Weak (spurious failures allowed)
+
+ /**
+ * Possibly atomically sets the value of a variable to the {@code newValue}
+ * with the semantics of {@link #set} if the variable's current value,
+ * referred to as the <em>witness value</em>, {@code ==} the
+ * {@code expectedValue}, as accessed with the memory semantics of
+ * {@link #get}.
+ *
+ * <p>This operation may fail spuriously (typically, due to memory
+ * contention) even if the witness value does match the expected value.
+ *
+ * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)boolean}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code
+ * weakCompareAndSetPlain} must match the access mode type that is the result of
+ * calling {@code accessModeType(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_PLAIN)}
+ * on this VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)}
+ * , statically represented using varargs.
+ * @return {@code true} if successful, otherwise {@code false} if the
+ * witness value was not the same as the {@code expectedValue} or if this
+ * operation spuriously failed.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type does not
+ * match the caller's symbolic type descriptor.
+ * @throws ClassCastException if the access mode type matches the caller's
+ * symbolic type descriptor, but a reference cast fails.
+ * @see #set(Object...)
+ * @see #get(Object...)
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ // Android-removed: unsupported annotation.
+ // @HotSpotIntrinsicCandidate
+ boolean weakCompareAndSetPlain(Object... args);
+
+ /**
+ * Possibly atomically sets the value of a variable to the {@code newValue}
+ * with the memory semantics of {@link #setVolatile} if the variable's
+ * current value, referred to as the <em>witness value</em>, {@code ==} the
+ * {@code expectedValue}, as accessed with the memory semantics of
+ * {@link #getVolatile}.
+ *
+ * <p>This operation may fail spuriously (typically, due to memory
+ * contention) even if the witness value does match the expected value.
+ *
+ * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)boolean}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code
+ * weakCompareAndSet} must match the access mode type that is the
+ * result of calling {@code accessModeType(VarHandle.AccessMode.WEAK_COMPARE_AND_SET)}
+ * on this VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)}
+ * , statically represented using varargs.
+ * @return {@code true} if successful, otherwise {@code false} if the
+ * witness value was not the same as the {@code expectedValue} or if this
+ * operation spuriously failed.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type does not
+ * match the caller's symbolic type descriptor.
+ * @throws ClassCastException if the access mode type matches the caller's
+ * symbolic type descriptor, but a reference cast fails.
+ * @see #setVolatile(Object...)
+ * @see #getVolatile(Object...)
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ // Android-removed: unsupported annotation.
+ // @HotSpotIntrinsicCandidate
+ boolean weakCompareAndSet(Object... args);
+
+ /**
+ * Possibly atomically sets the value of a variable to the {@code newValue}
+ * with the semantics of {@link #set} if the variable's current value,
+ * referred to as the <em>witness value</em>, {@code ==} the
+ * {@code expectedValue}, as accessed with the memory semantics of
+ * {@link #getAcquire}.
+ *
+ * <p>This operation may fail spuriously (typically, due to memory
+ * contention) even if the witness value does match the expected value.
+ *
+ * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)boolean}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code
+ * weakCompareAndSetAcquire}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE)}
+ * on this VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)}
+ * , statically represented using varargs.
+ * @return {@code true} if successful, otherwise {@code false} if the
+ * witness value was not the same as the {@code expectedValue} or if this
+ * operation spuriously failed.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type does not
+ * match the caller's symbolic type descriptor.
+ * @throws ClassCastException if the access mode type matches the caller's
+ * symbolic type descriptor, but a reference cast fails.
+ * @see #set(Object...)
+ * @see #getAcquire(Object...)
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ // Android-removed: unsupported annotation.
+ // @HotSpotIntrinsicCandidate
+ boolean weakCompareAndSetAcquire(Object... args);
+
+ /**
+ * Possibly atomically sets the value of a variable to the {@code newValue}
+ * with the semantics of {@link #setRelease} if the variable's current
+ * value, referred to as the <em>witness value</em>, {@code ==} the
+ * {@code expectedValue}, as accessed with the memory semantics of
+ * {@link #get}.
+ *
+ * <p>This operation may fail spuriously (typically, due to memory
+ * contention) even if the witness value does match the expected value.
+ *
+ * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)boolean}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code
+ * weakCompareAndSetRelease}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE)}
+ * on this VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT1 ct1, ..., CTn ctn, T expectedValue, T newValue)}
+ * , statically represented using varargs.
+ * @return {@code true} if successful, otherwise {@code false} if the
+ * witness value was not the same as the {@code expectedValue} or if this
+ * operation spuriously failed.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type does not
+ * match the caller's symbolic type descriptor.
+ * @throws ClassCastException if the access mode type matches the caller's
+ * symbolic type descriptor, but a reference cast fails.
+ * @see #setRelease(Object...)
+ * @see #get(Object...)
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ // Android-removed: unsupported annotation.
+ // @HotSpotIntrinsicCandidate
+ boolean weakCompareAndSetRelease(Object... args);
+
+ /**
+ * Atomically sets the value of a variable to the {@code newValue} with the
+ * memory semantics of {@link #setVolatile} and returns the variable's
+ * previous value, as accessed with the memory semantics of
+ * {@link #getVolatile}.
+ *
+ * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T newValue)T}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code getAndSet}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.GET_AND_SET)} on this
+ * VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT1 ct1, ..., CTn ctn, T newValue)}
+ * , statically represented using varargs.
+ * @return the signature-polymorphic result that is the previous value of
+ * the variable
+ * , statically represented using {@code Object}.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type does not
+ * match the caller's symbolic type descriptor.
+ * @throws ClassCastException if the access mode type matches the caller's
+ * symbolic type descriptor, but a reference cast fails.
+ * @see #setVolatile(Object...)
+ * @see #getVolatile(Object...)
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ // Android-removed: unsupported annotation.
+ // @HotSpotIntrinsicCandidate
+ Object getAndSet(Object... args);
+
+ /**
+ * Atomically sets the value of a variable to the {@code newValue} with the
+ * memory semantics of {@link #set} and returns the variable's
+ * previous value, as accessed with the memory semantics of
+ * {@link #getAcquire}.
+ *
+ * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T newValue)T}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code getAndSetAcquire}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.GET_AND_SET_ACQUIRE)} on this
+ * VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT1 ct1, ..., CTn ctn, T newValue)}
+ * , statically represented using varargs.
+ * @return the signature-polymorphic result that is the previous value of
+ * the variable
+ * , statically represented using {@code Object}.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type does not
+ * match the caller's symbolic type descriptor.
+ * @throws ClassCastException if the access mode type matches the caller's
+ * symbolic type descriptor, but a reference cast fails.
+ * @see #setVolatile(Object...)
+ * @see #getVolatile(Object...)
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ // Android-removed: unsupported annotation.
+ // @HotSpotIntrinsicCandidate
+ Object getAndSetAcquire(Object... args);
+
+ /**
+ * Atomically sets the value of a variable to the {@code newValue} with the
+ * memory semantics of {@link #setRelease} and returns the variable's
+ * previous value, as accessed with the memory semantics of
+ * {@link #get}.
+ *
+ * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T newValue)T}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code getAndSetRelease}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.GET_AND_SET_RELEASE)} on this
+ * VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT1 ct1, ..., CTn ctn, T newValue)}
+ * , statically represented using varargs.
+ * @return the signature-polymorphic result that is the previous value of
+ * the variable
+ * , statically represented using {@code Object}.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type does not
+ * match the caller's symbolic type descriptor.
+ * @throws ClassCastException if the access mode type matches the caller's
+ * symbolic type descriptor, but a reference cast fails.
+ * @see #setVolatile(Object...)
+ * @see #getVolatile(Object...)
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ // Android-removed: unsupported annotation.
+ // @HotSpotIntrinsicCandidate
+ Object getAndSetRelease(Object... args);
+
+ // Primitive adders
+ // Throw UnsupportedOperationException for refs
+
+ /**
+ * Atomically adds the {@code value} to the current value of a variable with
+ * the memory semantics of {@link #setVolatile}, and returns the variable's
+ * previous value, as accessed with the memory semantics of
+ * {@link #getVolatile}.
+ *
+ * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T value)T}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code getAndAdd}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.GET_AND_ADD)} on this
+ * VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT1 ct1, ..., CTn ctn, T value)}
+ * , statically represented using varargs.
+ * @return the signature-polymorphic result that is the previous value of
+ * the variable
+ * , statically represented using {@code Object}.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type does not
+ * match the caller's symbolic type descriptor.
+ * @throws ClassCastException if the access mode type matches the caller's
+ * symbolic type descriptor, but a reference cast fails.
+ * @see #setVolatile(Object...)
+ * @see #getVolatile(Object...)
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ // Android-removed: unsupported annotation.
+ // @HotSpotIntrinsicCandidate
+ Object getAndAdd(Object... args);
+
+ /**
+ * Atomically adds the {@code value} to the current value of a variable with
+ * the memory semantics of {@link #set}, and returns the variable's
+ * previous value, as accessed with the memory semantics of
+ * {@link #getAcquire}.
+ *
+ * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T value)T}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code getAndAddAcquire}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.GET_AND_ADD_ACQUIRE)} on this
+ * VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT1 ct1, ..., CTn ctn, T value)}
+ * , statically represented using varargs.
+ * @return the signature-polymorphic result that is the previous value of
+ * the variable
+ * , statically represented using {@code Object}.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type does not
+ * match the caller's symbolic type descriptor.
+ * @throws ClassCastException if the access mode type matches the caller's
+ * symbolic type descriptor, but a reference cast fails.
+ * @see #setVolatile(Object...)
+ * @see #getVolatile(Object...)
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ // Android-removed: unsupported annotation.
+ // @HotSpotIntrinsicCandidate
+ Object getAndAddAcquire(Object... args);
+
+ /**
+ * Atomically adds the {@code value} to the current value of a variable with
+ * the memory semantics of {@link #setRelease}, and returns the variable's
+ * previous value, as accessed with the memory semantics of
+ * {@link #get}.
+ *
+ * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T value)T}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code getAndAddRelease}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.GET_AND_ADD_RELEASE)} on this
+ * VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT1 ct1, ..., CTn ctn, T value)}
+ * , statically represented using varargs.
+ * @return the signature-polymorphic result that is the previous value of
+ * the variable
+ * , statically represented using {@code Object}.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type does not
+ * match the caller's symbolic type descriptor.
+ * @throws ClassCastException if the access mode type matches the caller's
+ * symbolic type descriptor, but a reference cast fails.
+ * @see #setVolatile(Object...)
+ * @see #getVolatile(Object...)
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ // Android-removed: unsupported annotation.
+ // @HotSpotIntrinsicCandidate
+ Object getAndAddRelease(Object... args);
+
+
+ // Bitwise operations
+ // Throw UnsupportedOperationException for refs
+
+ /**
+ * Atomically sets the value of a variable to the result of
+ * bitwise OR between the variable's current value and the {@code mask}
+ * with the memory semantics of {@link #setVolatile} and returns the
+ * variable's previous value, as accessed with the memory semantics of
+ * {@link #getVolatile}.
+ *
+ * <p>If the variable type is the non-integral {@code boolean} type then a
+ * logical OR is performed instead of a bitwise OR.
+ *
+ * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T mask)T}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code getAndBitwiseOr}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.GET_AND_BITWISE_OR)} on this
+ * VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT1 ct1, ..., CTn ctn, T mask)}
+ * , statically represented using varargs.
+ * @return the signature-polymorphic result that is the previous value of
+ * the variable
+ * , statically represented using {@code Object}.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type does not
+ * match the caller's symbolic type descriptor.
+ * @throws ClassCastException if the access mode type matches the caller's
+ * symbolic type descriptor, but a reference cast fails.
+ * @see #setVolatile(Object...)
+ * @see #getVolatile(Object...)
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ // Android-removed: unsupported annotation.
+ // @HotSpotIntrinsicCandidate
+ Object getAndBitwiseOr(Object... args);
+
+ /**
+ * Atomically sets the value of a variable to the result of
+ * bitwise OR between the variable's current value and the {@code mask}
+ * with the memory semantics of {@link #set} and returns the
+ * variable's previous value, as accessed with the memory semantics of
+ * {@link #getAcquire}.
+ *
+ * <p>If the variable type is the non-integral {@code boolean} type then a
+ * logical OR is performed instead of a bitwise OR.
+ *
+ * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T mask)T}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code getAndBitwiseOrAcquire}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.GET_AND_BITWISE_OR_ACQUIRE)} on this
+ * VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT1 ct1, ..., CTn ctn, T mask)}
+ * , statically represented using varargs.
+ * @return the signature-polymorphic result that is the previous value of
+ * the variable
+ * , statically represented using {@code Object}.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type does not
+ * match the caller's symbolic type descriptor.
+ * @throws ClassCastException if the access mode type matches the caller's
+ * symbolic type descriptor, but a reference cast fails.
+ * @see #set(Object...)
+ * @see #getAcquire(Object...)
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ // Android-removed: unsupported annotation.
+ // @HotSpotIntrinsicCandidate
+ Object getAndBitwiseOrAcquire(Object... args);
+
+ /**
+ * Atomically sets the value of a variable to the result of
+ * bitwise OR between the variable's current value and the {@code mask}
+ * with the memory semantics of {@link #setRelease} and returns the
+ * variable's previous value, as accessed with the memory semantics of
+ * {@link #get}.
+ *
+ * <p>If the variable type is the non-integral {@code boolean} type then a
+ * logical OR is performed instead of a bitwise OR.
+ *
+ * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T mask)T}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code getAndBitwiseOrRelease}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.GET_AND_BITWISE_OR_RELEASE)} on this
+ * VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT1 ct1, ..., CTn ctn, T mask)}
+ * , statically represented using varargs.
+ * @return the signature-polymorphic result that is the previous value of
+ * the variable
+ * , statically represented using {@code Object}.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type does not
+ * match the caller's symbolic type descriptor.
+ * @throws ClassCastException if the access mode type matches the caller's
+ * symbolic type descriptor, but a reference cast fails.
+ * @see #setRelease(Object...)
+ * @see #get(Object...)
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ // Android-removed: unsupported annotation.
+ // @HotSpotIntrinsicCandidate
+ Object getAndBitwiseOrRelease(Object... args);
+
+ /**
+ * Atomically sets the value of a variable to the result of
+ * bitwise AND between the variable's current value and the {@code mask}
+ * with the memory semantics of {@link #setVolatile} and returns the
+ * variable's previous value, as accessed with the memory semantics of
+ * {@link #getVolatile}.
+ *
+ * <p>If the variable type is the non-integral {@code boolean} type then a
+ * logical AND is performed instead of a bitwise AND.
+ *
+ * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T mask)T}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code getAndBitwiseAnd}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.GET_AND_BITWISE_AND)} on this
+ * VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT1 ct1, ..., CTn ctn, T mask)}
+ * , statically represented using varargs.
+ * @return the signature-polymorphic result that is the previous value of
+ * the variable
+ * , statically represented using {@code Object}.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type does not
+ * match the caller's symbolic type descriptor.
+ * @throws ClassCastException if the access mode type matches the caller's
+ * symbolic type descriptor, but a reference cast fails.
+ * @see #setVolatile(Object...)
+ * @see #getVolatile(Object...)
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ // Android-removed: unsupported annotation.
+ // @HotSpotIntrinsicCandidate
+ Object getAndBitwiseAnd(Object... args);
+
+ /**
+ * Atomically sets the value of a variable to the result of
+ * bitwise AND between the variable's current value and the {@code mask}
+ * with the memory semantics of {@link #set} and returns the
+ * variable's previous value, as accessed with the memory semantics of
+ * {@link #getAcquire}.
+ *
+ * <p>If the variable type is the non-integral {@code boolean} type then a
+ * logical AND is performed instead of a bitwise AND.
+ *
+ * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T mask)T}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code getAndBitwiseAndAcquire}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.GET_AND_BITWISE_AND_ACQUIRE)} on this
+ * VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT1 ct1, ..., CTn ctn, T mask)}
+ * , statically represented using varargs.
+ * @return the signature-polymorphic result that is the previous value of
+ * the variable
+ * , statically represented using {@code Object}.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type does not
+ * match the caller's symbolic type descriptor.
+ * @throws ClassCastException if the access mode type matches the caller's
+ * symbolic type descriptor, but a reference cast fails.
+ * @see #set(Object...)
+ * @see #getAcquire(Object...)
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ // Android-removed: unsupported annotation.
+ // @HotSpotIntrinsicCandidate
+ Object getAndBitwiseAndAcquire(Object... args);
+
+ /**
+ * Atomically sets the value of a variable to the result of
+ * bitwise AND between the variable's current value and the {@code mask}
+ * with the memory semantics of {@link #setRelease} and returns the
+ * variable's previous value, as accessed with the memory semantics of
+ * {@link #get}.
+ *
+ * <p>If the variable type is the non-integral {@code boolean} type then a
+ * logical AND is performed instead of a bitwise AND.
+ *
+ * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T mask)T}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code getAndBitwiseAndRelease}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.GET_AND_BITWISE_AND_RELEASE)} on this
+ * VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT1 ct1, ..., CTn ctn, T mask)}
+ * , statically represented using varargs.
+ * @return the signature-polymorphic result that is the previous value of
+ * the variable
+ * , statically represented using {@code Object}.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type does not
+ * match the caller's symbolic type descriptor.
+ * @throws ClassCastException if the access mode type matches the caller's
+ * symbolic type descriptor, but a reference cast fails.
+ * @see #setRelease(Object...)
+ * @see #get(Object...)
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ // Android-removed: unsupported annotation.
+ // @HotSpotIntrinsicCandidate
+ Object getAndBitwiseAndRelease(Object... args);
+
+ /**
+ * Atomically sets the value of a variable to the result of
+ * bitwise XOR between the variable's current value and the {@code mask}
+ * with the memory semantics of {@link #setVolatile} and returns the
+ * variable's previous value, as accessed with the memory semantics of
+ * {@link #getVolatile}.
+ *
+ * <p>If the variable type is the non-integral {@code boolean} type then a
+ * logical XOR is performed instead of a bitwise XOR.
+ *
+ * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T mask)T}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code getAndBitwiseXor}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.GET_AND_BITWISE_XOR)} on this
+ * VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT1 ct1, ..., CTn ctn, T mask)}
+ * , statically represented using varargs.
+ * @return the signature-polymorphic result that is the previous value of
+ * the variable
+ * , statically represented using {@code Object}.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type does not
+ * match the caller's symbolic type descriptor.
+ * @throws ClassCastException if the access mode type matches the caller's
+ * symbolic type descriptor, but a reference cast fails.
+ * @see #setVolatile(Object...)
+ * @see #getVolatile(Object...)
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ // Android-removed: unsupported annotation.
+ // @HotSpotIntrinsicCandidate
+ Object getAndBitwiseXor(Object... args);
+
+ /**
+ * Atomically sets the value of a variable to the result of
+ * bitwise XOR between the variable's current value and the {@code mask}
+ * with the memory semantics of {@link #set} and returns the
+ * variable's previous value, as accessed with the memory semantics of
+ * {@link #getAcquire}.
+ *
+ * <p>If the variable type is the non-integral {@code boolean} type then a
+ * logical XOR is performed instead of a bitwise XOR.
+ *
+ * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T mask)T}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code getAndBitwiseXorAcquire}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.GET_AND_BITWISE_XOR_ACQUIRE)} on this
+ * VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT1 ct1, ..., CTn ctn, T mask)}
+ * , statically represented using varargs.
+ * @return the signature-polymorphic result that is the previous value of
+ * the variable
+ * , statically represented using {@code Object}.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type does not
+ * match the caller's symbolic type descriptor.
+ * @throws ClassCastException if the access mode type matches the caller's
+ * symbolic type descriptor, but a reference cast fails.
+ * @see #set(Object...)
+ * @see #getAcquire(Object...)
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ // Android-removed: unsupported annotation.
+ // @HotSpotIntrinsicCandidate
+ Object getAndBitwiseXorAcquire(Object... args);
+
+ /**
+ * Atomically sets the value of a variable to the result of
+ * bitwise XOR between the variable's current value and the {@code mask}
+ * with the memory semantics of {@link #setRelease} and returns the
+ * variable's previous value, as accessed with the memory semantics of
+ * {@link #get}.
+ *
+ * <p>If the variable type is the non-integral {@code boolean} type then a
+ * logical XOR is performed instead of a bitwise XOR.
+ *
+ * <p>The method signature is of the form {@code (CT1 ct1, ..., CTn ctn, T mask)T}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code getAndBitwiseXorRelease}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.GET_AND_BITWISE_XOR_RELEASE)} on this
+ * VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT1 ct1, ..., CTn ctn, T mask)}
+ * , statically represented using varargs.
+ * @return the signature-polymorphic result that is the previous value of
+ * the variable
+ * , statically represented using {@code Object}.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type does not
+ * match the caller's symbolic type descriptor.
+ * @throws ClassCastException if the access mode type matches the caller's
+ * symbolic type descriptor, but a reference cast fails.
+ * @see #setRelease(Object...)
+ * @see #get(Object...)
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ // Android-removed: unsupported annotation.
+ // @HotSpotIntrinsicCandidate
+ Object getAndBitwiseXorRelease(Object... args);
+
+
+ // Android-changed: remove unused return type in AccessType constructor.
+ enum AccessType {
+ GET,
+ SET,
+ COMPARE_AND_SWAP,
+ COMPARE_AND_EXCHANGE,
+ GET_AND_UPDATE,
+ // Android-added: Finer grained access types.
+ // These are used to help categorize the access modes that a VarHandle supports.
+ GET_AND_UPDATE_BITWISE,
+ GET_AND_UPDATE_NUMERIC;
+
+ MethodType accessModeType(Class<?> receiver, Class<?> value,
+ Class<?>... intermediate) {
+ Class<?>[] ps;
+ int i;
+ switch (this) {
+ case GET:
+ ps = allocateParameters(0, receiver, intermediate);
+ fillParameters(ps, receiver, intermediate);
+ return MethodType.methodType(value, ps);
+ case SET:
+ ps = allocateParameters(1, receiver, intermediate);
+ i = fillParameters(ps, receiver, intermediate);
+ ps[i] = value;
+ return MethodType.methodType(void.class, ps);
+ case COMPARE_AND_SWAP:
+ ps = allocateParameters(2, receiver, intermediate);
+ i = fillParameters(ps, receiver, intermediate);
+ ps[i++] = value;
+ ps[i] = value;
+ return MethodType.methodType(boolean.class, ps);
+ case COMPARE_AND_EXCHANGE:
+ ps = allocateParameters(2, receiver, intermediate);
+ i = fillParameters(ps, receiver, intermediate);
+ ps[i++] = value;
+ ps[i] = value;
+ return MethodType.methodType(value, ps);
+ case GET_AND_UPDATE:
+ case GET_AND_UPDATE_BITWISE:
+ case GET_AND_UPDATE_NUMERIC:
+ ps = allocateParameters(1, receiver, intermediate);
+ i = fillParameters(ps, receiver, intermediate);
+ ps[i] = value;
+ return MethodType.methodType(value, ps);
+ default:
+ throw new InternalError("Unknown AccessType");
+ }
+ }
+
+ private static Class<?>[] allocateParameters(int values,
+ Class<?> receiver, Class<?>... intermediate) {
+ int size = ((receiver != null) ? 1 : 0) + intermediate.length + values;
+ return new Class<?>[size];
+ }
+
+ private static int fillParameters(Class<?>[] ps,
+ Class<?> receiver, Class<?>... intermediate) {
+ int i = 0;
+ if (receiver != null)
+ ps[i++] = receiver;
+ for (int j = 0; j < intermediate.length; j++)
+ ps[i++] = intermediate[j];
+ return i;
+ }
+ }
+
+ /**
+ * The set of access modes that specify how a variable, referenced by a
+ * VarHandle, is accessed.
+ */
+ public enum AccessMode {
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#get VarHandle.get}
+ */
+ GET("get", AccessType.GET),
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#set VarHandle.set}
+ */
+ SET("set", AccessType.SET),
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#getVolatile VarHandle.getVolatile}
+ */
+ GET_VOLATILE("getVolatile", AccessType.GET),
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#setVolatile VarHandle.setVolatile}
+ */
+ SET_VOLATILE("setVolatile", AccessType.SET),
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#getAcquire VarHandle.getAcquire}
+ */
+ GET_ACQUIRE("getAcquire", AccessType.GET),
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#setRelease VarHandle.setRelease}
+ */
+ SET_RELEASE("setRelease", AccessType.SET),
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#getOpaque VarHandle.getOpaque}
+ */
+ GET_OPAQUE("getOpaque", AccessType.GET),
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#setOpaque VarHandle.setOpaque}
+ */
+ SET_OPAQUE("setOpaque", AccessType.SET),
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#compareAndSet VarHandle.compareAndSet}
+ */
+ COMPARE_AND_SET("compareAndSet", AccessType.COMPARE_AND_SWAP),
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#compareAndExchange VarHandle.compareAndExchange}
+ */
+ COMPARE_AND_EXCHANGE("compareAndExchange", AccessType.COMPARE_AND_EXCHANGE),
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#compareAndExchangeAcquire VarHandle.compareAndExchangeAcquire}
+ */
+ COMPARE_AND_EXCHANGE_ACQUIRE("compareAndExchangeAcquire", AccessType.COMPARE_AND_EXCHANGE),
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#compareAndExchangeRelease VarHandle.compareAndExchangeRelease}
+ */
+ COMPARE_AND_EXCHANGE_RELEASE("compareAndExchangeRelease", AccessType.COMPARE_AND_EXCHANGE),
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#weakCompareAndSetPlain VarHandle.weakCompareAndSetPlain}
+ */
+ WEAK_COMPARE_AND_SET_PLAIN("weakCompareAndSetPlain", AccessType.COMPARE_AND_SWAP),
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#weakCompareAndSet VarHandle.weakCompareAndSet}
+ */
+ WEAK_COMPARE_AND_SET("weakCompareAndSet", AccessType.COMPARE_AND_SWAP),
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#weakCompareAndSetAcquire VarHandle.weakCompareAndSetAcquire}
+ */
+ WEAK_COMPARE_AND_SET_ACQUIRE("weakCompareAndSetAcquire", AccessType.COMPARE_AND_SWAP),
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#weakCompareAndSetRelease VarHandle.weakCompareAndSetRelease}
+ */
+ WEAK_COMPARE_AND_SET_RELEASE("weakCompareAndSetRelease", AccessType.COMPARE_AND_SWAP),
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#getAndSet VarHandle.getAndSet}
+ */
+ GET_AND_SET("getAndSet", AccessType.GET_AND_UPDATE),
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#getAndSetAcquire VarHandle.getAndSetAcquire}
+ */
+ GET_AND_SET_ACQUIRE("getAndSetAcquire", AccessType.GET_AND_UPDATE),
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#getAndSetRelease VarHandle.getAndSetRelease}
+ */
+ GET_AND_SET_RELEASE("getAndSetRelease", AccessType.GET_AND_UPDATE),
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#getAndAdd VarHandle.getAndAdd}
+ */
+ GET_AND_ADD("getAndAdd", AccessType.GET_AND_UPDATE_NUMERIC),
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#getAndAddAcquire VarHandle.getAndAddAcquire}
+ */
+ GET_AND_ADD_ACQUIRE("getAndAddAcquire", AccessType.GET_AND_UPDATE_NUMERIC),
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#getAndAddRelease VarHandle.getAndAddRelease}
+ */
+ GET_AND_ADD_RELEASE("getAndAddRelease", AccessType.GET_AND_UPDATE_NUMERIC),
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#getAndBitwiseOr VarHandle.getAndBitwiseOr}
+ */
+ GET_AND_BITWISE_OR("getAndBitwiseOr", AccessType.GET_AND_UPDATE_BITWISE),
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#getAndBitwiseOrRelease VarHandle.getAndBitwiseOrRelease}
+ */
+ GET_AND_BITWISE_OR_RELEASE("getAndBitwiseOrRelease", AccessType.GET_AND_UPDATE_BITWISE),
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#getAndBitwiseOrAcquire VarHandle.getAndBitwiseOrAcquire}
+ */
+ GET_AND_BITWISE_OR_ACQUIRE("getAndBitwiseOrAcquire", AccessType.GET_AND_UPDATE_BITWISE),
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#getAndBitwiseAnd VarHandle.getAndBitwiseAnd}
+ */
+ GET_AND_BITWISE_AND("getAndBitwiseAnd", AccessType.GET_AND_UPDATE_BITWISE),
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#getAndBitwiseAndRelease VarHandle.getAndBitwiseAndRelease}
+ */
+ GET_AND_BITWISE_AND_RELEASE("getAndBitwiseAndRelease", AccessType.GET_AND_UPDATE_BITWISE),
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#getAndBitwiseAndAcquire VarHandle.getAndBitwiseAndAcquire}
+ */
+ GET_AND_BITWISE_AND_ACQUIRE("getAndBitwiseAndAcquire", AccessType.GET_AND_UPDATE_BITWISE),
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#getAndBitwiseXor VarHandle.getAndBitwiseXor}
+ */
+ GET_AND_BITWISE_XOR("getAndBitwiseXor", AccessType.GET_AND_UPDATE_BITWISE),
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#getAndBitwiseXorRelease VarHandle.getAndBitwiseXorRelease}
+ */
+ GET_AND_BITWISE_XOR_RELEASE("getAndBitwiseXorRelease", AccessType.GET_AND_UPDATE_BITWISE),
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#getAndBitwiseXorAcquire VarHandle.getAndBitwiseXorAcquire}
+ */
+ GET_AND_BITWISE_XOR_ACQUIRE("getAndBitwiseXorAcquire", AccessType.GET_AND_UPDATE_BITWISE),
+ ;
+
+ static final Map<String, AccessMode> methodNameToAccessMode;
+ static {
+ // Initial capacity of # values is sufficient to avoid resizes
+ // for the smallest table size (32)
+ methodNameToAccessMode = new HashMap<>(AccessMode.values().length);
+ for (AccessMode am : AccessMode.values()) {
+ methodNameToAccessMode.put(am.methodName, am);
+ }
+ }
+
+ final String methodName;
+ final AccessType at;
+
+ AccessMode(final String methodName, AccessType at) {
+ this.methodName = methodName;
+ this.at = at;
+ }
+
+ /**
+ * Returns the {@code VarHandle} signature-polymorphic method name
+ * associated with this {@code AccessMode} value.
+ *
+ * @return the signature-polymorphic method name
+ * @see #valueFromMethodName
+ */
+ public String methodName() {
+ return methodName;
+ }
+
+ /**
+ * Returns the {@code AccessMode} value associated with the specified
+ * {@code VarHandle} signature-polymorphic method name.
+ *
+ * @param methodName the signature-polymorphic method name
+ * @return the {@code AccessMode} value
+ * @throws IllegalArgumentException if there is no {@code AccessMode}
+ * value associated with method name (indicating the method
+ * name does not correspond to a {@code VarHandle}
+ * signature-polymorphic method name).
+ * @see #methodName
+ */
+ public static AccessMode valueFromMethodName(String methodName) {
+ AccessMode am = methodNameToAccessMode.get(methodName);
+ if (am != null) return am;
+ throw new IllegalArgumentException("No AccessMode value for method name " + methodName);
+ }
+
+ // BEGIN Android-removed: MemberName and VarForm are not used in the Android implementation.
+ /*
+ @ForceInline
+ static MemberName getMemberName(int ordinal, VarForm vform) {
+ return vform.memberName_table[ordinal];
+ }
+ */
+ // END Android-removed: MemberName and VarForm are not used in the Android implementation.
+ }
+
+ // BEGIN Android-removed: AccessDescriptor not used in Android implementation.
+ /*
+ static final class AccessDescriptor {
+ final MethodType symbolicMethodTypeErased;
+ final MethodType symbolicMethodTypeInvoker;
+ final Class<?> returnType;
+ final int type;
+ final int mode;
+
+ public AccessDescriptor(MethodType symbolicMethodType, int type, int mode) {
+ this.symbolicMethodTypeErased = symbolicMethodType.erase();
+ this.symbolicMethodTypeInvoker = symbolicMethodType.insertParameterTypes(0, VarHandle.class);
+ this.returnType = symbolicMethodType.returnType();
+ this.type = type;
+ this.mode = mode;
+ }
+ }
+ */
+ // END Android-removed: AccessDescriptor not used in Android implementation.
+
+ /**
+ * Returns the variable type of variables referenced by this VarHandle.
+ *
+ * @return the variable type of variables referenced by this VarHandle
+ */
+ public final Class<?> varType() {
+ // Android-removed: existing implementation.
+ // MethodType typeSet = accessModeType(AccessMode.SET);
+ // return typeSet.parameterType(typeSet.parameterCount() - 1)
+ // Android-added: return instance field.
+ return varType;
+ }
+
+ /**
+ * Returns the coordinate types for this VarHandle.
+ *
+ * @return the coordinate types for this VarHandle. The returned
+ * list is unmodifiable
+ */
+ public final List<Class<?>> coordinateTypes() {
+ // Android-removed: existing implementation.
+ // MethodType typeGet = accessModeType(AccessMode.GET);
+ // return typeGet.parameterList();
+ // Android-added: Android specific implementation.
+ if (coordinateType0 == null) {
+ return Collections.EMPTY_LIST;
+ } else if (coordinateType1 == null) {
+ return Collections.singletonList(coordinateType0);
+ } else {
+ return Collections.unmodifiableList(Arrays.asList(coordinateType0, coordinateType1));
+ }
+ }
+
+ /**
+ * Obtains the access mode type for this VarHandle and a given access mode.
+ *
+ * <p>The access mode type's parameter types will consist of a prefix that
+ * is the coordinate types of this VarHandle followed by further
+ * types as defined by the access mode method.
+ * The access mode type's return type is defined by the return type of the
+ * access mode method.
+ *
+ * @param accessMode the access mode, corresponding to the
+ * signature-polymorphic method of the same name
+ * @return the access mode type for the given access mode
+ */
+ public final MethodType accessModeType(AccessMode accessMode) {
+ // BEGIN Android-removed: Relies on internal class that is not part of the
+ // Android implementation.
+ /*
+ TypesAndInvokers tis = getTypesAndInvokers();
+ MethodType mt = tis.methodType_table[accessMode.at.ordinal()];
+ if (mt == null) {
+ mt = tis.methodType_table[accessMode.at.ordinal()] =
+ accessModeTypeUncached(accessMode);
+ }
+ return mt;
+ */
+ // END Android-removed: Relies on internal class that is not part of the
+ // Android implementation.
+ // Android-added: alternative implementation.
+ if (coordinateType1 == null) {
+ // accessModeType() treats the first argument as the
+ // receiver and adapts accordingly if it is null.
+ return accessMode.at.accessModeType(coordinateType0, varType);
+ } else {
+ return accessMode.at.accessModeType(coordinateType0, varType, coordinateType1);
+ }
+ }
+
+ // Android-removed: Not part of the Android implementation.
+ // abstract MethodType accessModeTypeUncached(AccessMode accessMode);
+
+ /**
+ * Returns {@code true} if the given access mode is supported, otherwise
+ * {@code false}.
+ *
+ * <p>The return of a {@code false} value for a given access mode indicates
+ * that an {@code UnsupportedOperationException} is thrown on invocation
+ * of the corresponding access mode method.
+ *
+ * @param accessMode the access mode, corresponding to the
+ * signature-polymorphic method of the same name
+ * @return {@code true} if the given access mode is supported, otherwise
+ * {@code false}.
+ */
+ public final boolean isAccessModeSupported(AccessMode accessMode) {
+ // Android-removed: Refers to unused field vform.
+ // return AccessMode.getMemberName(accessMode.ordinal(), vform) != null;
+ // Android-added: use accessModesBitsMask field.
+ final int testBit = 1 << accessMode.ordinal();
+ return (accessModesBitMask & testBit) == testBit;
+ }
+
+ /**
+ * Obtains a method handle bound to this VarHandle and the given access
+ * mode.
+ *
+ * @apiNote This method, for a VarHandle {@code vh} and access mode
+ * {@code {access-mode}}, returns a method handle that is equivalent to
+ * method handle {@code bmh} in the following code (though it may be more
+ * efficient):
+ * <pre>{@code
+ * MethodHandle mh = MethodHandles.varHandleExactInvoker(
+ * vh.accessModeType(VarHandle.AccessMode.{access-mode}));
+ *
+ * MethodHandle bmh = mh.bindTo(vh);
+ * }</pre>
+ *
+ * @param accessMode the access mode, corresponding to the
+ * signature-polymorphic method of the same name
+ * @return a method handle bound to this VarHandle and the given access mode
+ */
+ public final MethodHandle toMethodHandle(AccessMode accessMode) {
+ // BEGIN Android-removed: no vform field in Android implementation.
+ /*
+ MemberName mn = AccessMode.getMemberName(accessMode.ordinal(), vform);
+ if (mn != null) {
+ MethodHandle mh = getMethodHandle(accessMode.ordinal());
+ return mh.bindTo(this);
+ }
+ else {
+ // Ensure an UnsupportedOperationException is thrown
+ return MethodHandles.varHandleInvoker(accessMode, accessModeType(accessMode)).
+ bindTo(this);
+ }
+ */
+ // END Android-removed: no vform field in Android implementation.
+
+ // Android-added: basic implementation following description in javadoc for this method.
+ MethodType type = accessModeType(accessMode);
+ return MethodHandles.varHandleExactInvoker(accessMode, type).bindTo(this);
+ }
+
+ // BEGIN Android-removed: Not used in Android implementation.
+ /*
+ @Stable
+ TypesAndInvokers typesAndInvokers;
+
+ static class TypesAndInvokers {
+ final @Stable
+ MethodType[] methodType_table =
+ new MethodType[VarHandle.AccessType.values().length];
+
+ final @Stable
+ MethodHandle[] methodHandle_table =
+ new MethodHandle[AccessMode.values().length];
+ }
+
+ @ForceInline
+ private final TypesAndInvokers getTypesAndInvokers() {
+ TypesAndInvokers tis = typesAndInvokers;
+ if (tis == null) {
+ tis = typesAndInvokers = new TypesAndInvokers();
+ }
+ return tis;
+ }
+
+ @ForceInline
+ final MethodHandle getMethodHandle(int mode) {
+ TypesAndInvokers tis = getTypesAndInvokers();
+ MethodHandle mh = tis.methodHandle_table[mode];
+ if (mh == null) {
+ mh = tis.methodHandle_table[mode] = getMethodHandleUncached(mode);
+ }
+ return mh;
+ }
+ private final MethodHandle getMethodHandleUncached(int mode) {
+ MethodType mt = accessModeType(AccessMode.values()[mode]).
+ insertParameterTypes(0, VarHandle.class);
+ MemberName mn = vform.getMemberName(mode);
+ DirectMethodHandle dmh = DirectMethodHandle.make(mn);
+ // Such a method handle must not be publically exposed directly
+ // otherwise it can be cracked, it must be transformed or rebound
+ // before exposure
+ MethodHandle mh = dmh.copyWith(mt, dmh.form);
+ assert mh.type().erase() == mn.getMethodType().erase();
+ return mh;
+ }
+ */
+ // END Android-removed: Not used in Android implementation.
+
+ // BEGIN Android-removed: No VarForm in Android implementation.
+ /*non-public*/
+ /*
+ final void updateVarForm(VarForm newVForm) {
+ if (vform == newVForm) return;
+ UNSAFE.putObject(this, VFORM_OFFSET, newVForm);
+ UNSAFE.fullFence();
+ }
+
+ static final BiFunction<String, List<Integer>, ArrayIndexOutOfBoundsException>
+ AIOOBE_SUPPLIER = Preconditions.outOfBoundsExceptionFormatter(
+ new Function<String, ArrayIndexOutOfBoundsException>() {
+ @Override
+ public ArrayIndexOutOfBoundsException apply(String s) {
+ return new ArrayIndexOutOfBoundsException(s);
+ }
+ });
+
+ private static final long VFORM_OFFSET;
+
+ static {
+ try {
+ VFORM_OFFSET = UNSAFE.objectFieldOffset(VarHandle.class.getDeclaredField("vform"));
+ }
+ catch (ReflectiveOperationException e) {
+ throw newInternalError(e);
+ }
+
+ // The VarHandleGuards must be initialized to ensure correct
+ // compilation of the guard methods
+ UNSAFE.ensureClassInitialized(VarHandleGuards.class);
+ }
+ */
+ // END Android-removed: No VarForm in Android implementation.
+
+ // Fence methods
+
+ /**
+ * Ensures that loads and stores before the fence will not be reordered
+ * with
+ * loads and stores after the fence.
+ *
+ * @apiNote Ignoring the many semantic differences from C and C++, this
+ * method has memory ordering effects compatible with
+ * {@code atomic_thread_fence(memory_order_seq_cst)}
+ */
+ // Android-removed: @ForceInline is an unsupported attribute.
+ // @ForceInline
+ public static void fullFence() {
+ UNSAFE.fullFence();
+ }
+
+ /**
+ * Ensures that loads before the fence will not be reordered with loads and
+ * stores after the fence.
+ *
+ * @apiNote Ignoring the many semantic differences from C and C++, this
+ * method has memory ordering effects compatible with
+ * {@code atomic_thread_fence(memory_order_acquire)}
+ */
+ // Android-removed: @ForceInline is an unsupported attribute.
+ // @ForceInline
+ public static void acquireFence() {
+ UNSAFE.loadFence();
+ }
+
+ /**
+ * Ensures that loads and stores before the fence will not be
+ * reordered with stores after the fence.
+ *
+ * @apiNote Ignoring the many semantic differences from C and C++, this
+ * method has memory ordering effects compatible with
+ * {@code atomic_thread_fence(memory_order_release)}
+ */
+ // Android-removed: @ForceInline is an unsupported attribute.
+ // @ForceInline
+ public static void releaseFence() {
+ UNSAFE.storeFence();
+ }
+
+ /**
+ * Ensures that loads before the fence will not be reordered with
+ * loads after the fence.
+ */
+ // Android-removed: @ForceInline is an unsupported attribute.
+ // @ForceInline
+ public static void loadLoadFence() {
+ // Android-changed: Not using UNSAFE.loadLoadFence() as not present on Android.
+ // NB The compiler recognizes all the fences here as intrinsics.
+ UNSAFE.loadFence();
+ }
+
+ /**
+ * Ensures that stores before the fence will not be reordered with
+ * stores after the fence.
+ */
+ // Android-removed: @ForceInline is an unsupported attribute.
+ // @ForceInline
+ public static void storeStoreFence() {
+ // Android-changed: Not using UNSAFE.storeStoreFence() as not present on Android.
+ // NB The compiler recognizes all the fences here as intrinsics.
+ UNSAFE.storeFence();
+ }
+
+ // BEGIN Android-added: package private constructors.
+ /**
+ * Constructor for VarHandle with no coordinates.
+ *
+ * @param varType the variable type of variables to be referenced
+ * @param isFinal whether the target variables are final (non-modifiable)
+ * @hide
+ */
+ VarHandle(Class<?> varType, boolean isFinal) {
+ this.varType = Objects.requireNonNull(varType);
+ this.coordinateType0 = null;
+ this.coordinateType1 = null;
+ this.accessModesBitMask = alignedAccessModesBitMask(varType, isFinal);
+ }
+
+ /**
+ * Constructor for VarHandle with one coordinate.
+ *
+ * @param varType the variable type of variables to be referenced
+ * @param isFinal whether the target variables are final (non-modifiable)
+ * @param coordinateType the coordinate
+ * @hide
+ */
+ VarHandle(Class<?> varType, boolean isFinal, Class<?> coordinateType) {
+ this.varType = Objects.requireNonNull(varType);
+ this.coordinateType0 = Objects.requireNonNull(coordinateType);
+ this.coordinateType1 = null;
+ this.accessModesBitMask = alignedAccessModesBitMask(varType, isFinal);
+ }
+
+ /**
+ * Constructor for VarHandle with two coordinates.
+ *
+ * @param varType the variable type of variables to be referenced
+ * @param backingArrayType the type of the array accesses will be performed on
+ * @param isFinal whether the target variables are final (non-modifiable)
+ * @param coordinateType0 the first coordinate
+ * @param coordinateType1 the second coordinate
+ * @hide
+ */
+ VarHandle(Class<?> varType, Class<?> backingArrayType, boolean isFinal,
+ Class<?> coordinateType0, Class<?> coordinateType1) {
+ this.varType = Objects.requireNonNull(varType);
+ this.coordinateType0 = Objects.requireNonNull(coordinateType0);
+ this.coordinateType1 = Objects.requireNonNull(coordinateType1);
+ Objects.requireNonNull(backingArrayType);
+ Class<?> backingArrayComponentType = backingArrayType.getComponentType();
+ if (backingArrayComponentType != varType && backingArrayComponentType != byte.class) {
+ throw new InternalError("Unsupported backingArrayType: " + backingArrayType);
+ }
+
+ if (backingArrayType.getComponentType() == varType) {
+ this.accessModesBitMask = alignedAccessModesBitMask(varType, isFinal);
+ } else {
+ this.accessModesBitMask = unalignedAccessModesBitMask(varType);
+ }
+ }
+ // END Android-added: package private constructors.
+
+ // BEGIN Android-added: helper state for VarHandle properties.
+
+ /** BitMask of access modes that do not change the memory referenced by a VarHandle.
+ * An example being a read of a variable with volatile ordering effects. */
+ private final static int READ_ACCESS_MODES_BIT_MASK;
+
+ /** BitMask of access modes that write to the memory referenced by
+ * a VarHandle. This does not include any compare and update
+ * access modes, nor any bitwise or numeric access modes. An
+ * example being a write to variable with release ordering
+ * effects.
+ */
+ private final static int WRITE_ACCESS_MODES_BIT_MASK;
+
+ /** BitMask of access modes that are applicable to types
+ * supporting for atomic updates. This includes access modes that
+ * both read and write a variable such as compare-and-set.
+ */
+ private final static int ATOMIC_UPDATE_ACCESS_MODES_BIT_MASK;
+
+ /** BitMask of access modes that are applicable to types
+ * supporting numeric atomic update operations. */
+ private final static int NUMERIC_ATOMIC_UPDATE_ACCESS_MODES_BIT_MASK;
+
+ /** BitMask of access modes that are applicable to types
+ * supporting bitwise atomic update operations. */
+ private final static int BITWISE_ATOMIC_UPDATE_ACCESS_MODES_BIT_MASK;
+
+ /** BitMask of all access modes. */
+ private final static int ALL_MODES_BIT_MASK;
+
+ static {
+ // Check we're not about to overflow the storage of the
+ // bitmasks here and in the accessModesBitMask field.
+ if (AccessMode.values().length > Integer.SIZE) {
+ throw new InternalError("accessModes overflow");
+ }
+
+ // Access modes bit mask declarations and initialization order
+ // follows the presentation order in JEP193.
+ READ_ACCESS_MODES_BIT_MASK = accessTypesToBitMask(EnumSet.of(AccessType.GET));
+
+ WRITE_ACCESS_MODES_BIT_MASK = accessTypesToBitMask(EnumSet.of(AccessType.SET));
+
+ ATOMIC_UPDATE_ACCESS_MODES_BIT_MASK =
+ accessTypesToBitMask(EnumSet.of(AccessType.COMPARE_AND_EXCHANGE,
+ AccessType.COMPARE_AND_SWAP,
+ AccessType.GET_AND_UPDATE));
+
+ NUMERIC_ATOMIC_UPDATE_ACCESS_MODES_BIT_MASK =
+ accessTypesToBitMask(EnumSet.of(AccessType.GET_AND_UPDATE_NUMERIC));
+
+ BITWISE_ATOMIC_UPDATE_ACCESS_MODES_BIT_MASK =
+ accessTypesToBitMask(EnumSet.of(AccessType.GET_AND_UPDATE_BITWISE));
+
+ ALL_MODES_BIT_MASK = (READ_ACCESS_MODES_BIT_MASK |
+ WRITE_ACCESS_MODES_BIT_MASK |
+ ATOMIC_UPDATE_ACCESS_MODES_BIT_MASK |
+ NUMERIC_ATOMIC_UPDATE_ACCESS_MODES_BIT_MASK |
+ BITWISE_ATOMIC_UPDATE_ACCESS_MODES_BIT_MASK);
+ }
+
+ static int accessTypesToBitMask(final EnumSet<AccessType> accessTypes) {
+ int m = 0;
+ for (AccessMode accessMode : AccessMode.values()) {
+ if (accessTypes.contains(accessMode.at)) {
+ m |= 1 << accessMode.ordinal();
+ }
+ }
+ return m;
+ }
+
+ static int alignedAccessModesBitMask(Class<?> varType, boolean isFinal) {
+ // For aligned accesses, the supported access modes are described in:
+ // @see java.lang.invoke.MethodHandles.Lookup#findVarHandle
+ int bitMask = ALL_MODES_BIT_MASK;
+
+ // If the field is declared final, keep only the read access modes.
+ if (isFinal) {
+ bitMask &= READ_ACCESS_MODES_BIT_MASK;
+ }
+
+ // If the field is anything other than byte, short, char, int,
+ // long, float, double then remove the numeric atomic update
+ // access modes.
+ if (varType != byte.class && varType != short.class && varType != char.class &&
+ varType != int.class && varType != long.class
+ && varType != float.class && varType != double.class) {
+ bitMask &= ~NUMERIC_ATOMIC_UPDATE_ACCESS_MODES_BIT_MASK;
+ }
+
+ // If the field is not integral, remove the bitwise atomic update access modes.
+ if (varType != boolean.class && varType != byte.class && varType != short.class &&
+ varType != char.class && varType != int.class && varType != long.class) {
+ bitMask &= ~BITWISE_ATOMIC_UPDATE_ACCESS_MODES_BIT_MASK;
+ }
+ return bitMask;
+ }
+
+ static int unalignedAccessModesBitMask(Class<?> varType) {
+ // The VarHandle refers to a view of byte array or a
+ // view of a byte buffer. The corresponding accesses
+ // maybe unaligned so the access modes are more
+ // restrictive than field or array element accesses.
+ //
+ // The supported access modes are described in:
+ // @see java.lang.invoke.MethodHandles#byteArrayViewVarHandle
+
+ // Read/write access modes supported for all types including
+ // long and double on 32-bit platforms (though these accesses
+ // may not be atomic).
+ int bitMask = READ_ACCESS_MODES_BIT_MASK | WRITE_ACCESS_MODES_BIT_MASK;
+
+ // int, long, float, double support atomic update modes per documentation.
+ if (varType == int.class || varType == long.class ||
+ varType == float.class || varType == double.class) {
+ bitMask |= ATOMIC_UPDATE_ACCESS_MODES_BIT_MASK;
+ }
+
+ // int and long support numeric updates per documentation.
+ if (varType == int.class || varType == long.class) {
+ bitMask |= NUMERIC_ATOMIC_UPDATE_ACCESS_MODES_BIT_MASK;
+ }
+
+ // int and long support bitwise updates per documentation.
+ if (varType == int.class || varType == long.class) {
+ bitMask |= BITWISE_ATOMIC_UPDATE_ACCESS_MODES_BIT_MASK;
+ }
+ return bitMask;
+ }
+ // END Android-added: helper state for VarHandle properties.
+}
diff --git a/java/lang/invoke/VolatileCallSite.java b/java/lang/invoke/VolatileCallSite.java
new file mode 100644
index 0000000..47d2689
--- /dev/null
+++ b/java/lang/invoke/VolatileCallSite.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2010, 2011, 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;
+
+// Android-changed: Removed references to MutableCallSite.syncAll().
+/**
+ * A {@code VolatileCallSite} is a {@link CallSite} whose target acts like a volatile variable.
+ * An {@code invokedynamic} instruction linked to a {@code VolatileCallSite} sees updates
+ * to its call site target immediately, even if the update occurs in another thread.
+ * There may be a performance penalty for such tight coupling between threads.
+ * <p>
+ * In other respects, a {@code VolatileCallSite} is interchangeable
+ * with {@code MutableCallSite}.
+ * @see MutableCallSite
+ * @author John Rose, JSR 292 EG
+ */
+public class VolatileCallSite extends CallSite {
+ /**
+ * Creates a call site with a volatile binding to its target.
+ * The initial target is set to a method handle
+ * of the given type which will throw an {@code IllegalStateException} if called.
+ * @param type the method type that this call site will have
+ * @throws NullPointerException if the proposed type is null
+ */
+ public VolatileCallSite(MethodType type) {
+ super(type);
+ }
+
+ /**
+ * Creates a call site with a volatile binding to its target.
+ * The target is set to the given value.
+ * @param target the method handle that will be the initial target of the call site
+ * @throws NullPointerException if the proposed target is null
+ */
+ public VolatileCallSite(MethodHandle target) {
+ super(target);
+ }
+
+ /**
+ * Returns the target method of the call site, which behaves
+ * like a {@code volatile} field of the {@code VolatileCallSite}.
+ * <p>
+ * The interactions of {@code getTarget} with memory are the same
+ * as of a read from a {@code volatile} field.
+ * <p>
+ * In particular, the current thread is required to issue a fresh
+ * read of the target from memory, and must not fail to see
+ * a recent update to the target by another thread.
+ *
+ * @return the linkage state of this call site, a method handle which can change over time
+ * @see #setTarget
+ */
+ @Override public final MethodHandle getTarget() {
+ return getTargetVolatile();
+ }
+
+ /**
+ * Updates the target method of this call site, as a volatile variable.
+ * The type of the new target must agree with the type of the old target.
+ * <p>
+ * The interactions with memory are the same as of a write to a volatile field.
+ * In particular, any threads is guaranteed to see the updated target
+ * the next time it calls {@code getTarget}.
+ * @param newTarget the new target
+ * @throws NullPointerException if the proposed new target is null
+ * @throws WrongMethodTypeException if the proposed new target
+ * has a method type that differs from the previous target
+ * @see #getTarget
+ */
+ @Override public void setTarget(MethodHandle newTarget) {
+ checkTargetChange(getTargetVolatile(), newTarget);
+ setTargetVolatile(newTarget);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public final MethodHandle dynamicInvoker() {
+ return makeDynamicInvoker();
+ }
+}
diff --git a/java/lang/invoke/WrongMethodTypeException.java b/java/lang/invoke/WrongMethodTypeException.java
new file mode 100644
index 0000000..d55e3cd
--- /dev/null
+++ b/java/lang/invoke/WrongMethodTypeException.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2008, 2012, 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;
+
+/**
+ * Thrown to indicate that code has attempted to call a method handle
+ * via the wrong method type. As with the bytecode representation of
+ * normal Java method calls, method handle calls are strongly typed
+ * to a specific type descriptor associated with a call site.
+ * <p>
+ * This exception may also be thrown when two method handles are
+ * composed, and the system detects that their types cannot be
+ * matched up correctly. This amounts to an early evaluation
+ * of the type mismatch, at method handle construction time,
+ * instead of when the mismatched method handle is called.
+ *
+ * @author John Rose, JSR 292 EG
+ * @since 1.7
+ */
+public class WrongMethodTypeException extends RuntimeException {
+ private static final long serialVersionUID = 292L;
+
+ /**
+ * Constructs a {@code WrongMethodTypeException} with no detail message.
+ */
+ public WrongMethodTypeException() {
+ super();
+ }
+
+ /**
+ * Constructs a {@code WrongMethodTypeException} with the specified
+ * detail message.
+ *
+ * @param s the detail message.
+ */
+ public WrongMethodTypeException(String s) {
+ super(s);
+ }
+
+ /**
+ * Constructs a {@code WrongMethodTypeException} with the specified
+ * detail message and cause.
+ *
+ * @param s the detail message.
+ * @param cause the cause of the exception, or null.
+ */
+ //FIXME: make this public in MR1
+ /*non-public*/ WrongMethodTypeException(String s, Throwable cause) {
+ super(s, cause);
+ }
+
+ /**
+ * Constructs a {@code WrongMethodTypeException} with the specified
+ * cause.
+ *
+ * @param cause the cause of the exception, or null.
+ */
+ //FIXME: make this public in MR1
+ /*non-public*/ WrongMethodTypeException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/java/lang/package-info.java b/java/lang/package-info.java
new file mode 100644
index 0000000..aa7a79d
--- /dev/null
+++ b/java/lang/package-info.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 1998, 2006, 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.
+ */
+
+/**
+ * Provides classes that are fundamental to the design of the Java
+ * programming language. The most important classes are {@code
+ * Object}, which is the root of the class hierarchy, and {@code
+ * Class}, instances of which represent classes at run time.
+ *
+ * <p>Frequently it is necessary to represent a value of primitive
+ * type as if it were an object. The wrapper classes {@code Boolean},
+ * {@code Character}, {@code Integer}, {@code Long}, {@code Float},
+ * and {@code Double} serve this purpose. An object of type {@code
+ * Double}, for example, contains a field whose type is double,
+ * representing that value in such a way that a reference to it can be
+ * stored in a variable of reference type. These classes also provide
+ * a number of methods for converting among primitive values, as well
+ * as supporting such standard methods as equals and hashCode. The
+ * {@code Void} class is a non-instantiable class that holds a
+ * reference to a {@code Class} object representing the type void.
+ *
+ * <p>The class {@code Math} provides commonly used mathematical
+ * functions such as sine, cosine, and square root. The classes {@code
+ * String}, {@code StringBuffer}, and {@code StringBuilder} similarly
+ * provide commonly used operations on character strings.
+ *
+ * <p>Classes {@code ClassLoader}, {@code Process}, {@code
+ * ProcessBuilder}, {@code Runtime}, {@code SecurityManager}, and
+ * {@code System} provide "system operations" that manage the dynamic
+ * loading of classes, creation of external processes, host
+ * environment inquiries such as the time of day, and enforcement of
+ * security policies.
+ *
+ * <p>Class {@code Throwable} encompasses objects that may be thrown
+ * by the {@code throw} statement. Subclasses of {@code Throwable}
+ * represent errors and exceptions.
+ *
+ * <a name="charenc"></a>
+ * <h3>Character Encodings</h3>
+ *
+ * The specification of the {@link java.nio.charset.Charset
+ * java.nio.charset.Charset} class describes the naming conventions
+ * for character encodings as well as the set of standard encodings
+ * that must be supported by every implementation of the Java
+ * platform.
+ *
+ * @since JDK1.0
+ */
+package java.lang;
diff --git a/java/lang/ref/FinalizerReference.java b/java/lang/ref/FinalizerReference.java
new file mode 100644
index 0000000..037af4a
--- /dev/null
+++ b/java/lang/ref/FinalizerReference.java
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.lang.ref;
+
+import android.compat.annotation.UnsupportedAppUsage;
+import dalvik.annotation.optimization.FastNative;
+
+/**
+ * @hide
+ */
+public final class FinalizerReference<T> extends Reference<T> {
+ // This queue contains those objects eligible for finalization.
+ @UnsupportedAppUsage
+ public static final ReferenceQueue<Object> queue = new ReferenceQueue<Object>();
+
+ // Guards the list (not the queue).
+ private static final Object LIST_LOCK = new Object();
+
+ // This list contains a FinalizerReference for every finalizable object in the heap.
+ // Objects in this list may or may not be eligible for finalization yet.
+ @UnsupportedAppUsage
+ private static FinalizerReference<?> head = null;
+
+ // The links used to construct the list.
+ private FinalizerReference<?> prev;
+ @UnsupportedAppUsage
+ private FinalizerReference<?> next;
+
+ // When the GC wants something finalized, it moves it from the 'referent' field to
+ // the 'zombie' field instead.
+ private T zombie;
+
+ public FinalizerReference(T r, ReferenceQueue<? super T> q) {
+ super(r, q);
+ }
+
+ @Override public T get() {
+ return zombie;
+ }
+
+ @Override public void clear() {
+ zombie = null;
+ }
+
+ @UnsupportedAppUsage
+ public static void add(Object referent) {
+ FinalizerReference<?> reference = new FinalizerReference<Object>(referent, queue);
+ synchronized (LIST_LOCK) {
+ reference.prev = null;
+ reference.next = head;
+ if (head != null) {
+ head.prev = reference;
+ }
+ head = reference;
+ }
+ }
+
+ @UnsupportedAppUsage
+ public static void remove(FinalizerReference<?> reference) {
+ synchronized (LIST_LOCK) {
+ FinalizerReference<?> next = reference.next;
+ FinalizerReference<?> prev = reference.prev;
+ reference.next = null;
+ reference.prev = null;
+ if (prev != null) {
+ prev.next = next;
+ } else {
+ head = next;
+ }
+ if (next != null) {
+ next.prev = prev;
+ }
+ }
+ }
+
+ /**
+ * Waits for all currently-enqueued references to be finalized.
+ */
+ public static void finalizeAllEnqueued(long timeout) throws InterruptedException {
+ // Alloate a new sentinel, this creates a FinalizerReference.
+ Sentinel sentinel;
+ // Keep looping until we safely enqueue our sentinel FinalizerReference.
+ // This is done to prevent races where the GC updates the pendingNext
+ // before we get the chance.
+ do {
+ sentinel = new Sentinel();
+ } while (!enqueueSentinelReference(sentinel));
+ sentinel.awaitFinalization(timeout);
+ }
+
+ private static boolean enqueueSentinelReference(Sentinel sentinel) {
+ synchronized (LIST_LOCK) {
+ // When a finalizable object is allocated, a FinalizerReference is added to the list.
+ // We search the list for that FinalizerReference (it should be at or near the head),
+ // and then put it on the queue so that it can be finalized.
+ for (FinalizerReference<?> r = head; r != null; r = r.next) {
+ // Use getReferent() instead of directly accessing the referent field not to race
+ // with GC reference processing. Can't use get() either because it's overridden to
+ // return the zombie.
+ if (r.getReferent() == sentinel) {
+ FinalizerReference<Sentinel> sentinelReference = (FinalizerReference<Sentinel>) r;
+ sentinelReference.clearReferent();
+ sentinelReference.zombie = sentinel;
+ // Make a single element list, then enqueue the reference on the daemon unenqueued
+ // list. This is required instead of enqueuing directly on the finalizer queue
+ // since there could be recently freed objects in the unqueued list which are not
+ // yet on the finalizer queue. This could cause the sentinel to run before the
+ // objects are finalized. b/17381967
+ // Make circular list if unenqueued goes through native so that we can prevent
+ // races where the GC updates the pendingNext before we do. If it is non null, then
+ // we update the pending next to make a circular list while holding a lock.
+ // b/17462553
+ if (!sentinelReference.makeCircularListIfUnenqueued()) {
+ return false;
+ }
+ ReferenceQueue.add(sentinelReference);
+ return true;
+ }
+ }
+ }
+ // We just created a finalizable object and still hold a reference to it.
+ // It must be on the list.
+ throw new AssertionError("newly-created live Sentinel not on list!");
+ }
+
+ @FastNative
+ private final native T getReferent();
+ @FastNative
+ private native boolean makeCircularListIfUnenqueued();
+
+ /**
+ * A marker object that we can immediately enqueue. When this object's
+ * finalize() method is called, we know all previously-enqueued finalizable
+ * references have been finalized.
+ */
+ private static class Sentinel {
+ boolean finalized = false;
+
+ @Override protected synchronized void finalize() throws Throwable {
+ if (finalized) {
+ throw new AssertionError();
+ }
+ finalized = true;
+ notifyAll();
+ }
+
+ synchronized void awaitFinalization(long timeout) throws InterruptedException {
+ final long startTime = System.nanoTime();
+ final long endTime = startTime + timeout;
+ while (!finalized) {
+ // 0 signifies no timeout.
+ if (timeout != 0) {
+ final long currentTime = System.nanoTime();
+ if (currentTime >= endTime) {
+ break;
+ } else {
+ final long deltaTime = endTime - currentTime;
+ wait(deltaTime / 1000000, (int)(deltaTime % 1000000));
+ }
+ } else {
+ wait();
+ }
+ }
+ }
+ }
+}
diff --git a/java/lang/ref/PhantomReference.java b/java/lang/ref/PhantomReference.java
new file mode 100644
index 0000000..1c1364a
--- /dev/null
+++ b/java/lang/ref/PhantomReference.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 1997, 2003, 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.ref;
+
+
+/**
+ * Phantom reference objects, which are enqueued after the collector
+ * determines that their referents may otherwise be reclaimed. Phantom
+ * references are most often used for scheduling pre-mortem cleanup actions in
+ * a more flexible way than is possible with the Java finalization mechanism.
+ *
+ * <p> If the garbage collector determines at a certain point in time that the
+ * referent of a phantom reference is <a
+ * href="package-summary.html#reachability">phantom reachable</a>, then at that
+ * time or at some later time it will enqueue the reference.
+ *
+ * <p> In order to ensure that a reclaimable object remains so, the referent of
+ * a phantom reference may not be retrieved: The <code>get</code> method of a
+ * phantom reference always returns <code>null</code>.
+ *
+ * <p> Unlike soft and weak references, phantom references are not
+ * automatically cleared by the garbage collector as they are enqueued. An
+ * object that is reachable via phantom references will remain so until all
+ * such references are cleared or themselves become unreachable.
+ *
+ * @author Mark Reinhold
+ * @since 1.2
+ */
+
+public class PhantomReference<T> extends Reference<T> {
+
+ /**
+ * Returns this reference object's referent. Because the referent of a
+ * phantom reference is always inaccessible, this method always returns
+ * <code>null</code>.
+ *
+ * @return <code>null</code>
+ */
+ public T get() {
+ return null;
+ }
+
+ /**
+ * Creates a new phantom reference that refers to the given object and
+ * is registered with the given queue.
+ *
+ * <p> It is possible to create a phantom reference with a <tt>null</tt>
+ * queue, but such a reference is completely useless: Its <tt>get</tt>
+ * method will always return null and, since it does not have a queue, it
+ * will never be enqueued.
+ *
+ * @param referent the object the new phantom reference will refer to
+ * @param q the queue with which the reference is to be registered,
+ * or <tt>null</tt> if registration is not required
+ */
+ public PhantomReference(T referent, ReferenceQueue<? super T> q) {
+ super(referent, q);
+ }
+
+}
diff --git a/java/lang/ref/Reference.java b/java/lang/ref/Reference.java
new file mode 100644
index 0000000..e5126b5
--- /dev/null
+++ b/java/lang/ref/Reference.java
@@ -0,0 +1,316 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1997, 2017, 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.ref;
+
+import dalvik.annotation.optimization.FastNative;
+
+
+/**
+ * Abstract base class for reference objects. This class defines the
+ * operations common to all reference objects. Because reference objects are
+ * implemented in close cooperation with the garbage collector, this class may
+ * not be subclassed directly.
+ *
+ * @author Mark Reinhold
+ * @since 1.2
+ */
+
+public abstract class Reference<T> {
+ // BEGIN Android-changed: Reimplemented to accommodate a different GC and compiler.
+ // ClassLinker knows about the fields of this class.
+
+ /**
+ * Forces JNI path.
+ * If GC is not in progress (ie: not going through slow path), the referent
+ * can be quickly returned through intrinsic without passing through JNI.
+ * This flag forces the JNI path so that it can be tested and benchmarked.
+ */
+ private static boolean disableIntrinsic = false;
+
+ /**
+ * Slow path flag for the reference processor.
+ * Used by the reference processor to determine whether or not the referent
+ * can be immediately returned. Because the referent might get swept during
+ * GC, the slow path, which passes through JNI, must be taken.
+ */
+ private static boolean slowPathEnabled = false;
+
+ // Treated specially by GC. ART's ClassLinker::LinkFields() knows this is the
+ // alphabetically last non-static field.
+ volatile T referent;
+
+ final ReferenceQueue<? super T> queue;
+
+ /*
+ * This field forms a singly-linked list of reference objects that have
+ * been enqueued. The queueNext field is non-null if and only if this
+ * reference has been enqueued. After this reference has been enqueued and
+ * before it has been removed from its queue, the queueNext field points
+ * to the next reference on the queue. The last reference on a queue
+ * points to itself. Once this reference has been removed from the
+ * reference queue, the queueNext field points to the
+ * ReferenceQueue.sQueueNextUnenqueued sentinel reference object for the
+ * rest of this reference's lifetime.
+ * <p>
+ * Access to the queueNext field is guarded by synchronization on a lock
+ * internal to 'queue'.
+ */
+ Reference queueNext;
+
+ /**
+ * The pendingNext field is initially set by the GC. After the GC forms a
+ * complete circularly linked list, the list is handed off to the
+ * ReferenceQueueDaemon using the ReferenceQueue.class lock. The
+ * ReferenceQueueDaemon can then read the pendingNext fields without
+ * additional synchronization.
+ */
+ Reference<?> pendingNext;
+
+ /* -- Referent accessor and setters -- */
+
+ /**
+ * Returns this reference object's referent. If this reference object has
+ * been cleared, either by the program or by the garbage collector, then
+ * this method returns <code>null</code>.
+ *
+ * @return The object to which this reference refers, or
+ * <code>null</code> if this reference object has been cleared
+ */
+ public T get() {
+ return getReferent();
+ }
+
+ @FastNative
+ private final native T getReferent();
+
+ /**
+ * Clears this reference object. Invoking this method will not cause this
+ * object to be enqueued.
+ *
+ * <p> This method is invoked only by Java code; when the garbage collector
+ * clears references it does so directly, without invoking this method.
+ */
+ public void clear() {
+ clearReferent();
+ }
+
+ // Direct access to the referent is prohibited, clearReferent blocks and set
+ // the referent to null when it is safe to do so.
+ @FastNative
+ native void clearReferent();
+
+ /* -- Queue operations -- */
+
+ /**
+ * Tells whether or not this reference object has been enqueued, either by
+ * the program or by the garbage collector. If this reference object was
+ * not registered with a queue when it was created, then this method will
+ * always return <code>false</code>.
+ *
+ * @return <code>true</code> if and only if this reference object has
+ * been enqueued
+ */
+ public boolean isEnqueued() {
+ // Contrary to what the documentation says, this method returns false
+ // after this reference object has been removed from its queue
+ // (b/26647823). ReferenceQueue.isEnqueued preserves this historically
+ // incorrect behavior.
+ return queue != null && queue.isEnqueued(this);
+ }
+
+ /**
+ * Adds this reference object to the queue with which it is registered,
+ * if any.
+ *
+ * <p> This method is invoked only by Java code; when the garbage collector
+ * enqueues references it does so directly, without invoking this method.
+ *
+ * @return <code>true</code> if this reference object was successfully
+ * enqueued; <code>false</code> if it was already enqueued or if
+ * it was not registered with a queue when it was created
+ */
+ public boolean enqueue() {
+ return queue != null && queue.enqueue(this);
+ }
+
+ /* -- Constructors -- */
+
+ Reference(T referent) {
+ this(referent, null);
+ }
+
+ Reference(T referent, ReferenceQueue<? super T> queue) {
+ this.referent = referent;
+ this.queue = queue;
+ }
+ // END Android-changed: Reimplemented to accommodate a different GC and compiler.
+
+ // BEGIN Android-added: reachabilityFence() from upstream OpenJDK9+181.
+ // The actual implementation differs from OpenJDK9.
+ /**
+ * Ensures that the object referenced by the given reference remains
+ * <a href="package-summary.html#reachability"><em>strongly reachable</em></a>,
+ * regardless of any prior actions of the program that might otherwise cause
+ * the object to become unreachable; thus, the referenced object is not
+ * reclaimable by garbage collection at least until after the invocation of
+ * this method. Invocation of this method does not itself initiate garbage
+ * collection or finalization.
+ *
+ * <p> This method establishes an ordering for
+ * <a href="package-summary.html#reachability"><em>strong reachability</em></a>
+ * with respect to garbage collection. It controls relations that are
+ * otherwise only implicit in a program -- the reachability conditions
+ * triggering garbage collection. This method is designed for use in
+ * uncommon situations of premature finalization where using
+ * {@code synchronized} blocks or methods, or using other synchronization
+ * facilities are not possible or do not provide the desired control. This
+ * method is applicable only when reclamation may have visible effects,
+ * which is possible for objects with finalizers (See
+ * <a href="https://docs.oracle.com/javase/specs/jls/se8/html/jls-12.html#jls-12.6">
+ * Section 12.6 17 of <cite>The Java™ Language Specification</cite></a>)
+ * that are implemented in ways that rely on ordering control for correctness.
+ *
+ * @apiNote
+ * Finalization may occur whenever the virtual machine detects that no
+ * reference to an object will ever be stored in the heap: The garbage
+ * collector may reclaim an object even if the fields of that object are
+ * still in use, so long as the object has otherwise become unreachable.
+ * This may have surprising and undesirable effects in cases such as the
+ * following example in which the bookkeeping associated with a class is
+ * managed through array indices. Here, method {@code action} uses a
+ * {@code reachabilityFence} to ensure that the {@code Resource} object is
+ * not reclaimed before bookkeeping on an associated
+ * {@code ExternalResource} has been performed; in particular here, to
+ * ensure that the array slot holding the {@code ExternalResource} is not
+ * nulled out in method {@link Object#finalize}, which may otherwise run
+ * concurrently.
+ *
+ * <pre> {@code
+ * class Resource {
+ * private static ExternalResource[] externalResourceArray = ...
+ *
+ * int myIndex;
+ * Resource(...) {
+ * myIndex = ...
+ * externalResourceArray[myIndex] = ...;
+ * ...
+ * }
+ * protected void finalize() {
+ * externalResourceArray[myIndex] = null;
+ * ...
+ * }
+ * public void action() {
+ * try {
+ * // ...
+ * int i = myIndex;
+ * Resource.update(externalResourceArray[i]);
+ * } finally {
+ * Reference.reachabilityFence(this);
+ * }
+ * }
+ * private static void update(ExternalResource ext) {
+ * ext.status = ...;
+ * }
+ * }}</pre>
+ *
+ * Here, the invocation of {@code reachabilityFence} is nonintuitively
+ * placed <em>after</em> the call to {@code update}, to ensure that the
+ * array slot is not nulled out by {@link Object#finalize} before the
+ * update, even if the call to {@code action} was the last use of this
+ * object. This might be the case if, for example a usage in a user program
+ * had the form {@code new Resource().action();} which retains no other
+ * reference to this {@code Resource}. While probably overkill here,
+ * {@code reachabilityFence} is placed in a {@code finally} block to ensure
+ * that it is invoked across all paths in the method. In a method with more
+ * complex control paths, you might need further precautions to ensure that
+ * {@code reachabilityFence} is encountered along all of them.
+ *
+ * <p> It is sometimes possible to better encapsulate use of
+ * {@code reachabilityFence}. Continuing the above example, if it were
+ * acceptable for the call to method {@code update} to proceed even if the
+ * finalizer had already executed (nulling out slot), then you could
+ * localize use of {@code reachabilityFence}:
+ *
+ * <pre> {@code
+ * public void action2() {
+ * // ...
+ * Resource.update(getExternalResource());
+ * }
+ * private ExternalResource getExternalResource() {
+ * ExternalResource ext = externalResourceArray[myIndex];
+ * Reference.reachabilityFence(this);
+ * return ext;
+ * }}</pre>
+ *
+ * <p> Method {@code reachabilityFence} is not required in constructions
+ * that themselves ensure reachability. For example, because objects that
+ * are locked cannot, in general, be reclaimed, it would suffice if all
+ * accesses of the object, in all methods of class {@code Resource}
+ * (including {@code finalize}) were enclosed in {@code synchronized (this)}
+ * blocks. (Further, such blocks must not include infinite loops, or
+ * themselves be unreachable, which fall into the corner case exceptions to
+ * the "in general" disclaimer.) However, method {@code reachabilityFence}
+ * remains a better option in cases where this approach is not as efficient,
+ * desirable, or possible; for example because it would encounter deadlock.
+ *
+ * @param ref the reference. If {@code null}, this method has no effect.
+ * @since 9
+ */
+ // @DontInline
+ public static void reachabilityFence(Object ref) {
+ // This code is usually replaced by much faster intrinsic implementations.
+ // It will be executed for tests run with the access checks interpreter in
+ // ART, e.g. with --verify-soft-fail. Since this is a volatile store, it
+ // cannot easily be moved up past prior accesses, even if this method is
+ // inlined.
+ SinkHolder.sink = ref;
+ // Leaving SinkHolder set to ref is unpleasant, since it keeps ref live
+ // until the next reachabilityFence call. This causes e.g. 036-finalizer
+ // to fail. Clear it again in a way that's unlikely to be optimizable.
+ // The fact that finalize_count is volatile makes it hard to move the test up.
+ if (SinkHolder.finalize_count == 0) {
+ SinkHolder.sink = null;
+ }
+ }
+
+ private static class SinkHolder {
+ static volatile Object sink;
+
+ // Ensure that sink looks live to even a reasonably clever compiler.
+ private static volatile int finalize_count = 0;
+
+ private static Object sinkUser = new Object() {
+ protected void finalize() {
+ if (sink == null && finalize_count > 0) {
+ throw new AssertionError("Can't get here");
+ }
+ finalize_count++;
+ }
+ };
+ }
+ // END Android-added: reachabilityFence() from upstream OpenJDK9+181.
+}
diff --git a/java/lang/ref/ReferenceQueue.java b/java/lang/ref/ReferenceQueue.java
new file mode 100644
index 0000000..72e55c1
--- /dev/null
+++ b/java/lang/ref/ReferenceQueue.java
@@ -0,0 +1,283 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1997, 2005, 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.ref;
+
+import sun.misc.Cleaner;
+
+/**
+ * Reference queues, to which registered reference objects are appended by the
+ * garbage collector after the appropriate reachability changes are detected.
+ *
+ * @author Mark Reinhold
+ * @since 1.2
+ */
+// BEGIN Android-changed: Reimplemented to accomodate a different GC and compiler.
+
+public class ReferenceQueue<T> {
+
+ // Reference.queueNext will be set to sQueueNextUnenqueued to indicate
+ // when a reference has been enqueued and removed from its queue.
+ private static final Reference sQueueNextUnenqueued = new PhantomReference(null, null);
+
+ // NOTE: This implementation of ReferenceQueue is FIFO (queue-like) whereas
+ // the OpenJdk implementation is LIFO (stack-like).
+ private Reference<? extends T> head = null;
+ private Reference<? extends T> tail = null;
+
+ private final Object lock = new Object();
+
+ /**
+ * Constructs a new reference-object queue.
+ */
+ public ReferenceQueue() { }
+
+ /**
+ * Enqueue the given reference onto this queue.
+ * The caller is responsible for ensuring the lock is held on this queue,
+ * and for calling notifyAll on this queue after the reference has been
+ * enqueued. Returns true if the reference was enqueued successfully,
+ * false if the reference had already been enqueued.
+ * @GuardedBy("lock")
+ */
+ private boolean enqueueLocked(Reference<? extends T> r) {
+ // Verify the reference has not already been enqueued.
+ if (r.queueNext != null) {
+ return false;
+ }
+
+ if (r instanceof Cleaner) {
+ // If this reference is a Cleaner, then simply invoke the clean method instead
+ // of enqueueing it in the queue. Cleaners are associated with dummy queues that
+ // are never polled and objects are never enqueued on them.
+ Cleaner cl = (sun.misc.Cleaner) r;
+ cl.clean();
+
+ // Update queueNext to indicate that the reference has been
+ // enqueued, but is now removed from the queue.
+ r.queueNext = sQueueNextUnenqueued;
+ return true;
+ }
+
+ if (tail == null) {
+ head = r;
+ } else {
+ tail.queueNext = r;
+ }
+ tail = r;
+ tail.queueNext = r;
+ return true;
+ }
+
+ /**
+ * Test if the given reference object has been enqueued but not yet
+ * removed from the queue, assuming this is the reference object's queue.
+ */
+ boolean isEnqueued(Reference<? extends T> reference) {
+ synchronized (lock) {
+ return reference.queueNext != null && reference.queueNext != sQueueNextUnenqueued;
+ }
+ }
+
+ /**
+ * Enqueue the reference object on the receiver.
+ *
+ * @param reference
+ * reference object to be enqueued.
+ * @return true if the reference was enqueued.
+ */
+ boolean enqueue(Reference<? extends T> reference) {
+ synchronized (lock) {
+ if (enqueueLocked(reference)) {
+ lock.notifyAll();
+ return true;
+ }
+ return false;
+ }
+ }
+
+ // @GuardedBy("lock")
+ private Reference<? extends T> reallyPollLocked() {
+ if (head != null) {
+ Reference<? extends T> r = head;
+ if (head == tail) {
+ tail = null;
+ head = null;
+ } else {
+ head = head.queueNext;
+ }
+
+ // Update queueNext to indicate that the reference has been
+ // enqueued, but is now removed from the queue.
+ r.queueNext = sQueueNextUnenqueued;
+ return r;
+ }
+
+ return null;
+ }
+
+ /**
+ * Polls this queue to see if a reference object is available. If one is
+ * available without further delay then it is removed from the queue and
+ * returned. Otherwise this method immediately returns <tt>null</tt>.
+ *
+ * @return A reference object, if one was immediately available,
+ * otherwise <code>null</code>
+ */
+ public Reference<? extends T> poll() {
+ synchronized (lock) {
+ if (head == null)
+ return null;
+
+ return reallyPollLocked();
+ }
+ }
+
+ /**
+ * Removes the next reference object in this queue, blocking until either
+ * one becomes available or the given timeout period expires.
+ *
+ * <p> This method does not offer real-time guarantees: It schedules the
+ * timeout as if by invoking the {@link Object#wait(long)} method.
+ *
+ * @param timeout If positive, block for up to <code>timeout</code>
+ * milliseconds while waiting for a reference to be
+ * added to this queue. If zero, block indefinitely.
+ *
+ * @return A reference object, if one was available within the specified
+ * timeout period, otherwise <code>null</code>
+ *
+ * @throws IllegalArgumentException
+ * If the value of the timeout argument is negative
+ *
+ * @throws InterruptedException
+ * If the timeout wait is interrupted
+ */
+ public Reference<? extends T> remove(long timeout)
+ throws IllegalArgumentException, InterruptedException
+ {
+ if (timeout < 0) {
+ throw new IllegalArgumentException("Negative timeout value");
+ }
+ synchronized (lock) {
+ Reference<? extends T> r = reallyPollLocked();
+ if (r != null) return r;
+ long start = (timeout == 0) ? 0 : System.nanoTime();
+ for (;;) {
+ lock.wait(timeout);
+ r = reallyPollLocked();
+ if (r != null) return r;
+ if (timeout != 0) {
+ long end = System.nanoTime();
+ timeout -= (end - start) / 1000_000;
+ if (timeout <= 0) return null;
+ start = end;
+ }
+ }
+ }
+ }
+
+ /**
+ * Removes the next reference object in this queue, blocking until one
+ * becomes available.
+ *
+ * @return A reference object, blocking until one becomes available
+ * @throws InterruptedException If the wait is interrupted
+ */
+ public Reference<? extends T> remove() throws InterruptedException {
+ return remove(0);
+ }
+
+ /**
+ * Enqueue the given list of currently pending (unenqueued) references.
+ *
+ * @hide
+ */
+ public static void enqueuePending(Reference<?> list) {
+ Reference<?> start = list;
+ do {
+ ReferenceQueue queue = list.queue;
+ if (queue == null) {
+ Reference<?> next = list.pendingNext;
+
+ // Make pendingNext a self-loop to preserve the invariant that
+ // once enqueued, pendingNext is non-null -- without leaking
+ // the object pendingNext was previously pointing to.
+ list.pendingNext = list;
+ list = next;
+ } else {
+ // To improve performance, we try to avoid repeated
+ // synchronization on the same queue by batching enqueue of
+ // consecutive references in the list that have the same
+ // queue.
+ synchronized (queue.lock) {
+ do {
+ Reference<?> next = list.pendingNext;
+
+ // Make pendingNext a self-loop to preserve the
+ // invariant that once enqueued, pendingNext is
+ // non-null -- without leaking the object pendingNext
+ // was previously pointing to.
+ list.pendingNext = list;
+ queue.enqueueLocked(list);
+ list = next;
+ } while (list != start && list.queue == queue);
+ queue.lock.notifyAll();
+ }
+ }
+ } while (list != start);
+ }
+
+ /**
+ * List of references that the GC says need to be enqueued.
+ * Protected by ReferenceQueue.class lock.
+ * @hide
+ */
+ public static Reference<?> unenqueued = null;
+
+ static void add(Reference<?> list) {
+ synchronized (ReferenceQueue.class) {
+ if (unenqueued == null) {
+ unenqueued = list;
+ } else {
+ // Find the last element in unenqueued.
+ Reference<?> last = unenqueued;
+ while (last.pendingNext != unenqueued) {
+ last = last.pendingNext;
+ }
+ // Add our list to the end. Update the pendingNext to point back to enqueued.
+ last.pendingNext = list;
+ last = list;
+ while (last.pendingNext != list) {
+ last = last.pendingNext;
+ }
+ last.pendingNext = unenqueued;
+ }
+ ReferenceQueue.class.notifyAll();
+ }
+ }
+}
+// END Android-changed: Reimplemented to accomodate a different GC and compiler.
diff --git a/java/lang/ref/SoftReference.java b/java/lang/ref/SoftReference.java
new file mode 100644
index 0000000..272d1bd
--- /dev/null
+++ b/java/lang/ref/SoftReference.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 1997, 2003, 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.ref;
+
+// Android-changed: Javadoc change to recommend against using SoftReferences for caches.
+/**
+ * Soft reference objects, which are cleared at the discretion of the garbage
+ * collector in response to memory demand.
+ *
+ * <p> Suppose that the garbage collector determines at a certain point in time
+ * that an object is <a href="package-summary.html#reachability">softly
+ * reachable</a>. At that time it may choose to clear atomically all soft
+ * references to that object and all soft references to any other
+ * softly-reachable objects from which that object is reachable through a chain
+ * of strong references. At the same time or at some later time it will
+ * enqueue those newly-cleared soft references that are registered with
+ * reference queues.
+ *
+ * <p> All soft references to softly-reachable objects are guaranteed to have
+ * been cleared before the virtual machine throws an
+ * <code>OutOfMemoryError</code>. Otherwise no constraints are placed upon the
+ * time at which a soft reference will be cleared or the order in which a set
+ * of such references to different objects will be cleared. Virtual machine
+ * implementations are, however, encouraged to bias against clearing
+ * recently-created or recently-used soft references.
+ *
+ * <h3>Avoid Soft References for Caching</h3>
+ * In practice, soft references are inefficient for caching. The runtime doesn't
+ * have enough information on which references to clear and which to keep. Most
+ * fatally, it doesn't know what to do when given the choice between clearing a
+ * soft reference and growing the heap.
+ *
+ * <p>The lack of information on the value to your application of each reference
+ * limits the usefulness of soft references. References that are cleared too
+ * early cause unnecessary work; those that are cleared too late waste memory.
+ *
+ * <p>Most applications should use an {@code android.util.LruCache} instead of
+ * soft references. LruCache has an effective eviction policy and lets the user
+ * tune how much memory is allotted.
+ *
+ * @author Mark Reinhold
+ * @since 1.2
+ */
+
+public class SoftReference<T> extends Reference<T> {
+
+ /**
+ * Timestamp clock, updated by the garbage collector
+ */
+ static private long clock;
+
+ /**
+ * Timestamp updated by each invocation of the get method. The VM may use
+ * this field when selecting soft references to be cleared, but it is not
+ * required to do so.
+ */
+ private long timestamp;
+
+ /**
+ * Creates a new soft reference that refers to the given object. The new
+ * reference is not registered with any queue.
+ *
+ * @param referent object the new soft reference will refer to
+ */
+ public SoftReference(T referent) {
+ super(referent);
+ this.timestamp = clock;
+ }
+
+ /**
+ * Creates a new soft reference that refers to the given object and is
+ * registered with the given queue.
+ *
+ * @param referent object the new soft reference will refer to
+ * @param q the queue with which the reference is to be registered,
+ * or <tt>null</tt> if registration is not required
+ *
+ */
+ public SoftReference(T referent, ReferenceQueue<? super T> q) {
+ super(referent, q);
+ this.timestamp = clock;
+ }
+
+ /**
+ * Returns this reference object's referent. If this reference object has
+ * been cleared, either by the program or by the garbage collector, then
+ * this method returns <code>null</code>.
+ *
+ * @return The object to which this reference refers, or
+ * <code>null</code> if this reference object has been cleared
+ */
+ public T get() {
+ T o = super.get();
+ if (o != null && this.timestamp != clock)
+ this.timestamp = clock;
+ return o;
+ }
+
+}
diff --git a/java/lang/ref/WeakReference.java b/java/lang/ref/WeakReference.java
new file mode 100644
index 0000000..025949a
--- /dev/null
+++ b/java/lang/ref/WeakReference.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 1997, 2003, 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.ref;
+
+
+/**
+ * Weak reference objects, which do not prevent their referents from being
+ * made finalizable, finalized, and then reclaimed. Weak references are most
+ * often used to implement canonicalizing mappings.
+ *
+ * <p> Suppose that the garbage collector determines at a certain point in time
+ * that an object is <a href="package-summary.html#reachability">weakly
+ * reachable</a>. At that time it will atomically clear all weak references to
+ * that object and all weak references to any other weakly-reachable objects
+ * from which that object is reachable through a chain of strong and soft
+ * references. At the same time it will declare all of the formerly
+ * weakly-reachable objects to be finalizable. At the same time or at some
+ * later time it will enqueue those newly-cleared weak references that are
+ * registered with reference queues.
+ *
+ * @author Mark Reinhold
+ * @since 1.2
+ */
+
+public class WeakReference<T> extends Reference<T> {
+
+ /**
+ * Creates a new weak reference that refers to the given object. The new
+ * reference is not registered with any queue.
+ *
+ * @param referent object the new weak reference will refer to
+ */
+ public WeakReference(T referent) {
+ super(referent);
+ }
+
+ /**
+ * Creates a new weak reference that refers to the given object and is
+ * registered with the given queue.
+ *
+ * @param referent object the new weak reference will refer to
+ * @param q the queue with which the reference is to be registered,
+ * or <tt>null</tt> if registration is not required
+ */
+ public WeakReference(T referent, ReferenceQueue<? super T> q) {
+ super(referent, q);
+ }
+
+}
diff --git a/java/lang/ref/package-info.java b/java/lang/ref/package-info.java
new file mode 100644
index 0000000..cc7f9ef
--- /dev/null
+++ b/java/lang/ref/package-info.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 1998, 2003, 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.
+ */
+
+
+/**
+ * Provides reference-object classes, which support a limited degree of
+ * interaction with the garbage collector. A program may use a reference object
+ * to maintain a reference to some other object in such a way that the latter
+ * object may still be reclaimed by the collector. A program may also arrange to
+ * be notified some time after the collector has determined that the reachability
+ * of a given object has changed.
+ *
+ *
+ * <h2>Package Specification</h2>
+ *
+ * A <em>reference object</em> encapsulates a reference to some other object so
+ * that the reference itself may be examined and manipulated like any other
+ * object. Three types of reference objects are provided, each weaker than the
+ * last: <em>soft</em>, <em>weak</em>, and <em>phantom</em>. Each type
+ * corresponds to a different level of reachability, as defined below. Soft
+ * references are for implementing memory-sensitive caches, weak references are
+ * for implementing canonicalizing mappings that do not prevent their keys (or
+ * values) from being reclaimed, and phantom references are for scheduling
+ * pre-mortem cleanup actions in a more flexible way than is possible with the
+ * Java finalization mechanism.
+ *
+ * <p> Each reference-object type is implemented by a subclass of the abstract
+ * base <code>{@link java.lang.ref.Reference}</code> class. An instance of one of
+ * these subclasses encapsulates a single reference to a particular object, called
+ * the <em>referent</em>. Every reference object provides methods for getting and
+ * clearing the reference. Aside from the clearing operation reference objects
+ * are otherwise immutable, so no <code>set</code> operation is provided. A
+ * program may further subclass these subclasses, adding whatever fields and
+ * methods are required for its purposes, or it may use these subclasses without
+ * change.
+ *
+ *
+ * <h3>Notification</h3>
+ *
+ * A program may request to be notified of changes in an object's reachability by
+ * <em>registering</em> an appropriate reference object with a <em>reference
+ * queue</em> at the time the reference object is created. Some time after the
+ * garbage collector determines that the reachability of the referent has changed
+ * to the value corresponding to the type of the reference, it will add the
+ * reference to the associated queue. At this point, the reference is considered
+ * to be <em>enqueued</em>. The program may remove references from a queue either
+ * by polling or by blocking until a reference becomes available. Reference
+ * queues are implemented by the <code>{@link java.lang.ref.ReferenceQueue}</code>
+ * class.
+ *
+ * <p> The relationship between a registered reference object and its queue is
+ * one-sided. That is, a queue does not keep track of the references that are
+ * registered with it. If a registered reference becomes unreachable itself, then
+ * it will never be enqueued. It is the responsibility of the program using
+ * reference objects to ensure that the objects remain reachable for as long as
+ * the program is interested in their referents.
+ *
+ * <p> While some programs will choose to dedicate a thread to removing reference
+ * objects from one or more queues and processing them, this is by no means
+ * necessary. A tactic that often works well is to examine a reference queue in
+ * the course of performing some other fairly-frequent action. For example, a
+ * hashtable that uses weak references to implement weak keys could poll its
+ * reference queue each time the table is accessed. This is how the <code>{@link
+ * java.util.WeakHashMap}</code> class works. Because the <code>{@link
+ * java.lang.ref.ReferenceQueue#poll ReferenceQueue.poll}</code> method simply
+ * checks an internal data structure, this check will add little overhead to the
+ * hashtable access methods.
+ *
+ *
+ * <h3>Automatically-cleared references</h3>
+ *
+ * Soft and weak references are automatically cleared by the collector before
+ * being added to the queues with which they are registered, if any. Therefore
+ * soft and weak references need not be registered with a queue in order to be
+ * useful, while phantom references do. An object that is reachable via phantom
+ * references will remain so until all such references are cleared or themselves
+ * become unreachable.
+ *
+ *
+ * <a name="reachability"></a>
+ * <h3>Reachability</h3>
+ *
+ * Going from strongest to weakest, the different levels of reachability reflect
+ * the life cycle of an object. They are operationally defined as follows:
+ *
+ * <ul>
+ *
+ * <li> An object is <em>strongly reachable</em> if it can be reached by some
+ * thread without traversing any reference objects. A newly-created object is
+ * strongly reachable by the thread that created it.
+ *
+ * <li> An object is <em>softly reachable</em> if it is not strongly reachable but
+ * can be reached by traversing a soft reference.
+ *
+ * <li> An object is <em>weakly reachable</em> if it is neither strongly nor
+ * softly reachable but can be reached by traversing a weak reference. When the
+ * weak references to a weakly-reachable object are cleared, the object becomes
+ * eligible for finalization.
+ *
+ * <li> An object is <em>phantom reachable</em> if it is neither strongly, softly,
+ * nor weakly reachable, it has been finalized, and some phantom reference refers
+ * to it.
+ *
+ * <li> Finally, an object is <em>unreachable</em>, and therefore eligible for
+ * reclamation, when it is not reachable in any of the above ways.
+ *
+ * </ul>
+ *
+ *
+ * @author Mark Reinhold
+ * @since 1.2
+ */
+package java.lang.ref;
diff --git a/java/lang/reflect/AccessibleObject.annotated.java b/java/lang/reflect/AccessibleObject.annotated.java
new file mode 100644
index 0000000..f601635
--- /dev/null
+++ b/java/lang/reflect/AccessibleObject.annotated.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1997, 2014, 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.reflect;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class AccessibleObject implements java.lang.reflect.AnnotatedElement {
+
+protected AccessibleObject() { throw new RuntimeException("Stub!"); }
+
+public static void setAccessible(java.lang.reflect.AccessibleObject[] array, boolean flag) throws java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+public void setAccessible(boolean flag) throws java.lang.SecurityException { throw new RuntimeException("Stub!"); }
+
+public boolean isAccessible() { throw new RuntimeException("Stub!"); }
+
[email protected] public <T extends java.lang.annotation.Annotation> T getAnnotation(@libcore.util.NonNull java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public boolean isAnnotationPresent(@libcore.util.NonNull java.lang.Class<? extends java.lang.annotation.Annotation> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public <T extends java.lang.annotation.Annotation> T[] getAnnotationsByType(@libcore.util.NonNull java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public [email protected] Annotation @libcore.util.NonNull [] getAnnotations() { throw new RuntimeException("Stub!"); }
+
[email protected] public <T extends java.lang.annotation.Annotation> T getDeclaredAnnotation(@libcore.util.NonNull java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public <T extends java.lang.annotation.Annotation> T[] getDeclaredAnnotationsByType(@libcore.util.NonNull java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public [email protected] Annotation @libcore.util.NonNull [] getDeclaredAnnotations() { throw new RuntimeException("Stub!"); }
+}
diff --git a/java/lang/reflect/AccessibleObject.java b/java/lang/reflect/AccessibleObject.java
new file mode 100644
index 0000000..18442fa
--- /dev/null
+++ b/java/lang/reflect/AccessibleObject.java
@@ -0,0 +1,330 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1997, 2014, 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.reflect;
+
+import java.lang.annotation.Annotation;
+
+/**
+ * The AccessibleObject class is the base class for Field, Method and
+ * Constructor objects. It provides the ability to flag a reflected
+ * object as suppressing default Java language access control checks
+ * when it is used. The access checks--for public, default (package)
+ * access, protected, and private members--are performed when Fields,
+ * Methods or Constructors are used to set or get fields, to invoke
+ * methods, or to create and initialize new instances of classes,
+ * respectively.
+ *
+ * <p>Setting the {@code accessible} flag in a reflected object
+ * permits sophisticated applications with sufficient privilege, such
+ * as Java Object Serialization or other persistence mechanisms, to
+ * manipulate objects in a manner that would normally be prohibited.
+ *
+ * <p>By default, a reflected object is <em>not</em> accessible.
+ *
+ * @see Field
+ * @see Method
+ * @see Constructor
+ * @see ReflectPermission
+ *
+ * @since 1.2
+ */
+public class AccessibleObject implements AnnotatedElement {
+
+ // Android-removed: Code associated with SecurityManager calls.
+ /*
+ /**
+ * The Permission object that is used to check whether a client
+ * has sufficient privilege to defeat Java language access
+ * control checks.
+ *
+ static final private java.security.Permission ACCESS_PERMISSION =
+ new ReflectPermission("suppressAccessChecks");
+ */
+
+ /**
+ * Convenience method to set the {@code accessible} flag for an
+ * array of objects with a single security check (for efficiency).
+ *
+ * <p>First, if there is a security manager, its
+ * {@code checkPermission} method is called with a
+ * {@code ReflectPermission("suppressAccessChecks")} permission.
+ *
+ * <p>A {@code SecurityException} is raised if {@code flag} is
+ * {@code true} but accessibility of any of the elements of the input
+ * {@code array} may not be changed (for example, if the element
+ * object is a {@link Constructor} object for the class {@link
+ * java.lang.Class}). In the event of such a SecurityException, the
+ * accessibility of objects is set to {@code flag} for array elements
+ * upto (and excluding) the element for which the exception occurred; the
+ * accessibility of elements beyond (and including) the element for which
+ * the exception occurred is unchanged.
+ *
+ * @param array the array of AccessibleObjects
+ * @param flag the new value for the {@code accessible} flag
+ * in each object
+ * @throws SecurityException if the request is denied.
+ * @see SecurityManager#checkPermission
+ * @see java.lang.RuntimePermission
+ */
+ public static void setAccessible(AccessibleObject[] array, boolean flag)
+ throws SecurityException {
+ // Android-removed: SecurityManager calls.
+ // SecurityManager sm = System.getSecurityManager();
+ // if (sm != null) sm.checkPermission(ACCESS_PERMISSION);
+ for (int i = 0; i < array.length; i++) {
+ setAccessible0(array[i], flag);
+ }
+ }
+
+ /**
+ * Set the {@code accessible} flag for this object to
+ * the indicated boolean value. A value of {@code true} indicates that
+ * the reflected object should suppress Java language access
+ * checking when it is used. A value of {@code false} indicates
+ * that the reflected object should enforce Java language access checks.
+ *
+ * <p>First, if there is a security manager, its
+ * {@code checkPermission} method is called with a
+ * {@code ReflectPermission("suppressAccessChecks")} permission.
+ *
+ * <p>A {@code SecurityException} is raised if {@code flag} is
+ * {@code true} but accessibility of this object may not be changed
+ * (for example, if this element object is a {@link Constructor} object for
+ * the class {@link java.lang.Class}).
+ *
+ * <p>A {@code SecurityException} is raised if this object is a {@link
+ * java.lang.reflect.Constructor} object for the class
+ * {@code java.lang.Class}, and {@code flag} is true.
+ *
+ * @param flag the new value for the {@code accessible} flag
+ * @throws SecurityException if the request is denied.
+ * @see SecurityManager#checkPermission
+ * @see java.lang.RuntimePermission
+ */
+ public void setAccessible(boolean flag) throws SecurityException {
+ // Android-removed: SecurityManager calls.
+ // SecurityManager sm = System.getSecurityManager();
+ // if (sm != null) sm.checkPermission(ACCESS_PERMISSION);
+ setAccessible0(this, flag);
+ }
+
+ /* Check that you aren't exposing java.lang.Class.<init> or sensitive
+ fields in java.lang.Class. */
+ private static void setAccessible0(AccessibleObject obj, boolean flag)
+ throws SecurityException
+ {
+ if (obj instanceof Constructor && flag == true) {
+ Constructor<?> c = (Constructor<?>)obj;
+ // BEGIN Android-changed: Disallow making Method & Field constructors accessible.
+ // if (c.getDeclaringClass() == Class.class) {
+ // throw new SecurityException("Cannot make a java.lang.Class" +
+ // " constructor accessible");
+ // }
+
+ Class<?> clazz = c.getDeclaringClass();
+ if (c.getDeclaringClass() == Class.class) {
+ throw new SecurityException("Can not make a java.lang.Class" +
+ " constructor accessible");
+ } else if (clazz == Method.class) {
+ throw new SecurityException("Can not make a java.lang.reflect.Method" +
+ " constructor accessible");
+ } else if (clazz == Field.class) {
+ throw new SecurityException("Can not make a java.lang.reflect.Field" +
+ " constructor accessible");
+ }
+ // END Android-changed: Disallow making Method & Field constructors accessible.
+ }
+ obj.override = flag;
+ }
+
+ /**
+ * Get the value of the {@code accessible} flag for this object.
+ *
+ * @return the value of the object's {@code accessible} flag
+ */
+ public boolean isAccessible() {
+ return override;
+ }
+
+ /**
+ * Constructor: only used by the Java Virtual Machine.
+ */
+ protected AccessibleObject() {}
+
+ // Indicates whether language-level access checks are overridden
+ // by this object. Initializes to "false". This field is used by
+ // Field, Method, and Constructor.
+ //
+ // NOTE: for security purposes, this field must not be visible
+ // outside this package.
+ boolean override;
+
+ // Android-removed: reflectionFactory: it is not used on Android.
+ /*
+ // Reflection factory used by subclasses for creating field,
+ // method, and constructor accessors. Note that this is called
+ // very early in the bootstrapping process.
+ static final ReflectionFactory reflectionFactory =
+ AccessController.doPrivileged(
+ new sun.reflect.ReflectionFactory.GetReflectionFactoryAction());
+ */
+
+ /**
+ * @throws NullPointerException {@inheritDoc}
+ * @since 1.5
+ */
+ public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
+ throw new AssertionError("All subclasses should override this method");
+ }
+
+ /**
+ * {@inheritDoc}
+ * @throws NullPointerException {@inheritDoc}
+ * @since 1.5
+ */
+ @Override
+ public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
+ return AnnotatedElement.super.isAnnotationPresent(annotationClass);
+ }
+
+ /**
+ * @throws NullPointerException {@inheritDoc}
+ * @since 1.8
+ */
+ @Override
+ public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) {
+ throw new AssertionError("All subclasses should override this method");
+ }
+
+ /**
+ * @since 1.5
+ */
+ public Annotation[] getAnnotations() {
+ return getDeclaredAnnotations();
+ }
+
+ /**
+ * @throws NullPointerException {@inheritDoc}
+ * @since 1.8
+ */
+ @Override
+ public <T extends Annotation> T getDeclaredAnnotation(Class<T> annotationClass) {
+ // Only annotations on classes are inherited, for all other
+ // objects getDeclaredAnnotation is the same as
+ // getAnnotation.
+ return getAnnotation(annotationClass);
+ }
+
+ /**
+ * @throws NullPointerException {@inheritDoc}
+ * @since 1.8
+ */
+ @Override
+ public <T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotationClass) {
+ // Only annotations on classes are inherited, for all other
+ // objects getDeclaredAnnotationsByType is the same as
+ // getAnnotationsByType.
+ return getAnnotationsByType(annotationClass);
+ }
+
+ /**
+ * @since 1.5
+ */
+ public Annotation[] getDeclaredAnnotations() {
+ throw new AssertionError("All subclasses should override this method");
+ }
+
+ // BEGIN Android-removed: Shared access checking logic: Not used on Android.
+ /*
+ // For non-public members or members in package-private classes,
+ // it is necessary to perform somewhat expensive security checks.
+ // If the security check succeeds for a given class, it will
+ // always succeed (it is not affected by the granting or revoking
+ // of permissions); we speed up the check in the common case by
+ // remembering the last Class for which the check succeeded.
+ //
+ // The simple security check for Constructor is to see if
+ // the caller has already been seen, verified, and cached.
+ // (See also Class.newInstance(), which uses a similar method.)
+ //
+ // A more complicated security check cache is needed for Method and Field
+ // The cache can be either null (empty cache), a 2-array of {caller,target},
+ // or a caller (with target implicitly equal to this.clazz).
+ // In the 2-array case, the target is always different from the clazz.
+ volatile Object securityCheckCache;
+
+ void checkAccess(Class<?> caller, Class<?> clazz, Object obj, int modifiers)
+ throws IllegalAccessException
+ {
+ if (caller == clazz) { // quick check
+ return; // ACCESS IS OK
+ }
+ Object cache = securityCheckCache; // read volatile
+ Class<?> targetClass = clazz;
+ if (obj != null
+ && Modifier.isProtected(modifiers)
+ && ((targetClass = obj.getClass()) != clazz)) {
+ // Must match a 2-list of { caller, targetClass }.
+ if (cache instanceof Class[]) {
+ Class<?>[] cache2 = (Class<?>[]) cache;
+ if (cache2[1] == targetClass &&
+ cache2[0] == caller) {
+ return; // ACCESS IS OK
+ }
+ // (Test cache[1] first since range check for [1]
+ // subsumes range check for [0].)
+ }
+ } else if (cache == caller) {
+ // Non-protected case (or obj.class == this.clazz).
+ return; // ACCESS IS OK
+ }
+
+ // If no return, fall through to the slow path.
+ slowCheckMemberAccess(caller, clazz, obj, modifiers, targetClass);
+ }
+
+ // Keep all this slow stuff out of line:
+ void slowCheckMemberAccess(Class<?> caller, Class<?> clazz, Object obj, int modifiers,
+ Class<?> targetClass)
+ throws IllegalAccessException
+ {
+ Reflection.ensureMemberAccess(caller, clazz, obj, modifiers);
+
+ // Success: Update the cache.
+ Object cache = ((targetClass == clazz)
+ ? caller
+ : new Class<?>[] { caller, targetClass });
+
+ // Note: The two cache elements are not volatile,
+ // but they are effectively final. The Java memory model
+ // guarantees that the initializing stores for the cache
+ // elements will occur before the volatile write.
+ securityCheckCache = cache; // write volatile
+ }
+ */
+ // END Android-removed: Shared access checking logic: Not used on Android.
+}
diff --git a/java/lang/reflect/AnnotatedElement.annotated.java b/java/lang/reflect/AnnotatedElement.annotated.java
new file mode 100644
index 0000000..97cb3a2
--- /dev/null
+++ b/java/lang/reflect/AnnotatedElement.annotated.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ * Copyright (c) 2003, 2013, 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.reflect;
+
+import java.lang.annotation.AnnotationFormatError;
+import java.lang.annotation.Annotation;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface AnnotatedElement {
+
+public default boolean isAnnotationPresent(@libcore.util.NonNull java.lang.Class<? extends java.lang.annotation.Annotation> annotationClass) { throw new RuntimeException("Stub!"); }
+
[email protected] public <T extends java.lang.annotation.Annotation> T getAnnotation(@libcore.util.NonNull java.lang.Class<T> annotationClass);
+
+public [email protected] Annotation @libcore.util.NonNull [] getAnnotations();
+
+public default <T extends java.lang.annotation.Annotation> T[] getAnnotationsByType(@libcore.util.NonNull java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
[email protected] public default <T extends java.lang.annotation.Annotation> T getDeclaredAnnotation(@libcore.util.NonNull java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public default <T extends java.lang.annotation.Annotation> T[] getDeclaredAnnotationsByType(@libcore.util.NonNull java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public [email protected] Annotation @libcore.util.NonNull [] getDeclaredAnnotations();
+}
diff --git a/java/lang/reflect/AnnotatedElement.java b/java/lang/reflect/AnnotatedElement.java
new file mode 100644
index 0000000..7bb2a60
--- /dev/null
+++ b/java/lang/reflect/AnnotatedElement.java
@@ -0,0 +1,429 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ * Copyright (c) 2003, 2013, 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.reflect;
+
+import java.lang.annotation.Annotation;
+import java.lang.annotation.AnnotationFormatError;
+import java.util.Objects;
+import libcore.reflect.AnnotatedElements;
+
+// Android-changed: Removed some references to bytecode spec below that do not
+// apply to DEX and added a note about annotation ordering.
+/**
+ * Represents an annotated element of the program currently running in this
+ * VM. This interface allows annotations to be read reflectively. All
+ * annotations returned by methods in this interface are immutable and
+ * serializable. The arrays returned by methods of this interface may be modified
+ * by callers without affecting the arrays returned to other callers.
+ *
+ * <p>Android note: methods that return multiple annotations of different types such as
+ * {@link #getAnnotations()} and {@link #getDeclaredAnnotations()} can be affected
+ * by the explicit character-code ordering of annotations types specified by the DEX format.
+ * Annotations of different types on a single element are not guaranteed to be returned in the order
+ * they are declared in source.
+ *
+ * <p>The {@link #getAnnotationsByType(Class)} and {@link
+ * #getDeclaredAnnotationsByType(Class)} methods support multiple
+ * annotations of the same type on an element. If the argument to
+ * either method is a repeatable annotation type (JLS 9.6), then the
+ * method will "look through" a container annotation (JLS 9.7), if
+ * present, and return any annotations inside the container. Container
+ * annotations may be generated at compile-time to wrap multiple
+ * annotations of the argument type.
+ *
+ * <p>The terms <em>directly present</em>, <em>indirectly present</em>,
+ * <em>present</em>, and <em>associated</em> are used throughout this
+ * interface to describe precisely which annotations are returned by
+ * methods:
+ *
+ * <ul>
+ *
+ * <li> An annotation <i>A</i> is <em>directly present</em> on an
+ * element <i>E</i> if <i>E</i> is annotated by <i>A</i> in the original source.
+ *
+ * <li>An annotation <i>A</i> is <em>indirectly present</em> on an
+ * element <i>E</i> if <i>E</i> is annotated by a container annotation
+ * of <i>A</i>.
+ *
+ * <li>An annotation <i>A</i> is present on an element <i>E</i> if either:
+ *
+ * <ul>
+ *
+ * <li><i>A</i> is directly present on <i>E</i>; or
+ *
+ * <li>No annotation of <i>A</i> 's type is directly present on
+ * <i>E</i>, and <i>E</i> is a class, and <i>A</i> 's type is
+ * inheritable, and <i>A</i> is present on the superclass of <i>E</i>.
+ *
+ * </ul>
+ *
+ * <li>An annotation <i>A</i> is <em>associated</em> with an element <i>E</i>
+ * if either:
+ *
+ * <ul>
+ *
+ * <li><i>A</i> is directly or indirectly present on <i>E</i>; or
+ *
+ * <li>No annotation of <i>A</i> 's type is directly or indirectly
+ * present on <i>E</i>, and <i>E</i> is a class, and <i>A</i>'s type
+ * is inheritable, and <i>A</i> is associated with the superclass of
+ * <i>E</i>.
+ *
+ * </ul>
+ *
+ * </ul>
+ *
+ * <p>The table below summarizes which kind of annotation presence
+ * different methods in this interface examine.
+ *
+ * <table border>
+ * <caption>Overview of kind of presence detected by different AnnotatedElement methods</caption>
+ * <tr><th colspan=2></th><th colspan=4>Kind of Presence</th>
+ * <tr><th colspan=2>Method</th><th>Directly Present</th><th>Indirectly Present</th><th>Present</th><th>Associated</th>
+ * <tr><td align=right>{@code T}</td><td>{@link #getAnnotation(Class) getAnnotation(Class<T>)}
+ * <td></td><td></td><td>X</td><td></td>
+ * </tr>
+ * <tr><td align=right>{@code Annotation[]}</td><td>{@link #getAnnotations getAnnotations()}
+ * <td></td><td></td><td>X</td><td></td>
+ * </tr>
+ * <tr><td align=right>{@code T[]}</td><td>{@link #getAnnotationsByType(Class) getAnnotationsByType(Class<T>)}
+ * <td></td><td></td><td></td><td>X</td>
+ * </tr>
+ * <tr><td align=right>{@code T}</td><td>{@link #getDeclaredAnnotation(Class) getDeclaredAnnotation(Class<T>)}
+ * <td>X</td><td></td><td></td><td></td>
+ * </tr>
+ * <tr><td align=right>{@code Annotation[]}</td><td>{@link #getDeclaredAnnotations getDeclaredAnnotations()}
+ * <td>X</td><td></td><td></td><td></td>
+ * </tr>
+ * <tr><td align=right>{@code T[]}</td><td>{@link #getDeclaredAnnotationsByType(Class) getDeclaredAnnotationsByType(Class<T>)}
+ * <td>X</td><td>X</td><td></td><td></td>
+ * </tr>
+ * </table>
+ *
+ * <p>For an invocation of {@code get[Declared]AnnotationsByType( Class <
+ * T >)}, the order of annotations which are directly or indirectly
+ * present on an element <i>E</i> is computed as if indirectly present
+ * annotations on <i>E</i> are directly present on <i>E</i> in place
+ * of their container annotation, in the order in which they appear in
+ * the value element of the container annotation.
+ *
+ * <p>There are several compatibility concerns to keep in mind if an
+ * annotation type <i>T</i> is originally <em>not</em> repeatable and
+ * later modified to be repeatable.
+ *
+ * The containing annotation type for <i>T</i> is <i>TC</i>.
+ *
+ * <ul>
+ *
+ * <li>Modifying <i>T</i> to be repeatable is source and binary
+ * compatible with existing uses of <i>T</i> and with existing uses
+ * of <i>TC</i>.
+ *
+ * That is, for source compatibility, source code with annotations of
+ * type <i>T</i> or of type <i>TC</i> will still compile. For binary
+ * compatibility, class files with annotations of type <i>T</i> or of
+ * type <i>TC</i> (or with other kinds of uses of type <i>T</i> or of
+ * type <i>TC</i>) will link against the modified version of <i>T</i>
+ * if they linked against the earlier version.
+ *
+ * (An annotation type <i>TC</i> may informally serve as an acting
+ * containing annotation type before <i>T</i> is modified to be
+ * formally repeatable. Alternatively, when <i>T</i> is made
+ * repeatable, <i>TC</i> can be introduced as a new type.)
+ *
+ * <li>If an annotation type <i>TC</i> is present on an element, and
+ * <i>T</i> is modified to be repeatable with <i>TC</i> as its
+ * containing annotation type then:
+ *
+ * <ul>
+ *
+ * <li>The change to <i>T</i> is behaviorally compatible with respect
+ * to the {@code get[Declared]Annotation(Class<T>)} (called with an
+ * argument of <i>T</i> or <i>TC</i>) and {@code
+ * get[Declared]Annotations()} methods because the results of the
+ * methods will not change due to <i>TC</i> becoming the containing
+ * annotation type for <i>T</i>.
+ *
+ * <li>The change to <i>T</i> changes the results of the {@code
+ * get[Declared]AnnotationsByType(Class<T>)} methods called with an
+ * argument of <i>T</i>, because those methods will now recognize an
+ * annotation of type <i>TC</i> as a container annotation for <i>T</i>
+ * and will "look through" it to expose annotations of type <i>T</i>.
+ *
+ * </ul>
+ *
+ * <li>If an annotation of type <i>T</i> is present on an
+ * element and <i>T</i> is made repeatable and more annotations of
+ * type <i>T</i> are added to the element:
+ *
+ * <ul>
+ *
+ * <li> The addition of the annotations of type <i>T</i> is both
+ * source compatible and binary compatible.
+ *
+ * <li>The addition of the annotations of type <i>T</i> changes the results
+ * of the {@code get[Declared]Annotation(Class<T>)} methods and {@code
+ * get[Declared]Annotations()} methods, because those methods will now
+ * only see a container annotation on the element and not see an
+ * annotation of type <i>T</i>.
+ *
+ * <li>The addition of the annotations of type <i>T</i> changes the
+ * results of the {@code get[Declared]AnnotationsByType(Class<T>)}
+ * methods, because their results will expose the additional
+ * annotations of type <i>T</i> whereas previously they exposed only a
+ * single annotation of type <i>T</i>.
+ *
+ * </ul>
+ *
+ * </ul>
+ *
+ * <p>If an annotation returned by a method in this interface contains
+ * (directly or indirectly) a {@link Class}-valued member referring to
+ * a class that is not accessible in this VM, attempting to read the class
+ * by calling the relevant Class-returning method on the returned annotation
+ * will result in a {@link TypeNotPresentException}.
+ *
+ * <p>Similarly, attempting to read an enum-valued member will result in
+ * a {@link EnumConstantNotPresentException} if the enum constant in the
+ * annotation is no longer present in the enum type.
+ *
+ * <p>If an annotation type <i>T</i> is (meta-)annotated with an
+ * {@code @Repeatable} annotation whose value element indicates a type
+ * <i>TC</i>, but <i>TC</i> does not declare a {@code value()} method
+ * with a return type of <i>T</i>{@code []}, then an exception of type
+ * {@link java.lang.annotation.AnnotationFormatError} is thrown.
+ *
+ * <p>Finally, attempting to read a member whose definition has evolved
+ * incompatibly will result in a {@link
+ * java.lang.annotation.AnnotationTypeMismatchException} or an
+ * {@link java.lang.annotation.IncompleteAnnotationException}.
+ *
+ * @see java.lang.EnumConstantNotPresentException
+ * @see java.lang.TypeNotPresentException
+ * @see AnnotationFormatError
+ * @see java.lang.annotation.AnnotationTypeMismatchException
+ * @see java.lang.annotation.IncompleteAnnotationException
+ * @since 1.5
+ * @author Josh Bloch
+ */
+public interface AnnotatedElement {
+ /**
+ * Returns true if an annotation for the specified type
+ * is <em>present</em> on this element, else false. This method
+ * is designed primarily for convenient access to marker annotations.
+ *
+ * <p>The truth value returned by this method is equivalent to:
+ * {@code getAnnotation(annotationClass) != null}
+ *
+ * <p>The body of the default method is specified to be the code
+ * above.
+ *
+ * @param annotationClass the Class object corresponding to the
+ * annotation type
+ * @return true if an annotation for the specified annotation
+ * type is present on this element, else false
+ * @throws NullPointerException if the given annotation class is null
+ * @since 1.5
+ */
+ default boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
+ return getAnnotation(annotationClass) != null;
+ }
+
+ /**
+ * Returns this element's annotation for the specified type if
+ * such an annotation is <em>present</em>, else null.
+ *
+ * @param <T> the type of the annotation to query for and return if present
+ * @param annotationClass the Class object corresponding to the
+ * annotation type
+ * @return this element's annotation for the specified annotation type if
+ * present on this element, else null
+ * @throws NullPointerException if the given annotation class is null
+ * @since 1.5
+ */
+ <T extends Annotation> T getAnnotation(Class<T> annotationClass);
+
+ /**
+ * Returns annotations that are <em>present</em> on this element.
+ *
+ * If there are no annotations <em>present</em> on this element, the return
+ * value is an array of length 0.
+ *
+ * The caller of this method is free to modify the returned array; it will
+ * have no effect on the arrays returned to other callers.
+ *
+ * @return annotations present on this element
+ * @since 1.5
+ */
+ Annotation[] getAnnotations();
+
+ /**
+ * Returns annotations that are <em>associated</em> with this element.
+ *
+ * If there are no annotations <em>associated</em> with this element, the return
+ * value is an array of length 0.
+ *
+ * The difference between this method and {@link #getAnnotation(Class)}
+ * is that this method detects if its argument is a <em>repeatable
+ * annotation type</em> (JLS 9.6), and if so, attempts to find one or
+ * more annotations of that type by "looking through" a container
+ * annotation.
+ *
+ * The caller of this method is free to modify the returned array; it will
+ * have no effect on the arrays returned to other callers.
+ *
+ * @implSpec The default implementation first calls {@link
+ * #getDeclaredAnnotationsByType(Class)} passing {@code
+ * annotationClass} as the argument. If the returned array has
+ * length greater than zero, the array is returned. If the returned
+ * array is zero-length and this {@code AnnotatedElement} is a
+ * class and the argument type is an inheritable annotation type,
+ * and the superclass of this {@code AnnotatedElement} is non-null,
+ * then the returned result is the result of calling {@link
+ * #getAnnotationsByType(Class)} on the superclass with {@code
+ * annotationClass} as the argument. Otherwise, a zero-length
+ * array is returned.
+ *
+ * @param <T> the type of the annotation to query for and return if present
+ * @param annotationClass the Class object corresponding to the
+ * annotation type
+ * @return all this element's annotations for the specified annotation type if
+ * associated with this element, else an array of length zero
+ * @throws NullPointerException if the given annotation class is null
+ * @since 1.8
+ */
+ default <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) {
+ // Android-changed: Altered method implementation for getAnnotationsByType(Class).
+ // Android's annotation code is customized because of the use of the DEX format on Android
+ // and code sharing with the runtime.
+ // This method does not handle inherited annotations and is intended for use for
+ // {@code Method}, {@code Field}, {@code Package}. The {@link Class#getAnnotationsByType}
+ // is implemented explicitly. Therefore this implementation does not fulfill the documented
+ // default implementation for {@link AnnotatedElement#getAnnotationsByType(Class)} but in an
+ // undetectable way because Class is final.
+ return AnnotatedElements.getDirectOrIndirectAnnotationsByType(this, annotationClass);
+ }
+
+ /**
+ * Returns this element's annotation for the specified type if
+ * such an annotation is <em>directly present</em>, else null.
+ *
+ * This method ignores inherited annotations. (Returns null if no
+ * annotations are directly present on this element.)
+ *
+ * @implSpec The default implementation first performs a null check
+ * and then loops over the results of {@link
+ * #getDeclaredAnnotations} returning the first annotation whose
+ * annotation type matches the argument type.
+ *
+ * @param <T> the type of the annotation to query for and return if directly present
+ * @param annotationClass the Class object corresponding to the
+ * annotation type
+ * @return this element's annotation for the specified annotation type if
+ * directly present on this element, else null
+ * @throws NullPointerException if the given annotation class is null
+ * @since 1.8
+ */
+ default <T extends Annotation> T getDeclaredAnnotation(Class<T> annotationClass) {
+ Objects.requireNonNull(annotationClass);
+ // Loop over all directly-present annotations looking for a matching one
+ for (Annotation annotation : getDeclaredAnnotations()) {
+ if (annotationClass.equals(annotation.annotationType())) {
+ // More robust to do a dynamic cast at runtime instead
+ // of compile-time only.
+ return annotationClass.cast(annotation);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns this element's annotation(s) for the specified type if
+ * such annotations are either <em>directly present</em> or
+ * <em>indirectly present</em>. This method ignores inherited
+ * annotations.
+ *
+ * If there are no specified annotations directly or indirectly
+ * present on this element, the return value is an array of length
+ * 0.
+ *
+ * The difference between this method and {@link
+ * #getDeclaredAnnotation(Class)} is that this method detects if its
+ * argument is a <em>repeatable annotation type</em> (JLS 9.6), and if so,
+ * attempts to find one or more annotations of that type by "looking
+ * through" a container annotation if one is present.
+ *
+ * The caller of this method is free to modify the returned array; it will
+ * have no effect on the arrays returned to other callers.
+ *
+ * @implSpec The default implementation may call {@link
+ * #getDeclaredAnnotation(Class)} one or more times to find a
+ * directly present annotation and, if the annotation type is
+ * repeatable, to find a container annotation. If annotations of
+ * the annotation type {@code annotationClass} are found to be both
+ * directly and indirectly present, then {@link
+ * #getDeclaredAnnotations()} will get called to determine the
+ * order of the elements in the returned array.
+ *
+ * <p>Alternatively, the default implementation may call {@link
+ * #getDeclaredAnnotations()} a single time and the returned array
+ * examined for both directly and indirectly present
+ * annotations. The results of calling {@link
+ * #getDeclaredAnnotations()} are assumed to be consistent with the
+ * results of calling {@link #getDeclaredAnnotation(Class)}.
+ *
+ * @param <T> the type of the annotation to query for and return
+ * if directly or indirectly present
+ * @param annotationClass the Class object corresponding to the
+ * annotation type
+ * @return all this element's annotations for the specified annotation type if
+ * directly or indirectly present on this element, else an array of length zero
+ * @throws NullPointerException if the given annotation class is null
+ * @since 1.8
+ */
+ default <T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotationClass) {
+ // Android-changed: Altered method implementation for getAnnotationsByType(Class).
+ // Android's annotation code is customized because of the use of the DEX format on Android
+ // and code sharing with the runtime.
+ return AnnotatedElements.getDirectOrIndirectAnnotationsByType(this, annotationClass);
+ }
+
+ /**
+ * Returns annotations that are <em>directly present</em> on this element.
+ * This method ignores inherited annotations.
+ *
+ * If there are no annotations <em>directly present</em> on this element,
+ * the return value is an array of length 0.
+ *
+ * The caller of this method is free to modify the returned array; it will
+ * have no effect on the arrays returned to other callers.
+ *
+ * @return annotations directly present on this element
+ * @since 1.5
+ */
+ Annotation[] getDeclaredAnnotations();
+}
diff --git a/java/lang/reflect/Array.annotated.java b/java/lang/reflect/Array.annotated.java
new file mode 100644
index 0000000..f0fba5c
--- /dev/null
+++ b/java/lang/reflect/Array.annotated.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1996, 2013, 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.reflect;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Array {
+
+Array() { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Object newInstance(@libcore.util.NonNull java.lang.Class<?> componentType, int length) throws java.lang.NegativeArraySizeException { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Object newInstance(@libcore.util.NonNull java.lang.Class<?> componentType, int... dimensions) throws java.lang.IllegalArgumentException, java.lang.NegativeArraySizeException { throw new RuntimeException("Stub!"); }
+
+public static int getLength(@libcore.util.NonNull java.lang.Object array) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Object get(@libcore.util.NonNull java.lang.Object array, int index) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static boolean getBoolean(@libcore.util.NonNull java.lang.Object array, int index) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static byte getByte(@libcore.util.NonNull java.lang.Object array, int index) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static char getChar(@libcore.util.NonNull java.lang.Object array, int index) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static short getShort(@libcore.util.NonNull java.lang.Object array, int index) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static int getInt(@libcore.util.NonNull java.lang.Object array, int index) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static long getLong(@libcore.util.NonNull java.lang.Object array, int index) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static float getFloat(@libcore.util.NonNull java.lang.Object array, int index) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static double getDouble(@libcore.util.NonNull java.lang.Object array, int index) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static void set(@libcore.util.NonNull java.lang.Object array, int index, @libcore.util.Nullable java.lang.Object value) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static void setBoolean(@libcore.util.NonNull java.lang.Object array, int index, boolean z) { throw new RuntimeException("Stub!"); }
+
+public static void setByte(@libcore.util.NonNull java.lang.Object array, int index, byte b) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static void setChar(@libcore.util.NonNull java.lang.Object array, int index, char c) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static void setShort(@libcore.util.NonNull java.lang.Object array, int index, short s) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static void setInt(@libcore.util.NonNull java.lang.Object array, int index, int i) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static void setLong(@libcore.util.NonNull java.lang.Object array, int index, long l) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static void setFloat(@libcore.util.NonNull java.lang.Object array, int index, float f) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static void setDouble(@libcore.util.NonNull java.lang.Object array, int index, double d) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+}
diff --git a/java/lang/reflect/Array.java b/java/lang/reflect/Array.java
new file mode 100644
index 0000000..95a8091
--- /dev/null
+++ b/java/lang/reflect/Array.java
@@ -0,0 +1,840 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1996, 2013, 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.reflect;
+
+import dalvik.annotation.optimization.FastNative;
+
+/**
+ * The {@code Array} class provides static methods to dynamically create and
+ * access Java arrays.
+ *
+ * <p>{@code Array} permits widening conversions to occur during a get or set
+ * operation, but throws an {@code IllegalArgumentException} if a narrowing
+ * conversion would occur.
+ *
+ * @author Nakul Saraiya
+ */
+public final
+class Array {
+
+ /**
+ * Constructor. Class Array is not instantiable.
+ */
+ private Array() {}
+
+ /**
+ * Creates a new array with the specified component type and
+ * length.
+ * Invoking this method is equivalent to creating an array
+ * as follows:
+ * <blockquote>
+ * <pre>
+ * int[] x = {length};
+ * Array.newInstance(componentType, x);
+ * </pre>
+ * </blockquote>
+ *
+ * <p>The number of dimensions of the new array must not
+ * exceed 255.
+ *
+ * @param componentType the {@code Class} object representing the
+ * component type of the new array
+ * @param length the length of the new array
+ * @return the new array
+ * @exception NullPointerException if the specified
+ * {@code componentType} parameter is null
+ * @exception IllegalArgumentException if componentType is {@link
+ * Void#TYPE} or if the number of dimensions of the requested array
+ * instance exceed 255.
+ * @exception NegativeArraySizeException if the specified {@code length}
+ * is negative
+ */
+ public static Object newInstance(Class<?> componentType, int length)
+ throws NegativeArraySizeException {
+ return newArray(componentType, length);
+ }
+
+ /**
+ * Creates a new array
+ * with the specified component type and dimensions.
+ * If {@code componentType}
+ * represents a non-array class or interface, the new array
+ * has {@code dimensions.length} dimensions and
+ * {@code componentType} as its component type. If
+ * {@code componentType} represents an array class, the
+ * number of dimensions of the new array is equal to the sum
+ * of {@code dimensions.length} and the number of
+ * dimensions of {@code componentType}. In this case, the
+ * component type of the new array is the component type of
+ * {@code componentType}.
+ *
+ * <p>The number of dimensions of the new array must not
+ * exceed 255.
+ *
+ * @param componentType the {@code Class} object representing the component
+ * type of the new array
+ * @param dimensions an array of {@code int} representing the dimensions of
+ * the new array
+ * @return the new array
+ * @exception NullPointerException if the specified
+ * {@code componentType} argument is null
+ * @exception IllegalArgumentException if the specified {@code dimensions}
+ * argument is a zero-dimensional array, if componentType is {@link
+ * Void#TYPE}, or if the number of dimensions of the requested array
+ * instance exceed 255.
+ * @exception NegativeArraySizeException if any of the components in
+ * the specified {@code dimensions} argument is negative.
+ */
+ public static Object newInstance(Class<?> componentType, int... dimensions)
+ throws IllegalArgumentException, NegativeArraySizeException {
+ // Android-changed: New implementation of newInstance(Class, int...)
+ if (dimensions.length <= 0 || dimensions.length > 255) {
+ throw new IllegalArgumentException("Bad number of dimensions: " + dimensions.length);
+ }
+ if (componentType == void.class) {
+ throw new IllegalArgumentException("Can't allocate an array of void");
+ }
+ if (componentType == null) {
+ throw new NullPointerException("componentType == null");
+ }
+ return createMultiArray(componentType, dimensions);
+ }
+
+ /**
+ * Returns the length of the specified array object, as an {@code int}.
+ *
+ * @param array the array
+ * @return the length of the array
+ * @exception IllegalArgumentException if the object argument is not
+ * an array
+ */
+ // Android-changed: Non-native implementation of getLength(Object)
+ // Android-changed: Removal of explicit throws IllegalArgumentException from method signature.
+ public static int getLength(Object array)
+ /* throws IllegalArgumentException */ {
+ if (array instanceof Object[]) {
+ return ((Object[]) array).length;
+ } else if (array instanceof boolean[]) {
+ return ((boolean[]) array).length;
+ } else if (array instanceof byte[]) {
+ return ((byte[]) array).length;
+ } else if (array instanceof char[]) {
+ return ((char[]) array).length;
+ } else if (array instanceof double[]) {
+ return ((double[]) array).length;
+ } else if (array instanceof float[]) {
+ return ((float[]) array).length;
+ } else if (array instanceof int[]) {
+ return ((int[]) array).length;
+ } else if (array instanceof long[]) {
+ return ((long[]) array).length;
+ } else if (array instanceof short[]) {
+ return ((short[]) array).length;
+ }
+ throw badArray(array);
+ }
+
+ /**
+ * Returns the value of the indexed component in the specified
+ * array object. The value is automatically wrapped in an object
+ * if it has a primitive type.
+ *
+ * @param array the array
+ * @param index the index
+ * @return the (possibly wrapped) value of the indexed component in
+ * the specified array
+ * @exception NullPointerException If the specified object is null
+ * @exception IllegalArgumentException If the specified object is not
+ * an array
+ * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
+ * argument is negative, or if it is greater than or equal to the
+ * length of the specified array
+ */
+ // Android-changed: Non-native implementation of get(Object, int)
+ public static Object get(Object array, int index)
+ throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
+ if (array instanceof Object[]) {
+ return ((Object[]) array)[index];
+ }
+ if (array instanceof boolean[]) {
+ return ((boolean[]) array)[index] ? Boolean.TRUE : Boolean.FALSE;
+ }
+ if (array instanceof byte[]) {
+ return Byte.valueOf(((byte[]) array)[index]);
+ }
+ if (array instanceof char[]) {
+ return Character.valueOf(((char[]) array)[index]);
+ }
+ if (array instanceof short[]) {
+ return Short.valueOf(((short[]) array)[index]);
+ }
+ if (array instanceof int[]) {
+ return Integer.valueOf(((int[]) array)[index]);
+ }
+ if (array instanceof long[]) {
+ return Long.valueOf(((long[]) array)[index]);
+ }
+ if (array instanceof float[]) {
+ return new Float(((float[]) array)[index]);
+ }
+ if (array instanceof double[]) {
+ return new Double(((double[]) array)[index]);
+ }
+ if (array == null) {
+ throw new NullPointerException("array == null");
+ }
+ throw notAnArray(array);
+ }
+
+ /**
+ * Returns the value of the indexed component in the specified
+ * array object, as a {@code boolean}.
+ *
+ * @param array the array
+ * @param index the index
+ * @return the value of the indexed component in the specified array
+ * @exception NullPointerException If the specified object is null
+ * @exception IllegalArgumentException If the specified object is not
+ * an array, or if the indexed element cannot be converted to the
+ * return type by an identity or widening conversion
+ * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
+ * argument is negative, or if it is greater than or equal to the
+ * length of the specified array
+ * @see Array#get
+ */
+ // Android-changed: Non-native implementation of getBoolean(Object, int)
+ public static boolean getBoolean(Object array, int index)
+ throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
+ if (array instanceof boolean[]) {
+ return ((boolean[]) array)[index];
+ }
+ throw badArray(array);
+ }
+
+ /**
+ * Returns the value of the indexed component in the specified
+ * array object, as a {@code byte}.
+ *
+ * @param array the array
+ * @param index the index
+ * @return the value of the indexed component in the specified array
+ * @exception NullPointerException If the specified object is null
+ * @exception IllegalArgumentException If the specified object is not
+ * an array, or if the indexed element cannot be converted to the
+ * return type by an identity or widening conversion
+ * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
+ * argument is negative, or if it is greater than or equal to the
+ * length of the specified array
+ * @see Array#get
+ */
+ // Android-changed: Non-native implementation of getByte(Object, int)
+ public static byte getByte(Object array, int index)
+ throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
+ if (array instanceof byte[]) {
+ return ((byte[]) array)[index];
+ }
+ throw badArray(array);
+ }
+
+ /**
+ * Returns the value of the indexed component in the specified
+ * array object, as a {@code char}.
+ *
+ * @param array the array
+ * @param index the index
+ * @return the value of the indexed component in the specified array
+ * @exception NullPointerException If the specified object is null
+ * @exception IllegalArgumentException If the specified object is not
+ * an array, or if the indexed element cannot be converted to the
+ * return type by an identity or widening conversion
+ * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
+ * argument is negative, or if it is greater than or equal to the
+ * length of the specified array
+ * @see Array#get
+ */
+ // Android-changed: Non-native implementation of getChar(Object, int)
+ public static char getChar(Object array, int index)
+ throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
+ if (array instanceof char[]) {
+ return ((char[]) array)[index];
+ }
+ throw badArray(array);
+ }
+
+ /**
+ * Returns the value of the indexed component in the specified
+ * array object, as a {@code short}.
+ *
+ * @param array the array
+ * @param index the index
+ * @return the value of the indexed component in the specified array
+ * @exception NullPointerException If the specified object is null
+ * @exception IllegalArgumentException If the specified object is not
+ * an array, or if the indexed element cannot be converted to the
+ * return type by an identity or widening conversion
+ * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
+ * argument is negative, or if it is greater than or equal to the
+ * length of the specified array
+ * @see Array#get
+ */
+ // Android-changed: Non-native implementation of getShort(Object, int)
+ public static short getShort(Object array, int index)
+ throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
+ if (array instanceof short[]) {
+ return ((short[]) array)[index];
+ } else if (array instanceof byte[]) {
+ return ((byte[]) array)[index];
+ }
+ throw badArray(array);
+ }
+
+ /**
+ * Returns the value of the indexed component in the specified
+ * array object, as an {@code int}.
+ *
+ * @param array the array
+ * @param index the index
+ * @return the value of the indexed component in the specified array
+ * @exception NullPointerException If the specified object is null
+ * @exception IllegalArgumentException If the specified object is not
+ * an array, or if the indexed element cannot be converted to the
+ * return type by an identity or widening conversion
+ * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
+ * argument is negative, or if it is greater than or equal to the
+ * length of the specified array
+ * @see Array#get
+ */
+ // Android-changed: Non-native implementation of getInt(Object, int)
+ public static int getInt(Object array, int index)
+ throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
+ if (array instanceof int[]) {
+ return ((int[]) array)[index];
+ } else if (array instanceof byte[]) {
+ return ((byte[]) array)[index];
+ } else if (array instanceof char[]) {
+ return ((char[]) array)[index];
+ } else if (array instanceof short[]) {
+ return ((short[]) array)[index];
+ }
+ throw badArray(array);
+ }
+
+ /**
+ * Returns the value of the indexed component in the specified
+ * array object, as a {@code long}.
+ *
+ * @param array the array
+ * @param index the index
+ * @return the value of the indexed component in the specified array
+ * @exception NullPointerException If the specified object is null
+ * @exception IllegalArgumentException If the specified object is not
+ * an array, or if the indexed element cannot be converted to the
+ * return type by an identity or widening conversion
+ * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
+ * argument is negative, or if it is greater than or equal to the
+ * length of the specified array
+ * @see Array#get
+ */
+ // Android-changed: Non-native implementation of getLong(Object, int)
+ public static long getLong(Object array, int index)
+ throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
+ if (array instanceof long[]) {
+ return ((long[]) array)[index];
+ } else if (array instanceof byte[]) {
+ return ((byte[]) array)[index];
+ } else if (array instanceof char[]) {
+ return ((char[]) array)[index];
+ } else if (array instanceof int[]) {
+ return ((int[]) array)[index];
+ } else if (array instanceof short[]) {
+ return ((short[]) array)[index];
+ }
+ throw badArray(array);
+ }
+
+ /**
+ * Returns the value of the indexed component in the specified
+ * array object, as a {@code float}.
+ *
+ * @param array the array
+ * @param index the index
+ * @return the value of the indexed component in the specified array
+ * @exception NullPointerException If the specified object is null
+ * @exception IllegalArgumentException If the specified object is not
+ * an array, or if the indexed element cannot be converted to the
+ * return type by an identity or widening conversion
+ * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
+ * argument is negative, or if it is greater than or equal to the
+ * length of the specified array
+ * @see Array#get
+ */
+ // Android-changed: Non-native implementation of getFloat(Object, int)
+ public static float getFloat(Object array, int index)
+ throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
+ if (array instanceof float[]) {
+ return ((float[]) array)[index];
+ } else if (array instanceof byte[]) {
+ return ((byte[]) array)[index];
+ } else if (array instanceof char[]) {
+ return ((char[]) array)[index];
+ } else if (array instanceof int[]) {
+ return ((int[]) array)[index];
+ } else if (array instanceof long[]) {
+ return ((long[]) array)[index];
+ } else if (array instanceof short[]) {
+ return ((short[]) array)[index];
+ }
+ throw badArray(array);
+ }
+
+ /**
+ * Returns the value of the indexed component in the specified
+ * array object, as a {@code double}.
+ *
+ * @param array the array
+ * @param index the index
+ * @return the value of the indexed component in the specified array
+ * @exception NullPointerException If the specified object is null
+ * @exception IllegalArgumentException If the specified object is not
+ * an array, or if the indexed element cannot be converted to the
+ * return type by an identity or widening conversion
+ * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
+ * argument is negative, or if it is greater than or equal to the
+ * length of the specified array
+ * @see Array#get
+ */
+ // Android-changed: Non-native implementation of getDouble(Object, int)
+ public static double getDouble(Object array, int index)
+ throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
+ if (array instanceof double[]) {
+ return ((double[]) array)[index];
+ } else if (array instanceof byte[]) {
+ return ((byte[]) array)[index];
+ } else if (array instanceof char[]) {
+ return ((char[]) array)[index];
+ } else if (array instanceof float[]) {
+ return ((float[]) array)[index];
+ } else if (array instanceof int[]) {
+ return ((int[]) array)[index];
+ } else if (array instanceof long[]) {
+ return ((long[]) array)[index];
+ } else if (array instanceof short[]) {
+ return ((short[]) array)[index];
+ }
+ throw badArray(array);
+ }
+
+ /**
+ * Sets the value of the indexed component of the specified array
+ * object to the specified new value. The new value is first
+ * automatically unwrapped if the array has a primitive component
+ * type.
+ * @param array the array
+ * @param index the index into the array
+ * @param value the new value of the indexed component
+ * @exception NullPointerException If the specified object argument
+ * is null
+ * @exception IllegalArgumentException If the specified object argument
+ * is not an array, or if the array component type is primitive and
+ * an unwrapping conversion fails
+ * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
+ * argument is negative, or if it is greater than or equal to
+ * the length of the specified array
+ */
+ // Android-changed: Non-native implementation of set(Object, int, Object)
+ public static void set(Object array, int index, Object value)
+ throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
+ if (!array.getClass().isArray()) {
+ throw notAnArray(array);
+ }
+
+ if (array instanceof Object[]) {
+ if (value != null && !array.getClass().getComponentType().isInstance(value)) {
+ throw incompatibleType(array);
+ }
+ ((Object[]) array)[index] = value;
+ } else {
+ if (value == null) {
+ throw new IllegalArgumentException("Primitive array can't take null values.");
+ }
+ if (value instanceof Boolean) {
+ setBoolean(array, index, ((Boolean) value).booleanValue());
+ } else if (value instanceof Byte) {
+ setByte(array, index, ((Byte) value).byteValue());
+ } else if (value instanceof Character) {
+ setChar(array, index, ((Character) value).charValue());
+ } else if (value instanceof Short) {
+ setShort(array, index, ((Short) value).shortValue());
+ } else if (value instanceof Integer) {
+ setInt(array, index, ((Integer) value).intValue());
+ } else if (value instanceof Long) {
+ setLong(array, index, ((Long) value).longValue());
+ } else if (value instanceof Float) {
+ setFloat(array, index, ((Float) value).floatValue());
+ } else if (value instanceof Double) {
+ setDouble(array, index, ((Double) value).doubleValue());
+ }
+ }
+ }
+
+ /**
+ * Sets the value of the indexed component of the specified array
+ * object to the specified {@code boolean} value.
+ * @param array the array
+ * @param index the index into the array
+ * @param z the new value of the indexed component
+ * @exception NullPointerException If the specified object argument
+ * is null
+ * @exception IllegalArgumentException If the specified object argument
+ * is not an array, or if the specified value cannot be converted
+ * to the underlying array's component type by an identity or a
+ * primitive widening conversion
+ * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
+ * argument is negative, or if it is greater than or equal to
+ * the length of the specified array
+ * @see Array#set
+ */
+ // Android-changed: Non-native implementation of setBoolean(Object, int, boolean)
+ // Android-changed: Removal of explicit runtime exceptions throws clause
+ public static void setBoolean(Object array, int index, boolean z)
+ /* throws IllegalArgumentException, ArrayIndexOutOfBoundsException */ {
+ if (array instanceof boolean[]) {
+ ((boolean[]) array)[index] = z;
+ } else {
+ throw badArray(array);
+ }
+ }
+
+ /**
+ * Sets the value of the indexed component of the specified array
+ * object to the specified {@code byte} value.
+ * @param array the array
+ * @param index the index into the array
+ * @param b the new value of the indexed component
+ * @exception NullPointerException If the specified object argument
+ * is null
+ * @exception IllegalArgumentException If the specified object argument
+ * is not an array, or if the specified value cannot be converted
+ * to the underlying array's component type by an identity or a
+ * primitive widening conversion
+ * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
+ * argument is negative, or if it is greater than or equal to
+ * the length of the specified array
+ * @see Array#set
+ */
+ // Android-changed: Non-native implementation of setByte(Object, int, byte)
+ public static void setByte(Object array, int index, byte b)
+ throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
+ if (array instanceof byte[]) {
+ ((byte[]) array)[index] = b;
+ } else if (array instanceof double[]) {
+ ((double[]) array)[index] = b;
+ } else if (array instanceof float[]) {
+ ((float[]) array)[index] = b;
+ } else if (array instanceof int[]) {
+ ((int[]) array)[index] = b;
+ } else if (array instanceof long[]) {
+ ((long[]) array)[index] = b;
+ } else if (array instanceof short[]) {
+ ((short[]) array)[index] = b;
+ } else {
+ throw badArray(array);
+ }
+ }
+
+ /**
+ * Sets the value of the indexed component of the specified array
+ * object to the specified {@code char} value.
+ * @param array the array
+ * @param index the index into the array
+ * @param c the new value of the indexed component
+ * @exception NullPointerException If the specified object argument
+ * is null
+ * @exception IllegalArgumentException If the specified object argument
+ * is not an array, or if the specified value cannot be converted
+ * to the underlying array's component type by an identity or a
+ * primitive widening conversion
+ * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
+ * argument is negative, or if it is greater than or equal to
+ * the length of the specified array
+ * @see Array#set
+ */
+ // Android-changed: Non-native implementation of setChar(Object, int, char)
+ public static void setChar(Object array, int index, char c)
+ throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
+ if (array instanceof char[]) {
+ ((char[]) array)[index] = c;
+ } else if (array instanceof double[]) {
+ ((double[]) array)[index] = c;
+ } else if (array instanceof float[]) {
+ ((float[]) array)[index] = c;
+ } else if (array instanceof int[]) {
+ ((int[]) array)[index] = c;
+ } else if (array instanceof long[]) {
+ ((long[]) array)[index] = c;
+ } else {
+ throw badArray(array);
+ }
+ }
+
+ /**
+ * Sets the value of the indexed component of the specified array
+ * object to the specified {@code short} value.
+ * @param array the array
+ * @param index the index into the array
+ * @param s the new value of the indexed component
+ * @exception NullPointerException If the specified object argument
+ * is null
+ * @exception IllegalArgumentException If the specified object argument
+ * is not an array, or if the specified value cannot be converted
+ * to the underlying array's component type by an identity or a
+ * primitive widening conversion
+ * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
+ * argument is negative, or if it is greater than or equal to
+ * the length of the specified array
+ * @see Array#set
+ */
+ // Android-changed: Non-native implementation of setShort(Object, int, short)
+ public static void setShort(Object array, int index, short s)
+ throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
+ if (array instanceof short[]) {
+ ((short[]) array)[index] = s;
+ } else if (array instanceof double[]) {
+ ((double[]) array)[index] = s;
+ } else if (array instanceof float[]) {
+ ((float[]) array)[index] = s;
+ } else if (array instanceof int[]) {
+ ((int[]) array)[index] = s;
+ } else if (array instanceof long[]) {
+ ((long[]) array)[index] = s;
+ } else {
+ throw badArray(array);
+ }
+ }
+
+ /**
+ * Sets the value of the indexed component of the specified array
+ * object to the specified {@code int} value.
+ * @param array the array
+ * @param index the index into the array
+ * @param i the new value of the indexed component
+ * @exception NullPointerException If the specified object argument
+ * is null
+ * @exception IllegalArgumentException If the specified object argument
+ * is not an array, or if the specified value cannot be converted
+ * to the underlying array's component type by an identity or a
+ * primitive widening conversion
+ * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
+ * argument is negative, or if it is greater than or equal to
+ * the length of the specified array
+ * @see Array#set
+ */
+ // Android-changed: Non-native implementation of setInt(Object, int, int)
+ public static void setInt(Object array, int index, int i)
+ throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
+ if (array instanceof int[]) {
+ ((int[]) array)[index] = i;
+ } else if (array instanceof double[]) {
+ ((double[]) array)[index] = i;
+ } else if (array instanceof float[]) {
+ ((float[]) array)[index] = i;
+ } else if (array instanceof long[]) {
+ ((long[]) array)[index] = i;
+ } else {
+ throw badArray(array);
+ }
+ }
+
+ /**
+ * Sets the value of the indexed component of the specified array
+ * object to the specified {@code long} value.
+ * @param array the array
+ * @param index the index into the array
+ * @param l the new value of the indexed component
+ * @exception NullPointerException If the specified object argument
+ * is null
+ * @exception IllegalArgumentException If the specified object argument
+ * is not an array, or if the specified value cannot be converted
+ * to the underlying array's component type by an identity or a
+ * primitive widening conversion
+ * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
+ * argument is negative, or if it is greater than or equal to
+ * the length of the specified array
+ * @see Array#set
+ */
+ // Android-changed: Non-native implementation of setBoolean(Object, int, long)
+ public static void setLong(Object array, int index, long l)
+ throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
+ if (array instanceof long[]) {
+ ((long[]) array)[index] = l;
+ } else if (array instanceof double[]) {
+ ((double[]) array)[index] = l;
+ } else if (array instanceof float[]) {
+ ((float[]) array)[index] = l;
+ } else {
+ throw badArray(array);
+ }
+ }
+
+ /**
+ * Sets the value of the indexed component of the specified array
+ * object to the specified {@code float} value.
+ * @param array the array
+ * @param index the index into the array
+ * @param f the new value of the indexed component
+ * @exception NullPointerException If the specified object argument
+ * is null
+ * @exception IllegalArgumentException If the specified object argument
+ * is not an array, or if the specified value cannot be converted
+ * to the underlying array's component type by an identity or a
+ * primitive widening conversion
+ * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
+ * argument is negative, or if it is greater than or equal to
+ * the length of the specified array
+ * @see Array#set
+ */
+ public static void setFloat(Object array, int index, float f)
+ throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
+ if (array instanceof float[]) {
+ ((float[]) array)[index] = f;
+ } else if (array instanceof double[]) {
+ ((double[]) array)[index] = f;
+ } else {
+ throw badArray(array);
+ }
+ }
+
+ /**
+ * Sets the value of the indexed component of the specified array
+ * object to the specified {@code double} value.
+ * @param array the array
+ * @param index the index into the array
+ * @param d the new value of the indexed component
+ * @exception NullPointerException If the specified object argument
+ * is null
+ * @exception IllegalArgumentException If the specified object argument
+ * is not an array, or if the specified value cannot be converted
+ * to the underlying array's component type by an identity or a
+ * primitive widening conversion
+ * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
+ * argument is negative, or if it is greater than or equal to
+ * the length of the specified array
+ * @see Array#set
+ */
+ // Android-changed: Non-native implementation of setDouble(Object, int, double)
+ public static void setDouble(Object array, int index, double d)
+ throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
+ if (array instanceof double[]) {
+ ((double[]) array)[index] = d;
+ } else {
+ throw badArray(array);
+ }
+ }
+
+ /*
+ * Private
+ */
+
+ // Android-added: Added javadocs for newArray(Class, int)
+ /**
+ * Returns a new array of the specified component type and length.
+ * Equivalent to {@code new componentType[size]}.
+ *
+ * @throws NullPointerException
+ * if the component type is null
+ * @throws NegativeArraySizeException
+ * if {@code size < 0}
+ */
+ // Android-changed: Non-native implementation of newArray(Class, int)
+ private static Object newArray(Class<?> componentType, int length)
+ throws NegativeArraySizeException {
+ if (!componentType.isPrimitive()) {
+ return createObjectArray(componentType, length);
+ } else if (componentType == char.class) {
+ return new char[length];
+ } else if (componentType == int.class) {
+ return new int[length];
+ } else if (componentType == byte.class) {
+ return new byte[length];
+ } else if (componentType == boolean.class) {
+ return new boolean[length];
+ } else if (componentType == short.class) {
+ return new short[length];
+ } else if (componentType == long.class) {
+ return new long[length];
+ } else if (componentType == float.class) {
+ return new float[length];
+ } else if (componentType == double.class) {
+ return new double[length];
+ } else if (componentType == void.class) {
+ throw new IllegalArgumentException("Can't allocate an array of void");
+ }
+ throw new AssertionError();
+ }
+
+ // Android-removed: multiNewArray(Class, int[]) method. createMultiArray used instead.
+ /*
+ private static native Object multiNewArray(Class<?> componentType,
+ int[] dimensions)
+ throws IllegalArgumentException, NegativeArraySizeException;
+ */
+
+ // Android-added: createMultiArray(Class, int[]) method. Used instead of multiNewArray
+ /*
+ * Create a multi-dimensional array of objects with the specified type.
+ */
+ @FastNative
+ private static native Object createMultiArray(Class<?> componentType, int[] dimensions)
+ throws NegativeArraySizeException;
+
+ // BEGIN Android-added: Helper methods to support custom method implementations.
+ /*
+ * Create a one-dimensional array of objects with the specified type.
+ */
+ @FastNative
+ private static native Object createObjectArray(Class<?> componentType, int length)
+ throws NegativeArraySizeException;
+
+ private static IllegalArgumentException notAnArray(Object o) {
+ throw new IllegalArgumentException("Not an array: " + o.getClass());
+ }
+
+ private static IllegalArgumentException incompatibleType(Object o) {
+ throw new IllegalArgumentException("Array has incompatible type: " + o.getClass());
+ }
+
+ private static RuntimeException badArray(Object array) {
+ if (array == null) {
+ throw new NullPointerException("array == null");
+ } else if (!array.getClass().isArray()) {
+ throw notAnArray(array);
+ } else {
+ throw incompatibleType(array);
+ }
+ }
+ // END Android-added: Helper methods to support custom method implementations.
+}
diff --git a/java/lang/reflect/Constructor.annotated.java b/java/lang/reflect/Constructor.annotated.java
new file mode 100644
index 0000000..58bd810
--- /dev/null
+++ b/java/lang/reflect/Constructor.annotated.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1996, 2013, 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.reflect;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Constructor<T> extends java.lang.reflect.Executable {
+
+Constructor() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.Class<T> getDeclaringClass() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String getName() { throw new RuntimeException("Stub!"); }
+
+public int getModifiers() { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.TypeVariable<java.lang.reflect.Constructor<T>>[] getTypeParameters() { throw new RuntimeException("Stub!"); }
+
+public [email protected] Class<?> @libcore.util.NonNull [] getParameterTypes() { throw new RuntimeException("Stub!"); }
+
+public int getParameterCount() { throw new RuntimeException("Stub!"); }
+
+public java.lang.reflect.Type[] getGenericParameterTypes() { throw new RuntimeException("Stub!"); }
+
+public native java.lang.Class<?>[] getExceptionTypes();
+
+public java.lang.reflect.Type[] getGenericExceptionTypes() { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String toGenericString() { throw new RuntimeException("Stub!"); }
+
[email protected] public T newInstance(java.lang.Object... initargs) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException, java.lang.InstantiationException, java.lang.reflect.InvocationTargetException { throw new RuntimeException("Stub!"); }
+
+public boolean isVarArgs() { throw new RuntimeException("Stub!"); }
+
+public boolean isSynthetic() { throw new RuntimeException("Stub!"); }
+
[email protected] public <T extends java.lang.annotation.Annotation> T getAnnotation(@libcore.util.NonNull java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public java.lang.annotation.Annotation[] getDeclaredAnnotations() { throw new RuntimeException("Stub!"); }
+
+public java.lang.annotation.Annotation[][] getParameterAnnotations() { throw new RuntimeException("Stub!"); }
+}
diff --git a/java/lang/reflect/Constructor.java b/java/lang/reflect/Constructor.java
new file mode 100644
index 0000000..cf6b29f
--- /dev/null
+++ b/java/lang/reflect/Constructor.java
@@ -0,0 +1,403 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1996, 2013, 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.reflect;
+
+import dalvik.annotation.optimization.FastNative;
+import libcore.util.EmptyArray;
+
+import sun.reflect.CallerSensitive;
+import java.lang.annotation.Annotation;
+import java.util.Comparator;
+
+/**
+ * {@code Constructor} provides information about, and access to, a single
+ * constructor for a class.
+ *
+ * <p>{@code Constructor} permits widening conversions to occur when matching the
+ * actual parameters to newInstance() with the underlying
+ * constructor's formal parameters, but throws an
+ * {@code IllegalArgumentException} if a narrowing conversion would occur.
+ *
+ * @param <T> the class in which the constructor is declared
+ *
+ * @see Member
+ * @see java.lang.Class
+ * @see java.lang.Class#getConstructors()
+ * @see java.lang.Class#getConstructor(Class[])
+ * @see java.lang.Class#getDeclaredConstructors()
+ *
+ * @author Kenneth Russell
+ * @author Nakul Saraiya
+ */
+public final class Constructor<T> extends Executable {
+ // Android-changed: Extensive modifications made throughout the class for ART.
+ // Android-changed: Many fields and methods removed / modified.
+ // Android-removed: Type annotations runtime code. Not supported on Android.
+ // Android-removed: Declared vs actual parameter annotation indexes handling.
+
+ private static final Comparator<Method> ORDER_BY_SIGNATURE = null; // Unused; must match Method.
+
+ private final Class<?> serializationClass;
+ private final Class<?> serializationCtor;
+
+ private Constructor() {
+ this(null, null);
+ }
+
+ private Constructor(Class<?> serializationCtor,
+ Class<?> serializationClass) {
+ this.serializationCtor = serializationCtor;
+ this.serializationClass = serializationClass;
+ }
+
+ /**
+ * @hide
+ */
+ public Constructor<T> serializationCopy(Class<?> ctor, Class<?> cl) {
+ return new Constructor<T>(ctor, cl);
+ }
+
+ @Override
+ boolean hasGenericInformation() {
+ // Android-changed: hasGenericInformation() implemented using Executable.
+ return super.hasGenericInformationInternal();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ // Android-changed: getDeclaringClass() implemented using Executable.
+ @SuppressWarnings({"rawtypes", "unchecked"})
+ public Class<T> getDeclaringClass() {
+ return (Class<T>) super.getDeclaringClassInternal();
+ }
+
+ /**
+ * Returns the name of this constructor, as a string. This is
+ * the binary name of the constructor's declaring class.
+ */
+ @Override
+ public String getName() {
+ return getDeclaringClass().getName();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int getModifiers() {
+ // Android-changed: getModifiers() implemented using Executable.
+ return super.getModifiersInternal();
+ }
+
+ /**
+ * {@inheritDoc}
+ * @throws GenericSignatureFormatError {@inheritDoc}
+ * @since 1.5
+ */
+ @Override
+ @SuppressWarnings({"rawtypes", "unchecked"})
+ public TypeVariable<Constructor<T>>[] getTypeParameters() {
+ // Android-changed: getTypeParameters() partly implemented using Executable.
+ GenericInfo info = getMethodOrConstructorGenericInfoInternal();
+ return (TypeVariable<Constructor<T>>[]) info.formalTypeParameters.clone();
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Class<?>[] getParameterTypes() {
+ // Android-changed: getParameterTypes() partly implemented using Executable.
+ Class<?>[] paramTypes = super.getParameterTypesInternal();
+ if (paramTypes == null) {
+ return EmptyArray.CLASS;
+ }
+
+ return paramTypes;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @since 1.8
+ */
+ public int getParameterCount() {
+ // Android-changed: getParameterCount() implemented using Executable.
+ return super.getParameterCountInternal();
+ }
+
+ /**
+ * {@inheritDoc}
+ * @throws GenericSignatureFormatError {@inheritDoc}
+ * @throws TypeNotPresentException {@inheritDoc}
+ * @throws MalformedParameterizedTypeException {@inheritDoc}
+ * @since 1.5
+ */
+ @Override
+ public Type[] getGenericParameterTypes() {
+ return super.getGenericParameterTypes();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ // Android-changed: getExceptionTypes() implemented in native code.
+ @FastNative
+ public native Class<?>[] getExceptionTypes();
+
+ /**
+ * {@inheritDoc}
+ * @throws GenericSignatureFormatError {@inheritDoc}
+ * @throws TypeNotPresentException {@inheritDoc}
+ * @throws MalformedParameterizedTypeException {@inheritDoc}
+ * @since 1.5
+ */
+ @Override
+ public Type[] getGenericExceptionTypes() {
+ return super.getGenericExceptionTypes();
+ }
+
+ /**
+ * Compares this {@code Constructor} against the specified object.
+ * Returns true if the objects are the same. Two {@code Constructor} objects are
+ * the same if they were declared by the same class and have the
+ * same formal parameter types.
+ */
+ public boolean equals(Object obj) {
+ if (obj != null && obj instanceof Constructor) {
+ Constructor<?> other = (Constructor<?>)obj;
+ if (getDeclaringClass() == other.getDeclaringClass()) {
+ // Android-changed: Use getParameterTypes() instead of deleted parameterTypes field
+ return equalParamTypes(getParameterTypes(), other.getParameterTypes());
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns a hashcode for this {@code Constructor}. The hashcode is
+ * the same as the hashcode for the underlying constructor's
+ * declaring class name.
+ */
+ public int hashCode() {
+ return getDeclaringClass().getName().hashCode();
+ }
+
+ /**
+ * Returns a string describing this {@code Constructor}. The string is
+ * formatted as the constructor access modifiers, if any,
+ * followed by the fully-qualified name of the declaring class,
+ * followed by a parenthesized, comma-separated list of the
+ * constructor's formal parameter types. For example:
+ * <pre>
+ * public java.util.Hashtable(int,float)
+ * </pre>
+ *
+ * <p>The only possible modifiers for constructors are the access
+ * modifiers {@code public}, {@code protected} or
+ * {@code private}. Only one of these may appear, or none if the
+ * constructor has default (package) access.
+ *
+ * @return a string describing this {@code Constructor}
+ * @jls 8.8.3. Constructor Modifiers
+ */
+ public String toString() {
+ // Android-changed: Use getParameterTypes() / getExceptionTypes() instead of deleted fields
+ return sharedToString(Modifier.constructorModifiers(),
+ false,
+ getParameterTypes(),
+ getExceptionTypes());
+ }
+
+ @Override
+ void specificToStringHeader(StringBuilder sb) {
+ sb.append(getDeclaringClass().getTypeName());
+ }
+
+ /**
+ * Returns a string describing this {@code Constructor},
+ * including type parameters. The string is formatted as the
+ * constructor access modifiers, if any, followed by an
+ * angle-bracketed comma separated list of the constructor's type
+ * parameters, if any, followed by the fully-qualified name of the
+ * declaring class, followed by a parenthesized, comma-separated
+ * list of the constructor's generic formal parameter types.
+ *
+ * If this constructor was declared to take a variable number of
+ * arguments, instead of denoting the last parameter as
+ * "<tt><i>Type</i>[]</tt>", it is denoted as
+ * "<tt><i>Type</i>...</tt>".
+ *
+ * A space is used to separate access modifiers from one another
+ * and from the type parameters or return type. If there are no
+ * type parameters, the type parameter list is elided; if the type
+ * parameter list is present, a space separates the list from the
+ * class name. If the constructor is declared to throw
+ * exceptions, the parameter list is followed by a space, followed
+ * by the word "{@code throws}" followed by a
+ * comma-separated list of the thrown exception types.
+ *
+ * <p>The only possible modifiers for constructors are the access
+ * modifiers {@code public}, {@code protected} or
+ * {@code private}. Only one of these may appear, or none if the
+ * constructor has default (package) access.
+ *
+ * @return a string describing this {@code Constructor},
+ * include type parameters
+ *
+ * @since 1.5
+ * @jls 8.8.3. Constructor Modifiers
+ */
+ @Override
+ public String toGenericString() {
+ return sharedToGenericString(Modifier.constructorModifiers(), false);
+ }
+
+ @Override
+ void specificToGenericStringHeader(StringBuilder sb) {
+ specificToStringHeader(sb);
+ }
+
+ /**
+ * Uses the constructor represented by this {@code Constructor} object to
+ * create and initialize a new instance of the constructor's
+ * declaring class, with the specified initialization parameters.
+ * Individual parameters are automatically unwrapped to match
+ * primitive formal parameters, and both primitive and reference
+ * parameters are subject to method invocation conversions as necessary.
+ *
+ * <p>If the number of formal parameters required by the underlying constructor
+ * is 0, the supplied {@code initargs} array may be of length 0 or null.
+ *
+ * <p>If the constructor's declaring class is an inner class in a
+ * non-static context, the first argument to the constructor needs
+ * to be the enclosing instance; see section 15.9.3 of
+ * <cite>The Java™ Language Specification</cite>.
+ *
+ * <p>If the required access and argument checks succeed and the
+ * instantiation will proceed, the constructor's declaring class
+ * is initialized if it has not already been initialized.
+ *
+ * <p>If the constructor completes normally, returns the newly
+ * created and initialized instance.
+ *
+ * @param initargs array of objects to be passed as arguments to
+ * the constructor call; values of primitive types are wrapped in
+ * a wrapper object of the appropriate type (e.g. a {@code float}
+ * in a {@link java.lang.Float Float})
+ *
+ * @return a new object created by calling the constructor
+ * this object represents
+ *
+ * @exception IllegalAccessException if this {@code Constructor} object
+ * is enforcing Java language access control and the underlying
+ * constructor is inaccessible.
+ * @exception IllegalArgumentException if the number of actual
+ * and formal parameters differ; if an unwrapping
+ * conversion for primitive arguments fails; or if,
+ * after possible unwrapping, a parameter value
+ * cannot be converted to the corresponding formal
+ * parameter type by a method invocation conversion; if
+ * this constructor pertains to an enum type.
+ * @exception InstantiationException if the class that declares the
+ * underlying constructor represents an abstract class.
+ * @exception InvocationTargetException if the underlying constructor
+ * throws an exception.
+ * @exception ExceptionInInitializerError if the initialization provoked
+ * by this method fails.
+ */
+ // BEGIN Android-changed: newInstance(Object...) implemented differently.
+ @CallerSensitive
+ public T newInstance(Object ... initargs)
+ throws InstantiationException, IllegalAccessException,
+ IllegalArgumentException, InvocationTargetException
+ {
+ if (serializationClass == null) {
+ return newInstance0(initargs);
+ } else {
+ return (T) newInstanceFromSerialization(serializationCtor, serializationClass);
+ }
+ }
+
+ @FastNative
+ private static native Object newInstanceFromSerialization(Class<?> ctorClass, Class<?> allocClass)
+ throws InstantiationException, IllegalArgumentException, InvocationTargetException;
+
+ @FastNative
+ private native T newInstance0(Object... args) throws InstantiationException,
+ IllegalAccessException, IllegalArgumentException, InvocationTargetException;
+ // END Android-changed: newInstance(Object...) implemented differently.
+
+ /**
+ * {@inheritDoc}
+ * @since 1.5
+ */
+ @Override
+ public boolean isVarArgs() {
+ return super.isVarArgs();
+ }
+
+ /**
+ * {@inheritDoc}
+ * @jls 13.1 The Form of a Binary
+ * @since 1.5
+ */
+ @Override
+ public boolean isSynthetic() {
+ return super.isSynthetic();
+ }
+
+ /**
+ * {@inheritDoc}
+ * @throws NullPointerException {@inheritDoc}
+ * @since 1.5
+ */
+ public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
+ return super.getAnnotation(annotationClass);
+ }
+
+ /**
+ * {@inheritDoc}
+ * @since 1.5
+ */
+ public Annotation[] getDeclaredAnnotations() {
+ return super.getDeclaredAnnotations();
+ }
+
+ /**
+ * {@inheritDoc}
+ * @since 1.5
+ */
+ @Override
+ public Annotation[][] getParameterAnnotations() {
+ // Android-changed: getParameterAnnotations() implemented using Executable.
+ return super.getParameterAnnotationsInternal();
+ }
+}
diff --git a/java/lang/reflect/Executable.annotated.java b/java/lang/reflect/Executable.annotated.java
new file mode 100644
index 0000000..d964aad
--- /dev/null
+++ b/java/lang/reflect/Executable.annotated.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2012, 2013, 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.reflect;
+
+import java.lang.annotation.Annotation;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class Executable extends java.lang.reflect.AccessibleObject implements java.lang.reflect.Member, java.lang.reflect.GenericDeclaration {
+
+Executable() { throw new RuntimeException("Stub!"); }
+
[email protected] public abstract java.lang.Class<?> getDeclaringClass();
+
[email protected] public abstract java.lang.String getName();
+
+public abstract int getModifiers();
+
+public abstract [email protected] TypeVariable<?> @libcore.util.NonNull [] getTypeParameters();
+
+public abstract [email protected] Class<?> @libcore.util.NonNull [] getParameterTypes();
+
+public int getParameterCount() { throw new RuntimeException("Stub!"); }
+
+public [email protected] Type @libcore.util.NonNull [] getGenericParameterTypes() { throw new RuntimeException("Stub!"); }
+
+public [email protected] Parameter @libcore.util.NonNull [] getParameters() { throw new RuntimeException("Stub!"); }
+
+public abstract [email protected] Class<?> @libcore.util.NonNull [] getExceptionTypes();
+
+public [email protected] Type @libcore.util.NonNull [] getGenericExceptionTypes() { throw new RuntimeException("Stub!"); }
+
[email protected] public abstract java.lang.String toGenericString();
+
+public boolean isVarArgs() { throw new RuntimeException("Stub!"); }
+
+public boolean isSynthetic() { throw new RuntimeException("Stub!"); }
+
+public abstract [email protected] Annotation @libcore.util.NonNull [] @libcore.util.NonNull [] getParameterAnnotations();
+
[email protected] public <T extends java.lang.annotation.Annotation> T getAnnotation(@libcore.util.NonNull java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public <T extends java.lang.annotation.Annotation> T[] getAnnotationsByType(@libcore.util.NonNull java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public [email protected] Annotation @libcore.util.NonNull [] getDeclaredAnnotations() { throw new RuntimeException("Stub!"); }
+
+public final boolean isAnnotationPresent(@libcore.util.NonNull java.lang.Class<? extends java.lang.annotation.Annotation> annotationType) { throw new RuntimeException("Stub!"); }
+}
diff --git a/java/lang/reflect/Executable.java b/java/lang/reflect/Executable.java
new file mode 100644
index 0000000..6782d00
--- /dev/null
+++ b/java/lang/reflect/Executable.java
@@ -0,0 +1,750 @@
+/*
+ * Copyright (c) 2012, 2013, 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.reflect;
+
+import dalvik.annotation.optimization.FastNative;
+
+import java.lang.annotation.Annotation;
+import java.util.Objects;
+import libcore.reflect.AnnotatedElements;
+import libcore.reflect.GenericSignatureParser;
+import libcore.reflect.ListOfTypes;
+import libcore.reflect.Types;
+import libcore.util.EmptyArray;
+
+/**
+ * A shared superclass for the common functionality of {@link Method}
+ * and {@link Constructor}.
+ *
+ * @since 1.8
+ */
+public abstract class Executable extends AccessibleObject
+ implements Member, GenericDeclaration {
+
+ // Android-changed: Extensive modifications made throughout the class for ART.
+ // Android-removed: Declared vs actual parameter annotation indexes handling.
+ // Android-removed: Type annotations runtime code. Not supported on Android.
+
+ /*
+ * Only grant package-visibility to the constructor.
+ */
+ Executable() {}
+
+ /**
+ * Does the Executable have generic information.
+ */
+ abstract boolean hasGenericInformation();
+
+ boolean equalParamTypes(Class<?>[] params1, Class<?>[] params2) {
+ /* Avoid unnecessary cloning */
+ if (params1.length == params2.length) {
+ for (int i = 0; i < params1.length; i++) {
+ if (params1[i] != params2[i])
+ return false;
+ }
+ return true;
+ }
+ return false;
+ }
+
+ void separateWithCommas(Class<?>[] types, StringBuilder sb) {
+ for (int j = 0; j < types.length; j++) {
+ sb.append(types[j].getTypeName());
+ if (j < (types.length - 1))
+ sb.append(",");
+ }
+
+ }
+
+ void printModifiersIfNonzero(StringBuilder sb, int mask, boolean isDefault) {
+ int mod = getModifiers() & mask;
+
+ if (mod != 0 && !isDefault) {
+ sb.append(Modifier.toString(mod)).append(' ');
+ } else {
+ int access_mod = mod & Modifier.ACCESS_MODIFIERS;
+ if (access_mod != 0)
+ sb.append(Modifier.toString(access_mod)).append(' ');
+ if (isDefault)
+ sb.append("default ");
+ mod = (mod & ~Modifier.ACCESS_MODIFIERS);
+ if (mod != 0)
+ sb.append(Modifier.toString(mod)).append(' ');
+ }
+ }
+
+ String sharedToString(int modifierMask,
+ boolean isDefault,
+ Class<?>[] parameterTypes,
+ Class<?>[] exceptionTypes) {
+ try {
+ StringBuilder sb = new StringBuilder();
+
+ printModifiersIfNonzero(sb, modifierMask, isDefault);
+ specificToStringHeader(sb);
+
+ sb.append('(');
+ separateWithCommas(parameterTypes, sb);
+ sb.append(')');
+ if (exceptionTypes.length > 0) {
+ sb.append(" throws ");
+ separateWithCommas(exceptionTypes, sb);
+ }
+ return sb.toString();
+ } catch (Exception e) {
+ return "<" + e + ">";
+ }
+ }
+
+ /**
+ * Generate toString header information specific to a method or
+ * constructor.
+ */
+ abstract void specificToStringHeader(StringBuilder sb);
+
+ String sharedToGenericString(int modifierMask, boolean isDefault) {
+ try {
+ StringBuilder sb = new StringBuilder();
+
+ printModifiersIfNonzero(sb, modifierMask, isDefault);
+
+ TypeVariable<?>[] typeparms = getTypeParameters();
+ if (typeparms.length > 0) {
+ boolean first = true;
+ sb.append('<');
+ for(TypeVariable<?> typeparm: typeparms) {
+ if (!first)
+ sb.append(',');
+ // Class objects can't occur here; no need to test
+ // and call Class.getName().
+ sb.append(typeparm.toString());
+ first = false;
+ }
+ sb.append("> ");
+ }
+
+ specificToGenericStringHeader(sb);
+
+ sb.append('(');
+ Type[] params = getGenericParameterTypes();
+ for (int j = 0; j < params.length; j++) {
+ String param = params[j].getTypeName();
+ if (isVarArgs() && (j == params.length - 1)) // replace T[] with T...
+ param = param.replaceFirst("\\[\\]$", "...");
+ sb.append(param);
+ if (j < (params.length - 1))
+ sb.append(',');
+ }
+ sb.append(')');
+ Type[] exceptions = getGenericExceptionTypes();
+ if (exceptions.length > 0) {
+ sb.append(" throws ");
+ for (int k = 0; k < exceptions.length; k++) {
+ sb.append((exceptions[k] instanceof Class)?
+ ((Class)exceptions[k]).getName():
+ exceptions[k].toString());
+ if (k < (exceptions.length - 1))
+ sb.append(',');
+ }
+ }
+ return sb.toString();
+ } catch (Exception e) {
+ return "<" + e + ">";
+ }
+ }
+
+ /**
+ * Generate toGenericString header information specific to a
+ * method or constructor.
+ */
+ abstract void specificToGenericStringHeader(StringBuilder sb);
+
+ /**
+ * Returns the {@code Class} object representing the class or interface
+ * that declares the executable represented by this object.
+ */
+ public abstract Class<?> getDeclaringClass();
+
+ /**
+ * Returns the name of the executable represented by this object.
+ */
+ public abstract String getName();
+
+ /**
+ * Returns the Java language {@linkplain Modifier modifiers} for
+ * the executable represented by this object.
+ */
+ public abstract int getModifiers();
+
+ /**
+ * Returns an array of {@code TypeVariable} objects that represent the
+ * type variables declared by the generic declaration represented by this
+ * {@code GenericDeclaration} object, in declaration order. Returns an
+ * array of length 0 if the underlying generic declaration declares no type
+ * variables.
+ *
+ * @return an array of {@code TypeVariable} objects that represent
+ * the type variables declared by this generic declaration
+ * @throws GenericSignatureFormatError if the generic
+ * signature of this generic declaration does not conform to
+ * the format specified in
+ * <cite>The Java™ Virtual Machine Specification</cite>
+ */
+ public abstract TypeVariable<?>[] getTypeParameters();
+
+ /**
+ * Returns an array of {@code Class} objects that represent the formal
+ * parameter types, in declaration order, of the executable
+ * represented by this object. Returns an array of length
+ * 0 if the underlying executable takes no parameters.
+ *
+ * @return the parameter types for the executable this object
+ * represents
+ */
+ public abstract Class<?>[] getParameterTypes();
+
+ /**
+ * Returns the number of formal parameters (whether explicitly
+ * declared or implicitly declared or neither) for the executable
+ * represented by this object.
+ *
+ * @return The number of formal parameters for the executable this
+ * object represents
+ */
+ public int getParameterCount() {
+ throw new AbstractMethodError();
+ }
+
+ /**
+ * Returns an array of {@code Type} objects that represent the formal
+ * parameter types, in declaration order, of the executable represented by
+ * this object. Returns an array of length 0 if the
+ * underlying executable takes no parameters.
+ *
+ * <p>If a formal parameter type is a parameterized type,
+ * the {@code Type} object returned for it must accurately reflect
+ * the actual type parameters used in the source code.
+ *
+ * <p>If a formal parameter type is a type variable or a parameterized
+ * type, it is created. Otherwise, it is resolved.
+ *
+ * @return an array of {@code Type}s that represent the formal
+ * parameter types of the underlying executable, in declaration order
+ * @throws GenericSignatureFormatError
+ * if the generic method signature does not conform to the format
+ * specified in
+ * <cite>The Java™ Virtual Machine Specification</cite>
+ * @throws TypeNotPresentException if any of the parameter
+ * types of the underlying executable refers to a non-existent type
+ * declaration
+ * @throws MalformedParameterizedTypeException if any of
+ * the underlying executable's parameter types refer to a parameterized
+ * type that cannot be instantiated for any reason
+ */
+ public Type[] getGenericParameterTypes() {
+ // Android-changed: getGenericParameterTypes() implementation for use with ART.
+ return Types.getTypeArray(
+ getMethodOrConstructorGenericInfoInternal().genericParameterTypes, false);
+ }
+
+ /**
+ * Behaves like {@code getGenericParameterTypes}, but returns type
+ * information for all parameters, including synthetic parameters.
+ */
+ Type[] getAllGenericParameterTypes() {
+ final boolean genericInfo = hasGenericInformation();
+
+ // Easy case: we don't have generic parameter information. In
+ // this case, we just return the result of
+ // getParameterTypes().
+ if (!genericInfo) {
+ return getParameterTypes();
+ } else {
+ final boolean realParamData = hasRealParameterData();
+ final Type[] genericParamTypes = getGenericParameterTypes();
+ final Type[] nonGenericParamTypes = getParameterTypes();
+ final Type[] out = new Type[nonGenericParamTypes.length];
+ final Parameter[] params = getParameters();
+ int fromidx = 0;
+ // If we have real parameter data, then we use the
+ // synthetic and mandate flags to our advantage.
+ if (realParamData) {
+ for (int i = 0; i < out.length; i++) {
+ final Parameter param = params[i];
+ if (param.isSynthetic() || param.isImplicit()) {
+ // If we hit a synthetic or mandated parameter,
+ // use the non generic parameter info.
+ out[i] = nonGenericParamTypes[i];
+ } else {
+ // Otherwise, use the generic parameter info.
+ out[i] = genericParamTypes[fromidx];
+ fromidx++;
+ }
+ }
+ } else {
+ // Otherwise, use the non-generic parameter data.
+ // Without method parameter reflection data, we have
+ // no way to figure out which parameters are
+ // synthetic/mandated, thus, no way to match up the
+ // indexes.
+ return genericParamTypes.length == nonGenericParamTypes.length ?
+ genericParamTypes : nonGenericParamTypes;
+ }
+ return out;
+ }
+ }
+
+ /**
+ * Returns an array of {@code Parameter} objects that represent
+ * all the parameters to the underlying executable represented by
+ * this object. Returns an array of length 0 if the executable
+ * has no parameters.
+ *
+ * <p>The parameters of the underlying executable do not necessarily
+ * have unique names, or names that are legal identifiers in the
+ * Java programming language (JLS 3.8).
+ *
+ * @throws MalformedParametersException if the class file contains
+ * a MethodParameters attribute that is improperly formatted.
+ * @return an array of {@code Parameter} objects representing all
+ * the parameters to the executable this object represents.
+ */
+ public Parameter[] getParameters() {
+ // TODO: This may eventually need to be guarded by security
+ // mechanisms similar to those in Field, Method, etc.
+ //
+ // Need to copy the cached array to prevent users from messing
+ // with it. Since parameters are immutable, we can
+ // shallow-copy.
+ return privateGetParameters().clone();
+ }
+
+ private Parameter[] synthesizeAllParams() {
+ final int realparams = getParameterCount();
+ final Parameter[] out = new Parameter[realparams];
+ for (int i = 0; i < realparams; i++)
+ // TODO: is there a way to synthetically derive the
+ // modifiers? Probably not in the general case, since
+ // we'd have no way of knowing about them, but there
+ // may be specific cases.
+ out[i] = new Parameter("arg" + i, 0, this, i);
+ return out;
+ }
+
+ private void verifyParameters(final Parameter[] parameters) {
+ final int mask = Modifier.FINAL | Modifier.SYNTHETIC | Modifier.MANDATED;
+
+ if (getParameterTypes().length != parameters.length)
+ throw new MalformedParametersException("Wrong number of parameters in MethodParameters attribute");
+
+ for (Parameter parameter : parameters) {
+ final String name = parameter.getRealName();
+ final int mods = parameter.getModifiers();
+
+ if (name != null) {
+ if (name.isEmpty() || name.indexOf('.') != -1 ||
+ name.indexOf(';') != -1 || name.indexOf('[') != -1 ||
+ name.indexOf('/') != -1) {
+ throw new MalformedParametersException("Invalid parameter name \"" + name + "\"");
+ }
+ }
+
+ if (mods != (mods & mask)) {
+ throw new MalformedParametersException("Invalid parameter modifiers");
+ }
+ }
+ }
+
+ private Parameter[] privateGetParameters() {
+ // Use tmp to avoid multiple writes to a volatile.
+ Parameter[] tmp = parameters;
+
+ if (tmp == null) {
+
+ // Otherwise, go to the JVM to get them
+ try {
+ tmp = getParameters0();
+ } catch(IllegalArgumentException e) {
+ // Rethrow ClassFormatErrors
+ // Android-changed: Exception changed to be more descriptive.
+ MalformedParametersException e2 =
+ new MalformedParametersException(
+ "Invalid parameter metadata in class file");
+ e2.initCause(e);
+ throw e2;
+ }
+
+ // If we get back nothing, then synthesize parameters
+ if (tmp == null) {
+ hasRealParameterData = false;
+ tmp = synthesizeAllParams();
+ } else {
+ hasRealParameterData = true;
+ verifyParameters(tmp);
+ }
+
+ parameters = tmp;
+ }
+
+ return tmp;
+ }
+
+ boolean hasRealParameterData() {
+ // If this somehow gets called before parameters gets
+ // initialized, force it into existence.
+ if (parameters == null) {
+ privateGetParameters();
+ }
+ return hasRealParameterData;
+ }
+
+ private transient volatile boolean hasRealParameterData;
+ private transient volatile Parameter[] parameters;
+
+ // Android-changed: Added @FastNative to getParameters0()
+ @FastNative
+ private native Parameter[] getParameters0();
+
+ /**
+ * Returns an array of {@code Class} objects that represent the
+ * types of exceptions declared to be thrown by the underlying
+ * executable represented by this object. Returns an array of
+ * length 0 if the executable declares no exceptions in its {@code
+ * throws} clause.
+ *
+ * @return the exception types declared as being thrown by the
+ * executable this object represents
+ */
+ public abstract Class<?>[] getExceptionTypes();
+
+ /**
+ * Returns an array of {@code Type} objects that represent the
+ * exceptions declared to be thrown by this executable object.
+ * Returns an array of length 0 if the underlying executable declares
+ * no exceptions in its {@code throws} clause.
+ *
+ * <p>If an exception type is a type variable or a parameterized
+ * type, it is created. Otherwise, it is resolved.
+ *
+ * @return an array of Types that represent the exception types
+ * thrown by the underlying executable
+ * @throws GenericSignatureFormatError
+ * if the generic method signature does not conform to the format
+ * specified in
+ * <cite>The Java™ Virtual Machine Specification</cite>
+ * @throws TypeNotPresentException if the underlying executable's
+ * {@code throws} clause refers to a non-existent type declaration
+ * @throws MalformedParameterizedTypeException if
+ * the underlying executable's {@code throws} clause refers to a
+ * parameterized type that cannot be instantiated for any reason
+ */
+ public Type[] getGenericExceptionTypes() {
+ // Android-changed: getGenericExceptionTypes() implementation for use with ART.
+ return Types.getTypeArray(
+ getMethodOrConstructorGenericInfoInternal().genericExceptionTypes, false);
+ }
+
+ /**
+ * Returns a string describing this {@code Executable}, including
+ * any type parameters.
+ * @return a string describing this {@code Executable}, including
+ * any type parameters
+ */
+ public abstract String toGenericString();
+
+ /**
+ * Returns {@code true} if this executable was declared to take a
+ * variable number of arguments; returns {@code false} otherwise.
+ *
+ * @return {@code true} if an only if this executable was declared
+ * to take a variable number of arguments.
+ */
+ public boolean isVarArgs() {
+ // Android-changed: isVarArgs() made slightly more efficient.
+ return (accessFlags & Modifier.VARARGS) != 0;
+ }
+
+ /**
+ * Returns {@code true} if this executable is a synthetic
+ * construct; returns {@code false} otherwise.
+ *
+ * @return true if and only if this executable is a synthetic
+ * construct as defined by
+ * <cite>The Java™ Language Specification</cite>.
+ * @jls 13.1 The Form of a Binary
+ */
+ public boolean isSynthetic() {
+ // Android-changed: isSynthetic() made slightly more efficient.
+ return (accessFlags & Modifier.SYNTHETIC) != 0;
+ }
+
+ /**
+ * Returns an array of arrays of {@code Annotation}s that
+ * represent the annotations on the formal parameters, in
+ * declaration order, of the {@code Executable} represented by
+ * this object. Synthetic and mandated parameters (see
+ * explanation below), such as the outer "this" parameter to an
+ * inner class constructor will be represented in the returned
+ * array. If the executable has no parameters (meaning no formal,
+ * no synthetic, and no mandated parameters), a zero-length array
+ * will be returned. If the {@code Executable} has one or more
+ * parameters, a nested array of length zero is returned for each
+ * parameter with no annotations. The annotation objects contained
+ * in the returned arrays are serializable. The caller of this
+ * method is free to modify the returned arrays; it will have no
+ * effect on the arrays returned to other callers.
+ *
+ * A compiler may add extra parameters that are implicitly
+ * declared in source ("mandated"), as well as parameters that
+ * are neither implicitly nor explicitly declared in source
+ * ("synthetic") to the parameter list for a method. See {@link
+ * java.lang.reflect.Parameter} for more information.
+ *
+ * @see java.lang.reflect.Parameter
+ * @see java.lang.reflect.Parameter#getAnnotations
+ * @return an array of arrays that represent the annotations on
+ * the formal and implicit parameters, in declaration order, of
+ * the executable represented by this object
+ */
+ public abstract Annotation[][] getParameterAnnotations();
+
+ /**
+ * {@inheritDoc}
+ * @throws NullPointerException {@inheritDoc}
+ */
+ public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
+ Objects.requireNonNull(annotationClass);
+ // Android-changed: Implemented getAnnotation(Class) natively.
+ return getAnnotationNative(annotationClass);
+ }
+
+ // Android-changed: Implemented getAnnotation(Class) natively.
+ @FastNative
+ private native <T extends Annotation> T getAnnotationNative(Class<T> annotationClass);
+
+ /**
+ * {@inheritDoc}
+ * @throws NullPointerException {@inheritDoc}
+ */
+ @Override
+ public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) {
+ // Android-changed: getAnnotationsByType(Class), Android uses AnnotatedElements instead.
+ return AnnotatedElements.getDirectOrIndirectAnnotationsByType(this, annotationClass);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Annotation[] getDeclaredAnnotations() {
+ // Android-changed: Implemented getDeclaredAnnotations() natively.
+ return getDeclaredAnnotationsNative();
+ }
+
+ // Android-added: Implemented getDeclaredAnnotations() natively.
+ @FastNative
+ private native Annotation[] getDeclaredAnnotationsNative();
+
+ // BEGIN Android-added: Additional ART-related fields and logic.
+ // This code is shared for Method and Constructor.
+
+ /** Bits encoding access (e.g. public, private) as well as other runtime specific flags */
+ @SuppressWarnings("unused") // set by runtime
+ private int accessFlags;
+
+ /**
+ * The ArtMethod associated with this Executable, required for dispatching due to entrypoints
+ * Classloader is held live by the declaring class.
+ */
+ @SuppressWarnings("unused") // set by runtime
+ private long artMethod;
+
+ /** Executable's declaring class */
+ @SuppressWarnings("unused") // set by runtime
+ private Class<?> declaringClass;
+
+ /**
+ * Overriden method's declaring class (same as declaringClass unless declaringClass is a proxy
+ * class).
+ */
+ @SuppressWarnings("unused") // set by runtime
+ private Class<?> declaringClassOfOverriddenMethod;
+
+ /** The method index of this method within its defining dex file */
+ @SuppressWarnings("unused") // set by runtime
+ private int dexMethodIndex;
+
+ /**
+ * We insert native method stubs for abstract methods so we don't have to
+ * check the access flags at the time of the method call. This results in
+ * "native abstract" methods, which can't exist. If we see the "abstract"
+ * flag set, clear the "native" flag.
+ *
+ * We also move the DECLARED_SYNCHRONIZED flag into the SYNCHRONIZED
+ * position, because the callers of this function are trying to convey
+ * the "traditional" meaning of the flags to their callers.
+ */
+ private static int fixMethodFlags(int flags) {
+ if ((flags & Modifier.ABSTRACT) != 0) {
+ flags &= ~Modifier.NATIVE;
+ }
+ flags &= ~Modifier.SYNCHRONIZED;
+ int ACC_DECLARED_SYNCHRONIZED = 0x00020000;
+ if ((flags & ACC_DECLARED_SYNCHRONIZED) != 0) {
+ flags |= Modifier.SYNCHRONIZED;
+ }
+ return flags & 0xffff; // mask out bits not used by Java
+ }
+
+ final int getModifiersInternal() {
+ return fixMethodFlags(accessFlags);
+ }
+
+ final Class<?> getDeclaringClassInternal() {
+ return declaringClass;
+ }
+
+ /**
+ * Returns an array of {@code Class} objects associated with the parameter types of this
+ * Executable. If the Executable was declared with no parameters, {@code null} will be
+ * returned.
+ *
+ * @return the parameter types, or {@code null} if no parameters were declared.
+ */
+ @FastNative
+ final native Class<?>[] getParameterTypesInternal();
+
+ @FastNative
+ final native int getParameterCountInternal();
+
+ // Android provides a more efficient implementation of this method for Executable than the one
+ // implemented in AnnotatedElement.
+ @Override
+ public final boolean isAnnotationPresent(Class<? extends Annotation> annotationType) {
+ Objects.requireNonNull(annotationType);
+ return isAnnotationPresentNative(annotationType);
+ }
+ @FastNative
+ private native boolean isAnnotationPresentNative(Class<? extends Annotation> annotationType);
+
+ final Annotation[][] getParameterAnnotationsInternal() {
+ Annotation[][] parameterAnnotations = getParameterAnnotationsNative();
+ if (parameterAnnotations == null) {
+ parameterAnnotations = new Annotation[getParameterTypes().length][0];
+ }
+ return parameterAnnotations;
+ }
+ @FastNative
+ private native Annotation[][] getParameterAnnotationsNative();
+
+ /**
+ * @hide - exposed for use by {@link Class}.
+ */
+ public final int getAccessFlags() {
+ return accessFlags;
+ }
+
+ /**
+ * @hide - exposed for use by {@code java.lang.invoke.*}.
+ */
+ public final long getArtMethod() {
+ return artMethod;
+ }
+
+ static final class GenericInfo {
+ final ListOfTypes genericExceptionTypes;
+ final ListOfTypes genericParameterTypes;
+ final Type genericReturnType;
+ final TypeVariable<?>[] formalTypeParameters;
+
+ GenericInfo(ListOfTypes exceptions, ListOfTypes parameters, Type ret,
+ TypeVariable<?>[] formal) {
+ genericExceptionTypes = exceptions;
+ genericParameterTypes = parameters;
+ genericReturnType = ret;
+ formalTypeParameters = formal;
+ }
+ }
+
+ final boolean hasGenericInformationInternal() {
+ return getSignatureAnnotation() != null;
+ }
+
+ /**
+ * Returns generic information associated with this method/constructor member.
+ */
+ final GenericInfo getMethodOrConstructorGenericInfoInternal() {
+ String signatureAttribute = getSignatureAttribute();
+ Class<?>[] exceptionTypes = this.getExceptionTypes();
+ GenericSignatureParser parser =
+ new GenericSignatureParser(this.getDeclaringClass().getClassLoader());
+ if (this instanceof Method) {
+ parser.parseForMethod(this, signatureAttribute, exceptionTypes);
+ } else {
+ parser.parseForConstructor(this, signatureAttribute, exceptionTypes);
+ }
+ return new GenericInfo(parser.exceptionTypes, parser.parameterTypes,
+ parser.returnType, parser.formalTypeParameters);
+ }
+
+ private String getSignatureAttribute() {
+ String[] annotation = getSignatureAnnotation();
+ if (annotation == null) {
+ return null;
+ }
+ StringBuilder result = new StringBuilder();
+ for (String s : annotation) {
+ result.append(s);
+ }
+ return result.toString();
+ }
+ @FastNative
+ private native String[] getSignatureAnnotation();
+
+ final boolean equalNameAndParametersInternal(Method m) {
+ return getName().equals(m.getName()) && (compareMethodParametersInternal(m) == 0);
+ }
+
+ @FastNative
+ native int compareMethodParametersInternal(Method meth);
+
+ @FastNative
+ final native String getMethodNameInternal();
+
+ @FastNative
+ final native Class<?> getMethodReturnTypeInternal();
+
+ /** A cheap implementation for {@link Method#isDefault()}. */
+ final boolean isDefaultMethodInternal() {
+ return (accessFlags & Modifier.DEFAULT) != 0;
+ }
+
+ /** A cheap implementation for {@link Method#isBridge()}. */
+ final boolean isBridgeMethodInternal() {
+ return (accessFlags & Modifier.BRIDGE) != 0;
+ }
+ // END Android-added: Additional ART-related fields and logic.
+
+}
diff --git a/java/lang/reflect/Field.annotated.java b/java/lang/reflect/Field.annotated.java
new file mode 100644
index 0000000..8a26ce3
--- /dev/null
+++ b/java/lang/reflect/Field.annotated.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1996, 2013, 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.reflect;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Field extends java.lang.reflect.AccessibleObject implements java.lang.reflect.Member {
+
+Field() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.Class<?> getDeclaringClass() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String getName() { throw new RuntimeException("Stub!"); }
+
+public int getModifiers() { throw new RuntimeException("Stub!"); }
+
+public boolean isEnumConstant() { throw new RuntimeException("Stub!"); }
+
+public boolean isSynthetic() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.Class<?> getType() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.reflect.Type getGenericType() { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String toGenericString() { throw new RuntimeException("Stub!"); }
+
[email protected] public native java.lang.Object get(@libcore.util.Nullable java.lang.Object obj) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native boolean getBoolean(@libcore.util.Nullable java.lang.Object obj) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native byte getByte(@libcore.util.Nullable java.lang.Object obj) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native char getChar(@libcore.util.Nullable java.lang.Object obj) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native short getShort(@libcore.util.Nullable java.lang.Object obj) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native int getInt(@libcore.util.Nullable java.lang.Object obj) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native long getLong(@libcore.util.Nullable java.lang.Object obj) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native float getFloat(@libcore.util.Nullable java.lang.Object obj) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native double getDouble(@libcore.util.Nullable java.lang.Object obj) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native void set(@libcore.util.Nullable java.lang.Object obj, @libcore.util.Nullable java.lang.Object value) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native void setBoolean(@libcore.util.Nullable java.lang.Object obj, boolean z) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native void setByte(@libcore.util.Nullable java.lang.Object obj, byte b) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native void setChar(@libcore.util.Nullable java.lang.Object obj, char c) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native void setShort(@libcore.util.Nullable java.lang.Object obj, short s) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native void setInt(@libcore.util.Nullable java.lang.Object obj, int i) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native void setLong(@libcore.util.Nullable java.lang.Object obj, long l) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native void setFloat(@libcore.util.Nullable java.lang.Object obj, float f) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
+public native void setDouble(@libcore.util.Nullable java.lang.Object obj, double d) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+
[email protected] public <T extends java.lang.annotation.Annotation> T getAnnotation(@libcore.util.NonNull java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public <T extends java.lang.annotation.Annotation> T[] getAnnotationsByType(@libcore.util.NonNull java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public boolean isAnnotationPresent(@libcore.util.NonNull java.lang.Class<? extends java.lang.annotation.Annotation> annotationType) { throw new RuntimeException("Stub!"); }
+
+public native java.lang.annotation.Annotation[] getDeclaredAnnotations();
+}
diff --git a/java/lang/reflect/Field.java b/java/lang/reflect/Field.java
new file mode 100644
index 0000000..ca5857a
--- /dev/null
+++ b/java/lang/reflect/Field.java
@@ -0,0 +1,950 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1996, 2013, 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.reflect;
+
+import dalvik.annotation.optimization.FastNative;
+import sun.reflect.CallerSensitive;
+import java.lang.annotation.Annotation;
+import java.util.Objects;
+import libcore.reflect.AnnotatedElements;
+import libcore.reflect.GenericSignatureParser;
+
+
+/**
+ * A {@code Field} provides information about, and dynamic access to, a
+ * single field of a class or an interface. The reflected field may
+ * be a class (static) field or an instance field.
+ *
+ * <p>A {@code Field} permits widening conversions to occur during a get or
+ * set access operation, but throws an {@code IllegalArgumentException} if a
+ * narrowing conversion would occur.
+ *
+ * @see Member
+ * @see java.lang.Class
+ * @see java.lang.Class#getFields()
+ * @see java.lang.Class#getField(String)
+ * @see java.lang.Class#getDeclaredFields()
+ * @see java.lang.Class#getDeclaredField(String)
+ *
+ * @author Kenneth Russell
+ * @author Nakul Saraiya
+ */
+public final
+class Field extends AccessibleObject implements Member {
+ // Android-changed: Extensive modifications made throughout the class for ART.
+ // Android-changed: Many fields and methods removed / modified.
+ // Android-removed: Type annotations runtime code. Not supported on Android.
+
+ private int accessFlags;
+ private Class<?> declaringClass;
+ private int artFieldIndex;
+ private int offset;
+ private Class<?> type;
+
+ private Field() {
+ }
+
+ /**
+ * Returns the {@code Class} object representing the class or interface
+ * that declares the field represented by this {@code Field} object.
+ */
+ public Class<?> getDeclaringClass() {
+ // Android-changed: Adjust code for different field names.
+ return declaringClass;
+ }
+
+ /**
+ * Returns the name of the field represented by this {@code Field} object.
+ */
+ public String getName() {
+ // Android-changed: getName() implemented differently.
+ if (declaringClass.isProxy()) {
+ // Proxy classes have 1 synthesized static field with no valid dex index.
+ if ((getModifiers() & Modifier.STATIC) == 0) {
+ throw new AssertionError("Invalid modifiers for proxy field: " + getModifiers());
+ }
+ // Only 2 fields are present on proxy classes.
+ switch (artFieldIndex) {
+ case 0: return "interfaces";
+ case 1: return "throws";
+ default: throw new AssertionError("Invalid index for proxy: " + artFieldIndex);
+ }
+ }
+
+ return getNameInternal();
+ }
+
+ // Android-added: getName() implemented differently.
+ @FastNative
+ private native String getNameInternal();
+
+ /**
+ * Returns the Java language modifiers for the field represented
+ * by this {@code Field} object, as an integer. The {@code Modifier} class should
+ * be used to decode the modifiers.
+ *
+ * @see Modifier
+ */
+ public int getModifiers() {
+ // Android-changed: Adjust getModifiers() implementation to mask extra bits used on Android.
+ return accessFlags & 0xffff; // mask out bits not used by Java
+ }
+
+ /**
+ * Returns {@code true} if this field represents an element of
+ * an enumerated type; returns {@code false} otherwise.
+ *
+ * @return {@code true} if and only if this field represents an element of
+ * an enumerated type.
+ * @since 1.5
+ */
+ public boolean isEnumConstant() {
+ return (getModifiers() & Modifier.ENUM) != 0;
+ }
+
+ /**
+ * Returns {@code true} if this field is a synthetic
+ * field; returns {@code false} otherwise.
+ *
+ * @return true if and only if this field is a synthetic
+ * field as defined by the Java Language Specification.
+ * @since 1.5
+ */
+ public boolean isSynthetic() {
+ return Modifier.isSynthetic(getModifiers());
+ }
+
+ /**
+ * Returns a {@code Class} object that identifies the
+ * declared type for the field represented by this
+ * {@code Field} object.
+ *
+ * @return a {@code Class} object identifying the declared
+ * type of the field represented by this object
+ */
+ public Class<?> getType() {
+ return type;
+ }
+
+ /**
+ * Returns a {@code Type} object that represents the declared type for
+ * the field represented by this {@code Field} object.
+ *
+ * <p>If the {@code Type} is a parameterized type, the
+ * {@code Type} object returned must accurately reflect the
+ * actual type parameters used in the source code.
+ *
+ * <p>If the type of the underlying field is a type variable or a
+ * parameterized type, it is created. Otherwise, it is resolved.
+ *
+ * @return a {@code Type} object that represents the declared type for
+ * the field represented by this {@code Field} object
+ * @throws GenericSignatureFormatError if the generic field
+ * signature does not conform to the format specified in
+ * <cite>The Java™ Virtual Machine Specification</cite>
+ * @throws TypeNotPresentException if the generic type
+ * signature of the underlying field refers to a non-existent
+ * type declaration
+ * @throws MalformedParameterizedTypeException if the generic
+ * signature of the underlying field refers to a parameterized type
+ * that cannot be instantiated for any reason
+ * @since 1.5
+ */
+ public Type getGenericType() {
+ // Android-changed: getGenericType() implemented differently.
+ String signatureAttribute = getSignatureAttribute();
+ ClassLoader cl = declaringClass.getClassLoader();
+ GenericSignatureParser parser = new GenericSignatureParser(cl);
+ parser.parseForField(declaringClass, signatureAttribute);
+ Type genericType = parser.fieldType;
+ if (genericType == null) {
+ genericType = getType();
+ }
+ return genericType;
+ }
+
+ // BEGIN Android-added: getGenericType() implemented differently.
+ private String getSignatureAttribute() {
+ String[] annotation = getSignatureAnnotation();
+ if (annotation == null) {
+ return null;
+ }
+ StringBuilder result = new StringBuilder();
+ for (String s : annotation) {
+ result.append(s);
+ }
+ return result.toString();
+ }
+ @FastNative
+ private native String[] getSignatureAnnotation();
+ // END Android-added: getGenericType() implemented differently.
+
+
+ /**
+ * Compares this {@code Field} against the specified object. Returns
+ * true if the objects are the same. Two {@code Field} objects are the same if
+ * they were declared by the same class and have the same name
+ * and type.
+ */
+ public boolean equals(Object obj) {
+ if (obj != null && obj instanceof Field) {
+ Field other = (Field)obj;
+ return (getDeclaringClass() == other.getDeclaringClass())
+ && (getName() == other.getName())
+ && (getType() == other.getType());
+ }
+ return false;
+ }
+
+ /**
+ * Returns a hashcode for this {@code Field}. This is computed as the
+ * exclusive-or of the hashcodes for the underlying field's
+ * declaring class name and its name.
+ */
+ public int hashCode() {
+ return getDeclaringClass().getName().hashCode() ^ getName().hashCode();
+ }
+
+ /**
+ * Returns a string describing this {@code Field}. The format is
+ * the access modifiers for the field, if any, followed
+ * by the field type, followed by a space, followed by
+ * the fully-qualified name of the class declaring the field,
+ * followed by a period, followed by the name of the field.
+ * For example:
+ * <pre>
+ * public static final int java.lang.Thread.MIN_PRIORITY
+ * private int java.io.FileDescriptor.fd
+ * </pre>
+ *
+ * <p>The modifiers are placed in canonical order as specified by
+ * "The Java Language Specification". This is {@code public},
+ * {@code protected} or {@code private} first, and then other
+ * modifiers in the following order: {@code static}, {@code final},
+ * {@code transient}, {@code volatile}.
+ *
+ * @return a string describing this {@code Field}
+ * @jls 8.3.1 Field Modifiers
+ */
+ public String toString() {
+ int mod = getModifiers();
+ return (((mod == 0) ? "" : (Modifier.toString(mod) + " "))
+ + getType().getTypeName() + " "
+ + getDeclaringClass().getTypeName() + "."
+ + getName());
+ }
+
+ /**
+ * Returns a string describing this {@code Field}, including
+ * its generic type. The format is the access modifiers for the
+ * field, if any, followed by the generic field type, followed by
+ * a space, followed by the fully-qualified name of the class
+ * declaring the field, followed by a period, followed by the name
+ * of the field.
+ *
+ * <p>The modifiers are placed in canonical order as specified by
+ * "The Java Language Specification". This is {@code public},
+ * {@code protected} or {@code private} first, and then other
+ * modifiers in the following order: {@code static}, {@code final},
+ * {@code transient}, {@code volatile}.
+ *
+ * @return a string describing this {@code Field}, including
+ * its generic type
+ *
+ * @since 1.5
+ * @jls 8.3.1 Field Modifiers
+ */
+ public String toGenericString() {
+ int mod = getModifiers();
+ Type fieldType = getGenericType();
+ return (((mod == 0) ? "" : (Modifier.toString(mod) + " "))
+ + fieldType.getTypeName() + " "
+ + getDeclaringClass().getTypeName() + "."
+ + getName());
+ }
+
+ /**
+ * Returns the value of the field represented by this {@code Field}, on
+ * the specified object. The value is automatically wrapped in an
+ * object if it has a primitive type.
+ *
+ * <p>The underlying field's value is obtained as follows:
+ *
+ * <p>If the underlying field is a static field, the {@code obj} argument
+ * is ignored; it may be null.
+ *
+ * <p>Otherwise, the underlying field is an instance field. If the
+ * specified {@code obj} argument is null, the method throws a
+ * {@code NullPointerException}. If the specified object is not an
+ * instance of the class or interface declaring the underlying
+ * field, the method throws an {@code IllegalArgumentException}.
+ *
+ * <p>If this {@code Field} object is enforcing Java language access control, and
+ * the underlying field is inaccessible, the method throws an
+ * {@code IllegalAccessException}.
+ * If the underlying field is static, the class that declared the
+ * field is initialized if it has not already been initialized.
+ *
+ * <p>Otherwise, the value is retrieved from the underlying instance
+ * or static field. If the field has a primitive type, the value
+ * is wrapped in an object before being returned, otherwise it is
+ * returned as is.
+ *
+ * <p>If the field is hidden in the type of {@code obj},
+ * the field's value is obtained according to the preceding rules.
+ *
+ * @param obj object from which the represented field's value is
+ * to be extracted
+ * @return the value of the represented field in object
+ * {@code obj}; primitive values are wrapped in an appropriate
+ * object before being returned
+ *
+ * @exception IllegalAccessException if this {@code Field} object
+ * is enforcing Java language access control and the underlying
+ * field is inaccessible.
+ * @exception IllegalArgumentException if the specified object is not an
+ * instance of the class or interface declaring the underlying
+ * field (or a subclass or implementor thereof).
+ * @exception NullPointerException if the specified object is null
+ * and the field is an instance field.
+ * @exception ExceptionInInitializerError if the initialization provoked
+ * by this method fails.
+ */
+ @CallerSensitive
+ // Android-changed: get*(Object) implemented natively.
+ @FastNative
+ public native Object get(Object obj)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ /**
+ * Gets the value of a static or instance {@code boolean} field.
+ *
+ * @param obj the object to extract the {@code boolean} value
+ * from
+ * @return the value of the {@code boolean} field
+ *
+ * @exception IllegalAccessException if this {@code Field} object
+ * is enforcing Java language access control and the underlying
+ * field is inaccessible.
+ * @exception IllegalArgumentException if the specified object is not
+ * an instance of the class or interface declaring the
+ * underlying field (or a subclass or implementor
+ * thereof), or if the field value cannot be
+ * converted to the type {@code boolean} by a
+ * widening conversion.
+ * @exception NullPointerException if the specified object is null
+ * and the field is an instance field.
+ * @exception ExceptionInInitializerError if the initialization provoked
+ * by this method fails.
+ * @see Field#get
+ */
+ @CallerSensitive
+ // Android-changed: get*(Object) implemented natively.
+ @FastNative
+ public native boolean getBoolean(Object obj)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ /**
+ * Gets the value of a static or instance {@code byte} field.
+ *
+ * @param obj the object to extract the {@code byte} value
+ * from
+ * @return the value of the {@code byte} field
+ *
+ * @exception IllegalAccessException if this {@code Field} object
+ * is enforcing Java language access control and the underlying
+ * field is inaccessible.
+ * @exception IllegalArgumentException if the specified object is not
+ * an instance of the class or interface declaring the
+ * underlying field (or a subclass or implementor
+ * thereof), or if the field value cannot be
+ * converted to the type {@code byte} by a
+ * widening conversion.
+ * @exception NullPointerException if the specified object is null
+ * and the field is an instance field.
+ * @exception ExceptionInInitializerError if the initialization provoked
+ * by this method fails.
+ * @see Field#get
+ */
+ @CallerSensitive
+ // Android-changed: get*(Object) implemented natively.
+ @FastNative
+ public native byte getByte(Object obj)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ /**
+ * Gets the value of a static or instance field of type
+ * {@code char} or of another primitive type convertible to
+ * type {@code char} via a widening conversion.
+ *
+ * @param obj the object to extract the {@code char} value
+ * from
+ * @return the value of the field converted to type {@code char}
+ *
+ * @exception IllegalAccessException if this {@code Field} object
+ * is enforcing Java language access control and the underlying
+ * field is inaccessible.
+ * @exception IllegalArgumentException if the specified object is not
+ * an instance of the class or interface declaring the
+ * underlying field (or a subclass or implementor
+ * thereof), or if the field value cannot be
+ * converted to the type {@code char} by a
+ * widening conversion.
+ * @exception NullPointerException if the specified object is null
+ * and the field is an instance field.
+ * @exception ExceptionInInitializerError if the initialization provoked
+ * by this method fails.
+ * @see Field#get
+ */
+ @CallerSensitive
+ // Android-changed: get*(Object) implemented natively.
+ @FastNative
+ public native char getChar(Object obj)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ /**
+ * Gets the value of a static or instance field of type
+ * {@code short} or of another primitive type convertible to
+ * type {@code short} via a widening conversion.
+ *
+ * @param obj the object to extract the {@code short} value
+ * from
+ * @return the value of the field converted to type {@code short}
+ *
+ * @exception IllegalAccessException if this {@code Field} object
+ * is enforcing Java language access control and the underlying
+ * field is inaccessible.
+ * @exception IllegalArgumentException if the specified object is not
+ * an instance of the class or interface declaring the
+ * underlying field (or a subclass or implementor
+ * thereof), or if the field value cannot be
+ * converted to the type {@code short} by a
+ * widening conversion.
+ * @exception NullPointerException if the specified object is null
+ * and the field is an instance field.
+ * @exception ExceptionInInitializerError if the initialization provoked
+ * by this method fails.
+ * @see Field#get
+ */
+ @CallerSensitive
+ // Android-changed: get*(Object) implemented natively.
+ @FastNative
+ public native short getShort(Object obj)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ /**
+ * Gets the value of a static or instance field of type
+ * {@code int} or of another primitive type convertible to
+ * type {@code int} via a widening conversion.
+ *
+ * @param obj the object to extract the {@code int} value
+ * from
+ * @return the value of the field converted to type {@code int}
+ *
+ * @exception IllegalAccessException if this {@code Field} object
+ * is enforcing Java language access control and the underlying
+ * field is inaccessible.
+ * @exception IllegalArgumentException if the specified object is not
+ * an instance of the class or interface declaring the
+ * underlying field (or a subclass or implementor
+ * thereof), or if the field value cannot be
+ * converted to the type {@code int} by a
+ * widening conversion.
+ * @exception NullPointerException if the specified object is null
+ * and the field is an instance field.
+ * @exception ExceptionInInitializerError if the initialization provoked
+ * by this method fails.
+ * @see Field#get
+ */
+ @CallerSensitive
+ // Android-changed: get*(Object) implemented natively.
+ @FastNative
+ public native int getInt(Object obj)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ /**
+ * Gets the value of a static or instance field of type
+ * {@code long} or of another primitive type convertible to
+ * type {@code long} via a widening conversion.
+ *
+ * @param obj the object to extract the {@code long} value
+ * from
+ * @return the value of the field converted to type {@code long}
+ *
+ * @exception IllegalAccessException if this {@code Field} object
+ * is enforcing Java language access control and the underlying
+ * field is inaccessible.
+ * @exception IllegalArgumentException if the specified object is not
+ * an instance of the class or interface declaring the
+ * underlying field (or a subclass or implementor
+ * thereof), or if the field value cannot be
+ * converted to the type {@code long} by a
+ * widening conversion.
+ * @exception NullPointerException if the specified object is null
+ * and the field is an instance field.
+ * @exception ExceptionInInitializerError if the initialization provoked
+ * by this method fails.
+ * @see Field#get
+ */
+ @CallerSensitive
+ // Android-changed: get*(Object) implemented natively.
+ @FastNative
+ public native long getLong(Object obj)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ /**
+ * Gets the value of a static or instance field of type
+ * {@code float} or of another primitive type convertible to
+ * type {@code float} via a widening conversion.
+ *
+ * @param obj the object to extract the {@code float} value
+ * from
+ * @return the value of the field converted to type {@code float}
+ *
+ * @exception IllegalAccessException if this {@code Field} object
+ * is enforcing Java language access control and the underlying
+ * field is inaccessible.
+ * @exception IllegalArgumentException if the specified object is not
+ * an instance of the class or interface declaring the
+ * underlying field (or a subclass or implementor
+ * thereof), or if the field value cannot be
+ * converted to the type {@code float} by a
+ * widening conversion.
+ * @exception NullPointerException if the specified object is null
+ * and the field is an instance field.
+ * @exception ExceptionInInitializerError if the initialization provoked
+ * by this method fails.
+ * @see Field#get
+ */
+ @CallerSensitive
+ // Android-changed: get*(Object) implemented natively.
+ @FastNative
+ public native float getFloat(Object obj)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ /**
+ * Gets the value of a static or instance field of type
+ * {@code double} or of another primitive type convertible to
+ * type {@code double} via a widening conversion.
+ *
+ * @param obj the object to extract the {@code double} value
+ * from
+ * @return the value of the field converted to type {@code double}
+ *
+ * @exception IllegalAccessException if this {@code Field} object
+ * is enforcing Java language access control and the underlying
+ * field is inaccessible.
+ * @exception IllegalArgumentException if the specified object is not
+ * an instance of the class or interface declaring the
+ * underlying field (or a subclass or implementor
+ * thereof), or if the field value cannot be
+ * converted to the type {@code double} by a
+ * widening conversion.
+ * @exception NullPointerException if the specified object is null
+ * and the field is an instance field.
+ * @exception ExceptionInInitializerError if the initialization provoked
+ * by this method fails.
+ * @see Field#get
+ */
+ @CallerSensitive
+ // Android-changed: get*(Object) implemented natively.
+ @FastNative
+ public native double getDouble(Object obj)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ /**
+ * Sets the field represented by this {@code Field} object on the
+ * specified object argument to the specified new value. The new
+ * value is automatically unwrapped if the underlying field has a
+ * primitive type.
+ *
+ * <p>The operation proceeds as follows:
+ *
+ * <p>If the underlying field is static, the {@code obj} argument is
+ * ignored; it may be null.
+ *
+ * <p>Otherwise the underlying field is an instance field. If the
+ * specified object argument is null, the method throws a
+ * {@code NullPointerException}. If the specified object argument is not
+ * an instance of the class or interface declaring the underlying
+ * field, the method throws an {@code IllegalArgumentException}.
+ *
+ * <p>If this {@code Field} object is enforcing Java language access control, and
+ * the underlying field is inaccessible, the method throws an
+ * {@code IllegalAccessException}.
+ *
+ * <p>If the underlying field is final, the method throws an
+ * {@code IllegalAccessException} unless {@code setAccessible(true)}
+ * has succeeded for this {@code Field} object
+ * and the field is non-static. Setting a final field in this way
+ * is meaningful only during deserialization or reconstruction of
+ * instances of classes with blank final fields, before they are
+ * made available for access by other parts of a program. Use in
+ * any other context may have unpredictable effects, including cases
+ * in which other parts of a program continue to use the original
+ * value of this field.
+ *
+ * <p>If the underlying field is of a primitive type, an unwrapping
+ * conversion is attempted to convert the new value to a value of
+ * a primitive type. If this attempt fails, the method throws an
+ * {@code IllegalArgumentException}.
+ *
+ * <p>If, after possible unwrapping, the new value cannot be
+ * converted to the type of the underlying field by an identity or
+ * widening conversion, the method throws an
+ * {@code IllegalArgumentException}.
+ *
+ * <p>If the underlying field is static, the class that declared the
+ * field is initialized if it has not already been initialized.
+ *
+ * <p>The field is set to the possibly unwrapped and widened new value.
+ *
+ * <p>If the field is hidden in the type of {@code obj},
+ * the field's value is set according to the preceding rules.
+ *
+ * @param obj the object whose field should be modified
+ * @param value the new value for the field of {@code obj}
+ * being modified
+ *
+ * @exception IllegalAccessException if this {@code Field} object
+ * is enforcing Java language access control and the underlying
+ * field is either inaccessible or final.
+ * @exception IllegalArgumentException if the specified object is not an
+ * instance of the class or interface declaring the underlying
+ * field (or a subclass or implementor thereof),
+ * or if an unwrapping conversion fails.
+ * @exception NullPointerException if the specified object is null
+ * and the field is an instance field.
+ * @exception ExceptionInInitializerError if the initialization provoked
+ * by this method fails.
+ */
+ @CallerSensitive
+ // Android-changed: set*(Object, ...) implemented natively.
+ @FastNative
+ public native void set(Object obj, Object value)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ /**
+ * Sets the value of a field as a {@code boolean} on the specified object.
+ * This method is equivalent to
+ * {@code set(obj, zObj)},
+ * where {@code zObj} is a {@code Boolean} object and
+ * {@code zObj.booleanValue() == z}.
+ *
+ * @param obj the object whose field should be modified
+ * @param z the new value for the field of {@code obj}
+ * being modified
+ *
+ * @exception IllegalAccessException if this {@code Field} object
+ * is enforcing Java language access control and the underlying
+ * field is either inaccessible or final.
+ * @exception IllegalArgumentException if the specified object is not an
+ * instance of the class or interface declaring the underlying
+ * field (or a subclass or implementor thereof),
+ * or if an unwrapping conversion fails.
+ * @exception NullPointerException if the specified object is null
+ * and the field is an instance field.
+ * @exception ExceptionInInitializerError if the initialization provoked
+ * by this method fails.
+ * @see Field#set
+ */
+ @CallerSensitive
+ // Android-changed: set*(Object, ...) implemented natively.
+ @FastNative
+ public native void setBoolean(Object obj, boolean z)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ /**
+ * Sets the value of a field as a {@code byte} on the specified object.
+ * This method is equivalent to
+ * {@code set(obj, bObj)},
+ * where {@code bObj} is a {@code Byte} object and
+ * {@code bObj.byteValue() == b}.
+ *
+ * @param obj the object whose field should be modified
+ * @param b the new value for the field of {@code obj}
+ * being modified
+ *
+ * @exception IllegalAccessException if this {@code Field} object
+ * is enforcing Java language access control and the underlying
+ * field is either inaccessible or final.
+ * @exception IllegalArgumentException if the specified object is not an
+ * instance of the class or interface declaring the underlying
+ * field (or a subclass or implementor thereof),
+ * or if an unwrapping conversion fails.
+ * @exception NullPointerException if the specified object is null
+ * and the field is an instance field.
+ * @exception ExceptionInInitializerError if the initialization provoked
+ * by this method fails.
+ * @see Field#set
+ */
+ @CallerSensitive
+ // Android-changed: set*(Object, ...) implemented natively.
+ @FastNative
+ public native void setByte(Object obj, byte b)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ /**
+ * Sets the value of a field as a {@code char} on the specified object.
+ * This method is equivalent to
+ * {@code set(obj, cObj)},
+ * where {@code cObj} is a {@code Character} object and
+ * {@code cObj.charValue() == c}.
+ *
+ * @param obj the object whose field should be modified
+ * @param c the new value for the field of {@code obj}
+ * being modified
+ *
+ * @exception IllegalAccessException if this {@code Field} object
+ * is enforcing Java language access control and the underlying
+ * field is either inaccessible or final.
+ * @exception IllegalArgumentException if the specified object is not an
+ * instance of the class or interface declaring the underlying
+ * field (or a subclass or implementor thereof),
+ * or if an unwrapping conversion fails.
+ * @exception NullPointerException if the specified object is null
+ * and the field is an instance field.
+ * @exception ExceptionInInitializerError if the initialization provoked
+ * by this method fails.
+ * @see Field#set
+ */
+ @CallerSensitive
+ // Android-changed: set*(Object, ...) implemented natively.
+ @FastNative
+ public native void setChar(Object obj, char c)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ /**
+ * Sets the value of a field as a {@code short} on the specified object.
+ * This method is equivalent to
+ * {@code set(obj, sObj)},
+ * where {@code sObj} is a {@code Short} object and
+ * {@code sObj.shortValue() == s}.
+ *
+ * @param obj the object whose field should be modified
+ * @param s the new value for the field of {@code obj}
+ * being modified
+ *
+ * @exception IllegalAccessException if this {@code Field} object
+ * is enforcing Java language access control and the underlying
+ * field is either inaccessible or final.
+ * @exception IllegalArgumentException if the specified object is not an
+ * instance of the class or interface declaring the underlying
+ * field (or a subclass or implementor thereof),
+ * or if an unwrapping conversion fails.
+ * @exception NullPointerException if the specified object is null
+ * and the field is an instance field.
+ * @exception ExceptionInInitializerError if the initialization provoked
+ * by this method fails.
+ * @see Field#set
+ */
+ @CallerSensitive
+ // Android-changed: set*(Object, ...) implemented natively.
+ @FastNative
+ public native void setShort(Object obj, short s)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ /**
+ * Sets the value of a field as an {@code int} on the specified object.
+ * This method is equivalent to
+ * {@code set(obj, iObj)},
+ * where {@code iObj} is a {@code Integer} object and
+ * {@code iObj.intValue() == i}.
+ *
+ * @param obj the object whose field should be modified
+ * @param i the new value for the field of {@code obj}
+ * being modified
+ *
+ * @exception IllegalAccessException if this {@code Field} object
+ * is enforcing Java language access control and the underlying
+ * field is either inaccessible or final.
+ * @exception IllegalArgumentException if the specified object is not an
+ * instance of the class or interface declaring the underlying
+ * field (or a subclass or implementor thereof),
+ * or if an unwrapping conversion fails.
+ * @exception NullPointerException if the specified object is null
+ * and the field is an instance field.
+ * @exception ExceptionInInitializerError if the initialization provoked
+ * by this method fails.
+ * @see Field#set
+ */
+ @CallerSensitive
+ // Android-changed: set*(Object, ...) implemented natively.
+ @FastNative
+ public native void setInt(Object obj, int i)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ /**
+ * Sets the value of a field as a {@code long} on the specified object.
+ * This method is equivalent to
+ * {@code set(obj, lObj)},
+ * where {@code lObj} is a {@code Long} object and
+ * {@code lObj.longValue() == l}.
+ *
+ * @param obj the object whose field should be modified
+ * @param l the new value for the field of {@code obj}
+ * being modified
+ *
+ * @exception IllegalAccessException if this {@code Field} object
+ * is enforcing Java language access control and the underlying
+ * field is either inaccessible or final.
+ * @exception IllegalArgumentException if the specified object is not an
+ * instance of the class or interface declaring the underlying
+ * field (or a subclass or implementor thereof),
+ * or if an unwrapping conversion fails.
+ * @exception NullPointerException if the specified object is null
+ * and the field is an instance field.
+ * @exception ExceptionInInitializerError if the initialization provoked
+ * by this method fails.
+ * @see Field#set
+ */
+ @CallerSensitive
+ // Android-changed: set*(Object, ...) implemented natively.
+ @FastNative
+ public native void setLong(Object obj, long l)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ /**
+ * Sets the value of a field as a {@code float} on the specified object.
+ * This method is equivalent to
+ * {@code set(obj, fObj)},
+ * where {@code fObj} is a {@code Float} object and
+ * {@code fObj.floatValue() == f}.
+ *
+ * @param obj the object whose field should be modified
+ * @param f the new value for the field of {@code obj}
+ * being modified
+ *
+ * @exception IllegalAccessException if this {@code Field} object
+ * is enforcing Java language access control and the underlying
+ * field is either inaccessible or final.
+ * @exception IllegalArgumentException if the specified object is not an
+ * instance of the class or interface declaring the underlying
+ * field (or a subclass or implementor thereof),
+ * or if an unwrapping conversion fails.
+ * @exception NullPointerException if the specified object is null
+ * and the field is an instance field.
+ * @exception ExceptionInInitializerError if the initialization provoked
+ * by this method fails.
+ * @see Field#set
+ */
+ @CallerSensitive
+ // Android-changed: set*(Object, ...) implemented natively.
+ @FastNative
+ public native void setFloat(Object obj, float f)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ /**
+ * Sets the value of a field as a {@code double} on the specified object.
+ * This method is equivalent to
+ * {@code set(obj, dObj)},
+ * where {@code dObj} is a {@code Double} object and
+ * {@code dObj.doubleValue() == d}.
+ *
+ * @param obj the object whose field should be modified
+ * @param d the new value for the field of {@code obj}
+ * being modified
+ *
+ * @exception IllegalAccessException if this {@code Field} object
+ * is enforcing Java language access control and the underlying
+ * field is either inaccessible or final.
+ * @exception IllegalArgumentException if the specified object is not an
+ * instance of the class or interface declaring the underlying
+ * field (or a subclass or implementor thereof),
+ * or if an unwrapping conversion fails.
+ * @exception NullPointerException if the specified object is null
+ * and the field is an instance field.
+ * @exception ExceptionInInitializerError if the initialization provoked
+ * by this method fails.
+ * @see Field#set
+ */
+ @CallerSensitive
+ // Android-changed: set*(Object, ...) implemented natively.
+ @FastNative
+ public native void setDouble(Object obj, double d)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ /**
+ * @throws NullPointerException {@inheritDoc}
+ * @since 1.5
+ */
+ public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
+ Objects.requireNonNull(annotationClass);
+ // Android-changed: getAnnotation(Class) implemented differently.
+ return getAnnotationNative(annotationClass);
+ }
+ // Android-added: getAnnotation(Class) implemented differently.
+ @FastNative
+ private native <A extends Annotation> A getAnnotationNative(Class<A> annotationType);
+
+ /**
+ * {@inheritDoc}
+ * @throws NullPointerException {@inheritDoc}
+ * @since 1.8
+ */
+ @Override
+ public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) {
+ // Android-added: getAnnotationsByType(Class) implemented differently.
+ return AnnotatedElements.getDirectOrIndirectAnnotationsByType(this, annotationClass);
+ }
+
+ // BEGIN Android-added: isAnnotationPresent(Class) overridden in Field.
+ @Override
+ public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) {
+ if (annotationType == null) {
+ throw new NullPointerException("annotationType == null");
+ }
+ return isAnnotationPresentNative(annotationType);
+ }
+ @FastNative
+ private native boolean isAnnotationPresentNative(Class<? extends Annotation> annotationType);
+ // END Android-added: isAnnotationPresent(Class) overridden in Field.
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ @FastNative
+ public native Annotation[] getDeclaredAnnotations();
+
+ // BEGIN Android-added: Methods for use by Android-specific code.
+ /**
+ * Returns the offset of the field within an instance, or for static fields, the class.
+ *
+ * @hide
+ */
+ public int getOffset() {
+ return offset;
+ }
+
+ /**
+ * @hide - export for use by {@code java.lang.invoke.*}
+ */
+ @FastNative
+ public native long getArtField();
+ // END Android-added: Methods for use by Android-specific code.
+}
diff --git a/java/lang/reflect/GenericArrayType.annotated.java b/java/lang/reflect/GenericArrayType.annotated.java
new file mode 100644
index 0000000..c173408
--- /dev/null
+++ b/java/lang/reflect/GenericArrayType.annotated.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2003, 2004, 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.reflect;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface GenericArrayType extends java.lang.reflect.Type {
+
[email protected] public java.lang.reflect.Type getGenericComponentType();
+}
+
diff --git a/java/lang/reflect/GenericArrayType.java b/java/lang/reflect/GenericArrayType.java
new file mode 100644
index 0000000..c45399e
--- /dev/null
+++ b/java/lang/reflect/GenericArrayType.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2003, 2004, 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.reflect;
+
+/**
+ * {@code GenericArrayType} represents an array type whose component
+ * type is either a parameterized type or a type variable.
+ * @since 1.5
+ */
+public interface GenericArrayType extends Type {
+ /**
+ * Returns a {@code Type} object representing the component type
+ * of this array. This method creates the component type of the
+ * array. See the declaration of {@link
+ * java.lang.reflect.ParameterizedType ParameterizedType} for the
+ * semantics of the creation process for parameterized types and
+ * see {@link java.lang.reflect.TypeVariable TypeVariable} for the
+ * creation process for type variables.
+ *
+ * @return a {@code Type} object representing the component type
+ * of this array
+ * @throws TypeNotPresentException if the underlying array type's
+ * component type refers to a non-existent type declaration
+ * @throws MalformedParameterizedTypeException if the
+ * underlying array type's component type refers to a
+ * parameterized type that cannot be instantiated for any reason
+ */
+ Type getGenericComponentType();
+}
diff --git a/java/lang/reflect/GenericDeclaration.annotated.java b/java/lang/reflect/GenericDeclaration.annotated.java
new file mode 100644
index 0000000..3614d84
--- /dev/null
+++ b/java/lang/reflect/GenericDeclaration.annotated.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2003, 2013, 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.reflect;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface GenericDeclaration extends java.lang.reflect.AnnotatedElement {
+
[email protected] public java.lang.reflect.TypeVariable<?>[] getTypeParameters();
+}
+
diff --git a/java/lang/reflect/GenericDeclaration.java b/java/lang/reflect/GenericDeclaration.java
new file mode 100644
index 0000000..042e359
--- /dev/null
+++ b/java/lang/reflect/GenericDeclaration.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2003, 2013, 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.reflect;
+
+/**
+ * A common interface for all entities that declare type variables.
+ *
+ * @since 1.5
+ */
+public interface GenericDeclaration extends AnnotatedElement {
+ /**
+ * Returns an array of {@code TypeVariable} objects that
+ * represent the type variables declared by the generic
+ * declaration represented by this {@code GenericDeclaration}
+ * object, in declaration order. Returns an array of length 0 if
+ * the underlying generic declaration declares no type variables.
+ *
+ * @return an array of {@code TypeVariable} objects that represent
+ * the type variables declared by this generic declaration
+ * @throws GenericSignatureFormatError if the generic
+ * signature of this generic declaration does not conform to
+ * the format specified in
+ * <cite>The Java™ Virtual Machine Specification</cite>
+ */
+ public TypeVariable<?>[] getTypeParameters();
+}
diff --git a/java/lang/reflect/GenericSignatureFormatError.java b/java/lang/reflect/GenericSignatureFormatError.java
new file mode 100644
index 0000000..3fd70d3
--- /dev/null
+++ b/java/lang/reflect/GenericSignatureFormatError.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2003, 2011, 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.reflect;
+
+
+/**
+ * Thrown when a syntactically malformed signature attribute is
+ * encountered by a reflective method that needs to interpret the
+ * generic signature information for a type, method or constructor.
+ *
+ * @since 1.5
+ */
+public class GenericSignatureFormatError extends ClassFormatError {
+ private static final long serialVersionUID = 6709919147137911034L;
+
+ /**
+ * Constructs a new {@code GenericSignatureFormatError}.
+ *
+ */
+ public GenericSignatureFormatError() {
+ super();
+ }
+
+ /**
+ * Constructs a new {@code GenericSignatureFormatError} with the
+ * specified message.
+ *
+ * @param message the detail message, may be {@code null}
+ */
+ public GenericSignatureFormatError(String message) {
+ super(message);
+ }
+}
diff --git a/java/lang/reflect/InvocationHandler.java b/java/lang/reflect/InvocationHandler.java
new file mode 100644
index 0000000..c35e460
--- /dev/null
+++ b/java/lang/reflect/InvocationHandler.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 1999, 2006, 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.reflect;
+
+/**
+ * {@code InvocationHandler} is the interface implemented by
+ * the <i>invocation handler</i> of a proxy instance.
+ *
+ * <p>Each proxy instance has an associated invocation handler.
+ * When a method is invoked on a proxy instance, the method
+ * invocation is encoded and dispatched to the {@code invoke}
+ * method of its invocation handler.
+ *
+ * @author Peter Jones
+ * @see Proxy
+ * @since 1.3
+ */
+public interface InvocationHandler {
+
+ /**
+ * Processes a method invocation on a proxy instance and returns
+ * the result. This method will be invoked on an invocation handler
+ * when a method is invoked on a proxy instance that it is
+ * associated with.
+ *
+ * @param proxy the proxy instance that the method was invoked on
+ *
+ * @param method the {@code Method} instance corresponding to
+ * the interface method invoked on the proxy instance. The declaring
+ * class of the {@code Method} object will be the interface that
+ * the method was declared in, which may be a superinterface of the
+ * proxy interface that the proxy class inherits the method through.
+ *
+ * @param args an array of objects containing the values of the
+ * arguments passed in the method invocation on the proxy instance,
+ * or {@code null} if interface method takes no arguments.
+ * Arguments of primitive types are wrapped in instances of the
+ * appropriate primitive wrapper class, such as
+ * {@code java.lang.Integer} or {@code java.lang.Boolean}.
+ *
+ * @return the value to return from the method invocation on the
+ * proxy instance. If the declared return type of the interface
+ * method is a primitive type, then the value returned by
+ * this method must be an instance of the corresponding primitive
+ * wrapper class; otherwise, it must be a type assignable to the
+ * declared return type. If the value returned by this method is
+ * {@code null} and the interface method's return type is
+ * primitive, then a {@code NullPointerException} will be
+ * thrown by the method invocation on the proxy instance. If the
+ * value returned by this method is otherwise not compatible with
+ * the interface method's declared return type as described above,
+ * a {@code ClassCastException} will be thrown by the method
+ * invocation on the proxy instance.
+ *
+ * @throws Throwable the exception to throw from the method
+ * invocation on the proxy instance. The exception's type must be
+ * assignable either to any of the exception types declared in the
+ * {@code throws} clause of the interface method or to the
+ * unchecked exception types {@code java.lang.RuntimeException}
+ * or {@code java.lang.Error}. If a checked exception is
+ * thrown by this method that is not assignable to any of the
+ * exception types declared in the {@code throws} clause of
+ * the interface method, then an
+ * {@link UndeclaredThrowableException} containing the
+ * exception that was thrown by this method will be thrown by the
+ * method invocation on the proxy instance.
+ *
+ * @see UndeclaredThrowableException
+ */
+ public Object invoke(Object proxy, Method method, Object[] args)
+ throws Throwable;
+}
diff --git a/java/lang/reflect/InvocationTargetException.java b/java/lang/reflect/InvocationTargetException.java
new file mode 100644
index 0000000..360d0ba
--- /dev/null
+++ b/java/lang/reflect/InvocationTargetException.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 1996, 2004, 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.reflect;
+
+/**
+ * InvocationTargetException is a checked exception that wraps
+ * an exception thrown by an invoked method or constructor.
+ *
+ * <p>As of release 1.4, this exception has been retrofitted to conform to
+ * the general purpose exception-chaining mechanism. The "target exception"
+ * that is provided at construction time and accessed via the
+ * {@link #getTargetException()} method is now known as the <i>cause</i>,
+ * and may be accessed via the {@link Throwable#getCause()} method,
+ * as well as the aforementioned "legacy method."
+ *
+ * @see Method
+ * @see Constructor
+ */
+public class InvocationTargetException extends ReflectiveOperationException {
+ /**
+ * Use serialVersionUID from JDK 1.1.X for interoperability
+ */
+ private static final long serialVersionUID = 4085088731926701167L;
+
+ /**
+ * This field holds the target if the
+ * InvocationTargetException(Throwable target) constructor was
+ * used to instantiate the object
+ *
+ * @serial
+ *
+ */
+ private Throwable target;
+
+ /**
+ * Constructs an {@code InvocationTargetException} with
+ * {@code null} as the target exception.
+ */
+ protected InvocationTargetException() {
+ super((Throwable)null); // Disallow initCause
+ }
+
+ /**
+ * Constructs a InvocationTargetException with a target exception.
+ *
+ * @param target the target exception
+ */
+ public InvocationTargetException(Throwable target) {
+ super((Throwable)null); // Disallow initCause
+ this.target = target;
+ }
+
+ /**
+ * Constructs a InvocationTargetException with a target exception
+ * and a detail message.
+ *
+ * @param target the target exception
+ * @param s the detail message
+ */
+ public InvocationTargetException(Throwable target, String s) {
+ super(s, null); // Disallow initCause
+ this.target = target;
+ }
+
+ /**
+ * Get the thrown target exception.
+ *
+ * <p>This method predates the general-purpose exception chaining facility.
+ * The {@link Throwable#getCause()} method is now the preferred means of
+ * obtaining this information.
+ *
+ * @return the thrown target exception (cause of this exception).
+ */
+ public Throwable getTargetException() {
+ return target;
+ }
+
+ /**
+ * Returns the cause of this exception (the thrown target exception,
+ * which may be {@code null}).
+ *
+ * @return the cause of this exception.
+ * @since 1.4
+ */
+ public Throwable getCause() {
+ return target;
+ }
+}
diff --git a/java/lang/reflect/MalformedParameterizedTypeException.java b/java/lang/reflect/MalformedParameterizedTypeException.java
new file mode 100644
index 0000000..a9efc55
--- /dev/null
+++ b/java/lang/reflect/MalformedParameterizedTypeException.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2003, 2008, 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.reflect;
+
+/**
+ * Thrown when a semantically malformed parameterized type is
+ * encountered by a reflective method that needs to instantiate it.
+ * For example, if the number of type arguments to a parameterized type
+ * is wrong.
+ *
+ * @since 1.5
+ */
+public class MalformedParameterizedTypeException extends RuntimeException {
+ private static final long serialVersionUID = -5696557788586220964L;
+}
diff --git a/java/lang/reflect/MalformedParametersException.java b/java/lang/reflect/MalformedParametersException.java
new file mode 100644
index 0000000..7479624
--- /dev/null
+++ b/java/lang/reflect/MalformedParametersException.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2013, 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.reflect;
+
+/**
+ * Thrown when {@link java.lang.reflect.Executable#getParameters the
+ * java.lang.reflect package} attempts to read method parameters from
+ * a class file and determines that one or more parameters are
+ * malformed.
+ *
+ * <p>The following is a list of conditions under which this exception
+ * can be thrown:
+ * <ul>
+ * <li> The number of parameters (parameter_count) is wrong for the method
+ * <li> A constant pool index is out of bounds.
+ * <li> A constant pool index does not refer to a UTF-8 entry
+ * <li> A parameter's name is "", or contains an illegal character
+ * <li> The flags field contains an illegal flag (something other than
+ * FINAL, SYNTHETIC, or MANDATED)
+ * </ul>
+ *
+ * See {@link java.lang.reflect.Executable#getParameters} for more
+ * information.
+ *
+ * @see java.lang.reflect.Executable#getParameters
+ * @since 1.8
+ */
+public class MalformedParametersException extends RuntimeException {
+
+ /**
+ * Version for serialization.
+ */
+ private static final long serialVersionUID = 20130919L;
+
+ /**
+ * Create a {@code MalformedParametersException} with an empty
+ * reason.
+ */
+ public MalformedParametersException() {}
+
+ /**
+ * Create a {@code MalformedParametersException}.
+ *
+ * @param reason The reason for the exception.
+ */
+ public MalformedParametersException(String reason) {
+ super(reason);
+ }
+}
diff --git a/java/lang/reflect/Member.annotated.java b/java/lang/reflect/Member.annotated.java
new file mode 100644
index 0000000..0552ce2
--- /dev/null
+++ b/java/lang/reflect/Member.annotated.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 1996, 2013, 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.reflect;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface Member {
+
[email protected] public java.lang.Class<?> getDeclaringClass();
+
[email protected] public java.lang.String getName();
+
+public int getModifiers();
+
+public boolean isSynthetic();
+
+public static final int DECLARED = 1; // 0x1
+
+public static final int PUBLIC = 0; // 0x0
+}
+
diff --git a/java/lang/reflect/Member.java b/java/lang/reflect/Member.java
new file mode 100644
index 0000000..2241d45
--- /dev/null
+++ b/java/lang/reflect/Member.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 1996, 2013, 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.reflect;
+
+/**
+ * Member is an interface that reflects identifying information about
+ * a single member (a field or a method) or a constructor.
+ *
+ * @see java.lang.Class
+ * @see Field
+ * @see Method
+ * @see Constructor
+ *
+ * @author Nakul Saraiya
+ */
+public
+interface Member {
+
+ /**
+ * Identifies the set of all public members of a class or interface,
+ * including inherited members.
+ */
+ public static final int PUBLIC = 0;
+
+ /**
+ * Identifies the set of declared members of a class or interface.
+ * Inherited members are not included.
+ */
+ public static final int DECLARED = 1;
+
+ /**
+ * Returns the Class object representing the class or interface
+ * that declares the member or constructor represented by this Member.
+ *
+ * @return an object representing the declaring class of the
+ * underlying member
+ */
+ public Class<?> getDeclaringClass();
+
+ /**
+ * Returns the simple name of the underlying member or constructor
+ * represented by this Member.
+ *
+ * @return the simple name of the underlying member
+ */
+ public String getName();
+
+ /**
+ * Returns the Java language modifiers for the member or
+ * constructor represented by this Member, as an integer. The
+ * Modifier class should be used to decode the modifiers in
+ * the integer.
+ *
+ * @return the Java language modifiers for the underlying member
+ * @see Modifier
+ */
+ public int getModifiers();
+
+ /**
+ * Returns {@code true} if this member was introduced by
+ * the compiler; returns {@code false} otherwise.
+ *
+ * @return true if and only if this member was introduced by
+ * the compiler.
+ * @jls 13.1 The Form of a Binary
+ * @since 1.5
+ */
+ public boolean isSynthetic();
+}
diff --git a/java/lang/reflect/Method.annotated.java b/java/lang/reflect/Method.annotated.java
new file mode 100644
index 0000000..004a5ed
--- /dev/null
+++ b/java/lang/reflect/Method.annotated.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1996, 2013, 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.reflect;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Method extends java.lang.reflect.Executable {
+
+Method() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.Class<?> getDeclaringClass() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String getName() { throw new RuntimeException("Stub!"); }
+
+public int getModifiers() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.reflect.TypeVariable<java.lang.reflect.Method>[] getTypeParameters() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.Class<?> getReturnType() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.reflect.Type getGenericReturnType() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.Class<?>[] getParameterTypes() { throw new RuntimeException("Stub!"); }
+
+public int getParameterCount() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.reflect.Type[] getGenericParameterTypes() { throw new RuntimeException("Stub!"); }
+
[email protected] public native java.lang.Class<?>[] getExceptionTypes();
+
[email protected] public java.lang.reflect.Type[] getGenericExceptionTypes() { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String toGenericString() { throw new RuntimeException("Stub!"); }
+
[email protected] public native java.lang.Object invoke(@libcore.util.Nullable java.lang.Object obj, [email protected] Object @libcore.util.Nullable ... args) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException, java.lang.reflect.InvocationTargetException;
+
+public boolean isBridge() { throw new RuntimeException("Stub!"); }
+
+public boolean isVarArgs() { throw new RuntimeException("Stub!"); }
+
+public boolean isSynthetic() { throw new RuntimeException("Stub!"); }
+
+public boolean isDefault() { throw new RuntimeException("Stub!"); }
+
[email protected] public native java.lang.Object getDefaultValue();
+
[email protected] public <T extends java.lang.annotation.Annotation> T getAnnotation(@libcore.util.NonNull java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.annotation.Annotation[] getDeclaredAnnotations() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.annotation.Annotation[][] getParameterAnnotations() { throw new RuntimeException("Stub!"); }
+}
diff --git a/java/lang/reflect/Method.java b/java/lang/reflect/Method.java
new file mode 100644
index 0000000..3da75c5
--- /dev/null
+++ b/java/lang/reflect/Method.java
@@ -0,0 +1,526 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1996, 2013, 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.reflect;
+
+import sun.reflect.CallerSensitive;
+import dalvik.annotation.optimization.FastNative;
+import java.lang.annotation.Annotation;
+import java.util.Comparator;
+import libcore.reflect.Types;
+import libcore.util.EmptyArray;
+
+/**
+ * A {@code Method} provides information about, and access to, a single method
+ * on a class or interface. The reflected method may be a class method
+ * or an instance method (including an abstract method).
+ *
+ * <p>A {@code Method} permits widening conversions to occur when matching the
+ * actual parameters to invoke with the underlying method's formal
+ * parameters, but it throws an {@code IllegalArgumentException} if a
+ * narrowing conversion would occur.
+ *
+ * @see Member
+ * @see java.lang.Class
+ * @see java.lang.Class#getMethods()
+ * @see java.lang.Class#getMethod(String, Class[])
+ * @see java.lang.Class#getDeclaredMethods()
+ * @see java.lang.Class#getDeclaredMethod(String, Class[])
+ *
+ * @author Kenneth Russell
+ * @author Nakul Saraiya
+ */
+public final class Method extends Executable {
+ // Android-changed: Extensive modifications made throughout the class for ART.
+ // Android-changed: Many fields and methods removed / modified.
+ // Android-removed: Type annotations runtime code. Not supported on Android.
+ // Android-removed: Declared vs actual parameter annotation indexes handling.
+
+ /**
+ * Orders methods by their name, parameters and return type.
+ *
+ * @hide
+ */
+ public static final Comparator<Method> ORDER_BY_SIGNATURE = new Comparator<Method>() {
+ @Override public int compare(Method a, Method b) {
+ if (a == b) {
+ return 0;
+ }
+ int comparison = a.getName().compareTo(b.getName());
+ if (comparison == 0) {
+ comparison = a.compareMethodParametersInternal(b);
+ if (comparison == 0) {
+ // This is necessary for methods that have covariant return types.
+ Class<?> aReturnType = a.getReturnType();
+ Class<?> bReturnType = b.getReturnType();
+ if (aReturnType == bReturnType) {
+ comparison = 0;
+ } else {
+ comparison = aReturnType.getName().compareTo(bReturnType.getName());
+ }
+ }
+ }
+ return comparison;
+ }
+ };
+
+ private Method() {
+ }
+
+ @Override
+ boolean hasGenericInformation() {
+ // Android-changed: hasGenericInformation() implemented using Executable.
+ return super.hasGenericInformationInternal();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Class<?> getDeclaringClass() {
+ // Android-changed: getDeclaringClass() implemented using Executable.
+ return super.getDeclaringClassInternal();
+ }
+
+ /**
+ * Returns the name of the method represented by this {@code Method}
+ * object, as a {@code String}.
+ */
+ @Override
+ public String getName() {
+ // Android-changed: getName() implemented using Executable.
+ return getMethodNameInternal();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int getModifiers() {
+ // Android-changed: getModifiers() implemented using Executable.
+ return super.getModifiersInternal();
+ }
+
+ /**
+ * {@inheritDoc}
+ * @throws GenericSignatureFormatError {@inheritDoc}
+ * @since 1.5
+ */
+ @Override
+ @SuppressWarnings({"rawtypes", "unchecked"})
+ public TypeVariable<Method>[] getTypeParameters() {
+ // Android-changed: getTypeParameters() partly implemented using Executable.
+ GenericInfo info = getMethodOrConstructorGenericInfoInternal();
+ return (TypeVariable<Method>[]) info.formalTypeParameters.clone();
+ }
+
+ /**
+ * Returns a {@code Class} object that represents the formal return type
+ * of the method represented by this {@code Method} object.
+ *
+ * @return the return type for the method this object represents
+ */
+ public Class<?> getReturnType() {
+ // Android-changed: getReturnType() implemented using Executable.
+ return getMethodReturnTypeInternal();
+ }
+
+ /**
+ * Returns a {@code Type} object that represents the formal return
+ * type of the method represented by this {@code Method} object.
+ *
+ * <p>If the return type is a parameterized type,
+ * the {@code Type} object returned must accurately reflect
+ * the actual type parameters used in the source code.
+ *
+ * <p>If the return type is a type variable or a parameterized type, it
+ * is created. Otherwise, it is resolved.
+ *
+ * @return a {@code Type} object that represents the formal return
+ * type of the underlying method
+ * @throws GenericSignatureFormatError
+ * if the generic method signature does not conform to the format
+ * specified in
+ * <cite>The Java™ Virtual Machine Specification</cite>
+ * @throws TypeNotPresentException if the underlying method's
+ * return type refers to a non-existent type declaration
+ * @throws MalformedParameterizedTypeException if the
+ * underlying method's return typed refers to a parameterized
+ * type that cannot be instantiated for any reason
+ * @since 1.5
+ */
+ public Type getGenericReturnType() {
+ // Android-changed: getGenericReturnType() partly implemented using Executable.
+ return Types.getType(getMethodOrConstructorGenericInfoInternal().genericReturnType);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Class<?>[] getParameterTypes() {
+ // Android-changed: getParameterTypes() partly implemented using Executable.
+ Class<?>[] paramTypes = super.getParameterTypesInternal();
+ if (paramTypes == null) {
+ return EmptyArray.CLASS;
+ }
+
+ return paramTypes;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @since 1.8
+ */
+ public int getParameterCount() {
+ // Android-changed: getParameterTypes() implemented using Executable.
+ return super.getParameterCountInternal();
+ }
+
+ /**
+ * {@inheritDoc}
+ * @throws GenericSignatureFormatError {@inheritDoc}
+ * @throws TypeNotPresentException {@inheritDoc}
+ * @throws MalformedParameterizedTypeException {@inheritDoc}
+ * @since 1.5
+ */
+ @Override
+ public Type[] getGenericParameterTypes() {
+ return super.getGenericParameterTypes();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ // Android-changed: getExceptionTypes() implemented natively.
+ @FastNative
+ public native Class<?>[] getExceptionTypes();
+
+ /**
+ * {@inheritDoc}
+ * @throws GenericSignatureFormatError {@inheritDoc}
+ * @throws TypeNotPresentException {@inheritDoc}
+ * @throws MalformedParameterizedTypeException {@inheritDoc}
+ * @since 1.5
+ */
+ @Override
+ public Type[] getGenericExceptionTypes() {
+ return super.getGenericExceptionTypes();
+ }
+
+ /**
+ * Compares this {@code Method} against the specified object. Returns
+ * true if the objects are the same. Two {@code Methods} are the same if
+ * they were declared by the same class and have the same name
+ * and formal parameter types and return type.
+ */
+ public boolean equals(Object obj) {
+ if (obj != null && obj instanceof Method) {
+ Method other = (Method)obj;
+ if ((getDeclaringClass() == other.getDeclaringClass())
+ && (getName() == other.getName())) {
+ // Android-changed: Use getReturnType() instead of deleted returnType field
+ if (!getReturnType().equals(other.getReturnType()))
+ return false;
+ // Android-changed: Use getParameterTypes() instead of deleted parameterTypes field
+ return equalParamTypes(getParameterTypes(), other.getParameterTypes());
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns a hashcode for this {@code Method}. The hashcode is computed
+ * as the exclusive-or of the hashcodes for the underlying
+ * method's declaring class name and the method's name.
+ */
+ public int hashCode() {
+ return getDeclaringClass().getName().hashCode() ^ getName().hashCode();
+ }
+
+ /**
+ * Returns a string describing this {@code Method}. The string is
+ * formatted as the method access modifiers, if any, followed by
+ * the method return type, followed by a space, followed by the
+ * class declaring the method, followed by a period, followed by
+ * the method name, followed by a parenthesized, comma-separated
+ * list of the method's formal parameter types. If the method
+ * throws checked exceptions, the parameter list is followed by a
+ * space, followed by the word throws followed by a
+ * comma-separated list of the thrown exception types.
+ * For example:
+ * <pre>
+ * public boolean java.lang.Object.equals(java.lang.Object)
+ * </pre>
+ *
+ * <p>The access modifiers are placed in canonical order as
+ * specified by "The Java Language Specification". This is
+ * {@code public}, {@code protected} or {@code private} first,
+ * and then other modifiers in the following order:
+ * {@code abstract}, {@code default}, {@code static}, {@code final},
+ * {@code synchronized}, {@code native}, {@code strictfp}.
+ *
+ * @return a string describing this {@code Method}
+ *
+ * @jls 8.4.3 Method Modifiers
+ */
+ public String toString() {
+ // Android-changed: Use getParameterTypes() / getExceptionTypes() instead of deleted fields
+ return sharedToString(Modifier.methodModifiers(),
+ isDefault(),
+ getParameterTypes(),
+ getExceptionTypes());
+ }
+
+ @Override
+ void specificToStringHeader(StringBuilder sb) {
+ sb.append(getReturnType().getTypeName()).append(' ');
+ sb.append(getDeclaringClass().getTypeName()).append('.');
+ sb.append(getName());
+ }
+
+ /**
+ * Returns a string describing this {@code Method}, including
+ * type parameters. The string is formatted as the method access
+ * modifiers, if any, followed by an angle-bracketed
+ * comma-separated list of the method's type parameters, if any,
+ * followed by the method's generic return type, followed by a
+ * space, followed by the class declaring the method, followed by
+ * a period, followed by the method name, followed by a
+ * parenthesized, comma-separated list of the method's generic
+ * formal parameter types.
+ *
+ * If this method was declared to take a variable number of
+ * arguments, instead of denoting the last parameter as
+ * "<tt><i>Type</i>[]</tt>", it is denoted as
+ * "<tt><i>Type</i>...</tt>".
+ *
+ * A space is used to separate access modifiers from one another
+ * and from the type parameters or return type. If there are no
+ * type parameters, the type parameter list is elided; if the type
+ * parameter list is present, a space separates the list from the
+ * class name. If the method is declared to throw exceptions, the
+ * parameter list is followed by a space, followed by the word
+ * throws followed by a comma-separated list of the generic thrown
+ * exception types.
+ *
+ * <p>The access modifiers are placed in canonical order as
+ * specified by "The Java Language Specification". This is
+ * {@code public}, {@code protected} or {@code private} first,
+ * and then other modifiers in the following order:
+ * {@code abstract}, {@code default}, {@code static}, {@code final},
+ * {@code synchronized}, {@code native}, {@code strictfp}.
+ *
+ * @return a string describing this {@code Method},
+ * include type parameters
+ *
+ * @since 1.5
+ *
+ * @jls 8.4.3 Method Modifiers
+ */
+ @Override
+ public String toGenericString() {
+ return sharedToGenericString(Modifier.methodModifiers(), isDefault());
+ }
+
+ @Override
+ void specificToGenericStringHeader(StringBuilder sb) {
+ Type genRetType = getGenericReturnType();
+ sb.append(genRetType.getTypeName()).append(' ');
+ sb.append(getDeclaringClass().getTypeName()).append('.');
+ sb.append(getName());
+ }
+
+ /**
+ * Invokes the underlying method represented by this {@code Method}
+ * object, on the specified object with the specified parameters.
+ * Individual parameters are automatically unwrapped to match
+ * primitive formal parameters, and both primitive and reference
+ * parameters are subject to method invocation conversions as
+ * necessary.
+ *
+ * <p>If the underlying method is static, then the specified {@code obj}
+ * argument is ignored. It may be null.
+ *
+ * <p>If the number of formal parameters required by the underlying method is
+ * 0, the supplied {@code args} array may be of length 0 or null.
+ *
+ * <p>If the underlying method is an instance method, it is invoked
+ * using dynamic method lookup as documented in The Java Language
+ * Specification, Second Edition, section 15.12.4.4; in particular,
+ * overriding based on the runtime type of the target object will occur.
+ *
+ * <p>If the underlying method is static, the class that declared
+ * the method is initialized if it has not already been initialized.
+ *
+ * <p>If the method completes normally, the value it returns is
+ * returned to the caller of invoke; if the value has a primitive
+ * type, it is first appropriately wrapped in an object. However,
+ * if the value has the type of an array of a primitive type, the
+ * elements of the array are <i>not</i> wrapped in objects; in
+ * other words, an array of primitive type is returned. If the
+ * underlying method return type is void, the invocation returns
+ * null.
+ *
+ * @param obj the object the underlying method is invoked from
+ * @param args the arguments used for the method call
+ * @return the result of dispatching the method represented by
+ * this object on {@code obj} with parameters
+ * {@code args}
+ *
+ * @exception IllegalAccessException if this {@code Method} object
+ * is enforcing Java language access control and the underlying
+ * method is inaccessible.
+ * @exception IllegalArgumentException if the method is an
+ * instance method and the specified object argument
+ * is not an instance of the class or interface
+ * declaring the underlying method (or of a subclass
+ * or implementor thereof); if the number of actual
+ * and formal parameters differ; if an unwrapping
+ * conversion for primitive arguments fails; or if,
+ * after possible unwrapping, a parameter value
+ * cannot be converted to the corresponding formal
+ * parameter type by a method invocation conversion.
+ * @exception InvocationTargetException if the underlying method
+ * throws an exception.
+ * @exception NullPointerException if the specified object is null
+ * and the method is an instance method.
+ * @exception ExceptionInInitializerError if the initialization
+ * provoked by this method fails.
+ */
+ @CallerSensitive
+ // Android-changed: invoke(Object, Object...) implemented natively.
+ @FastNative
+ public native Object invoke(Object obj, Object... args)
+ throws IllegalAccessException, IllegalArgumentException, InvocationTargetException;
+
+ /**
+ * Returns {@code true} if this method is a bridge
+ * method; returns {@code false} otherwise.
+ *
+ * @return true if and only if this method is a bridge
+ * method as defined by the Java Language Specification.
+ * @since 1.5
+ */
+ public boolean isBridge() {
+ // Android-changed: isBridge() implemented using Executable.
+ return super.isBridgeMethodInternal();
+ }
+
+ /**
+ * {@inheritDoc}
+ * @since 1.5
+ */
+ @Override
+ public boolean isVarArgs() {
+ return super.isVarArgs();
+ }
+
+ /**
+ * {@inheritDoc}
+ * @jls 13.1 The Form of a Binary
+ * @since 1.5
+ */
+ @Override
+ public boolean isSynthetic() {
+ return super.isSynthetic();
+ }
+
+ /**
+ * Returns {@code true} if this method is a default
+ * method; returns {@code false} otherwise.
+ *
+ * A default method is a public non-abstract instance method, that
+ * is, a non-static method with a body, declared in an interface
+ * type.
+ *
+ * @return true if and only if this method is a default
+ * method as defined by the Java Language Specification.
+ * @since 1.8
+ */
+ public boolean isDefault() {
+ // Android-changed: isDefault() implemented using Executable.
+ return super.isDefaultMethodInternal();
+ }
+
+ /**
+ * Returns the default value for the annotation member represented by
+ * this {@code Method} instance. If the member is of a primitive type,
+ * an instance of the corresponding wrapper type is returned. Returns
+ * null if no default is associated with the member, or if the method
+ * instance does not represent a declared member of an annotation type.
+ *
+ * @return the default value for the annotation member represented
+ * by this {@code Method} instance.
+ * @throws TypeNotPresentException if the annotation is of type
+ * {@link Class} and no definition can be found for the
+ * default class value.
+ * @since 1.5
+ */
+ // Android-changed: isDefault() implemented natively.
+ @FastNative
+ public native Object getDefaultValue();
+
+ /**
+ * {@inheritDoc}
+ * @throws NullPointerException {@inheritDoc}
+ * @since 1.5
+ */
+ public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
+ return super.getAnnotation(annotationClass);
+ }
+
+ /**
+ * {@inheritDoc}
+ * @since 1.5
+ */
+ public Annotation[] getDeclaredAnnotations() {
+ return super.getDeclaredAnnotations();
+ }
+
+ /**
+ * {@inheritDoc}
+ * @since 1.5
+ */
+ @Override
+ public Annotation[][] getParameterAnnotations() {
+ // Android-changed: getParameterAnnotations() implemented using Executable.
+ return super.getParameterAnnotationsInternal();
+ }
+
+ // Android-added: equalNameAndParameters(Method) for Proxy support.
+ /**
+ * Returns true if this and {@code method} have the same name and the same
+ * parameters in the same order. Such methods can share implementation if
+ * one method's return types is assignable to the other.
+ *
+ * @hide needed by Proxy
+ */
+ boolean equalNameAndParameters(Method m) {
+ return equalNameAndParametersInternal(m);
+ }
+}
diff --git a/java/lang/reflect/Modifier.java b/java/lang/reflect/Modifier.java
new file mode 100644
index 0000000..28d89bb
--- /dev/null
+++ b/java/lang/reflect/Modifier.java
@@ -0,0 +1,527 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1996, 2013, 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.reflect;
+
+/**
+ * The Modifier class provides {@code static} methods and
+ * constants to decode class and member access modifiers. The sets of
+ * modifiers are represented as integers with distinct bit positions
+ * representing different modifiers. The values for the constants
+ * representing the modifiers are taken from the tables in sections 4.1, 4.4, 4.5, and 4.7 of
+ * <cite>The Java™ Virtual Machine Specification</cite>.
+ *
+ * @see Class#getModifiers()
+ * @see Member#getModifiers()
+ *
+ * @author Nakul Saraiya
+ * @author Kenneth Russell
+ */
+public class Modifier {
+
+ // Android-removed: ReflectionFactory bootstrapping code not used on Android.
+ /*
+ /*
+ * Bootstrapping protocol between java.lang and java.lang.reflect
+ * packages
+ *
+ static {
+ sun.reflect.ReflectionFactory factory =
+ AccessController.doPrivileged(
+ new ReflectionFactory.GetReflectionFactoryAction());
+ factory.setLangReflectAccess(new java.lang.reflect.ReflectAccess());
+ }
+ */
+
+ /**
+ * Return {@code true} if the integer argument includes the
+ * {@code public} modifier, {@code false} otherwise.
+ *
+ * @param mod a set of modifiers
+ * @return {@code true} if {@code mod} includes the
+ * {@code public} modifier; {@code false} otherwise.
+ */
+ public static boolean isPublic(int mod) {
+ return (mod & PUBLIC) != 0;
+ }
+
+ /**
+ * Return {@code true} if the integer argument includes the
+ * {@code private} modifier, {@code false} otherwise.
+ *
+ * @param mod a set of modifiers
+ * @return {@code true} if {@code mod} includes the
+ * {@code private} modifier; {@code false} otherwise.
+ */
+ public static boolean isPrivate(int mod) {
+ return (mod & PRIVATE) != 0;
+ }
+
+ /**
+ * Return {@code true} if the integer argument includes the
+ * {@code protected} modifier, {@code false} otherwise.
+ *
+ * @param mod a set of modifiers
+ * @return {@code true} if {@code mod} includes the
+ * {@code protected} modifier; {@code false} otherwise.
+ */
+ public static boolean isProtected(int mod) {
+ return (mod & PROTECTED) != 0;
+ }
+
+ /**
+ * Return {@code true} if the integer argument includes the
+ * {@code static} modifier, {@code false} otherwise.
+ *
+ * @param mod a set of modifiers
+ * @return {@code true} if {@code mod} includes the
+ * {@code static} modifier; {@code false} otherwise.
+ */
+ public static boolean isStatic(int mod) {
+ return (mod & STATIC) != 0;
+ }
+
+ /**
+ * Return {@code true} if the integer argument includes the
+ * {@code final} modifier, {@code false} otherwise.
+ *
+ * @param mod a set of modifiers
+ * @return {@code true} if {@code mod} includes the
+ * {@code final} modifier; {@code false} otherwise.
+ */
+ public static boolean isFinal(int mod) {
+ return (mod & FINAL) != 0;
+ }
+
+ /**
+ * Return {@code true} if the integer argument includes the
+ * {@code synchronized} modifier, {@code false} otherwise.
+ *
+ * @param mod a set of modifiers
+ * @return {@code true} if {@code mod} includes the
+ * {@code synchronized} modifier; {@code false} otherwise.
+ */
+ public static boolean isSynchronized(int mod) {
+ return (mod & SYNCHRONIZED) != 0;
+ }
+
+ /**
+ * Return {@code true} if the integer argument includes the
+ * {@code volatile} modifier, {@code false} otherwise.
+ *
+ * @param mod a set of modifiers
+ * @return {@code true} if {@code mod} includes the
+ * {@code volatile} modifier; {@code false} otherwise.
+ */
+ public static boolean isVolatile(int mod) {
+ return (mod & VOLATILE) != 0;
+ }
+
+ // Android-added: isConstructor(int) to support DEX-defined modifier flag.
+ /**
+ * Returns true if the given modifiers contain {@link Modifier#CONSTRUCTOR}.
+ * @hide
+ */
+ public static boolean isConstructor(int modifiers) {
+ return ((modifiers & Modifier.CONSTRUCTOR) != 0);
+ }
+
+ /**
+ * Return {@code true} if the integer argument includes the
+ * {@code transient} modifier, {@code false} otherwise.
+ *
+ * @param mod a set of modifiers
+ * @return {@code true} if {@code mod} includes the
+ * {@code transient} modifier; {@code false} otherwise.
+ */
+ public static boolean isTransient(int mod) {
+ return (mod & TRANSIENT) != 0;
+ }
+
+ /**
+ * Return {@code true} if the integer argument includes the
+ * {@code native} modifier, {@code false} otherwise.
+ *
+ * @param mod a set of modifiers
+ * @return {@code true} if {@code mod} includes the
+ * {@code native} modifier; {@code false} otherwise.
+ */
+ public static boolean isNative(int mod) {
+ return (mod & NATIVE) != 0;
+ }
+
+ /**
+ * Return {@code true} if the integer argument includes the
+ * {@code interface} modifier, {@code false} otherwise.
+ *
+ * @param mod a set of modifiers
+ * @return {@code true} if {@code mod} includes the
+ * {@code interface} modifier; {@code false} otherwise.
+ */
+ public static boolean isInterface(int mod) {
+ return (mod & INTERFACE) != 0;
+ }
+
+ /**
+ * Return {@code true} if the integer argument includes the
+ * {@code abstract} modifier, {@code false} otherwise.
+ *
+ * @param mod a set of modifiers
+ * @return {@code true} if {@code mod} includes the
+ * {@code abstract} modifier; {@code false} otherwise.
+ */
+ public static boolean isAbstract(int mod) {
+ return (mod & ABSTRACT) != 0;
+ }
+
+ /**
+ * Return {@code true} if the integer argument includes the
+ * {@code strictfp} modifier, {@code false} otherwise.
+ *
+ * @param mod a set of modifiers
+ * @return {@code true} if {@code mod} includes the
+ * {@code strictfp} modifier; {@code false} otherwise.
+ */
+ public static boolean isStrict(int mod) {
+ return (mod & STRICT) != 0;
+ }
+
+ /**
+ * Return a string describing the access modifier flags in
+ * the specified modifier. For example:
+ * <blockquote><pre>
+ * public final synchronized strictfp
+ * </pre></blockquote>
+ * The modifier names are returned in an order consistent with the
+ * suggested modifier orderings given in sections 8.1.1, 8.3.1, 8.4.3, 8.8.3, and 9.1.1 of
+ * <cite>The Java™ Language Specification</cite>.
+ * The full modifier ordering used by this method is:
+ * <blockquote> {@code
+ * public protected private abstract static final transient
+ * volatile synchronized native strictfp
+ * interface } </blockquote>
+ * The {@code interface} modifier discussed in this class is
+ * not a true modifier in the Java language and it appears after
+ * all other modifiers listed by this method. This method may
+ * return a string of modifiers that are not valid modifiers of a
+ * Java entity; in other words, no checking is done on the
+ * possible validity of the combination of modifiers represented
+ * by the input.
+ *
+ * Note that to perform such checking for a known kind of entity,
+ * such as a constructor or method, first AND the argument of
+ * {@code toString} with the appropriate mask from a method like
+ * {@link #constructorModifiers} or {@link #methodModifiers}.
+ *
+ * @param mod a set of modifiers
+ * @return a string representation of the set of modifiers
+ * represented by {@code mod}
+ */
+ public static String toString(int mod) {
+ StringBuilder sb = new StringBuilder();
+ int len;
+
+ if ((mod & PUBLIC) != 0) sb.append("public ");
+ if ((mod & PROTECTED) != 0) sb.append("protected ");
+ if ((mod & PRIVATE) != 0) sb.append("private ");
+
+ /* Canonical order */
+ if ((mod & ABSTRACT) != 0) sb.append("abstract ");
+ if ((mod & STATIC) != 0) sb.append("static ");
+ if ((mod & FINAL) != 0) sb.append("final ");
+ if ((mod & TRANSIENT) != 0) sb.append("transient ");
+ if ((mod & VOLATILE) != 0) sb.append("volatile ");
+ if ((mod & SYNCHRONIZED) != 0) sb.append("synchronized ");
+ if ((mod & NATIVE) != 0) sb.append("native ");
+ if ((mod & STRICT) != 0) sb.append("strictfp ");
+ if ((mod & INTERFACE) != 0) sb.append("interface ");
+
+ if ((len = sb.length()) > 0) /* trim trailing space */
+ return sb.toString().substring(0, len-1);
+ return "";
+ }
+
+ /*
+ * Access modifier flag constants from tables 4.1, 4.4, 4.5, and 4.7 of
+ * <cite>The Java™ Virtual Machine Specification</cite>
+ */
+
+ /**
+ * The {@code int} value representing the {@code public}
+ * modifier.
+ */
+ public static final int PUBLIC = 0x00000001;
+
+ /**
+ * The {@code int} value representing the {@code private}
+ * modifier.
+ */
+ public static final int PRIVATE = 0x00000002;
+
+ /**
+ * The {@code int} value representing the {@code protected}
+ * modifier.
+ */
+ public static final int PROTECTED = 0x00000004;
+
+ /**
+ * The {@code int} value representing the {@code static}
+ * modifier.
+ */
+ public static final int STATIC = 0x00000008;
+
+ /**
+ * The {@code int} value representing the {@code final}
+ * modifier.
+ */
+ public static final int FINAL = 0x00000010;
+
+ /**
+ * The {@code int} value representing the {@code synchronized}
+ * modifier.
+ */
+ public static final int SYNCHRONIZED = 0x00000020;
+
+ /**
+ * The {@code int} value representing the {@code volatile}
+ * modifier.
+ */
+ public static final int VOLATILE = 0x00000040;
+
+ /**
+ * The {@code int} value representing the {@code transient}
+ * modifier.
+ */
+ public static final int TRANSIENT = 0x00000080;
+
+ /**
+ * The {@code int} value representing the {@code native}
+ * modifier.
+ */
+ public static final int NATIVE = 0x00000100;
+
+ /**
+ * The {@code int} value representing the {@code interface}
+ * modifier.
+ */
+ public static final int INTERFACE = 0x00000200;
+
+ /**
+ * The {@code int} value representing the {@code abstract}
+ * modifier.
+ */
+ public static final int ABSTRACT = 0x00000400;
+
+ /**
+ * The {@code int} value representing the {@code strictfp}
+ * modifier.
+ */
+ public static final int STRICT = 0x00000800;
+
+ // Bits not (yet) exposed in the public API either because they
+ // have different meanings for fields and methods and there is no
+ // way to distinguish between the two in this class, or because
+ // they are not Java programming language keywords
+ static final int BRIDGE = 0x00000040;
+ static final int VARARGS = 0x00000080;
+ // Android-changed: SYNTHETIC made public for use in tests.
+ /**
+ * @hide
+ */
+ public static final int SYNTHETIC = 0x00001000;
+ static final int ANNOTATION = 0x00002000;
+ static final int ENUM = 0x00004000;
+ static final int MANDATED = 0x00008000;
+ static boolean isSynthetic(int mod) {
+ return (mod & SYNTHETIC) != 0;
+ }
+
+ static boolean isMandated(int mod) {
+ return (mod & MANDATED) != 0;
+ }
+
+ // Note on the FOO_MODIFIERS fields and fooModifiers() methods:
+ // the sets of modifiers are not guaranteed to be constants
+ // across time and Java SE releases. Therefore, it would not be
+ // appropriate to expose an external interface to this information
+ // that would allow the values to be treated as Java-level
+ // constants since the values could be constant folded and updates
+ // to the sets of modifiers missed. Thus, the fooModifiers()
+ // methods return an unchanging values for a given release, but a
+ // value that can potentially change over time.
+
+ // Android-added: CONSTRUCTOR to support DEX-defined modifier flag.
+ /**
+ * Dex addition to mark instance constructors and static class
+ * initializer methods.
+ * @hide
+ */
+ public static final int CONSTRUCTOR = 0x10000;
+
+ // Android-added: DEFAULT to support DEX-defined modifier flag.
+ /**
+ * Default methods are marked with a synthetic access flag
+ * to speed up class loading and invocation target lookup.
+ * Implies INTERFACE, not-ABSTRACT, and not-STATIC.
+ *
+ * @hide
+ */
+ public static final int DEFAULT = 0x00400000;
+
+ /**
+ * The Java source modifiers that can be applied to a class.
+ * @jls 8.1.1 Class Modifiers
+ */
+ private static final int CLASS_MODIFIERS =
+ Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE |
+ Modifier.ABSTRACT | Modifier.STATIC | Modifier.FINAL |
+ Modifier.STRICT;
+
+ /**
+ * The Java source modifiers that can be applied to an interface.
+ * @jls 9.1.1 Interface Modifiers
+ */
+ private static final int INTERFACE_MODIFIERS =
+ Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE |
+ Modifier.ABSTRACT | Modifier.STATIC | Modifier.STRICT;
+
+
+ /**
+ * The Java source modifiers that can be applied to a constructor.
+ * @jls 8.8.3 Constructor Modifiers
+ */
+ private static final int CONSTRUCTOR_MODIFIERS =
+ Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE;
+
+ /**
+ * The Java source modifiers that can be applied to a method.
+ * @jls8.4.3 Method Modifiers
+ */
+ private static final int METHOD_MODIFIERS =
+ Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE |
+ Modifier.ABSTRACT | Modifier.STATIC | Modifier.FINAL |
+ Modifier.SYNCHRONIZED | Modifier.NATIVE | Modifier.STRICT;
+
+ /**
+ * The Java source modifiers that can be applied to a field.
+ * @jls 8.3.1 Field Modifiers
+ */
+ private static final int FIELD_MODIFIERS =
+ Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE |
+ Modifier.STATIC | Modifier.FINAL | Modifier.TRANSIENT |
+ Modifier.VOLATILE;
+
+ /**
+ * The Java source modifiers that can be applied to a method or constructor parameter.
+ * @jls 8.4.1 Formal Parameters
+ */
+ private static final int PARAMETER_MODIFIERS =
+ Modifier.FINAL;
+
+ /**
+ *
+ */
+ static final int ACCESS_MODIFIERS =
+ Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE;
+
+ /**
+ * Return an {@code int} value OR-ing together the source language
+ * modifiers that can be applied to a class.
+ * @return an {@code int} value OR-ing together the source language
+ * modifiers that can be applied to a class.
+ *
+ * @jls 8.1.1 Class Modifiers
+ * @since 1.7
+ */
+ public static int classModifiers() {
+ return CLASS_MODIFIERS;
+ }
+
+ /**
+ * Return an {@code int} value OR-ing together the source language
+ * modifiers that can be applied to an interface.
+ * @return an {@code int} value OR-ing together the source language
+ * modifiers that can be applied to an interface.
+ *
+ * @jls 9.1.1 Interface Modifiers
+ * @since 1.7
+ */
+ public static int interfaceModifiers() {
+ return INTERFACE_MODIFIERS;
+ }
+
+ /**
+ * Return an {@code int} value OR-ing together the source language
+ * modifiers that can be applied to a constructor.
+ * @return an {@code int} value OR-ing together the source language
+ * modifiers that can be applied to a constructor.
+ *
+ * @jls 8.8.3 Constructor Modifiers
+ * @since 1.7
+ */
+ public static int constructorModifiers() {
+ return CONSTRUCTOR_MODIFIERS;
+ }
+
+ /**
+ * Return an {@code int} value OR-ing together the source language
+ * modifiers that can be applied to a method.
+ * @return an {@code int} value OR-ing together the source language
+ * modifiers that can be applied to a method.
+ *
+ * @jls 8.4.3 Method Modifiers
+ * @since 1.7
+ */
+ public static int methodModifiers() {
+ return METHOD_MODIFIERS;
+ }
+
+ /**
+ * Return an {@code int} value OR-ing together the source language
+ * modifiers that can be applied to a field.
+ * @return an {@code int} value OR-ing together the source language
+ * modifiers that can be applied to a field.
+ *
+ * @jls 8.3.1 Field Modifiers
+ * @since 1.7
+ */
+ public static int fieldModifiers() {
+ return FIELD_MODIFIERS;
+ }
+
+ /**
+ * Return an {@code int} value OR-ing together the source language
+ * modifiers that can be applied to a parameter.
+ * @return an {@code int} value OR-ing together the source language
+ * modifiers that can be applied to a parameter.
+ *
+ * @jls 8.4.1 Formal Parameters
+ * @since 1.8
+ */
+ public static int parameterModifiers() {
+ return PARAMETER_MODIFIERS;
+ }
+}
diff --git a/java/lang/reflect/Parameter.annotated.java b/java/lang/reflect/Parameter.annotated.java
new file mode 100644
index 0000000..247db53
--- /dev/null
+++ b/java/lang/reflect/Parameter.annotated.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2013, 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.reflect;
+
+import java.lang.annotation.*;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Parameter implements java.lang.reflect.AnnotatedElement {
+
+Parameter(java.lang.String name, int modifiers, java.lang.reflect.Executable executable, int index) { throw new RuntimeException("Stub!"); }
+
+public boolean equals(@libcore.util.Nullable java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public boolean isNamePresent() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.reflect.Executable getDeclaringExecutable() { throw new RuntimeException("Stub!"); }
+
+public int getModifiers() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.String getName() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.reflect.Type getParameterizedType() { throw new RuntimeException("Stub!"); }
+
[email protected] public java.lang.Class<?> getType() { throw new RuntimeException("Stub!"); }
+
+public boolean isImplicit() { throw new RuntimeException("Stub!"); }
+
+public boolean isSynthetic() { throw new RuntimeException("Stub!"); }
+
+public boolean isVarArgs() { throw new RuntimeException("Stub!"); }
+
[email protected] public <T extends java.lang.annotation.Annotation> T getAnnotation(@libcore.util.NonNull java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public <T extends java.lang.annotation.Annotation> T[] getAnnotationsByType(@libcore.util.NonNull java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public [email protected] Annotation @libcore.util.NonNull [] getDeclaredAnnotations() { throw new RuntimeException("Stub!"); }
+
[email protected] public <T extends java.lang.annotation.Annotation> T getDeclaredAnnotation(@libcore.util.NonNull java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public <T extends java.lang.annotation.Annotation> T[] getDeclaredAnnotationsByType(@libcore.util.NonNull java.lang.Class<T> annotationClass) { throw new RuntimeException("Stub!"); }
+
+public [email protected] Annotation @libcore.util.NonNull [] getAnnotations() { throw new RuntimeException("Stub!"); }
+}
diff --git a/java/lang/reflect/Parameter.java b/java/lang/reflect/Parameter.java
new file mode 100644
index 0000000..4dc32b4
--- /dev/null
+++ b/java/lang/reflect/Parameter.java
@@ -0,0 +1,330 @@
+/*
+ * Copyright (c) 2013, 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.reflect;
+
+import dalvik.annotation.optimization.FastNative;
+import java.lang.annotation.*;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import libcore.reflect.AnnotatedElements;
+
+/**
+ * Information about method parameters.
+ *
+ * A {@code Parameter} provides information about method parameters,
+ * including its name and modifiers. It also provides an alternate
+ * means of obtaining attributes for the parameter.
+ *
+ * @since 1.8
+ */
+public final class Parameter implements AnnotatedElement {
+ // Android-changed: Extensive modifications made throughout the class for ART.
+ // Android-removed: Type annotations runtime code. Not supported on Android.
+ // Android-removed: Annotation retrieval is implemented natively in ART.
+
+ private final String name;
+ private final int modifiers;
+ private final Executable executable;
+ private final int index;
+
+ /**
+ * Package-private constructor for {@code Parameter}.
+ *
+ * If method parameter data is present in the classfile, then the
+ * JVM creates {@code Parameter} objects directly. If it is
+ * absent, however, then {@code Executable} uses this constructor
+ * to synthesize them.
+ *
+ * @param name The name of the parameter.
+ * @param modifiers The modifier flags for the parameter.
+ * @param executable The executable which defines this parameter.
+ * @param index The index of the parameter.
+ */
+ Parameter(String name,
+ int modifiers,
+ Executable executable,
+ int index) {
+ this.name = name;
+ this.modifiers = modifiers;
+ this.executable = executable;
+ this.index = index;
+ }
+
+ /**
+ * Compares based on the executable and the index.
+ *
+ * @param obj The object to compare.
+ * @return Whether or not this is equal to the argument.
+ */
+ public boolean equals(Object obj) {
+ if(obj instanceof Parameter) {
+ Parameter other = (Parameter)obj;
+ return (other.executable.equals(executable) &&
+ other.index == index);
+ }
+ return false;
+ }
+
+ /**
+ * Returns a hash code based on the executable's hash code and the
+ * index.
+ *
+ * @return A hash code based on the executable's hash code.
+ */
+ public int hashCode() {
+ return executable.hashCode() ^ index;
+ }
+
+ // Android-changed: Removed references in javadoc to the class file format.
+ /**
+ * Returns true if the parameter has a name; returns false otherwise.
+ * Whether a parameter has a name is determined by compiler options
+ * and whether the parameter is synthesized.
+ *
+ * @return true if and only if the parameter has a name
+ */
+ public boolean isNamePresent() {
+ return executable.hasRealParameterData() && name != null;
+ }
+
+ /**
+ * Returns a string describing this parameter. The format is the
+ * modifiers for the parameter, if any, in canonical order as
+ * recommended by <cite>The Java™ Language
+ * Specification</cite>, followed by the fully- qualified type of
+ * the parameter (excluding the last [] if the parameter is
+ * variable arity), followed by "..." if the parameter is variable
+ * arity, followed by a space, followed by the name of the
+ * parameter.
+ *
+ * @return A string representation of the parameter and associated
+ * information.
+ */
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+ final Type type = getParameterizedType();
+ final String typename = type.getTypeName();
+
+ sb.append(Modifier.toString(getModifiers()));
+
+ if(0 != modifiers)
+ sb.append(' ');
+
+ if(isVarArgs())
+ sb.append(typename.replaceFirst("\\[\\]$", "..."));
+ else
+ sb.append(typename);
+
+ sb.append(' ');
+ sb.append(getName());
+
+ return sb.toString();
+ }
+
+ /**
+ * Return the {@code Executable} which declares this parameter.
+ *
+ * @return The {@code Executable} declaring this parameter.
+ */
+ public Executable getDeclaringExecutable() {
+ return executable;
+ }
+
+ /**
+ * Get the modifier flags for this the parameter represented by
+ * this {@code Parameter} object.
+ *
+ * @return The modifier flags for this parameter.
+ */
+ public int getModifiers() {
+ return modifiers;
+ }
+
+ /**
+ * Returns the name of the parameter. If the parameter's name is
+ * {@linkplain #isNamePresent() present}, then this method returns
+ * the name provided by the class file. Otherwise, this method
+ * synthesizes a name of the form argN, where N is the index of
+ * the parameter in the descriptor of the method which declares
+ * the parameter.
+ *
+ * @return The name of the parameter, either provided by the class
+ * file or synthesized if the class file does not provide
+ * a name.
+ */
+ public String getName() {
+ // Note: empty strings as paramete names are now outlawed.
+ // The .equals("") is for compatibility with current JVM
+ // behavior. It may be removed at some point.
+ if(name == null || name.equals(""))
+ return "arg" + index;
+ else
+ return name;
+ }
+
+ // Package-private accessor to the real name field.
+ String getRealName() {
+ return name;
+ }
+
+ /**
+ * Returns a {@code Type} object that identifies the parameterized
+ * type for the parameter represented by this {@code Parameter}
+ * object.
+ *
+ * @return a {@code Type} object identifying the parameterized
+ * type of the parameter represented by this object
+ */
+ public Type getParameterizedType() {
+ Type tmp = parameterTypeCache;
+ if (null == tmp) {
+ tmp = executable.getAllGenericParameterTypes()[index];
+ parameterTypeCache = tmp;
+ }
+
+ return tmp;
+ }
+
+ private transient volatile Type parameterTypeCache = null;
+
+ /**
+ * Returns a {@code Class} object that identifies the
+ * declared type for the parameter represented by this
+ * {@code Parameter} object.
+ *
+ * @return a {@code Class} object identifying the declared
+ * type of the parameter represented by this object
+ */
+ public Class<?> getType() {
+ Class<?> tmp = parameterClassCache;
+ if (null == tmp) {
+ tmp = executable.getParameterTypes()[index];
+ parameterClassCache = tmp;
+ }
+ return tmp;
+ }
+
+ private transient volatile Class<?> parameterClassCache = null;
+
+ /**
+ * Returns {@code true} if this parameter is implicitly declared
+ * in source code; returns {@code false} otherwise.
+ *
+ * @return true if and only if this parameter is implicitly
+ * declared as defined by <cite>The Java™ Language
+ * Specification</cite>.
+ */
+ public boolean isImplicit() {
+ return Modifier.isMandated(getModifiers());
+ }
+
+ /**
+ * Returns {@code true} if this parameter is neither implicitly
+ * nor explicitly declared in source code; returns {@code false}
+ * otherwise.
+ *
+ * @jls 13.1 The Form of a Binary
+ * @return true if and only if this parameter is a synthetic
+ * construct as defined by
+ * <cite>The Java™ Language Specification</cite>.
+ */
+ public boolean isSynthetic() {
+ return Modifier.isSynthetic(getModifiers());
+ }
+
+ /**
+ * Returns {@code true} if this parameter represents a variable
+ * argument list; returns {@code false} otherwise.
+ *
+ * @return {@code true} if an only if this parameter represents a
+ * variable argument list.
+ */
+ public boolean isVarArgs() {
+ return executable.isVarArgs() &&
+ index == executable.getParameterCount() - 1;
+ }
+
+
+ /**
+ * {@inheritDoc}
+ * @throws NullPointerException {@inheritDoc}
+ */
+ public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
+ Objects.requireNonNull(annotationClass);
+ // Android-changed: getAnnotation(Class) Uses native code to obtain annotation information.
+ return getAnnotationNative(executable, index, annotationClass);
+ }
+ // Android-added: getAnnotation(Class) Uses native code to obtain annotation information.
+ @FastNative
+ private static native <A extends Annotation> A getAnnotationNative(
+ Executable executable, int parameterIndex, Class<A> annotationType);
+
+ /**
+ * {@inheritDoc}
+ * @throws NullPointerException {@inheritDoc}
+ */
+ @Override
+ public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) {
+ // Android-changed: getAnnotationsByType(Class), Android uses AnnotatedElements instead.
+ return AnnotatedElements.getDirectOrIndirectAnnotationsByType(this, annotationClass);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Annotation[] getDeclaredAnnotations() {
+ return executable.getParameterAnnotations()[index];
+ }
+
+ /**
+ * @throws NullPointerException {@inheritDoc}
+ */
+ public <T extends Annotation> T getDeclaredAnnotation(Class<T> annotationClass) {
+ // Only annotations on classes are inherited, for all other
+ // objects getDeclaredAnnotation is the same as
+ // getAnnotation.
+ return getAnnotation(annotationClass);
+ }
+
+ /**
+ * @throws NullPointerException {@inheritDoc}
+ */
+ @Override
+ public <T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotationClass) {
+ // Only annotations on classes are inherited, for all other
+ // objects getDeclaredAnnotations is the same as
+ // getAnnotations.
+ return getAnnotationsByType(annotationClass);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Annotation[] getAnnotations() {
+ return getDeclaredAnnotations();
+ }
+
+}
diff --git a/java/lang/reflect/ParameterizedType.annotated.java b/java/lang/reflect/ParameterizedType.annotated.java
new file mode 100644
index 0000000..1502d68
--- /dev/null
+++ b/java/lang/reflect/ParameterizedType.annotated.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2003, 2004, 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.reflect;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface ParameterizedType extends java.lang.reflect.Type {
+
+public [email protected] Type @libcore.util.NonNull [] getActualTypeArguments();
+
[email protected] public java.lang.reflect.Type getRawType();
+
[email protected] public java.lang.reflect.Type getOwnerType();
+}
diff --git a/java/lang/reflect/ParameterizedType.java b/java/lang/reflect/ParameterizedType.java
new file mode 100644
index 0000000..a1b1398
--- /dev/null
+++ b/java/lang/reflect/ParameterizedType.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2003, 2004, 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.reflect;
+
+
+/**
+ * ParameterizedType represents a parameterized type such as
+ * Collection<String>.
+ *
+ * <p>A parameterized type is created the first time it is needed by a
+ * reflective method, as specified in this package. When a
+ * parameterized type p is created, the generic type declaration that
+ * p instantiates is resolved, and all type arguments of p are created
+ * recursively. See {@link java.lang.reflect.TypeVariable
+ * TypeVariable} for details on the creation process for type
+ * variables. Repeated creation of a parameterized type has no effect.
+ *
+ * <p>Instances of classes that implement this interface must implement
+ * an equals() method that equates any two instances that share the
+ * same generic type declaration and have equal type parameters.
+ *
+ * @since 1.5
+ */
+public interface ParameterizedType extends Type {
+ /**
+ * Returns an array of {@code Type} objects representing the actual type
+ * arguments to this type.
+ *
+ * <p>Note that in some cases, the returned array be empty. This can occur
+ * if this type represents a non-parameterized type nested within
+ * a parameterized type.
+ *
+ * @return an array of {@code Type} objects representing the actual type
+ * arguments to this type
+ * @throws TypeNotPresentException if any of the
+ * actual type arguments refers to a non-existent type declaration
+ * @throws MalformedParameterizedTypeException if any of the
+ * actual type parameters refer to a parameterized type that cannot
+ * be instantiated for any reason
+ * @since 1.5
+ */
+ Type[] getActualTypeArguments();
+
+ /**
+ * Returns the {@code Type} object representing the class or interface
+ * that declared this type.
+ *
+ * @return the {@code Type} object representing the class or interface
+ * that declared this type
+ * @since 1.5
+ */
+ Type getRawType();
+
+ /**
+ * Returns a {@code Type} object representing the type that this type
+ * is a member of. For example, if this type is {@code O<T>.I<S>},
+ * return a representation of {@code O<T>}.
+ *
+ * <p>If this type is a top-level type, {@code null} is returned.
+ *
+ * @return a {@code Type} object representing the type that
+ * this type is a member of. If this type is a top-level type,
+ * {@code null} is returned
+ * @throws TypeNotPresentException if the owner type
+ * refers to a non-existent type declaration
+ * @throws MalformedParameterizedTypeException if the owner type
+ * refers to a parameterized type that cannot be instantiated
+ * for any reason
+ * @since 1.5
+ */
+ Type getOwnerType();
+}
diff --git a/java/lang/reflect/Proxy.annotated.java b/java/lang/reflect/Proxy.annotated.java
new file mode 100644
index 0000000..eb396c7
--- /dev/null
+++ b/java/lang/reflect/Proxy.annotated.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1999, 2013, 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.reflect;
+
+import java.security.Permission;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class Proxy implements java.io.Serializable {
+
+protected Proxy(@libcore.util.NonNull java.lang.reflect.InvocationHandler h) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Class<?> getProxyClass(@libcore.util.Nullable java.lang.ClassLoader loader, [email protected] Class<?> @libcore.util.NonNull ... interfaces) throws java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.Object newProxyInstance(@libcore.util.Nullable java.lang.ClassLoader loader, [email protected] Class<?> @libcore.util.NonNull [] interfaces, @libcore.util.NonNull java.lang.reflect.InvocationHandler h) throws java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+public static boolean isProxyClass(@libcore.util.NonNull java.lang.Class<?> cl) { throw new RuntimeException("Stub!"); }
+
[email protected] public static java.lang.reflect.InvocationHandler getInvocationHandler(@libcore.util.NonNull java.lang.Object proxy) throws java.lang.IllegalArgumentException { throw new RuntimeException("Stub!"); }
+
+protected java.lang.reflect.InvocationHandler h;
+}
diff --git a/java/lang/reflect/Proxy.java b/java/lang/reflect/Proxy.java
new file mode 100644
index 0000000..584d568
--- /dev/null
+++ b/java/lang/reflect/Proxy.java
@@ -0,0 +1,1008 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1999, 2013, 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.reflect;
+
+
+import dalvik.annotation.optimization.FastNative;
+import java.lang.ref.Reference;
+import java.lang.ref.WeakReference;
+import java.security.Permission;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.IdentityHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.WeakHashMap;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.function.BiFunction;
+import libcore.util.EmptyArray;
+import sun.reflect.CallerSensitive;
+import sun.reflect.misc.ReflectUtil;
+import sun.security.util.SecurityConstants;
+
+/**
+ * {@code Proxy} provides static methods for creating dynamic proxy
+ * classes and instances, and it is also the superclass of all
+ * dynamic proxy classes created by those methods.
+ *
+ * <p>To create a proxy for some interface {@code Foo}:
+ * <pre>
+ * InvocationHandler handler = new MyInvocationHandler(...);
+ * Class<?> proxyClass = Proxy.getProxyClass(Foo.class.getClassLoader(), Foo.class);
+ * Foo f = (Foo) proxyClass.getConstructor(InvocationHandler.class).
+ * newInstance(handler);
+ * </pre>
+ * or more simply:
+ * <pre>
+ * Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
+ * new Class<?>[] { Foo.class },
+ * handler);
+ * </pre>
+ *
+ * <p>A <i>dynamic proxy class</i> (simply referred to as a <i>proxy
+ * class</i> below) is a class that implements a list of interfaces
+ * specified at runtime when the class is created, with behavior as
+ * described below.
+ *
+ * A <i>proxy interface</i> is such an interface that is implemented
+ * by a proxy class.
+ *
+ * A <i>proxy instance</i> is an instance of a proxy class.
+ *
+ * Each proxy instance has an associated <i>invocation handler</i>
+ * object, which implements the interface {@link InvocationHandler}.
+ * A method invocation on a proxy instance through one of its proxy
+ * interfaces will be dispatched to the {@link InvocationHandler#invoke
+ * invoke} method of the instance's invocation handler, passing the proxy
+ * instance, a {@code java.lang.reflect.Method} object identifying
+ * the method that was invoked, and an array of type {@code Object}
+ * containing the arguments. The invocation handler processes the
+ * encoded method invocation as appropriate and the result that it
+ * returns will be returned as the result of the method invocation on
+ * the proxy instance.
+ *
+ * <p>A proxy class has the following properties:
+ *
+ * <ul>
+ * <li>Proxy classes are <em>public, final, and not abstract</em> if
+ * all proxy interfaces are public.</li>
+ *
+ * <li>Proxy classes are <em>non-public, final, and not abstract</em> if
+ * any of the proxy interfaces is non-public.</li>
+ *
+ * <li>The unqualified name of a proxy class is unspecified. The space
+ * of class names that begin with the string {@code "$Proxy"}
+ * should be, however, reserved for proxy classes.
+ *
+ * <li>A proxy class extends {@code java.lang.reflect.Proxy}.
+ *
+ * <li>A proxy class implements exactly the interfaces specified at its
+ * creation, in the same order.
+ *
+ * <li>If a proxy class implements a non-public interface, then it will
+ * be defined in the same package as that interface. Otherwise, the
+ * package of a proxy class is also unspecified. Note that package
+ * sealing will not prevent a proxy class from being successfully defined
+ * in a particular package at runtime, and neither will classes already
+ * defined by the same class loader and the same package with particular
+ * signers.
+ *
+ * <li>Since a proxy class implements all of the interfaces specified at
+ * its creation, invoking {@code getInterfaces} on its
+ * {@code Class} object will return an array containing the same
+ * list of interfaces (in the order specified at its creation), invoking
+ * {@code getMethods} on its {@code Class} object will return
+ * an array of {@code Method} objects that include all of the
+ * methods in those interfaces, and invoking {@code getMethod} will
+ * find methods in the proxy interfaces as would be expected.
+ *
+ * <li>The {@link Proxy#isProxyClass Proxy.isProxyClass} method will
+ * return true if it is passed a proxy class-- a class returned by
+ * {@code Proxy.getProxyClass} or the class of an object returned by
+ * {@code Proxy.newProxyInstance}-- and false otherwise.
+ *
+ * <li>The {@code java.security.ProtectionDomain} of a proxy class
+ * is the same as that of system classes loaded by the bootstrap class
+ * loader, such as {@code java.lang.Object}, because the code for a
+ * proxy class is generated by trusted system code. This protection
+ * domain will typically be granted
+ * {@code java.security.AllPermission}.
+ *
+ * <li>Each proxy class has one public constructor that takes one argument,
+ * an implementation of the interface {@link InvocationHandler}, to set
+ * the invocation handler for a proxy instance. Rather than having to use
+ * the reflection API to access the public constructor, a proxy instance
+ * can be also be created by calling the {@link Proxy#newProxyInstance
+ * Proxy.newProxyInstance} method, which combines the actions of calling
+ * {@link Proxy#getProxyClass Proxy.getProxyClass} with invoking the
+ * constructor with an invocation handler.
+ * </ul>
+ *
+ * <p>A proxy instance has the following properties:
+ *
+ * <ul>
+ * <li>Given a proxy instance {@code proxy} and one of the
+ * interfaces implemented by its proxy class {@code Foo}, the
+ * following expression will return true:
+ * <pre>
+ * {@code proxy instanceof Foo}
+ * </pre>
+ * and the following cast operation will succeed (rather than throwing
+ * a {@code ClassCastException}):
+ * <pre>
+ * {@code (Foo) proxy}
+ * </pre>
+ *
+ * <li>Each proxy instance has an associated invocation handler, the one
+ * that was passed to its constructor. The static
+ * {@link Proxy#getInvocationHandler Proxy.getInvocationHandler} method
+ * will return the invocation handler associated with the proxy instance
+ * passed as its argument.
+ *
+ * <li>An interface method invocation on a proxy instance will be
+ * encoded and dispatched to the invocation handler's {@link
+ * InvocationHandler#invoke invoke} method as described in the
+ * documentation for that method.
+ *
+ * <li>An invocation of the {@code hashCode},
+ * {@code equals}, or {@code toString} methods declared in
+ * {@code java.lang.Object} on a proxy instance will be encoded and
+ * dispatched to the invocation handler's {@code invoke} method in
+ * the same manner as interface method invocations are encoded and
+ * dispatched, as described above. The declaring class of the
+ * {@code Method} object passed to {@code invoke} will be
+ * {@code java.lang.Object}. Other public methods of a proxy
+ * instance inherited from {@code java.lang.Object} are not
+ * overridden by a proxy class, so invocations of those methods behave
+ * like they do for instances of {@code java.lang.Object}.
+ * </ul>
+ *
+ * <h3>Methods Duplicated in Multiple Proxy Interfaces</h3>
+ *
+ * <p>When two or more interfaces of a proxy class contain a method with
+ * the same name and parameter signature, the order of the proxy class's
+ * interfaces becomes significant. When such a <i>duplicate method</i>
+ * is invoked on a proxy instance, the {@code Method} object passed
+ * to the invocation handler will not necessarily be the one whose
+ * declaring class is assignable from the reference type of the interface
+ * that the proxy's method was invoked through. This limitation exists
+ * because the corresponding method implementation in the generated proxy
+ * class cannot determine which interface it was invoked through.
+ * Therefore, when a duplicate method is invoked on a proxy instance,
+ * the {@code Method} object for the method in the foremost interface
+ * that contains the method (either directly or inherited through a
+ * superinterface) in the proxy class's list of interfaces is passed to
+ * the invocation handler's {@code invoke} method, regardless of the
+ * reference type through which the method invocation occurred.
+ *
+ * <p>If a proxy interface contains a method with the same name and
+ * parameter signature as the {@code hashCode}, {@code equals},
+ * or {@code toString} methods of {@code java.lang.Object},
+ * when such a method is invoked on a proxy instance, the
+ * {@code Method} object passed to the invocation handler will have
+ * {@code java.lang.Object} as its declaring class. In other words,
+ * the public, non-final methods of {@code java.lang.Object}
+ * logically precede all of the proxy interfaces for the determination of
+ * which {@code Method} object to pass to the invocation handler.
+ *
+ * <p>Note also that when a duplicate method is dispatched to an
+ * invocation handler, the {@code invoke} method may only throw
+ * checked exception types that are assignable to one of the exception
+ * types in the {@code throws} clause of the method in <i>all</i> of
+ * the proxy interfaces that it can be invoked through. If the
+ * {@code invoke} method throws a checked exception that is not
+ * assignable to any of the exception types declared by the method in one
+ * of the proxy interfaces that it can be invoked through, then an
+ * unchecked {@code UndeclaredThrowableException} will be thrown by
+ * the invocation on the proxy instance. This restriction means that not
+ * all of the exception types returned by invoking
+ * {@code getExceptionTypes} on the {@code Method} object
+ * passed to the {@code invoke} method can necessarily be thrown
+ * successfully by the {@code invoke} method.
+ *
+ * @author Peter Jones
+ * @see InvocationHandler
+ * @since 1.3
+ */
+public class Proxy implements java.io.Serializable {
+
+ private static final long serialVersionUID = -2222568056686623797L;
+
+ /** parameter types of a proxy class constructor */
+ private static final Class<?>[] constructorParams =
+ { InvocationHandler.class };
+
+ /**
+ * a cache of proxy classes
+ */
+ private static final WeakCache<ClassLoader, Class<?>[], Class<?>>
+ proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());
+
+ /**
+ * the invocation handler for this proxy instance.
+ * @serial
+ */
+ protected InvocationHandler h;
+
+ /**
+ * Prohibits instantiation.
+ */
+ private Proxy() {
+ }
+
+ /**
+ * Constructs a new {@code Proxy} instance from a subclass
+ * (typically, a dynamic proxy class) with the specified value
+ * for its invocation handler.
+ *
+ * @param h the invocation handler for this proxy instance
+ *
+ * @throws NullPointerException if the given invocation handler, {@code h},
+ * is {@code null}.
+ */
+ protected Proxy(InvocationHandler h) {
+ Objects.requireNonNull(h);
+ this.h = h;
+ }
+
+ /**
+ * Returns the {@code java.lang.Class} object for a proxy class
+ * given a class loader and an array of interfaces. The proxy class
+ * will be defined by the specified class loader and will implement
+ * all of the supplied interfaces. If any of the given interfaces
+ * is non-public, the proxy class will be non-public. If a proxy class
+ * for the same permutation of interfaces has already been defined by the
+ * class loader, then the existing proxy class will be returned; otherwise,
+ * a proxy class for those interfaces will be generated dynamically
+ * and defined by the class loader.
+ *
+ * <p>There are several restrictions on the parameters that may be
+ * passed to {@code Proxy.getProxyClass}:
+ *
+ * <ul>
+ * <li>All of the {@code Class} objects in the
+ * {@code interfaces} array must represent interfaces, not
+ * classes or primitive types.
+ *
+ * <li>No two elements in the {@code interfaces} array may
+ * refer to identical {@code Class} objects.
+ *
+ * <li>All of the interface types must be visible by name through the
+ * specified class loader. In other words, for class loader
+ * {@code cl} and every interface {@code i}, the following
+ * expression must be true:
+ * <pre>
+ * Class.forName(i.getName(), false, cl) == i
+ * </pre>
+ *
+ * <li>All non-public interfaces must be in the same package;
+ * otherwise, it would not be possible for the proxy class to
+ * implement all of the interfaces, regardless of what package it is
+ * defined in.
+ *
+ * <li>For any set of member methods of the specified interfaces
+ * that have the same signature:
+ * <ul>
+ * <li>If the return type of any of the methods is a primitive
+ * type or void, then all of the methods must have that same
+ * return type.
+ * <li>Otherwise, one of the methods must have a return type that
+ * is assignable to all of the return types of the rest of the
+ * methods.
+ * </ul>
+ *
+ * <li>The resulting proxy class must not exceed any limits imposed
+ * on classes by the virtual machine. For example, the VM may limit
+ * the number of interfaces that a class may implement to 65535; in
+ * that case, the size of the {@code interfaces} array must not
+ * exceed 65535.
+ * </ul>
+ *
+ * <p>If any of these restrictions are violated,
+ * {@code Proxy.getProxyClass} will throw an
+ * {@code IllegalArgumentException}. If the {@code interfaces}
+ * array argument or any of its elements are {@code null}, a
+ * {@code NullPointerException} will be thrown.
+ *
+ * <p>Note that the order of the specified proxy interfaces is
+ * significant: two requests for a proxy class with the same combination
+ * of interfaces but in a different order will result in two distinct
+ * proxy classes.
+ *
+ * @param loader the class loader to define the proxy class
+ * @param interfaces the list of interfaces for the proxy class
+ * to implement
+ * @return a proxy class that is defined in the specified class loader
+ * and that implements the specified interfaces
+ * @throws IllegalArgumentException if any of the restrictions on the
+ * parameters that may be passed to {@code getProxyClass}
+ * are violated
+ * @throws SecurityException if a security manager, <em>s</em>, is present
+ * and any of the following conditions is met:
+ * <ul>
+ * <li> the given {@code loader} is {@code null} and
+ * the caller's class loader is not {@code null} and the
+ * invocation of {@link SecurityManager#checkPermission
+ * s.checkPermission} with
+ * {@code RuntimePermission("getClassLoader")} permission
+ * denies access.</li>
+ * <li> for each proxy interface, {@code intf},
+ * the caller's class loader is not the same as or an
+ * ancestor of the class loader for {@code intf} and
+ * invocation of {@link SecurityManager#checkPackageAccess
+ * s.checkPackageAccess()} denies access to {@code intf}.</li>
+ * </ul>
+ * @throws NullPointerException if the {@code interfaces} array
+ * argument or any of its elements are {@code null}
+ */
+ @CallerSensitive
+ public static Class<?> getProxyClass(ClassLoader loader,
+ Class<?>... interfaces)
+ throws IllegalArgumentException
+ {
+ // BEGIN Android-changed: Excluded SecurityManager / permission checks.
+ /*
+ final Class<?>[] intfs = interfaces.clone();
+ final SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
+ }
+
+ return getProxyClass0(loader, intfs);
+ */
+
+ return getProxyClass0(loader, interfaces);
+ // END Android-changed: Excluded SecurityManager / permission checks.
+ }
+
+ // Android-removed: SecurityManager / permission check code.
+ /*
+ /*
+ * Check permissions required to create a Proxy class.
+ *
+ * To define a proxy class, it performs the access checks as in
+ * Class.forName (VM will invoke ClassLoader.checkPackageAccess):
+ * 1. "getClassLoader" permission check if loader == null
+ * 2. checkPackageAccess on the interfaces it implements
+ *
+ * To get a constructor and new instance of a proxy class, it performs
+ * the package access check on the interfaces it implements
+ * as in Class.getConstructor.
+ *
+ * If an interface is non-public, the proxy class must be defined by
+ * the defining loader of the interface. If the caller's class loader
+ * is not the same as the defining loader of the interface, the VM
+ * will throw IllegalAccessError when the generated proxy class is
+ * being defined via the defineClass0 method.
+ *
+ private static void checkProxyAccess(Class<?> caller,
+ ClassLoader loader,
+ Class<?>... interfaces)
+ {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ ClassLoader ccl = caller.getClassLoader();
+ if (VM.isSystemDomainLoader(loader) && !VM.isSystemDomainLoader(ccl)) {
+ sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
+ }
+ ReflectUtil.checkProxyPackageAccess(ccl, interfaces);
+ }
+ }
+ */
+
+ /**
+ * Generate a proxy class. Must call the checkProxyAccess method
+ * to perform permission checks before calling this.
+ */
+ private static Class<?> getProxyClass0(ClassLoader loader,
+ Class<?>... interfaces) {
+ if (interfaces.length > 65535) {
+ throw new IllegalArgumentException("interface limit exceeded");
+ }
+
+ // If the proxy class defined by the given loader implementing
+ // the given interfaces exists, this will simply return the cached copy;
+ // otherwise, it will create the proxy class via the ProxyClassFactory
+ return proxyClassCache.get(loader, interfaces);
+ }
+
+ /*
+ * a key used for proxy class with 0 implemented interfaces
+ */
+ private static final Object key0 = new Object();
+
+ /*
+ * Key1 and Key2 are optimized for the common use of dynamic proxies
+ * that implement 1 or 2 interfaces.
+ */
+
+ /*
+ * a key used for proxy class with 1 implemented interface
+ */
+ private static final class Key1 extends WeakReference<Class<?>> {
+ private final int hash;
+
+ Key1(Class<?> intf) {
+ super(intf);
+ this.hash = intf.hashCode();
+ }
+
+ @Override
+ public int hashCode() {
+ return hash;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ Class<?> intf;
+ return this == obj ||
+ obj != null &&
+ obj.getClass() == Key1.class &&
+ (intf = get()) != null &&
+ intf == ((Key1) obj).get();
+ }
+ }
+
+ /*
+ * a key used for proxy class with 2 implemented interfaces
+ */
+ private static final class Key2 extends WeakReference<Class<?>> {
+ private final int hash;
+ private final WeakReference<Class<?>> ref2;
+
+ Key2(Class<?> intf1, Class<?> intf2) {
+ super(intf1);
+ hash = 31 * intf1.hashCode() + intf2.hashCode();
+ ref2 = new WeakReference<Class<?>>(intf2);
+ }
+
+ @Override
+ public int hashCode() {
+ return hash;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ Class<?> intf1, intf2;
+ return this == obj ||
+ obj != null &&
+ obj.getClass() == Key2.class &&
+ (intf1 = get()) != null &&
+ intf1 == ((Key2) obj).get() &&
+ (intf2 = ref2.get()) != null &&
+ intf2 == ((Key2) obj).ref2.get();
+ }
+ }
+
+ /*
+ * a key used for proxy class with any number of implemented interfaces
+ * (used here for 3 or more only)
+ */
+ private static final class KeyX {
+ private final int hash;
+ private final WeakReference<Class<?>>[] refs;
+
+ @SuppressWarnings("unchecked")
+ KeyX(Class<?>[] interfaces) {
+ hash = Arrays.hashCode(interfaces);
+ refs = (WeakReference<Class<?>>[])new WeakReference<?>[interfaces.length];
+ for (int i = 0; i < interfaces.length; i++) {
+ refs[i] = new WeakReference<>(interfaces[i]);
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return hash;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return this == obj ||
+ obj != null &&
+ obj.getClass() == KeyX.class &&
+ equals(refs, ((KeyX) obj).refs);
+ }
+
+ private static boolean equals(WeakReference<Class<?>>[] refs1,
+ WeakReference<Class<?>>[] refs2) {
+ if (refs1.length != refs2.length) {
+ return false;
+ }
+ for (int i = 0; i < refs1.length; i++) {
+ Class<?> intf = refs1[i].get();
+ if (intf == null || intf != refs2[i].get()) {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+
+ /**
+ * A function that maps an array of interfaces to an optimal key where
+ * Class objects representing interfaces are weakly referenced.
+ */
+ private static final class KeyFactory
+ implements BiFunction<ClassLoader, Class<?>[], Object>
+ {
+ @Override
+ public Object apply(ClassLoader classLoader, Class<?>[] interfaces) {
+ switch (interfaces.length) {
+ case 1: return new Key1(interfaces[0]); // the most frequent
+ case 2: return new Key2(interfaces[0], interfaces[1]);
+ case 0: return key0;
+ default: return new KeyX(interfaces);
+ }
+ }
+ }
+
+ // BEGIN Android-changed: How proxies are generated.
+ /**
+ * Orders methods by their name, parameters, return type and inheritance relationship.
+ *
+ * @hide
+ */
+ private static final Comparator<Method> ORDER_BY_SIGNATURE_AND_SUBTYPE = new Comparator<Method>() {
+ @Override public int compare(Method a, Method b) {
+ int comparison = Method.ORDER_BY_SIGNATURE.compare(a, b);
+ if (comparison != 0) {
+ return comparison;
+ }
+ Class<?> aClass = a.getDeclaringClass();
+ Class<?> bClass = b.getDeclaringClass();
+ if (aClass == bClass) {
+ return 0;
+ } else if (aClass.isAssignableFrom(bClass)) {
+ return 1;
+ } else if (bClass.isAssignableFrom(aClass)) {
+ return -1;
+ } else {
+ return 0;
+ }
+ }
+ };
+
+ /**
+ * A factory function that generates, defines and returns the proxy class given
+ * the ClassLoader and array of interfaces.
+ */
+ private static final class ProxyClassFactory
+ implements BiFunction<ClassLoader, Class<?>[], Class<?>>
+ {
+ // prefix for all proxy class names
+ private static final String proxyClassNamePrefix = "$Proxy";
+
+ // next number to use for generation of unique proxy class names
+ private static final AtomicLong nextUniqueNumber = new AtomicLong();
+
+ @Override
+ public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {
+
+ Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length);
+ for (Class<?> intf : interfaces) {
+ /*
+ * Verify that the class loader resolves the name of this
+ * interface to the same Class object.
+ */
+ Class<?> interfaceClass = null;
+ try {
+ interfaceClass = Class.forName(intf.getName(), false, loader);
+ } catch (ClassNotFoundException e) {
+ }
+ if (interfaceClass != intf) {
+ throw new IllegalArgumentException(
+ intf + " is not visible from class loader");
+ }
+ /*
+ * Verify that the Class object actually represents an
+ * interface.
+ */
+ if (!interfaceClass.isInterface()) {
+ throw new IllegalArgumentException(
+ interfaceClass.getName() + " is not an interface");
+ }
+ /*
+ * Verify that this interface is not a duplicate.
+ */
+ if (interfaceSet.put(interfaceClass, Boolean.TRUE) != null) {
+ throw new IllegalArgumentException(
+ "repeated interface: " + interfaceClass.getName());
+ }
+ }
+
+ String proxyPkg = null; // package to define proxy class in
+ int accessFlags = Modifier.PUBLIC | Modifier.FINAL;
+
+ /*
+ * Record the package of a non-public proxy interface so that the
+ * proxy class will be defined in the same package. Verify that
+ * all non-public proxy interfaces are in the same package.
+ */
+ for (Class<?> intf : interfaces) {
+ int flags = intf.getModifiers();
+ if (!Modifier.isPublic(flags)) {
+ accessFlags = Modifier.FINAL;
+ String name = intf.getName();
+ int n = name.lastIndexOf('.');
+ String pkg = ((n == -1) ? "" : name.substring(0, n + 1));
+ if (proxyPkg == null) {
+ proxyPkg = pkg;
+ } else if (!pkg.equals(proxyPkg)) {
+ throw new IllegalArgumentException(
+ "non-public interfaces from different packages");
+ }
+ }
+ }
+
+ if (proxyPkg == null) {
+ // if no non-public proxy interfaces, use the default package.
+ proxyPkg = "";
+ }
+
+ {
+ // Android-changed: Generate the proxy directly instead of calling
+ // through to ProxyGenerator.
+ List<Method> methods = getMethods(interfaces);
+ Collections.sort(methods, ORDER_BY_SIGNATURE_AND_SUBTYPE);
+ validateReturnTypes(methods);
+ List<Class<?>[]> exceptions = deduplicateAndGetExceptions(methods);
+
+ Method[] methodsArray = methods.toArray(new Method[methods.size()]);
+ Class<?>[][] exceptionsArray = exceptions.toArray(new Class<?>[exceptions.size()][]);
+
+ /*
+ * Choose a name for the proxy class to generate.
+ */
+ long num = nextUniqueNumber.getAndIncrement();
+ String proxyName = proxyPkg + proxyClassNamePrefix + num;
+
+ return generateProxy(proxyName, interfaces, loader, methodsArray,
+ exceptionsArray);
+ }
+ }
+ }
+
+ /**
+ * Remove methods that have the same name, parameters and return type. This
+ * computes the exceptions of each method; this is the intersection of the
+ * exceptions of equivalent methods.
+ *
+ * @param methods the methods to find exceptions for, ordered by name and
+ * signature.
+ */
+ private static List<Class<?>[]> deduplicateAndGetExceptions(List<Method> methods) {
+ List<Class<?>[]> exceptions = new ArrayList<Class<?>[]>(methods.size());
+
+ for (int i = 0; i < methods.size(); ) {
+ Method method = methods.get(i);
+ Class<?>[] exceptionTypes = method.getExceptionTypes();
+
+ if (i > 0 && Method.ORDER_BY_SIGNATURE.compare(method, methods.get(i - 1)) == 0) {
+ exceptions.set(i - 1, intersectExceptions(exceptions.get(i - 1), exceptionTypes));
+ methods.remove(i);
+ } else {
+ exceptions.add(exceptionTypes);
+ i++;
+ }
+ }
+ return exceptions;
+ }
+
+ /**
+ * Returns the exceptions that are declared in both {@code aExceptions} and
+ * {@code bExceptions}. If an exception type in one array is a subtype of an
+ * exception from the other, the subtype is included in the intersection.
+ */
+ private static Class<?>[] intersectExceptions(Class<?>[] aExceptions, Class<?>[] bExceptions) {
+ if (aExceptions.length == 0 || bExceptions.length == 0) {
+ return EmptyArray.CLASS;
+ }
+ if (Arrays.equals(aExceptions, bExceptions)) {
+ return aExceptions;
+ }
+ Set<Class<?>> intersection = new HashSet<Class<?>>();
+ for (Class<?> a : aExceptions) {
+ for (Class<?> b : bExceptions) {
+ if (a.isAssignableFrom(b)) {
+ intersection.add(b);
+ } else if (b.isAssignableFrom(a)) {
+ intersection.add(a);
+ }
+ }
+ }
+ return intersection.toArray(new Class<?>[intersection.size()]);
+ }
+
+ /**
+ * Throws if any two methods in {@code methods} have the same name and
+ * parameters but incompatible return types.
+ *
+ * @param methods the methods to find exceptions for, ordered by name and
+ * signature.
+ */
+ private static void validateReturnTypes(List<Method> methods) {
+ Method vs = null;
+ for (Method method : methods) {
+ if (vs == null || !vs.equalNameAndParameters(method)) {
+ vs = method; // this has a different name or parameters
+ continue;
+ }
+ Class<?> returnType = method.getReturnType();
+ Class<?> vsReturnType = vs.getReturnType();
+ if (returnType.isInterface() && vsReturnType.isInterface()) {
+ // all interfaces are mutually compatible
+ } else if (vsReturnType.isAssignableFrom(returnType)) {
+ vs = method; // the new return type is a subtype; use it instead
+ } else if (!returnType.isAssignableFrom(vsReturnType)) {
+ throw new IllegalArgumentException("proxied interface methods have incompatible "
+ + "return types:\n " + vs + "\n " + method);
+ }
+ }
+ }
+
+ private static List<Method> getMethods(Class<?>[] interfaces) {
+ List<Method> result = new ArrayList<Method>();
+ try {
+ result.add(Object.class.getMethod("equals", Object.class));
+ result.add(Object.class.getMethod("hashCode", EmptyArray.CLASS));
+ result.add(Object.class.getMethod("toString", EmptyArray.CLASS));
+ } catch (NoSuchMethodException e) {
+ throw new AssertionError();
+ }
+
+ getMethodsRecursive(interfaces, result);
+ return result;
+ }
+
+ /**
+ * Fills {@code proxiedMethods} with the methods of {@code interfaces} and
+ * the interfaces they extend. May contain duplicates.
+ */
+ private static void getMethodsRecursive(Class<?>[] interfaces, List<Method> methods) {
+ for (Class<?> i : interfaces) {
+ getMethodsRecursive(i.getInterfaces(), methods);
+ Collections.addAll(methods, i.getDeclaredMethods());
+ }
+ }
+
+ @FastNative
+ private static native Class<?> generateProxy(String name, Class<?>[] interfaces,
+ ClassLoader loader, Method[] methods,
+ Class<?>[][] exceptions);
+ // END Android-changed: How proxies are generated.
+
+
+ /**
+ * Returns an instance of a proxy class for the specified interfaces
+ * that dispatches method invocations to the specified invocation
+ * handler.
+ *
+ * <p>{@code Proxy.newProxyInstance} throws
+ * {@code IllegalArgumentException} for the same reasons that
+ * {@code Proxy.getProxyClass} does.
+ *
+ * @param loader the class loader to define the proxy class
+ * @param interfaces the list of interfaces for the proxy class
+ * to implement
+ * @param h the invocation handler to dispatch method invocations to
+ * @return a proxy instance with the specified invocation handler of a
+ * proxy class that is defined by the specified class loader
+ * and that implements the specified interfaces
+ * @throws IllegalArgumentException if any of the restrictions on the
+ * parameters that may be passed to {@code getProxyClass}
+ * are violated
+ * @throws SecurityException if a security manager, <em>s</em>, is present
+ * and any of the following conditions is met:
+ * <ul>
+ * <li> the given {@code loader} is {@code null} and
+ * the caller's class loader is not {@code null} and the
+ * invocation of {@link SecurityManager#checkPermission
+ * s.checkPermission} with
+ * {@code RuntimePermission("getClassLoader")} permission
+ * denies access;</li>
+ * <li> for each proxy interface, {@code intf},
+ * the caller's class loader is not the same as or an
+ * ancestor of the class loader for {@code intf} and
+ * invocation of {@link SecurityManager#checkPackageAccess
+ * s.checkPackageAccess()} denies access to {@code intf};</li>
+ * <li> any of the given proxy interfaces is non-public and the
+ * caller class is not in the same {@linkplain Package runtime package}
+ * as the non-public interface and the invocation of
+ * {@link SecurityManager#checkPermission s.checkPermission} with
+ * {@code ReflectPermission("newProxyInPackage.{package name}")}
+ * permission denies access.</li>
+ * </ul>
+ * @throws NullPointerException if the {@code interfaces} array
+ * argument or any of its elements are {@code null}, or
+ * if the invocation handler, {@code h}, is
+ * {@code null}
+ */
+ @CallerSensitive
+ public static Object newProxyInstance(ClassLoader loader,
+ Class<?>[] interfaces,
+ InvocationHandler h)
+ throws IllegalArgumentException
+ {
+ Objects.requireNonNull(h);
+
+ final Class<?>[] intfs = interfaces.clone();
+ // Android-removed: SecurityManager calls
+ /*
+ final SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
+ }
+ */
+
+ /*
+ * Look up or generate the designated proxy class.
+ */
+ Class<?> cl = getProxyClass0(loader, intfs);
+
+ /*
+ * Invoke its constructor with the designated invocation handler.
+ */
+ try {
+ // Android-removed: SecurityManager / permission checks.
+ /*
+ if (sm != null) {
+ checkNewProxyPermission(Reflection.getCallerClass(), cl);
+ }
+ */
+
+ final Constructor<?> cons = cl.getConstructor(constructorParams);
+ final InvocationHandler ih = h;
+ if (!Modifier.isPublic(cl.getModifiers())) {
+ // BEGIN Android-removed: Excluded AccessController.doPrivileged call.
+ /*
+ AccessController.doPrivileged(new PrivilegedAction<Void>() {
+ public Void run() {
+ cons.setAccessible(true);
+ return null;
+ }
+ });
+ */
+
+ cons.setAccessible(true);
+ // END Android-removed: Excluded AccessController.doPrivileged call.
+ }
+ return cons.newInstance(new Object[]{h});
+ } catch (IllegalAccessException|InstantiationException e) {
+ throw new InternalError(e.toString(), e);
+ } catch (InvocationTargetException e) {
+ Throwable t = e.getCause();
+ if (t instanceof RuntimeException) {
+ throw (RuntimeException) t;
+ } else {
+ throw new InternalError(t.toString(), t);
+ }
+ } catch (NoSuchMethodException e) {
+ throw new InternalError(e.toString(), e);
+ }
+ }
+
+ // Android-removed: SecurityManager / permission checks.
+ /*
+ private static void checkNewProxyPermission(Class<?> caller, Class<?> proxyClass) {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ if (ReflectUtil.isNonPublicProxyClass(proxyClass)) {
+ ClassLoader ccl = caller.getClassLoader();
+ ClassLoader pcl = proxyClass.getClassLoader();
+
+ // do permission check if the caller is in a different runtime package
+ // of the proxy class
+ int n = proxyClass.getName().lastIndexOf('.');
+ String pkg = (n == -1) ? "" : proxyClass.getName().substring(0, n);
+
+ n = caller.getName().lastIndexOf('.');
+ String callerPkg = (n == -1) ? "" : caller.getName().substring(0, n);
+
+ if (pcl != ccl || !pkg.equals(callerPkg)) {
+ sm.checkPermission(new ReflectPermission("newProxyInPackage." + pkg));
+ }
+ }
+ }
+ }
+ */
+
+ /**
+ * Returns true if and only if the specified class was dynamically
+ * generated to be a proxy class using the {@code getProxyClass}
+ * method or the {@code newProxyInstance} method.
+ *
+ * <p>The reliability of this method is important for the ability
+ * to use it to make security decisions, so its implementation should
+ * not just test if the class in question extends {@code Proxy}.
+ *
+ * @param cl the class to test
+ * @return {@code true} if the class is a proxy class and
+ * {@code false} otherwise
+ * @throws NullPointerException if {@code cl} is {@code null}
+ */
+ public static boolean isProxyClass(Class<?> cl) {
+ return Proxy.class.isAssignableFrom(cl) && proxyClassCache.containsValue(cl);
+ }
+
+ /**
+ * Returns the invocation handler for the specified proxy instance.
+ *
+ * @param proxy the proxy instance to return the invocation handler for
+ * @return the invocation handler for the proxy instance
+ * @throws IllegalArgumentException if the argument is not a
+ * proxy instance
+ * @throws SecurityException if a security manager, <em>s</em>, is present
+ * and the caller's class loader is not the same as or an
+ * ancestor of the class loader for the invocation handler
+ * and invocation of {@link SecurityManager#checkPackageAccess
+ * s.checkPackageAccess()} denies access to the invocation
+ * handler's class.
+ */
+ @CallerSensitive
+ public static InvocationHandler getInvocationHandler(Object proxy)
+ throws IllegalArgumentException
+ {
+ /*
+ * Verify that the object is actually a proxy instance.
+ */
+ if (!isProxyClass(proxy.getClass())) {
+ throw new IllegalArgumentException("not a proxy instance");
+ }
+
+ final Proxy p = (Proxy) proxy;
+ final InvocationHandler ih = p.h;
+ // Android-removed: SecurityManager / access checks.
+ /*
+ if (System.getSecurityManager() != null) {
+ Class<?> ihClass = ih.getClass();
+ Class<?> caller = Reflection.getCallerClass();
+ if (ReflectUtil.needsPackageAccessCheck(caller.getClassLoader(),
+ ihClass.getClassLoader()))
+ {
+ ReflectUtil.checkPackageAccess(ihClass);
+ }
+ }
+ */
+
+ return ih;
+ }
+
+ // Android-added: Helper method invoke(Proxy, Method, Object[]) for ART native code.
+ private static Object invoke(Proxy proxy, Method method, Object[] args) throws Throwable {
+ InvocationHandler h = proxy.h;
+ return h.invoke(proxy, method, args);
+ }
+}
diff --git a/java/lang/reflect/ReflectPermission.java b/java/lang/reflect/ReflectPermission.java
new file mode 100644
index 0000000..a5e5be1
--- /dev/null
+++ b/java/lang/reflect/ReflectPermission.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 1997, 2013, 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.reflect;
+
+// Android-changed: Stubbed the implementation. Android doesn't support SecurityManager.
+// See comments in java.lang.SecurityManager for details.
+/**
+ * Legacy security code; do not use.
+ */
+public final
+class ReflectPermission extends java.security.BasicPermission {
+
+ public ReflectPermission(String name) {
+ super(name);
+ }
+
+ public ReflectPermission(String name, String actions) {
+ super("", "");
+ }
+}
diff --git a/java/lang/reflect/Type.annotated.java b/java/lang/reflect/Type.annotated.java
new file mode 100644
index 0000000..f2b646b
--- /dev/null
+++ b/java/lang/reflect/Type.annotated.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2003, 2013, 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.reflect;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface Type {
+
[email protected] public default java.lang.String getTypeName() { throw new RuntimeException("Stub!"); }
+}
+
diff --git a/java/lang/reflect/Type.java b/java/lang/reflect/Type.java
new file mode 100644
index 0000000..eee7443
--- /dev/null
+++ b/java/lang/reflect/Type.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2003, 2013, 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.reflect;
+
+/**
+ * Type is the common superinterface for all types in the Java
+ * programming language. These include raw types, parameterized types,
+ * array types, type variables and primitive types.
+ *
+ * @since 1.5
+ */
+public interface Type {
+ /**
+ * Returns a string describing this type, including information
+ * about any type parameters.
+ *
+ * @implSpec The default implementation calls {@code toString}.
+ *
+ * @return a string describing this type
+ * @since 1.8
+ */
+ default String getTypeName() {
+ return toString();
+ }
+}
diff --git a/java/lang/reflect/TypeVariable.annotated.java b/java/lang/reflect/TypeVariable.annotated.java
new file mode 100644
index 0000000..5654963
--- /dev/null
+++ b/java/lang/reflect/TypeVariable.annotated.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2003, 2013, 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.reflect;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface TypeVariable<D extends java.lang.reflect.GenericDeclaration> extends java.lang.reflect.Type {
+
+public [email protected] Type @libcore.util.NonNull [] getBounds();
+
[email protected] public D getGenericDeclaration();
+
[email protected] public java.lang.String getName();
+}
diff --git a/java/lang/reflect/TypeVariable.java b/java/lang/reflect/TypeVariable.java
new file mode 100644
index 0000000..4e29a94
--- /dev/null
+++ b/java/lang/reflect/TypeVariable.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2003, 2013, 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.reflect;
+
+/**
+ * TypeVariable is the common superinterface for type variables of kinds.
+ * A type variable is created the first time it is needed by a reflective
+ * method, as specified in this package. If a type variable t is referenced
+ * by a type (i.e, class, interface or annotation type) T, and T is declared
+ * by the nth enclosing class of T (see JLS 8.1.2), then the creation of t
+ * requires the resolution (see JVMS 5) of the ith enclosing class of T,
+ * for i = 0 to n, inclusive. Creating a type variable must not cause the
+ * creation of its bounds. Repeated creation of a type variable has no effect.
+ *
+ * <p>Multiple objects may be instantiated at run-time to
+ * represent a given type variable. Even though a type variable is
+ * created only once, this does not imply any requirement to cache
+ * instances representing the type variable. However, all instances
+ * representing a type variable must be equal() to each other.
+ * As a consequence, users of type variables must not rely on the identity
+ * of instances of classes implementing this interface.
+ *
+ * @param <D> the type of generic declaration that declared the
+ * underlying type variable.
+ *
+ * @since 1.5
+ */
+// Android-changed: Removed support for type annotations at runtime.
+// Removed AnnotatedElement super-class.
+public interface TypeVariable<D extends GenericDeclaration> extends Type/*, AnnotatedElement*/ {
+ /**
+ * Returns an array of {@code Type} objects representing the
+ * upper bound(s) of this type variable. Note that if no upper bound is
+ * explicitly declared, the upper bound is {@code Object}.
+ *
+ * <p>For each upper bound B: <ul> <li>if B is a parameterized
+ * type or a type variable, it is created, (see {@link
+ * java.lang.reflect.ParameterizedType ParameterizedType} for the
+ * details of the creation process for parameterized types).
+ * <li>Otherwise, B is resolved. </ul>
+ *
+ * @throws TypeNotPresentException if any of the
+ * bounds refers to a non-existent type declaration
+ * @throws MalformedParameterizedTypeException if any of the
+ * bounds refer to a parameterized type that cannot be instantiated
+ * for any reason
+ * @return an array of {@code Type}s representing the upper
+ * bound(s) of this type variable
+ */
+ Type[] getBounds();
+
+ /**
+ * Returns the {@code GenericDeclaration} object representing the
+ * generic declaration declared this type variable.
+ *
+ * @return the generic declaration declared for this type variable.
+ *
+ * @since 1.5
+ */
+ D getGenericDeclaration();
+
+ /**
+ * Returns the name of this type variable, as it occurs in the source code.
+ *
+ * @return the name of this type variable, as it appears in the source code
+ */
+ String getName();
+
+ // Android-removed: getAnnotatedBounds(), no support for runtime type annotations on Android.
+ /*
+ /**
+ * Returns an array of AnnotatedType objects that represent the use of
+ * types to denote the upper bounds of the type parameter represented by
+ * this TypeVariable. The order of the objects in the array corresponds to
+ * the order of the bounds in the declaration of the type parameter.
+ *
+ * Returns an array of length 0 if the type parameter declares no bounds.
+ *
+ * @return an array of objects representing the upper bounds of the type variable
+ * @since 1.8
+ *
+ AnnotatedType[] getAnnotatedBounds();
+ */
+}
diff --git a/java/lang/reflect/UndeclaredThrowableException.java b/java/lang/reflect/UndeclaredThrowableException.java
new file mode 100644
index 0000000..a585745
--- /dev/null
+++ b/java/lang/reflect/UndeclaredThrowableException.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 1999, 2006, 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.reflect;
+
+/**
+ * Thrown by a method invocation on a proxy instance if its invocation
+ * handler's {@link InvocationHandler#invoke invoke} method throws a
+ * checked exception (a {@code Throwable} that is not assignable
+ * to {@code RuntimeException} or {@code Error}) that
+ * is not assignable to any of the exception types declared in the
+ * {@code throws} clause of the method that was invoked on the
+ * proxy instance and dispatched to the invocation handler.
+ *
+ * <p>An {@code UndeclaredThrowableException} instance contains
+ * the undeclared checked exception that was thrown by the invocation
+ * handler, and it can be retrieved with the
+ * {@code getUndeclaredThrowable()} method.
+ * {@code UndeclaredThrowableException} extends
+ * {@code RuntimeException}, so it is an unchecked exception
+ * that wraps a checked exception.
+ *
+ * <p>As of release 1.4, this exception has been retrofitted to
+ * conform to the general purpose exception-chaining mechanism. The
+ * "undeclared checked exception that was thrown by the invocation
+ * handler" that may be provided at construction time and accessed via
+ * the {@link #getUndeclaredThrowable()} method is now known as the
+ * <i>cause</i>, and may be accessed via the {@link
+ * Throwable#getCause()} method, as well as the aforementioned "legacy
+ * method."
+ *
+ * @author Peter Jones
+ * @see InvocationHandler
+ * @since 1.3
+ */
+public class UndeclaredThrowableException extends RuntimeException {
+ static final long serialVersionUID = 330127114055056639L;
+
+ /**
+ * the undeclared checked exception that was thrown
+ * @serial
+ */
+ private Throwable undeclaredThrowable;
+
+ /**
+ * Constructs an {@code UndeclaredThrowableException} with the
+ * specified {@code Throwable}.
+ *
+ * @param undeclaredThrowable the undeclared checked exception
+ * that was thrown
+ */
+ public UndeclaredThrowableException(Throwable undeclaredThrowable) {
+ super((Throwable) null); // Disallow initCause
+ this.undeclaredThrowable = undeclaredThrowable;
+ }
+
+ /**
+ * Constructs an {@code UndeclaredThrowableException} with the
+ * specified {@code Throwable} and a detail message.
+ *
+ * @param undeclaredThrowable the undeclared checked exception
+ * that was thrown
+ * @param s the detail message
+ */
+ public UndeclaredThrowableException(Throwable undeclaredThrowable,
+ String s)
+ {
+ super(s, null); // Disallow initCause
+ this.undeclaredThrowable = undeclaredThrowable;
+ }
+
+ /**
+ * Returns the {@code Throwable} instance wrapped in this
+ * {@code UndeclaredThrowableException}, which may be {@code null}.
+ *
+ * <p>This method predates the general-purpose exception chaining facility.
+ * The {@link Throwable#getCause()} method is now the preferred means of
+ * obtaining this information.
+ *
+ * @return the undeclared checked exception that was thrown
+ */
+ public Throwable getUndeclaredThrowable() {
+ return undeclaredThrowable;
+ }
+
+ /**
+ * Returns the cause of this exception (the {@code Throwable}
+ * instance wrapped in this {@code UndeclaredThrowableException},
+ * which may be {@code null}).
+ *
+ * @return the cause of this exception.
+ * @since 1.4
+ */
+ public Throwable getCause() {
+ return undeclaredThrowable;
+ }
+}
diff --git a/java/lang/reflect/WeakCache.java b/java/lang/reflect/WeakCache.java
new file mode 100644
index 0000000..4c28024
--- /dev/null
+++ b/java/lang/reflect/WeakCache.java
@@ -0,0 +1,379 @@
+/*
+ * Copyright (c) 2013, 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.reflect;
+
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.function.BiFunction;
+import java.util.function.Supplier;
+
+/**
+ * Cache mapping pairs of {@code (key, sub-key) -> value}. Keys and values are
+ * weakly but sub-keys are strongly referenced. Keys are passed directly to
+ * {@link #get} method which also takes a {@code parameter}. Sub-keys are
+ * calculated from keys and parameters using the {@code subKeyFactory} function
+ * passed to the constructor. Values are calculated from keys and parameters
+ * using the {@code valueFactory} function passed to the constructor.
+ * Keys can be {@code null} and are compared by identity while sub-keys returned by
+ * {@code subKeyFactory} or values returned by {@code valueFactory}
+ * can not be null. Sub-keys are compared using their {@link #equals} method.
+ * Entries are expunged from cache lazily on each invocation to {@link #get},
+ * {@link #containsValue} or {@link #size} methods when the WeakReferences to
+ * keys are cleared. Cleared WeakReferences to individual values don't cause
+ * expunging, but such entries are logically treated as non-existent and
+ * trigger re-evaluation of {@code valueFactory} on request for their
+ * key/subKey.
+ *
+ * @author Peter Levart
+ * @param <K> type of keys
+ * @param <P> type of parameters
+ * @param <V> type of values
+ */
+final class WeakCache<K, P, V> {
+
+ private final ReferenceQueue<K> refQueue
+ = new ReferenceQueue<>();
+ // the key type is Object for supporting null key
+ private final ConcurrentMap<Object, ConcurrentMap<Object, Supplier<V>>> map
+ = new ConcurrentHashMap<>();
+ private final ConcurrentMap<Supplier<V>, Boolean> reverseMap
+ = new ConcurrentHashMap<>();
+ private final BiFunction<K, P, ?> subKeyFactory;
+ private final BiFunction<K, P, V> valueFactory;
+
+ /**
+ * Construct an instance of {@code WeakCache}
+ *
+ * @param subKeyFactory a function mapping a pair of
+ * {@code (key, parameter) -> sub-key}
+ * @param valueFactory a function mapping a pair of
+ * {@code (key, parameter) -> value}
+ * @throws NullPointerException if {@code subKeyFactory} or
+ * {@code valueFactory} is null.
+ */
+ public WeakCache(BiFunction<K, P, ?> subKeyFactory,
+ BiFunction<K, P, V> valueFactory) {
+ this.subKeyFactory = Objects.requireNonNull(subKeyFactory);
+ this.valueFactory = Objects.requireNonNull(valueFactory);
+ }
+
+ /**
+ * Look-up the value through the cache. This always evaluates the
+ * {@code subKeyFactory} function and optionally evaluates
+ * {@code valueFactory} function if there is no entry in the cache for given
+ * pair of (key, subKey) or the entry has already been cleared.
+ *
+ * @param key possibly null key
+ * @param parameter parameter used together with key to create sub-key and
+ * value (should not be null)
+ * @return the cached value (never null)
+ * @throws NullPointerException if {@code parameter} passed in or
+ * {@code sub-key} calculated by
+ * {@code subKeyFactory} or {@code value}
+ * calculated by {@code valueFactory} is null.
+ */
+ public V get(K key, P parameter) {
+ Objects.requireNonNull(parameter);
+
+ expungeStaleEntries();
+
+ Object cacheKey = CacheKey.valueOf(key, refQueue);
+
+ // lazily install the 2nd level valuesMap for the particular cacheKey
+ ConcurrentMap<Object, Supplier<V>> valuesMap = map.get(cacheKey);
+ if (valuesMap == null) {
+ ConcurrentMap<Object, Supplier<V>> oldValuesMap
+ = map.putIfAbsent(cacheKey,
+ valuesMap = new ConcurrentHashMap<>());
+ if (oldValuesMap != null) {
+ valuesMap = oldValuesMap;
+ }
+ }
+
+ // create subKey and retrieve the possible Supplier<V> stored by that
+ // subKey from valuesMap
+ Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));
+ Supplier<V> supplier = valuesMap.get(subKey);
+ Factory factory = null;
+
+ while (true) {
+ if (supplier != null) {
+ // supplier might be a Factory or a CacheValue<V> instance
+ V value = supplier.get();
+ if (value != null) {
+ return value;
+ }
+ }
+ // else no supplier in cache
+ // or a supplier that returned null (could be a cleared CacheValue
+ // or a Factory that wasn't successful in installing the CacheValue)
+
+ // lazily construct a Factory
+ if (factory == null) {
+ factory = new Factory(key, parameter, subKey, valuesMap);
+ }
+
+ if (supplier == null) {
+ supplier = valuesMap.putIfAbsent(subKey, factory);
+ if (supplier == null) {
+ // successfully installed Factory
+ supplier = factory;
+ }
+ // else retry with winning supplier
+ } else {
+ if (valuesMap.replace(subKey, supplier, factory)) {
+ // successfully replaced
+ // cleared CacheEntry / unsuccessful Factory
+ // with our Factory
+ supplier = factory;
+ } else {
+ // retry with current supplier
+ supplier = valuesMap.get(subKey);
+ }
+ }
+ }
+ }
+
+ /**
+ * Checks whether the specified non-null value is already present in this
+ * {@code WeakCache}. The check is made using identity comparison regardless
+ * of whether value's class overrides {@link Object#equals} or not.
+ *
+ * @param value the non-null value to check
+ * @return true if given {@code value} is already cached
+ * @throws NullPointerException if value is null
+ */
+ public boolean containsValue(V value) {
+ Objects.requireNonNull(value);
+
+ expungeStaleEntries();
+ return reverseMap.containsKey(new LookupValue<>(value));
+ }
+
+ /**
+ * Returns the current number of cached entries that
+ * can decrease over time when keys/values are GC-ed.
+ */
+ public int size() {
+ expungeStaleEntries();
+ return reverseMap.size();
+ }
+
+ private void expungeStaleEntries() {
+ CacheKey<K> cacheKey;
+ while ((cacheKey = (CacheKey<K>)refQueue.poll()) != null) {
+ cacheKey.expungeFrom(map, reverseMap);
+ }
+ }
+
+ /**
+ * A factory {@link Supplier} that implements the lazy synchronized
+ * construction of the value and installment of it into the cache.
+ */
+ private final class Factory implements Supplier<V> {
+
+ private final K key;
+ private final P parameter;
+ private final Object subKey;
+ private final ConcurrentMap<Object, Supplier<V>> valuesMap;
+
+ Factory(K key, P parameter, Object subKey,
+ ConcurrentMap<Object, Supplier<V>> valuesMap) {
+ this.key = key;
+ this.parameter = parameter;
+ this.subKey = subKey;
+ this.valuesMap = valuesMap;
+ }
+
+ @Override
+ public synchronized V get() { // serialize access
+ // re-check
+ Supplier<V> supplier = valuesMap.get(subKey);
+ if (supplier != this) {
+ // something changed while we were waiting:
+ // might be that we were replaced by a CacheValue
+ // or were removed because of failure ->
+ // return null to signal WeakCache.get() to retry
+ // the loop
+ return null;
+ }
+ // else still us (supplier == this)
+
+ // create new value
+ V value = null;
+ try {
+ value = Objects.requireNonNull(valueFactory.apply(key, parameter));
+ } finally {
+ if (value == null) { // remove us on failure
+ valuesMap.remove(subKey, this);
+ }
+ }
+ // the only path to reach here is with non-null value
+ assert value != null;
+
+ // wrap value with CacheValue (WeakReference)
+ CacheValue<V> cacheValue = new CacheValue<>(value);
+
+ // try replacing us with CacheValue (this should always succeed)
+ if (valuesMap.replace(subKey, this, cacheValue)) {
+ // put also in reverseMap
+ reverseMap.put(cacheValue, Boolean.TRUE);
+ } else {
+ throw new AssertionError("Should not reach here");
+ }
+
+ // successfully replaced us with new CacheValue -> return the value
+ // wrapped by it
+ return value;
+ }
+ }
+
+ /**
+ * Common type of value suppliers that are holding a referent.
+ * The {@link #equals} and {@link #hashCode} of implementations is defined
+ * to compare the referent by identity.
+ */
+ private interface Value<V> extends Supplier<V> {}
+
+ /**
+ * An optimized {@link Value} used to look-up the value in
+ * {@link WeakCache#containsValue} method so that we are not
+ * constructing the whole {@link CacheValue} just to look-up the referent.
+ */
+ private static final class LookupValue<V> implements Value<V> {
+ private final V value;
+
+ LookupValue(V value) {
+ this.value = value;
+ }
+
+ @Override
+ public V get() {
+ return value;
+ }
+
+ @Override
+ public int hashCode() {
+ return System.identityHashCode(value); // compare by identity
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj == this ||
+ obj instanceof Value &&
+ this.value == ((Value<?>) obj).get(); // compare by identity
+ }
+ }
+
+ /**
+ * A {@link Value} that weakly references the referent.
+ */
+ private static final class CacheValue<V>
+ extends WeakReference<V> implements Value<V>
+ {
+ private final int hash;
+
+ CacheValue(V value) {
+ super(value);
+ this.hash = System.identityHashCode(value); // compare by identity
+ }
+
+ @Override
+ public int hashCode() {
+ return hash;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ V value;
+ return obj == this ||
+ obj instanceof Value &&
+ // cleared CacheValue is only equal to itself
+ (value = get()) != null &&
+ value == ((Value<?>) obj).get(); // compare by identity
+ }
+ }
+
+ /**
+ * CacheKey containing a weakly referenced {@code key}. It registers
+ * itself with the {@code refQueue} so that it can be used to expunge
+ * the entry when the {@link WeakReference} is cleared.
+ */
+ private static final class CacheKey<K> extends WeakReference<K> {
+
+ // a replacement for null keys
+ private static final Object NULL_KEY = new Object();
+
+ static <K> Object valueOf(K key, ReferenceQueue<K> refQueue) {
+ return key == null
+ // null key means we can't weakly reference it,
+ // so we use a NULL_KEY singleton as cache key
+ ? NULL_KEY
+ // non-null key requires wrapping with a WeakReference
+ : new CacheKey<>(key, refQueue);
+ }
+
+ private final int hash;
+
+ private CacheKey(K key, ReferenceQueue<K> refQueue) {
+ super(key, refQueue);
+ this.hash = System.identityHashCode(key); // compare by identity
+ }
+
+ @Override
+ public int hashCode() {
+ return hash;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ K key;
+ return obj == this ||
+ obj != null &&
+ obj.getClass() == this.getClass() &&
+ // cleared CacheKey is only equal to itself
+ (key = this.get()) != null &&
+ // compare key by identity
+ key == ((CacheKey<K>) obj).get();
+ }
+
+ void expungeFrom(ConcurrentMap<?, ? extends ConcurrentMap<?, ?>> map,
+ ConcurrentMap<?, Boolean> reverseMap) {
+ // removing just by key is always safe here because after a CacheKey
+ // is cleared and enqueue-ed it is only equal to itself
+ // (see equals method)...
+ ConcurrentMap<?, ?> valuesMap = map.remove(this);
+ // remove also from reverseMap if needed
+ if (valuesMap != null) {
+ for (Object cacheValue : valuesMap.values()) {
+ reverseMap.remove(cacheValue);
+ }
+ }
+ }
+ }
+}
diff --git a/java/lang/reflect/WildcardType.annotated.java b/java/lang/reflect/WildcardType.annotated.java
new file mode 100644
index 0000000..c8b90a0
--- /dev/null
+++ b/java/lang/reflect/WildcardType.annotated.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2003, 2004, 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.reflect;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public interface WildcardType extends java.lang.reflect.Type {
+
+public [email protected] Type @libcore.util.NonNull [] getUpperBounds();
+
+public [email protected] Type @libcore.util.NonNull [] getLowerBounds();
+}
diff --git a/java/lang/reflect/WildcardType.java b/java/lang/reflect/WildcardType.java
new file mode 100644
index 0000000..aa8e824
--- /dev/null
+++ b/java/lang/reflect/WildcardType.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2003, 2004, 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.reflect;
+
+/**
+ * WildcardType represents a wildcard type expression, such as
+ * {@code ?}, {@code ? extends Number}, or {@code ? super Integer}.
+ *
+ * @since 1.5
+ */
+public interface WildcardType extends Type {
+ /**
+ * Returns an array of {@code Type} objects representing the upper
+ * bound(s) of this type variable. Note that if no upper bound is
+ * explicitly declared, the upper bound is {@code Object}.
+ *
+ * <p>For each upper bound B :
+ * <ul>
+ * <li>if B is a parameterized type or a type variable, it is created,
+ * (see {@link java.lang.reflect.ParameterizedType ParameterizedType}
+ * for the details of the creation process for parameterized types).
+ * <li>Otherwise, B is resolved.
+ * </ul>
+ *
+ * @return an array of Types representing the upper bound(s) of this
+ * type variable
+ * @throws TypeNotPresentException if any of the
+ * bounds refers to a non-existent type declaration
+ * @throws MalformedParameterizedTypeException if any of the
+ * bounds refer to a parameterized type that cannot be instantiated
+ * for any reason
+ */
+ Type[] getUpperBounds();
+
+ /**
+ * Returns an array of {@code Type} objects representing the
+ * lower bound(s) of this type variable. Note that if no lower bound is
+ * explicitly declared, the lower bound is the type of {@code null}.
+ * In this case, a zero length array is returned.
+ *
+ * <p>For each lower bound B :
+ * <ul>
+ * <li>if B is a parameterized type or a type variable, it is created,
+ * (see {@link java.lang.reflect.ParameterizedType ParameterizedType}
+ * for the details of the creation process for parameterized types).
+ * <li>Otherwise, B is resolved.
+ * </ul>
+ *
+ * @return an array of Types representing the lower bound(s) of this
+ * type variable
+ * @throws TypeNotPresentException if any of the
+ * bounds refers to a non-existent type declaration
+ * @throws MalformedParameterizedTypeException if any of the
+ * bounds refer to a parameterized type that cannot be instantiated
+ * for any reason
+ */
+ Type[] getLowerBounds();
+ // one or many? Up to language spec; currently only one, but this API
+ // allows for generalization.
+}
diff --git a/java/lang/reflect/package-info.java b/java/lang/reflect/package-info.java
new file mode 100644
index 0000000..258a07e
--- /dev/null
+++ b/java/lang/reflect/package-info.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 1998, 2006, 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.
+ */
+
+/**
+ * Provides classes and interfaces for obtaining reflective
+ * information about classes and objects. Reflection allows
+ * programmatic access to information about the fields, methods and
+ * constructors of loaded classes, and the use of reflected fields,
+ * methods, and constructors to operate on their underlying
+ * counterparts, within security restrictions.
+ *
+ * <p>{@code AccessibleObject} allows suppression of access checks if
+ * the necessary {@code ReflectPermission} is available.
+ *
+ * <p>{@code Array} provides static methods to dynamically create and
+ * access arrays.
+ *
+ * <p>Classes in this package, along with {@code java.lang.Class}
+ * accommodate applications such as debuggers, interpreters, object
+ * inspectors, class browsers, and services such as Object
+ * Serialization and JavaBeans that need access to either the public
+ * members of a target object (based on its runtime class) or the
+ * members declared by a given class.
+ *
+ * @since JDK1.1
+ */
+package java.lang.reflect;