diff --git a/pom.xml b/pom.xml index e3f158d..218f320 100644 --- a/pom.xml +++ b/pom.xml @@ -137,7 +137,7 @@ org.objenesis objenesis - 3.0.1 + 3.2 diff --git a/src/main/java/com/rits/cloning/Cloner.java b/src/main/java/com/rits/cloning/Cloner.java index 53b6d9f..1696b02 100644 --- a/src/main/java/com/rits/cloning/Cloner.java +++ b/src/main/java/com/rits/cloning/Cloner.java @@ -5,6 +5,7 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Array; import java.lang.reflect.Field; + import java.lang.reflect.Modifier; import java.math.BigDecimal; import java.math.BigInteger; @@ -113,6 +114,10 @@ protected void registerFastCloners() { registerInaccessibleClassToBeFastCloned("java.util.ArrayList$SubList", subListCloner); registerInaccessibleClassToBeFastCloned("java.util.SubList", subListCloner); registerInaccessibleClassToBeFastCloned("java.util.RandomAccessSubList", subListCloner); + FastClonerListOf12 listOf12 = new FastClonerListOf12(); + registerInaccessibleClassToBeFastCloned("java.util.ImmutableCollections$List12",listOf12); + FastClonerSetOf12 setOf12 = new FastClonerSetOf12(); + registerInaccessibleClassToBeFastCloned("java.util.ImmutableCollections$Set12",setOf12); } protected void registerInaccessibleClassToBeFastCloned(String className, IFastCloner fastCloner) { diff --git a/src/main/java/com/rits/cloning/FastClonerListOf12.java b/src/main/java/com/rits/cloning/FastClonerListOf12.java new file mode 100644 index 0000000..2990b04 --- /dev/null +++ b/src/main/java/com/rits/cloning/FastClonerListOf12.java @@ -0,0 +1,22 @@ +package com.rits.cloning; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class FastClonerListOf12 implements IFastCloner { + @SuppressWarnings({"unchecked", "rawtypes"}) + public Object clone(final Object t, final IDeepCloner cloner, final Map clones) { + List al = (List) t; + if (al.size() == 1) { + return List.of(cloner.deepClone(al.get(0), clones)); + } else if (al.size() == 2) { + Object o1 = cloner.deepClone(al.get(0), clones); + Object o2 = cloner.deepClone(al.get(1), clones); + return List.of(o1, o2); + } else { + return new ArrayList<>(); + } + } + +} diff --git a/src/main/java/com/rits/cloning/FastClonerSetOf12.java b/src/main/java/com/rits/cloning/FastClonerSetOf12.java new file mode 100644 index 0000000..d5bd0b9 --- /dev/null +++ b/src/main/java/com/rits/cloning/FastClonerSetOf12.java @@ -0,0 +1,20 @@ +package com.rits.cloning; + +import java.util.*; + +public class FastClonerSetOf12 implements IFastCloner { + @SuppressWarnings({"unchecked", "rawtypes"}) + public Object clone(final Object t, final IDeepCloner cloner, final Map clones) { + Set set = (Set) t; + Object[] a = set.toArray(); + if (set.size() == 1) { + return Set.of(cloner.deepClone(a[0], clones)); + } else if (set.size() == 2) { + Object o1 = cloner.deepClone(a[0], clones); + Object o2 = cloner.deepClone(a[1], clones); + return Set.of(o1, o2); + } else { + return new HashSet<>(); + } + } +} diff --git a/src/test/java/com/rits/tests/cloning/TestCloner.java b/src/test/java/com/rits/tests/cloning/TestCloner.java index cf3f97f..c1c7525 100644 --- a/src/test/java/com/rits/tests/cloning/TestCloner.java +++ b/src/test/java/com/rits/tests/cloning/TestCloner.java @@ -10,8 +10,11 @@ import java.lang.annotation.Retention; import java.lang.annotation.Target; +import java.time.ZonedDateTime; import java.util.*; import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.TimeUnit; +import java.util.function.Function; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; @@ -39,6 +42,24 @@ public class TestCloner extends TestCase { static private class MyAX { } + public void testCloneListOf12() { + List list1 = List.of(1); + Assert.assertEquals(list1, cloner.deepClone(list1)); + Assert.assertEquals(1, cloner.deepClone(list1).size()); + List list2 = List.of(1, 2); + Assert.assertEquals(list2, cloner.deepClone(list2)); + Assert.assertEquals(2, cloner.deepClone(list2).size()); + } + + public void testCloneSetOf12() { + Set set1 = Set.of(1); + Assert.assertEquals(set1, cloner.deepClone(set1)); + Assert.assertEquals(1, cloner.deepClone(set1).size()); + Set set2 = Set.of(1, 2); + Assert.assertEquals(set2, cloner.deepClone(set2)); + Assert.assertEquals(2, cloner.deepClone(set2).size()); + } + public void testCalendarTimezone() { TimeZone timeZone = TimeZone.getTimeZone("America/Los_Angeles"); Calendar c = Calendar.getInstance(timeZone); @@ -875,7 +896,7 @@ public void testLinkedHashSetEquals() { /** * Test if insertion order of LinkedhashSet is the same */ - public void testLinkedHashSetInserationOrder() { + public void testLinkedHashSetIterationOrder() { LinkedHashSet originalSet = new LinkedHashSet<>(); for (int i = 1000; i >= 1; i--) { originalSet.add(i); @@ -915,5 +936,22 @@ class StaticTransient extends ArrayList { cloner.deepClone(new StaticTransient()); } + + public void ignoreTestLambda() { + // this fails with "Caused by: java.lang.ClassNotFoundException: com.rits.tests.cloning.TestCloner$$Lambda$54.0x0000000800c24210" + Function f = ZonedDateTime::getNano; + cloner.deepClone(f); + } + + private static class ClassWithEnum { + TimeUnit timeUnit; + } + + public void testClassWithEnum() { + ClassWithEnum a = new ClassWithEnum(); + a.timeUnit = TimeUnit.SECONDS; + ClassWithEnum b = cloner.deepClone(a); + assertSame(TimeUnit.SECONDS, b.timeUnit); + } }