[
https://issues.apache.org/jira/browse/LANG-307?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12967257#action_12967257
]
Griffin DeJohn edited comment on LANG-307 at 12/10/10 9:01 PM:
---------------------------------------------------------------
Second version of AutoClone source code attached. Please let me know if you
have any comments or questions, and if anybody can contribute good test cases,
I'd appreciate it.
It works with the null type, primitive types, reference types, and arbitrarily
nested arrays. Classes that maintain their state partly or wholly in instance
variables declared in a superclass (e.g. StringBuilder) are handled, as are
instances of static nested classes, inner classes (nested inside concrete or
abstract classes), local classes, and anonymous classes.
The way it works is this. Given a target object that is a reference type, the
first step is to reflectively create a new instance of the dynamic type of that
object. This is accomplished by trying to invoke each declared constructor in
that object's class until a working one is found (starting with the fewest
parameters and working up from there). For each constructor, an argument to
match each parameter is recursively instantiated (with primitives as one base
case, for which the respective default value is passed, arrays as another base
case, for which an empty array of the same component type is passed, and enum
types as the last base case, for which the first declared constant is passed,
or null if none are declared). Once an instance of the target object's class
has been successfully created, all non-static fields in the target object from
its class and superclasses are recursively cloned (with primitives as a base
case once again, as well as Strings and enum types, for which the value is
simply assigned to the corresponding field in the clone), ensuring a deep copy.
An object can't be cloned if its fields are private and can't be made
accessible, or if its fields can't be cloned, or if its class can't be
instantiated. A class can't be instantiated if it's an interface (I'm looking
at using java.lang.reflect.Proxy for this), or if no working constructors are
found. A constructor fails if it's private and can't be made accessible, or if
the declaring class is abstract, or if it throws an exception when passed the
default value for a primitive type parameter or null for a reference type
parameter that can't be instantiated, or if it's otherwise picky and requires
specific arguments.
One special case that fails is an array that contains itself, which isn't
handled yet, and another is an inner class constructor attempting to
dereference it's enclosing instance if that declaring class can't be
instantiated, in which case the enclosing instance would be null and a
NullPointerException would be thrown.
The attached version is written to be generic through the use of unchecked
casts (the generated compiler warnings are suppressed). It seems to work well
enough, since e.g. the following won't compile.
{quote}
{{Integer foo = new Integer(0);}}
{{String bar = AutoClone.toClone(foo); // Error: incompatible types}}
{quote}
However, I'd still like to hear what other people think about the type-safety
of my code.
was (Author: gdejohn):
Second version of AutoClone source code attached. Please let me know if you
have any comments or questions, and if anybody can contribute good test cases,
I'd appreciate it.
The way it works is this. Given a target object that is a reference type, the
first step is to reflectively create a new instance of the dynamic type of that
object. This is accomplished by trying to invoke each declared constructor in
that object's class until a working one is found (starting with the fewest
parameters and working up from there). For each constructor, an argument to
match each parameter is recursively instantiated (with primitives as one base
case, for which the respective default value is passed, arrays as another base
case, for which an empty array of the same component type is passed, and enum
types as the last base case, for which the first declared constant is passed).
Once an instance of the target object's class has been successfully created,
all non-static fields in the target object from its class and superclasses are
recursively cloned (with primitives as a base case once again, as well as
Strings and enum types, for which the value is simply assigned to the
corresponding field in the clone), ensuring a deep copy.
It works with the null type, primitive types, reference types, and arbitrarily
nested arrays of any type. Classes that maintain their state partly or wholly
in instance variables declared in a superclass (e.g. StringBuilder) are
handled, as are instances of static nested classes, inner classes (nested in a
concrete class or an interface), local classes, and anonymous classes.
It doesn't work yet with an array that contains itself, and it fails with
instances of inner classes (i.e. non-static nested classes) that are dependent
on an enclosing abstract class (haven't figured out a way to dynamically
instantiate such a class; any ideas?). It also fails if necessary fields or
constructors are private and can't be made accessible due to a restrictive
security manager, or if a necessary constructor is picky and throws an
exception when passed arguments that don't meet certain requirements, or if a
necessary constructor has a parameter that is an enum type which doesn't
declare any constants, or if a necessary constructor has parameters that can't
be instantiated (e.g. abstract classes or interfaces). I'm looking into using
java.lang.reflect.Proxy for that last bit.
The attached version is written to be generic through the use of unchecked
casts (the generated compiler warnings are suppressed). It seems to work well
enough, since e.g. "int foo = AutoClone.toClone(0.0d)" won't compile, but I'd
still like to hear what other people think about the type-safety of my code.
> CloneUtils - utility class to enable cloning via various different mechanisms
> -----------------------------------------------------------------------------
>
> Key: LANG-307
> URL: https://issues.apache.org/jira/browse/LANG-307
> Project: Commons Lang
> Issue Type: New Feature
> Components: lang.*
> Reporter: Henri Yandell
> Fix For: 3.1
>
> Attachments: AutoClone.java, lang-307.patch
>
>
> Taken from the tasks.html. No idea if we want to do it or not.
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.