提交 8e249cfe 编写于 作者: J jgish

6206780: (str) Forwarding append methods in String{Buffer,Builder} are inconsistent

Summary: update StringBuilder & StringBuffer to consistently handle forwarding to AbstractStringBuilder. Some additional cleanup (removal of refs to sub-classes from AbstractStringBuilder)
Reviewed-by: chegar, alanb, mduigou
上级 32eece14
...@@ -70,6 +70,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { ...@@ -70,6 +70,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
* @return the length of the sequence of characters currently * @return the length of the sequence of characters currently
* represented by this object * represented by this object
*/ */
@Override
public int length() { public int length() {
return count; return count;
} }
...@@ -200,6 +201,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { ...@@ -200,6 +201,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
* @throws IndexOutOfBoundsException if {@code index} is * @throws IndexOutOfBoundsException if {@code index} is
* negative or greater than or equal to {@code length()}. * negative or greater than or equal to {@code length()}.
*/ */
@Override
public char charAt(int index) { public char charAt(int index) {
if ((index < 0) || (index >= count)) if ((index < 0) || (index >= count))
throw new StringIndexOutOfBoundsException(index); throw new StringIndexOutOfBoundsException(index);
...@@ -431,14 +433,29 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { ...@@ -431,14 +433,29 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
return this; return this;
} }
/**
* @since 1.8
*/
AbstractStringBuilder append(AbstractStringBuilder asb) {
if (asb == null)
return append("null");
int len = asb.length();
ensureCapacityInternal(count + len);
asb.getChars(0, len, value, count);
count += len;
return this;
}
// Documentation in subclasses because of synchro difference // Documentation in subclasses because of synchro difference
@Override
public AbstractStringBuilder append(CharSequence s) { public AbstractStringBuilder append(CharSequence s) {
if (s == null) if (s == null)
s = "null"; s = "null";
if (s instanceof String) if (s instanceof String)
return this.append((String)s); return this.append((String)s);
if (s instanceof StringBuffer) if (s instanceof AbstractStringBuilder)
return this.append((StringBuffer)s); return this.append((AbstractStringBuilder)s);
return this.append(s, 0, s.length()); return this.append(s, 0, s.length());
} }
...@@ -471,6 +488,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { ...@@ -471,6 +488,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
* {@code start} is greater than {@code end} or * {@code start} is greater than {@code end} or
* {@code end} is greater than {@code s.length()} * {@code end} is greater than {@code s.length()}
*/ */
@Override
public AbstractStringBuilder append(CharSequence s, int start, int end) { public AbstractStringBuilder append(CharSequence s, int start, int end) {
if (s == null) if (s == null)
s = "null"; s = "null";
...@@ -585,6 +603,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { ...@@ -585,6 +603,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
* @param c a {@code char}. * @param c a {@code char}.
* @return a reference to this object. * @return a reference to this object.
*/ */
@Override
public AbstractStringBuilder append(char c) { public AbstractStringBuilder append(char c) {
ensureCapacityInternal(count + 1); ensureCapacityInternal(count + 1);
value[count++] = c; value[count++] = c;
...@@ -847,6 +866,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { ...@@ -847,6 +866,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
* or if <tt>start</tt> is greater than <tt>end</tt> * or if <tt>start</tt> is greater than <tt>end</tt>
* @spec JSR-51 * @spec JSR-51
*/ */
@Override
public CharSequence subSequence(int start, int end) { public CharSequence subSequence(int start, int end) {
return substring(start, end); return substring(start, end);
} }
...@@ -1397,6 +1417,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { ...@@ -1397,6 +1417,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
* *
* @return a string representation of this sequence of characters. * @return a string representation of this sequence of characters.
*/ */
@Override
public abstract String toString(); public abstract String toString();
/** /**
......
...@@ -149,15 +149,18 @@ package java.lang; ...@@ -149,15 +149,18 @@ package java.lang;
append(seq); append(seq);
} }
@Override
public synchronized int length() { public synchronized int length() {
return count; return count;
} }
@Override
public synchronized int capacity() { public synchronized int capacity() {
return value.length; return value.length;
} }
@Override
public synchronized void ensureCapacity(int minimumCapacity) { public synchronized void ensureCapacity(int minimumCapacity) {
if (minimumCapacity > value.length) { if (minimumCapacity > value.length) {
expandCapacity(minimumCapacity); expandCapacity(minimumCapacity);
...@@ -167,6 +170,7 @@ package java.lang; ...@@ -167,6 +170,7 @@ package java.lang;
/** /**
* @since 1.5 * @since 1.5
*/ */
@Override
public synchronized void trimToSize() { public synchronized void trimToSize() {
super.trimToSize(); super.trimToSize();
} }
...@@ -175,6 +179,7 @@ package java.lang; ...@@ -175,6 +179,7 @@ package java.lang;
* @throws IndexOutOfBoundsException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc}
* @see #length() * @see #length()
*/ */
@Override
public synchronized void setLength(int newLength) { public synchronized void setLength(int newLength) {
super.setLength(newLength); super.setLength(newLength);
} }
...@@ -183,6 +188,7 @@ package java.lang; ...@@ -183,6 +188,7 @@ package java.lang;
* @throws IndexOutOfBoundsException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc}
* @see #length() * @see #length()
*/ */
@Override
public synchronized char charAt(int index) { public synchronized char charAt(int index) {
if ((index < 0) || (index >= count)) if ((index < 0) || (index >= count))
throw new StringIndexOutOfBoundsException(index); throw new StringIndexOutOfBoundsException(index);
...@@ -192,6 +198,7 @@ package java.lang; ...@@ -192,6 +198,7 @@ package java.lang;
/** /**
* @since 1.5 * @since 1.5
*/ */
@Override
public synchronized int codePointAt(int index) { public synchronized int codePointAt(int index) {
return super.codePointAt(index); return super.codePointAt(index);
} }
...@@ -199,6 +206,7 @@ package java.lang; ...@@ -199,6 +206,7 @@ package java.lang;
/** /**
* @since 1.5 * @since 1.5
*/ */
@Override
public synchronized int codePointBefore(int index) { public synchronized int codePointBefore(int index) {
return super.codePointBefore(index); return super.codePointBefore(index);
} }
...@@ -206,6 +214,7 @@ package java.lang; ...@@ -206,6 +214,7 @@ package java.lang;
/** /**
* @since 1.5 * @since 1.5
*/ */
@Override
public synchronized int codePointCount(int beginIndex, int endIndex) { public synchronized int codePointCount(int beginIndex, int endIndex) {
return super.codePointCount(beginIndex, endIndex); return super.codePointCount(beginIndex, endIndex);
} }
...@@ -213,6 +222,7 @@ package java.lang; ...@@ -213,6 +222,7 @@ package java.lang;
/** /**
* @since 1.5 * @since 1.5
*/ */
@Override
public synchronized int offsetByCodePoints(int index, int codePointOffset) { public synchronized int offsetByCodePoints(int index, int codePointOffset) {
return super.offsetByCodePoints(index, codePointOffset); return super.offsetByCodePoints(index, codePointOffset);
} }
...@@ -221,6 +231,7 @@ package java.lang; ...@@ -221,6 +231,7 @@ package java.lang;
* @throws NullPointerException {@inheritDoc} * @throws NullPointerException {@inheritDoc}
* @throws IndexOutOfBoundsException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc}
*/ */
@Override
public synchronized void getChars(int srcBegin, int srcEnd, char[] dst, public synchronized void getChars(int srcBegin, int srcEnd, char[] dst,
int dstBegin) int dstBegin)
{ {
...@@ -231,17 +242,20 @@ package java.lang; ...@@ -231,17 +242,20 @@ package java.lang;
* @throws IndexOutOfBoundsException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc}
* @see #length() * @see #length()
*/ */
@Override
public synchronized void setCharAt(int index, char ch) { public synchronized void setCharAt(int index, char ch) {
if ((index < 0) || (index >= count)) if ((index < 0) || (index >= count))
throw new StringIndexOutOfBoundsException(index); throw new StringIndexOutOfBoundsException(index);
value[index] = ch; value[index] = ch;
} }
@Override
public synchronized StringBuffer append(Object obj) { public synchronized StringBuffer append(Object obj) {
super.append(String.valueOf(obj)); super.append(String.valueOf(obj));
return this; return this;
} }
@Override
public synchronized StringBuffer append(String str) { public synchronized StringBuffer append(String str) {
super.append(str); super.append(str);
return this; return this;
...@@ -276,6 +290,14 @@ package java.lang; ...@@ -276,6 +290,14 @@ package java.lang;
return this; return this;
} }
/**
* @since 1.8
*/
@Override
synchronized StringBuffer append(AbstractStringBuilder asb) {
super.append(asb);
return this;
}
/** /**
* Appends the specified {@code CharSequence} to this * Appends the specified {@code CharSequence} to this
...@@ -298,27 +320,26 @@ package java.lang; ...@@ -298,27 +320,26 @@ package java.lang;
* @return a reference to this object. * @return a reference to this object.
* @since 1.5 * @since 1.5
*/ */
@Override
public StringBuffer append(CharSequence s) { public StringBuffer append(CharSequence s) {
// Note, synchronization achieved via other invocations // Note, synchronization achieved via invocations of other StringBuffer methods after
if (s == null) // narrowing of s to specific type
s = "null"; super.append(s);
if (s instanceof String) return this;
return this.append((String)s);
if (s instanceof StringBuffer)
return this.append((StringBuffer)s);
return this.append(s, 0, s.length());
} }
/** /**
* @throws IndexOutOfBoundsException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc}
* @since 1.5 * @since 1.5
*/ */
@Override
public synchronized StringBuffer append(CharSequence s, int start, int end) public synchronized StringBuffer append(CharSequence s, int start, int end)
{ {
super.append(s, start, end); super.append(s, start, end);
return this; return this;
} }
@Override
public synchronized StringBuffer append(char[] str) { public synchronized StringBuffer append(char[] str) {
super.append(str); super.append(str);
return this; return this;
...@@ -327,21 +348,25 @@ package java.lang; ...@@ -327,21 +348,25 @@ package java.lang;
/** /**
* @throws IndexOutOfBoundsException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc}
*/ */
@Override
public synchronized StringBuffer append(char[] str, int offset, int len) { public synchronized StringBuffer append(char[] str, int offset, int len) {
super.append(str, offset, len); super.append(str, offset, len);
return this; return this;
} }
@Override
public synchronized StringBuffer append(boolean b) { public synchronized StringBuffer append(boolean b) {
super.append(b); super.append(b);
return this; return this;
} }
@Override
public synchronized StringBuffer append(char c) { public synchronized StringBuffer append(char c) {
super.append(c); super.append(c);
return this; return this;
} }
@Override
public synchronized StringBuffer append(int i) { public synchronized StringBuffer append(int i) {
super.append(i); super.append(i);
return this; return this;
...@@ -350,21 +375,25 @@ package java.lang; ...@@ -350,21 +375,25 @@ package java.lang;
/** /**
* @since 1.5 * @since 1.5
*/ */
@Override
public synchronized StringBuffer appendCodePoint(int codePoint) { public synchronized StringBuffer appendCodePoint(int codePoint) {
super.appendCodePoint(codePoint); super.appendCodePoint(codePoint);
return this; return this;
} }
@Override
public synchronized StringBuffer append(long lng) { public synchronized StringBuffer append(long lng) {
super.append(lng); super.append(lng);
return this; return this;
} }
@Override
public synchronized StringBuffer append(float f) { public synchronized StringBuffer append(float f) {
super.append(f); super.append(f);
return this; return this;
} }
@Override
public synchronized StringBuffer append(double d) { public synchronized StringBuffer append(double d) {
super.append(d); super.append(d);
return this; return this;
...@@ -374,6 +403,7 @@ package java.lang; ...@@ -374,6 +403,7 @@ package java.lang;
* @throws StringIndexOutOfBoundsException {@inheritDoc} * @throws StringIndexOutOfBoundsException {@inheritDoc}
* @since 1.2 * @since 1.2
*/ */
@Override
public synchronized StringBuffer delete(int start, int end) { public synchronized StringBuffer delete(int start, int end) {
super.delete(start, end); super.delete(start, end);
return this; return this;
...@@ -383,6 +413,7 @@ package java.lang; ...@@ -383,6 +413,7 @@ package java.lang;
* @throws StringIndexOutOfBoundsException {@inheritDoc} * @throws StringIndexOutOfBoundsException {@inheritDoc}
* @since 1.2 * @since 1.2
*/ */
@Override
public synchronized StringBuffer deleteCharAt(int index) { public synchronized StringBuffer deleteCharAt(int index) {
super.deleteCharAt(index); super.deleteCharAt(index);
return this; return this;
...@@ -392,6 +423,7 @@ package java.lang; ...@@ -392,6 +423,7 @@ package java.lang;
* @throws StringIndexOutOfBoundsException {@inheritDoc} * @throws StringIndexOutOfBoundsException {@inheritDoc}
* @since 1.2 * @since 1.2
*/ */
@Override
public synchronized StringBuffer replace(int start, int end, String str) { public synchronized StringBuffer replace(int start, int end, String str) {
super.replace(start, end, str); super.replace(start, end, str);
return this; return this;
...@@ -401,6 +433,7 @@ package java.lang; ...@@ -401,6 +433,7 @@ package java.lang;
* @throws StringIndexOutOfBoundsException {@inheritDoc} * @throws StringIndexOutOfBoundsException {@inheritDoc}
* @since 1.2 * @since 1.2
*/ */
@Override
public synchronized String substring(int start) { public synchronized String substring(int start) {
return substring(start, count); return substring(start, count);
} }
...@@ -409,6 +442,7 @@ package java.lang; ...@@ -409,6 +442,7 @@ package java.lang;
* @throws IndexOutOfBoundsException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc}
* @since 1.4 * @since 1.4
*/ */
@Override
public synchronized CharSequence subSequence(int start, int end) { public synchronized CharSequence subSequence(int start, int end) {
return super.substring(start, end); return super.substring(start, end);
} }
...@@ -417,6 +451,7 @@ package java.lang; ...@@ -417,6 +451,7 @@ package java.lang;
* @throws StringIndexOutOfBoundsException {@inheritDoc} * @throws StringIndexOutOfBoundsException {@inheritDoc}
* @since 1.2 * @since 1.2
*/ */
@Override
public synchronized String substring(int start, int end) { public synchronized String substring(int start, int end) {
return super.substring(start, end); return super.substring(start, end);
} }
...@@ -425,6 +460,7 @@ package java.lang; ...@@ -425,6 +460,7 @@ package java.lang;
* @throws StringIndexOutOfBoundsException {@inheritDoc} * @throws StringIndexOutOfBoundsException {@inheritDoc}
* @since 1.2 * @since 1.2
*/ */
@Override
public synchronized StringBuffer insert(int index, char[] str, int offset, public synchronized StringBuffer insert(int index, char[] str, int offset,
int len) int len)
{ {
...@@ -435,6 +471,7 @@ package java.lang; ...@@ -435,6 +471,7 @@ package java.lang;
/** /**
* @throws StringIndexOutOfBoundsException {@inheritDoc} * @throws StringIndexOutOfBoundsException {@inheritDoc}
*/ */
@Override
public synchronized StringBuffer insert(int offset, Object obj) { public synchronized StringBuffer insert(int offset, Object obj) {
super.insert(offset, String.valueOf(obj)); super.insert(offset, String.valueOf(obj));
return this; return this;
...@@ -443,6 +480,7 @@ package java.lang; ...@@ -443,6 +480,7 @@ package java.lang;
/** /**
* @throws StringIndexOutOfBoundsException {@inheritDoc} * @throws StringIndexOutOfBoundsException {@inheritDoc}
*/ */
@Override
public synchronized StringBuffer insert(int offset, String str) { public synchronized StringBuffer insert(int offset, String str) {
super.insert(offset, str); super.insert(offset, str);
return this; return this;
...@@ -451,6 +489,7 @@ package java.lang; ...@@ -451,6 +489,7 @@ package java.lang;
/** /**
* @throws StringIndexOutOfBoundsException {@inheritDoc} * @throws StringIndexOutOfBoundsException {@inheritDoc}
*/ */
@Override
public synchronized StringBuffer insert(int offset, char[] str) { public synchronized StringBuffer insert(int offset, char[] str) {
super.insert(offset, str); super.insert(offset, str);
return this; return this;
...@@ -460,21 +499,21 @@ package java.lang; ...@@ -460,21 +499,21 @@ package java.lang;
* @throws IndexOutOfBoundsException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc}
* @since 1.5 * @since 1.5
*/ */
@Override
public StringBuffer insert(int dstOffset, CharSequence s) { public StringBuffer insert(int dstOffset, CharSequence s) {
// Note, synchronization achieved via other invocations // Note, synchronization achieved via invocations of other StringBuffer methods
if (s == null) // after narrowing of s to specific type
s = "null"; super.insert(dstOffset, s);
if (s instanceof String) return this;
return this.insert(dstOffset, (String)s);
return this.insert(dstOffset, s, 0, s.length());
} }
/** /**
* @throws IndexOutOfBoundsException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc}
* @since 1.5 * @since 1.5
*/ */
@Override
public synchronized StringBuffer insert(int dstOffset, CharSequence s, public synchronized StringBuffer insert(int dstOffset, CharSequence s,
int start, int end) int start, int end)
{ {
super.insert(dstOffset, s, start, end); super.insert(dstOffset, s, start, end);
return this; return this;
...@@ -483,13 +522,18 @@ package java.lang; ...@@ -483,13 +522,18 @@ package java.lang;
/** /**
* @throws StringIndexOutOfBoundsException {@inheritDoc} * @throws StringIndexOutOfBoundsException {@inheritDoc}
*/ */
public StringBuffer insert(int offset, boolean b) { @Override
return insert(offset, String.valueOf(b)); 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
super.insert(offset, b);
return this;
} }
/** /**
* @throws IndexOutOfBoundsException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc}
*/ */
@Override
public synchronized StringBuffer insert(int offset, char c) { public synchronized StringBuffer insert(int offset, char c) {
super.insert(offset, c); super.insert(offset, c);
return this; return this;
...@@ -498,54 +542,73 @@ package java.lang; ...@@ -498,54 +542,73 @@ package java.lang;
/** /**
* @throws StringIndexOutOfBoundsException {@inheritDoc} * @throws StringIndexOutOfBoundsException {@inheritDoc}
*/ */
@Override
public StringBuffer insert(int offset, int i) { public StringBuffer insert(int offset, int i) {
return insert(offset, String.valueOf(i)); // Note, synchronization achieved via invocation of StringBuffer insert(int, String)
// after conversion of i to String by super class method
super.insert(offset, i);
return this;
} }
/** /**
* @throws StringIndexOutOfBoundsException {@inheritDoc} * @throws StringIndexOutOfBoundsException {@inheritDoc}
*/ */
@Override
public StringBuffer insert(int offset, long l) { public StringBuffer insert(int offset, long l) {
return insert(offset, String.valueOf(l)); // Note, synchronization achieved via invocation of StringBuffer insert(int, String)
// after conversion of l to String by super class method
super.insert(offset, l);
return this;
} }
/** /**
* @throws StringIndexOutOfBoundsException {@inheritDoc} * @throws StringIndexOutOfBoundsException {@inheritDoc}
*/ */
@Override
public StringBuffer insert(int offset, float f) { public StringBuffer insert(int offset, float f) {
return insert(offset, String.valueOf(f)); // Note, synchronization achieved via invocation of StringBuffer insert(int, String)
// after conversion of f to String by super class method
super.insert(offset, f);
return this;
} }
/** /**
* @throws StringIndexOutOfBoundsException {@inheritDoc} * @throws StringIndexOutOfBoundsException {@inheritDoc}
*/ */
@Override
public StringBuffer insert(int offset, double d) { public StringBuffer insert(int offset, double d) {
return insert(offset, String.valueOf(d)); // Note, synchronization achieved via invocation of StringBuffer insert(int, String)
// after conversion of d to String by super class method
super.insert(offset, d);
return this;
} }
/** /**
* @throws NullPointerException {@inheritDoc} * @throws NullPointerException {@inheritDoc}
* @since 1.4 * @since 1.4
*/ */
@Override
public int indexOf(String str) { public int indexOf(String str) {
return indexOf(str, 0); // Note, synchronization achieved via invocations of other StringBuffer methods
return super.indexOf(str);
} }
/** /**
* @throws NullPointerException {@inheritDoc} * @throws NullPointerException {@inheritDoc}
* @since 1.4 * @since 1.4
*/ */
@Override
public synchronized int indexOf(String str, int fromIndex) { public synchronized int indexOf(String str, int fromIndex) {
return String.indexOf(value, 0, count, return super.indexOf(str, fromIndex);
str.toCharArray(), 0, str.length(), fromIndex);
} }
/** /**
* @throws NullPointerException {@inheritDoc} * @throws NullPointerException {@inheritDoc}
* @since 1.4 * @since 1.4
*/ */
@Override
public int lastIndexOf(String str) { public int lastIndexOf(String str) {
// Note, synchronization achieved via other invocations // Note, synchronization achieved via invocations of other StringBuffer methods
return lastIndexOf(str, count); return lastIndexOf(str, count);
} }
...@@ -553,19 +616,21 @@ package java.lang; ...@@ -553,19 +616,21 @@ package java.lang;
* @throws NullPointerException {@inheritDoc} * @throws NullPointerException {@inheritDoc}
* @since 1.4 * @since 1.4
*/ */
@Override
public synchronized int lastIndexOf(String str, int fromIndex) { public synchronized int lastIndexOf(String str, int fromIndex) {
return String.lastIndexOf(value, 0, count, return super.lastIndexOf(str, fromIndex);
str.toCharArray(), 0, str.length(), fromIndex);
} }
/** /**
* @since JDK1.0.2 * @since JDK1.0.2
*/ */
@Override
public synchronized StringBuffer reverse() { public synchronized StringBuffer reverse() {
super.reverse(); super.reverse();
return this; return this;
} }
@Override
public synchronized String toString() { public synchronized String toString() {
return new String(value, 0, count); return new String(value, 0, count);
} }
......
...@@ -124,28 +124,17 @@ public final class StringBuilder ...@@ -124,28 +124,17 @@ public final class StringBuilder
append(seq); append(seq);
} }
@Override
public StringBuilder append(Object obj) { public StringBuilder append(Object obj) {
return append(String.valueOf(obj)); return append(String.valueOf(obj));
} }
@Override
public StringBuilder append(String str) { public StringBuilder append(String str) {
super.append(str); super.append(str);
return this; return this;
} }
// Appends the specified string builder to this sequence.
private StringBuilder append(StringBuilder sb) {
if (sb == null)
return append("null");
int len = sb.length();
int newcount = count + len;
if (newcount > value.length)
expandCapacity(newcount);
sb.getChars(0, len, value, count);
count = newcount;
return this;
}
/** /**
* Appends the specified <tt>StringBuffer</tt> to this sequence. * Appends the specified <tt>StringBuffer</tt> to this sequence.
* <p> * <p>
...@@ -170,28 +159,22 @@ public final class StringBuilder ...@@ -170,28 +159,22 @@ public final class StringBuilder
return this; return this;
} }
/** @Override
*/
public StringBuilder append(CharSequence s) { public StringBuilder append(CharSequence s) {
if (s == null) super.append(s);
s = "null"; return this;
if (s instanceof String)
return this.append((String)s);
if (s instanceof StringBuffer)
return this.append((StringBuffer)s);
if (s instanceof StringBuilder)
return this.append((StringBuilder)s);
return this.append(s, 0, s.length());
} }
/** /**
* @throws IndexOutOfBoundsException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc}
*/ */
@Override
public StringBuilder append(CharSequence s, int start, int end) { public StringBuilder append(CharSequence s, int start, int end) {
super.append(s, start, end); super.append(s, start, end);
return this; return this;
} }
@Override
public StringBuilder append(char[] str) { public StringBuilder append(char[] str) {
super.append(str); super.append(str);
return this; return this;
...@@ -200,36 +183,43 @@ public final class StringBuilder ...@@ -200,36 +183,43 @@ public final class StringBuilder
/** /**
* @throws IndexOutOfBoundsException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc}
*/ */
@Override
public StringBuilder append(char[] str, int offset, int len) { public StringBuilder append(char[] str, int offset, int len) {
super.append(str, offset, len); super.append(str, offset, len);
return this; return this;
} }
@Override
public StringBuilder append(boolean b) { public StringBuilder append(boolean b) {
super.append(b); super.append(b);
return this; return this;
} }
@Override
public StringBuilder append(char c) { public StringBuilder append(char c) {
super.append(c); super.append(c);
return this; return this;
} }
@Override
public StringBuilder append(int i) { public StringBuilder append(int i) {
super.append(i); super.append(i);
return this; return this;
} }
@Override
public StringBuilder append(long lng) { public StringBuilder append(long lng) {
super.append(lng); super.append(lng);
return this; return this;
} }
@Override
public StringBuilder append(float f) { public StringBuilder append(float f) {
super.append(f); super.append(f);
return this; return this;
} }
@Override
public StringBuilder append(double d) { public StringBuilder append(double d) {
super.append(d); super.append(d);
return this; return this;
...@@ -238,6 +228,7 @@ public final class StringBuilder ...@@ -238,6 +228,7 @@ public final class StringBuilder
/** /**
* @since 1.5 * @since 1.5
*/ */
@Override
public StringBuilder appendCodePoint(int codePoint) { public StringBuilder appendCodePoint(int codePoint) {
super.appendCodePoint(codePoint); super.appendCodePoint(codePoint);
return this; return this;
...@@ -246,6 +237,7 @@ public final class StringBuilder ...@@ -246,6 +237,7 @@ public final class StringBuilder
/** /**
* @throws StringIndexOutOfBoundsException {@inheritDoc} * @throws StringIndexOutOfBoundsException {@inheritDoc}
*/ */
@Override
public StringBuilder delete(int start, int end) { public StringBuilder delete(int start, int end) {
super.delete(start, end); super.delete(start, end);
return this; return this;
...@@ -254,6 +246,7 @@ public final class StringBuilder ...@@ -254,6 +246,7 @@ public final class StringBuilder
/** /**
* @throws StringIndexOutOfBoundsException {@inheritDoc} * @throws StringIndexOutOfBoundsException {@inheritDoc}
*/ */
@Override
public StringBuilder deleteCharAt(int index) { public StringBuilder deleteCharAt(int index) {
super.deleteCharAt(index); super.deleteCharAt(index);
return this; return this;
...@@ -262,6 +255,7 @@ public final class StringBuilder ...@@ -262,6 +255,7 @@ public final class StringBuilder
/** /**
* @throws StringIndexOutOfBoundsException {@inheritDoc} * @throws StringIndexOutOfBoundsException {@inheritDoc}
*/ */
@Override
public StringBuilder replace(int start, int end, String str) { public StringBuilder replace(int start, int end, String str) {
super.replace(start, end, str); super.replace(start, end, str);
return this; return this;
...@@ -270,6 +264,7 @@ public final class StringBuilder ...@@ -270,6 +264,7 @@ public final class StringBuilder
/** /**
* @throws StringIndexOutOfBoundsException {@inheritDoc} * @throws StringIndexOutOfBoundsException {@inheritDoc}
*/ */
@Override
public StringBuilder insert(int index, char[] str, int offset, public StringBuilder insert(int index, char[] str, int offset,
int len) int len)
{ {
...@@ -280,13 +275,16 @@ public final class StringBuilder ...@@ -280,13 +275,16 @@ public final class StringBuilder
/** /**
* @throws StringIndexOutOfBoundsException {@inheritDoc} * @throws StringIndexOutOfBoundsException {@inheritDoc}
*/ */
@Override
public StringBuilder insert(int offset, Object obj) { public StringBuilder insert(int offset, Object obj) {
return insert(offset, String.valueOf(obj)); super.insert(offset, obj);
return this;
} }
/** /**
* @throws StringIndexOutOfBoundsException {@inheritDoc} * @throws StringIndexOutOfBoundsException {@inheritDoc}
*/ */
@Override
public StringBuilder insert(int offset, String str) { public StringBuilder insert(int offset, String str) {
super.insert(offset, str); super.insert(offset, str);
return this; return this;
...@@ -295,6 +293,7 @@ public final class StringBuilder ...@@ -295,6 +293,7 @@ public final class StringBuilder
/** /**
* @throws StringIndexOutOfBoundsException {@inheritDoc} * @throws StringIndexOutOfBoundsException {@inheritDoc}
*/ */
@Override
public StringBuilder insert(int offset, char[] str) { public StringBuilder insert(int offset, char[] str) {
super.insert(offset, str); super.insert(offset, str);
return this; return this;
...@@ -303,17 +302,16 @@ public final class StringBuilder ...@@ -303,17 +302,16 @@ public final class StringBuilder
/** /**
* @throws IndexOutOfBoundsException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc}
*/ */
@Override
public StringBuilder insert(int dstOffset, CharSequence s) { public StringBuilder insert(int dstOffset, CharSequence s) {
if (s == null) super.insert(dstOffset, s);
s = "null"; return this;
if (s instanceof String)
return this.insert(dstOffset, (String)s);
return this.insert(dstOffset, s, 0, s.length());
} }
/** /**
* @throws IndexOutOfBoundsException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc}
*/ */
@Override
public StringBuilder insert(int dstOffset, CharSequence s, public StringBuilder insert(int dstOffset, CharSequence s,
int start, int end) int start, int end)
{ {
...@@ -324,6 +322,7 @@ public final class StringBuilder ...@@ -324,6 +322,7 @@ public final class StringBuilder
/** /**
* @throws StringIndexOutOfBoundsException {@inheritDoc} * @throws StringIndexOutOfBoundsException {@inheritDoc}
*/ */
@Override
public StringBuilder insert(int offset, boolean b) { public StringBuilder insert(int offset, boolean b) {
super.insert(offset, b); super.insert(offset, b);
return this; return this;
...@@ -332,6 +331,7 @@ public final class StringBuilder ...@@ -332,6 +331,7 @@ public final class StringBuilder
/** /**
* @throws IndexOutOfBoundsException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc}
*/ */
@Override
public StringBuilder insert(int offset, char c) { public StringBuilder insert(int offset, char c) {
super.insert(offset, c); super.insert(offset, c);
return this; return this;
...@@ -340,66 +340,78 @@ public final class StringBuilder ...@@ -340,66 +340,78 @@ public final class StringBuilder
/** /**
* @throws StringIndexOutOfBoundsException {@inheritDoc} * @throws StringIndexOutOfBoundsException {@inheritDoc}
*/ */
@Override
public StringBuilder insert(int offset, int i) { public StringBuilder insert(int offset, int i) {
return insert(offset, String.valueOf(i)); super.insert(offset, i);
return this;
} }
/** /**
* @throws StringIndexOutOfBoundsException {@inheritDoc} * @throws StringIndexOutOfBoundsException {@inheritDoc}
*/ */
@Override
public StringBuilder insert(int offset, long l) { public StringBuilder insert(int offset, long l) {
return insert(offset, String.valueOf(l)); super.insert(offset, l);
return this;
} }
/** /**
* @throws StringIndexOutOfBoundsException {@inheritDoc} * @throws StringIndexOutOfBoundsException {@inheritDoc}
*/ */
@Override
public StringBuilder insert(int offset, float f) { public StringBuilder insert(int offset, float f) {
return insert(offset, String.valueOf(f)); super.insert(offset, f);
return this;
} }
/** /**
* @throws StringIndexOutOfBoundsException {@inheritDoc} * @throws StringIndexOutOfBoundsException {@inheritDoc}
*/ */
@Override
public StringBuilder insert(int offset, double d) { public StringBuilder insert(int offset, double d) {
return insert(offset, String.valueOf(d)); super.insert(offset, d);
return this;
} }
/** /**
* @throws NullPointerException {@inheritDoc} * @throws NullPointerException {@inheritDoc}
*/ */
@Override
public int indexOf(String str) { public int indexOf(String str) {
return indexOf(str, 0); return super.indexOf(str);
} }
/** /**
* @throws NullPointerException {@inheritDoc} * @throws NullPointerException {@inheritDoc}
*/ */
@Override
public int indexOf(String str, int fromIndex) { public int indexOf(String str, int fromIndex) {
return String.indexOf(value, 0, count, return super.indexOf(str, fromIndex);
str.toCharArray(), 0, str.length(), fromIndex);
} }
/** /**
* @throws NullPointerException {@inheritDoc} * @throws NullPointerException {@inheritDoc}
*/ */
@Override
public int lastIndexOf(String str) { public int lastIndexOf(String str) {
return lastIndexOf(str, count); return super.lastIndexOf(str);
} }
/** /**
* @throws NullPointerException {@inheritDoc} * @throws NullPointerException {@inheritDoc}
*/ */
@Override
public int lastIndexOf(String str, int fromIndex) { public int lastIndexOf(String str, int fromIndex) {
return String.lastIndexOf(value, 0, count, return super.lastIndexOf(str, fromIndex);
str.toCharArray(), 0, str.length(), fromIndex);
} }
@Override
public StringBuilder reverse() { public StringBuilder reverse() {
super.reverse(); super.reverse();
return this; return this;
} }
@Override
public String toString() { public String toString() {
// Create a copy, don't share the array // Create a copy, don't share the array
return new String(value, 0, count); return new String(value, 0, count);
......
/*
* 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.
*
* 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.
*/
/* @test
* @bug 6206780
* @summary Test StringBuffer.append(StringBuilder);
*/
import java.util.Random;
public class AppendStringBuilder {
private static Random generator = new Random();
public static void main(String[] args) throws Exception {
for (int i=0; i<1000; i++) {
StringBuilder sb1 = generateTestBuilder(10, 100);
StringBuilder sb2 = generateTestBuilder(10, 100);
StringBuilder sb3 = generateTestBuilder(10, 100);
String s1 = sb1.toString();
String s2 = sb2.toString();
String s3 = sb3.toString();
String concatResult = new String(s1+s2+s3);
StringBuffer test = new StringBuffer();
test.append(sb1);
test.append(sb2);
test.append(sb3);
if (!test.toString().equals(concatResult))
throw new RuntimeException("StringBuffer.append failure");
}
}
private static int getRandomIndex(int constraint1, int constraint2) {
int range = constraint2 - constraint1;
int x = generator.nextInt(range);
return constraint1 + x;
}
private static StringBuilder generateTestBuilder(int min, int max) {
StringBuilder aNewStringBuilder = new StringBuilder(120);
int aNewLength = getRandomIndex(min, max);
for(int y=0; y<aNewLength; y++) {
int achar = generator.nextInt(30)+30;
char test = (char)(achar);
aNewStringBuilder.append(test);
}
return aNewStringBuilder;
}
}
/*
* 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.
*/
/**
* @test
* @bug 6206780
* @summary Test forwarding of methods to super in StringBuffer
* @author Jim Gish <jim.gish@oracle.com>
*/
import java.util.ArrayList;
import java.util.List;
public class BufferForwarding {
private final static String A_STRING_BUFFER_VAL = "aStringBuffer";
private final static String A_STRING_BUILDER_VAL = "aStringBuilder";
private final static String A_STRING_VAL = "aString";
private final static String NON_EMPTY_VAL = "NonEmpty";
public BufferForwarding() {
System.out.println( "Starting BufferForwarding");
}
public static void main(String... args) {
new BufferForwarding().executeTestMethods();
}
public void executeTestMethods() {
appendCharSequence();
indexOfString();
indexOfStringIntNull();
indexOfStringNull();
indexOfStringint();
insertintCharSequence();
insertintObject();
insertintboolean();
insertintchar();
insertintdouble();
insertintfloat();
insertintint();
insertintlong();
lastIndexOfString();
lastIndexOfStringint();
}
public void appendCharSequence() {
// three different flavors of CharSequence
CharSequence aString = A_STRING_VAL;
CharSequence aStringBuilder = new StringBuilder(A_STRING_BUILDER_VAL);
CharSequence aStringBuffer = new StringBuffer(A_STRING_BUFFER_VAL);
assertEquals( /*actual*/ new StringBuilder().append(aString).toString(), /*expected*/ A_STRING_VAL );
assertEquals( new StringBuilder().append(aStringBuilder).toString(), A_STRING_BUILDER_VAL );
assertEquals( new StringBuilder().append(aStringBuffer).toString(), A_STRING_BUFFER_VAL );
assertEquals( /*actual*/ new StringBuilder(NON_EMPTY_VAL).append(aString).toString(), NON_EMPTY_VAL+A_STRING_VAL );
assertEquals( new StringBuilder(NON_EMPTY_VAL).append(aStringBuilder).toString(), NON_EMPTY_VAL+A_STRING_BUILDER_VAL );
assertEquals( new StringBuilder(NON_EMPTY_VAL).append(aStringBuffer).toString(), NON_EMPTY_VAL+A_STRING_BUFFER_VAL );
}
void indexOfString() {
StringBuffer sb = new StringBuffer("xyz");
assertEquals( sb.indexOf("y"), 1 );
assertEquals( sb.indexOf("not found"), -1 );
}
public void indexOfStringint() {
StringBuffer sb = new StringBuffer("xyyz");
assertEquals( sb.indexOf("y",0), 1 );
assertEquals( sb.indexOf("y",1), 1 );
assertEquals( sb.indexOf("y",2), 2 );
assertEquals( sb.indexOf("not found"), -1 );
}
public void indexOfStringIntNull() {
StringBuffer sb = new StringBuffer();
// should be NPE if null passed
try {
sb.indexOf(null,1);
throw new RuntimeException("Test failed: should have thrown NPE");
} catch (NullPointerException npe) {
// expected: passed
} catch (Throwable t) {
throw new RuntimeException("Test failed: should have thrown NPE. Instead threw "
+ t);
}
}
public void indexOfStringNull() {
StringBuffer sb = new StringBuffer();
// should be NPE if null passed
try {
sb.indexOf(null);
throw new RuntimeException("Test failed: should have thrown NPE");
} catch (NullPointerException npe) {
// expected: passed
} catch (Throwable t) {
throw new RuntimeException("Test failed: should have thrown NPE. Instead threw "
+ t);
}
}
public void insertintboolean() {
boolean b = true;
StringBuffer sb = new StringBuffer("012345");
assertEquals( sb.insert( 2, b).toString(), "01true2345");
}
public void insertintchar() {
char c = 'C';
StringBuffer sb = new StringBuffer("012345");
assertEquals( sb.insert( 2, c ).toString(), "01C2345");
}
public void insertintCharSequence() {
final String initString = "012345";
// three different flavors of CharSequence
CharSequence aString = A_STRING_VAL;
CharSequence aStringBuilder = new StringBuilder(A_STRING_BUILDER_VAL);
CharSequence aStringBuffer = new StringBuffer(A_STRING_BUFFER_VAL);
assertEquals( new StringBuffer(initString).insert(2, aString).toString(), "01"+A_STRING_VAL+"2345" );
assertEquals( new StringBuffer(initString).insert(2, aStringBuilder).toString(), "01"+A_STRING_BUILDER_VAL+"2345" );
assertEquals( new StringBuffer(initString).insert(2, aStringBuffer).toString(), "01"+A_STRING_BUFFER_VAL+"2345" );
try {
new StringBuffer(initString).insert(7, aString);
throw new RuntimeException("Test failed: should have thrown IndexOutOfBoundsException");
} catch (IndexOutOfBoundsException soob) {
// expected: passed
} catch (Throwable t) {
throw new RuntimeException("Test failed: should have thrown IndexOutOfBoundsException, but instead threw " + t.getMessage());
}
}
public void insertintdouble() {
double d = 99d;
StringBuffer sb = new StringBuffer("012345");
assertEquals( sb.insert( 2, d ).toString(), "0199.02345"); }
public void insertintfloat() {
float f = 99.0f;
StringBuffer sb = new StringBuffer("012345");
assertEquals( sb.insert( 2, f ).toString(), "0199.02345"); }
public void insertintint() {
int i = 99;
StringBuffer sb = new StringBuffer("012345");
assertEquals( sb.insert( 2, i ).toString(), "01992345");
}
public void insertintlong() {
long l = 99;
StringBuffer sb = new StringBuffer("012345");
assertEquals( sb.insert( 2, l ).toString(), "01992345"); }
public void insertintObject() {
StringBuffer sb = new StringBuffer("012345");
List<String> ls = new ArrayList<String>();
ls.add("A"); ls.add("B");
String lsString = ls.toString();
assertEquals( sb.insert(2, ls).toString(), "01"+lsString+"2345");
try {
sb.insert(sb.length()+1, ls);
throw new RuntimeException("Test failed: should have thrown StringIndexOutOfBoundsException");
} catch (StringIndexOutOfBoundsException soob) {
// expected: passed
} catch (Throwable t) {
throw new RuntimeException("Test failed: should have thrown StringIndexOutOfBoundsException, but instead threw:"
+ t);
}
}
public void lastIndexOfString() {
String xyz = "xyz";
String xyz3 = "xyzxyzxyz";
StringBuffer sb = new StringBuffer(xyz3);
int pos = sb.lastIndexOf("xyz");
assertEquals( pos, 2*xyz.length() );
}
public void lastIndexOfStringint() {
StringBuffer sb = new StringBuffer("xyzxyzxyz");
int pos = sb.lastIndexOf("xyz",5);
assertEquals( pos, 3 );
pos = sb.lastIndexOf("xyz", 6);
assertEquals( pos, 6 );
}
public void assertEquals( String actual, String expected) {
if (!actual.equals( expected )) {
throw new RuntimeException( "Test failed: actual = '" + actual +
"', expected = '" + expected + "'");
}
}
public void assertEquals( int actual, int expected) {
if (actual != expected) {
throw new RuntimeException( "Test failed: actual = '" + actual +
"', expected = '" + expected + "'");
}
}
}
/*
* 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.
*
* 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.
*/
/* @test
* @bug 6206780
* @summary Test that all public unsynchronized methods of StringBuffer are either directly or indirectly synchronized
*/
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* TestSynchronization tests whether synchronized methods calls on an object
* result in synchronized calls. Note that this may not test all cases desired.
* It only tests whether some synchronization has occurred on the object during
* the call chain, and can't tell whether the object was locked across all
* operations that have been performed on the object.
*/
public class TestSynchronization {
/**
* Define parameters used in methods of StringBuffer - admittedly a bit of
* hack but 'purpose-built' for StringBuffer. Something more general could
* probably be developed if the test needs to be more widely adopted.
* <p/>
* boolean char char[] int double float long Object CharSequence String
* StringBuffer StringBuilder
* <p/>
*/
private static final boolean BOOLEAN_VAL = true;
private static final char CHAR_VAL = 'x';
private static final char[] CHAR_ARRAY_VAL = {'c', 'h', 'a', 'r', 'a', 'r',
'r', 'a', 'y'};
private static final int INT_VAL = 1;
private static final double DOUBLE_VAL = 1.0d;
private static final float FLOAT_VAL = 1.0f;
private static final long LONG_VAL = 1L;
private static final Object OBJECT_VAL = new Object();
private static final String STRING_VAL = "String value";
private static final StringBuilder STRING_BUILDER_VAL =
new StringBuilder("StringBuilder value");
private static final StringBuffer STRING_BUFFER_VAL =
new StringBuffer("StringBuffer value");
private static final CharSequence[] CHAR_SEQUENCE_VAL = {STRING_VAL,
STRING_BUILDER_VAL, STRING_BUFFER_VAL};
public static void main(String... args) throws Exception {
// First, test the tester
testClass(MyTestClass.class, /*
* self-test
*/ true);
// Finally, test StringBuffer
testClass(StringBuffer.class, /*
* self-test
*/ false);
}
/**
* Test all the public, unsynchronized methods of the given class. If
* isSelfTest is true, this is a self-test to ensure that the test program
* itself is working correctly. Should help ensure correctness of this
* program if it changes.
* <p/>
* @param aClass - the class to test
* @param isSelfTest - true if this is the special self-test class
* @throws SecurityException
*/
private static void testClass(Class<?> aClass, boolean isSelfTest) throws
Exception {
// Get all unsynchronized public methods via reflection. We don't need
// to test synchronized methods. By definition. they are already doing
// the right thing.
List<Method> methods = Arrays.asList(aClass.getDeclaredMethods());
for (Method m : methods) {
int modifiers = m.getModifiers();
if (Modifier.isPublic(modifiers)
&& !Modifier.isSynchronized(modifiers)) {
try {
testMethod(aClass, m);
} catch (TestFailedException e) {
if (isSelfTest) {
String methodName = e.getMethod().getName();
switch (methodName) {
case "should_pass":
throw new RuntimeException(
"Test failed: self-test failed. The 'should_pass' method did not pass the synchronization test. Check the test code.");
case "should_fail":
break;
default:
throw new RuntimeException(
"Test failed: something is amiss with the test. A TestFailedException was generated on a call to "
+ methodName + " which we didn't expect to test in the first place.");
}
} else {
throw new RuntimeException("Test failed: the method "
+ e.getMethod().toString()
+ " should be synchronized, but isn't.");
}
}
}
}
}
private static void invokeMethod(Class<?> aClass, final Method m,
final Object[] args) throws TestFailedException, Exception {
//System.out.println( "Invoking " + m.toString() + " with parameters " + Arrays.toString(args));
final Constructor<?> objConstructor;
Object obj = null;
objConstructor = aClass.getConstructor(String.class);
obj = objConstructor.newInstance("LeftPalindrome-emordnilaP-thgiR");
// test method m for synchronization
if (!isSynchronized(m, obj, args)) {
throw new TestFailedException(m);
}
}
private static void testMethod(Class<?> aClass, Method m) throws
Exception {
/*
* Construct call with arguments of the correct type. Note that the
* values are somewhat irrelevant. If the call actually succeeds, it
* means we aren't synchronized and the test has failed.
*/
Class<?>[] pTypes = m.getParameterTypes();
List<Integer> charSequenceArgs = new ArrayList<>();
Object[] args = new Object[pTypes.length];
for (int i = 0; i < pTypes.length; i++) {
// determine the type and create the corresponding actual argument
Class<?> pType = pTypes[i];
if (pType.equals(boolean.class)) {
args[i] = BOOLEAN_VAL;
} else if (pType.equals(char.class)) {
args[i] = CHAR_VAL;
} else if (pType.equals(int.class)) {
args[i] = INT_VAL;
} else if (pType.equals(double.class)) {
args[i] = DOUBLE_VAL;
} else if (pType.equals(float.class)) {
args[i] = FLOAT_VAL;
} else if (pType.equals(long.class)) {
args[i] = LONG_VAL;
} else if (pType.equals(Object.class)) {
args[i] = OBJECT_VAL;
} else if (pType.equals(StringBuilder.class)) {
args[i] = STRING_BUILDER_VAL;
} else if (pType.equals(StringBuffer.class)) {
args[i] = STRING_BUFFER_VAL;
} else if (pType.equals(String.class)) {
args[i] = STRING_VAL;
} else if (pType.isArray() && pType.getComponentType().equals(char.class)) {
args[i] = CHAR_ARRAY_VAL;
} else if (pType.equals(CharSequence.class)) {
charSequenceArgs.add(new Integer(i));
} else {
throw new RuntimeException("Test Failed: not accounting for method call with parameter type of " + pType.getName() + " You must update the test.");
}
}
/*
* If there are no CharSequence args, we can simply invoke our method
* and test it
*/
if (charSequenceArgs.isEmpty()) {
invokeMethod(aClass, m, args);
} else {
/*
* Iterate through the different CharSequence types and invoke the
* method for each type.
*/
if (charSequenceArgs.size() > 1) {
throw new RuntimeException("Test Failed: the test cannot handle a method with multiple CharSequence arguments. You must update the test to handle the method "
+ m.toString());
}
for (int j = 0; j < CHAR_SEQUENCE_VAL.length; j++) {
args[charSequenceArgs.get(0)] = CHAR_SEQUENCE_VAL[j];
invokeMethod(aClass, m, args);
}
}
}
@SuppressWarnings("serial")
private static class TestFailedException extends Exception {
final Method m;
public Method getMethod() {
return m;
}
public TestFailedException(Method m) {
this.m = m;
}
}
static class InvokeTask implements Runnable {
private final Method m;
private final Object target;
private final Object[] args;
InvokeTask(Method m, Object target, Object... args) {
this.m = m;
this.target = target;
this.args = args;
}
@Override
public void run() {
try {
m.invoke(target, args);
} catch (IllegalAccessException | IllegalArgumentException |
InvocationTargetException e) {
e.printStackTrace();
}
}
}
/**
* isSynchronized tests whether the given method is synchronized or not by
* invoking it in a thread and testing the thread state after starting the
* thread
* <p/>
* @param m the method to test
* @param target the object the method is executed on
* @param args the arguments passed to the method
* @return true iff the method is synchronized
*/
private static boolean isSynchronized(Method m, Object target,
Object... args) {
Thread t = new Thread(new InvokeTask(m, target, args));
Boolean isSynchronized = null;
synchronized (target) {
t.start();
while (isSynchronized == null) {
switch (t.getState()) {
case NEW:
case RUNNABLE:
case WAITING:
case TIMED_WAITING:
Thread.yield();
break;
case BLOCKED:
isSynchronized = true;
break;
case TERMINATED:
isSynchronized = false;
break;
}
}
}
try {
t.join();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
return isSynchronized;
}
/*
* This class is used to test the synchronization tester above. It has a
* method, should_pass, that is unsynchronized but calls a synchronized
* method. It has another method, should_fail, which isn't synchronized and
* doesn't call a synchronized method. The former should pass and the latter
* should fail.
*/
private static class MyTestClass {
@SuppressWarnings("unused")
public MyTestClass(String s) {
}
@SuppressWarnings("unused")
public void should_pass() {
// call sync method
sync_shouldnt_be_tested();
}
@SuppressWarnings("unused")
public void should_fail() {
}
public synchronized void sync_shouldnt_be_tested() {
}
}
}
/*
* 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.
*
* 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.
*/
/* @test
* @bug 6206780
* @summary Test StringBuilder.append(StringBuffer);
*/
import java.util.Random;
public class AppendStringBuffer {
private static Random generator = new Random();
public static void main(String[] args) throws Exception {
for (int i=0; i<1000; i++) {
StringBuffer sb1 = generateTestBuffer(10, 100);
StringBuffer sb2 = generateTestBuffer(10, 100);
StringBuffer sb3 = generateTestBuffer(10, 100);
String s1 = sb1.toString();
String s2 = sb2.toString();
String s3 = sb3.toString();
String concatResult = new String(s1+s2+s3);
StringBuilder test = new StringBuilder();
test.append(sb1);
test.append(sb2);
test.append(sb3);
if (!test.toString().equals(concatResult))
throw new RuntimeException("StringBuffer.append failure");
}
}
private static int getRandomIndex(int constraint1, int constraint2) {
int range = constraint2 - constraint1;
int x = generator.nextInt(range);
return constraint1 + x;
}
private static StringBuffer generateTestBuffer(int min, int max) {
StringBuffer aNewStringBuffer = new StringBuffer(120);
int aNewLength = getRandomIndex(min, max);
for(int y=0; y<aNewLength; y++) {
int achar = generator.nextInt(30)+30;
char test = (char)(achar);
aNewStringBuffer.append(test);
}
return aNewStringBuffer;
}
}
/*
* 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.
*/
/**
* @test
* @bug 6206780
* @summary Test forwarding of methods to super in StringBuilder
* @author Jim Gish <jim.gish@oracle.com>
*/
import java.util.ArrayList;
import java.util.List;
public class BuilderForwarding {
private final static String A_STRING_BUFFER_VAL = "aStringBuffer";
private final static String A_STRING_BUILDER_VAL = "aStringBuilder";
private final static String A_STRING_VAL = "aString";
private final static String NON_EMPTY_VAL = "NonEmpty";
public BuilderForwarding() {
System.out.println( "Starting BuilderForwarding");
}
public static void main(String... args) {
new BuilderForwarding().executeTestMethods();
}
public void executeTestMethods() {
appendCharSequence();
indexOfString();
indexOfStringIntNull();
indexOfStringNull();
indexOfStringint();
insertintCharSequence();
insertintObject();
insertintboolean();
insertintchar();
insertintdouble();
insertintfloat();
insertintint();
insertintlong();
lastIndexOfString();
lastIndexOfStringint();
}
public void appendCharSequence() {
// three different flavors of CharSequence
CharSequence aString = A_STRING_VAL;
CharSequence aStringBuilder = new StringBuilder(A_STRING_BUILDER_VAL);
CharSequence aStringBuffer = new StringBuffer(A_STRING_BUFFER_VAL);
assertEquals( /*actual*/ new StringBuilder().append(aString).toString(), /*expected*/ A_STRING_VAL );
assertEquals( new StringBuilder().append(aStringBuilder).toString(), A_STRING_BUILDER_VAL );
assertEquals( new StringBuilder().append(aStringBuffer).toString(), A_STRING_BUFFER_VAL );
assertEquals( /*actual*/ new StringBuilder(NON_EMPTY_VAL).append(aString).toString(), NON_EMPTY_VAL+A_STRING_VAL );
assertEquals( new StringBuilder(NON_EMPTY_VAL).append(aStringBuilder).toString(), NON_EMPTY_VAL+A_STRING_BUILDER_VAL );
assertEquals( new StringBuilder(NON_EMPTY_VAL).append(aStringBuffer).toString(), NON_EMPTY_VAL+A_STRING_BUFFER_VAL );
}
public void indexOfString() {
StringBuilder sb = new StringBuilder();
// should be NPE if null passed
try {
sb.indexOf(null);
throw new RuntimeException("Test failed: should have thrown NPE");
} catch (NullPointerException npe) {
// expected: passed
} catch (Throwable t) {
throw new RuntimeException("Test failed: should have thrown NPE. Instead threw "
+ t);
}
sb = new StringBuilder("xyz");
assertEquals( sb.indexOf("y"), 1 );
assertEquals( sb.indexOf("not found"), -1 );
}
public void indexOfStringint() {
StringBuilder sb = new StringBuilder();
// should be NPE if null passed
try {
sb.indexOf(null,1);
throw new RuntimeException("Test failed: should have thrown NPE");
} catch (NullPointerException npe) {
// expected: passed
} catch (Throwable t) {
throw new RuntimeException("Test failed: should have thrown NPE");
}
sb = new StringBuilder("xyyz");
assertEquals( sb.indexOf("y",0), 1 );
assertEquals( sb.indexOf("y",1), 1 );
assertEquals( sb.indexOf("y",2), 2 );
assertEquals( sb.indexOf("not found"), -1 );
}
public void indexOfStringIntNull() {
StringBuffer sb = new StringBuffer();
// should be NPE if null passed
try {
sb.indexOf(null,1);
throw new RuntimeException("Test failed: should have thrown NPE");
} catch (NullPointerException npe) {
// expected: passed
} catch (Throwable t) {
throw new RuntimeException("Test failed: should have thrown NPE. Instead threw "
+ t);
}
}
public void indexOfStringNull() {
StringBuilder sb = new StringBuilder();
// should be NPE if null passed
try {
sb.indexOf(null);
throw new RuntimeException("Test failed: should have thrown NPE");
} catch (NullPointerException npe) {
// expected: passed
} catch (Throwable t) {
throw new RuntimeException("Test failed: should have thrown NPE. Instead threw "
+ t);
}
}
public void insertintboolean() {
boolean b = true;
StringBuilder sb = new StringBuilder("012345");
assertEquals( sb.insert( 2, b).toString(), "01true2345");
}
public void insertintchar() {
char c = 'C';
StringBuilder sb = new StringBuilder("012345");
assertEquals( sb.insert( 2, c ).toString(), "01C2345");
}
public void insertintCharSequence() {
final String initString = "012345";
// three different flavors of CharSequence
CharSequence aString = A_STRING_VAL;
CharSequence aStringBuilder = new StringBuilder(A_STRING_BUILDER_VAL);
CharSequence aStringBuffer = new StringBuffer(A_STRING_BUFFER_VAL);
assertEquals( new StringBuilder(initString).insert(2, aString).toString(), "01"+A_STRING_VAL+"2345" );
assertEquals( new StringBuilder(initString).insert(2, aStringBuilder).toString(), "01"+A_STRING_BUILDER_VAL+"2345" );
assertEquals( new StringBuilder(initString).insert(2, aStringBuffer).toString(), "01"+A_STRING_BUFFER_VAL+"2345" );
try {
new StringBuilder(initString).insert(7, aString);
throw new RuntimeException("Test failed: should have thrown IndexOutOfBoundsException");
} catch (IndexOutOfBoundsException soob) {
// expected: passed
} catch (Throwable t) {
throw new RuntimeException("Test failed: should have thrown IndexOutOfBoundsException, but instead threw " + t.getMessage());
}
}
public void insertintdouble() {
double d = 99d;
StringBuilder sb = new StringBuilder("012345");
assertEquals( sb.insert( 2, d ).toString(), "0199.02345"); }
public void insertintfloat() {
float f = 99.0f;
StringBuilder sb = new StringBuilder("012345");
assertEquals( sb.insert( 2, f ).toString(), "0199.02345"); }
public void insertintint() {
int i = 99;
StringBuilder sb = new StringBuilder("012345");
assertEquals( sb.insert( 2, i ).toString(), "01992345");
}
public void insertintlong() {
long l = 99;
StringBuilder sb = new StringBuilder("012345");
assertEquals( sb.insert( 2, l ).toString(), "01992345"); }
public void insertintObject() {
StringBuilder sb = new StringBuilder("012345");
List<String> ls = new ArrayList<String>();
ls.add("A"); ls.add("B");
String lsString = ls.toString();
assertEquals( sb.insert(2, ls).toString(), "01"+lsString+"2345");
try {
sb.insert(sb.length()+1, ls);
throw new RuntimeException("Test failed: should have thrown StringIndexOutOfBoundsException");
} catch (StringIndexOutOfBoundsException soob) {
// expected: passed
} catch (Throwable t) {
throw new RuntimeException("Test failed: should have thrown StringIndexOutOfBoundsException, but instead threw:"
+ t);
}
}
public void lastIndexOfString() {
String xyz = "xyz";
String xyz3 = "xyzxyzxyz";
StringBuilder sb = new StringBuilder(xyz3);
int pos = sb.lastIndexOf("xyz");
assertEquals( pos, 2*xyz.length() );
}
public void lastIndexOfStringint() {
StringBuilder sb = new StringBuilder("xyzxyzxyz");
int pos = sb.lastIndexOf("xyz",5);
assertEquals( pos, 3 );
pos = sb.lastIndexOf("xyz", 6);
assertEquals( pos, 6 );
}
public void assertEquals( String actual, String expected) {
if (!actual.equals( expected )) {
throw new RuntimeException( "Test failed: actual = '" + actual +
"', expected = '" + expected + "'");
}
}
public void assertEquals( int actual, int expected) {
if (actual != expected) {
throw new RuntimeException( "Test failed: actual = '" + actual +
"', expected = '" + expected + "'");
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册