41 |
|
import java.security.SecurityPermission; |
42 |
|
import java.util.ArrayList; |
43 |
|
import java.util.Arrays; |
44 |
+ |
import java.util.Collection; |
45 |
|
import java.util.Collections; |
46 |
|
import java.util.Date; |
47 |
|
import java.util.Enumeration; |
1828 |
|
} |
1829 |
|
} |
1830 |
|
|
1831 |
+ |
void assertImmutable(Object o) { |
1832 |
+ |
if (o instanceof Collection) { |
1833 |
+ |
assertThrows( |
1834 |
+ |
UnsupportedOperationException.class, |
1835 |
+ |
new Runnable() { public void run() { |
1836 |
+ |
((Collection) o).add(null);}}); |
1837 |
+ |
} |
1838 |
+ |
} |
1839 |
+ |
|
1840 |
|
@SuppressWarnings("unchecked") |
1841 |
|
<T> T serialClone(T o) { |
1842 |
|
try { |
1843 |
|
ObjectInputStream ois = new ObjectInputStream |
1844 |
|
(new ByteArrayInputStream(serialBytes(o))); |
1845 |
|
T clone = (T) ois.readObject(); |
1846 |
+ |
if (o == clone) assertImmutable(o); |
1847 |
|
assertSame(o.getClass(), clone.getClass()); |
1848 |
|
return clone; |
1849 |
|
} catch (Throwable fail) { |
1852 |
|
} |
1853 |
|
} |
1854 |
|
|
1855 |
+ |
/** |
1856 |
+ |
* If o implements Cloneable and has a public clone method, |
1857 |
+ |
* returns a clone of o, else null. |
1858 |
+ |
*/ |
1859 |
+ |
@SuppressWarnings("unchecked") |
1860 |
+ |
<T> T cloneableClone(T o) { |
1861 |
+ |
if (!(o instanceof Cloneable)) return null; |
1862 |
+ |
final T clone; |
1863 |
+ |
try { |
1864 |
+ |
clone = (T) o.getClass().getMethod("clone").invoke(o); |
1865 |
+ |
} catch (NoSuchMethodException ok) { |
1866 |
+ |
return null; |
1867 |
+ |
} catch (ReflectiveOperationException unexpected) { |
1868 |
+ |
throw new Error(unexpected); |
1869 |
+ |
} |
1870 |
+ |
assertNotSame(o, clone); // not 100% guaranteed by spec |
1871 |
+ |
assertSame(o.getClass(), clone.getClass()); |
1872 |
+ |
return clone; |
1873 |
+ |
} |
1874 |
+ |
|
1875 |
|
public void assertThrows(Class<? extends Throwable> expectedExceptionClass, |
1876 |
|
Runnable... throwingActions) { |
1877 |
|
for (Runnable throwingAction : throwingActions) { |