diff --git a/jme3-core/src/main/java/com/jme3/util/clone/Cloner.java b/jme3-core/src/main/java/com/jme3/util/clone/Cloner.java index be34755be..ba202e463 100644 --- a/jme3-core/src/main/java/com/jme3/util/clone/Cloner.java +++ b/jme3-core/src/main/java/com/jme3/util/clone/Cloner.java @@ -277,10 +277,12 @@ public class Cloner { } /** - * Sets a custom CloneFunction for the exact Java type. Note: no inheritence - * checks are performed so a function must be registered for each specific type - * that it handles. By default ListCloneFunction is registered for - * ArrayList, LinkedList, CopyOnWriteArrayList, Vector, Stack, and JME's SafeArrayList. + * Sets a custom CloneFunction for implementations of the specified Java type. Some + * inheritance checks are made but no disambiguation is performed. + *

Note: in the general case, it is better to register against specific classes and + * not super-classes or super-interfaces unless you know specifically that they are cloneable.

+ *

By default ListCloneFunction is registered for ArrayList, LinkedList, CopyOnWriteArrayList, + * Vector, Stack, and JME's SafeArrayList.

*/ public void setCloneFunction( Class type, CloneFunction function ) { if( function == null ) { @@ -296,7 +298,21 @@ public class Cloner { */ @SuppressWarnings("unchecked") public CloneFunction getCloneFunction( Class type ) { - return (CloneFunction)functions.get(type); + CloneFunction result = (CloneFunction)functions.get(type); + if( result == null ) { + // Do a more exhaustive search + for( Map.Entry e : functions.entrySet() ) { + if( e.getKey().isAssignableFrom(type) ) { + result = e.getValue(); + break; + } + } + if( result != null ) { + // Cache it for later + functions.put(type, result); + } + } + return result; } /**