First, the situation. I am doing school project. I have to implement my own clone function. It takes object as argument, creates exact copy and returns it. Function declaration:
Object clone(Object obj);
Problem is that obj.getClass() doesn't have to have appropriate constructor. For example private constructor that takes 3 arguments. So I don't know how should I create objects. Constructor.newInstance(arguments) won't work. And I don't know any other way. So I was wondering if there isn't such method as GetUninitializedObject, which is in C#. Suggestions for different solutions are welcomed.
Thanks in advance
Have a nice day
You can get constructors of a class and also their parameter types. you can read from here:
http://tutorials.jenkov.com/java-reflection/constructors.html
if a class hasn't any public constructors, there's nothing to do with that.
In Java your best options are either to require a public no-args constructor and require setters (often referred to as a Bean), or use Java's built in Serialization via ObjectInputStream and ObjectOutputStream. You can also use Object.clone() to do this, although it's discouraged by many Java experts (for example, Josh Bloch warns against it in "Effective Java")
Related
I'm new to java and was studying object cloning. My question is that since Object class is the top most class in java and all other classes inherits this class and clone() method is defined in the Object class, then what is purpose of using cloneable interface? Why can't we just override the clone() method of Object class in our class and return super.clone() from it(or modify it for deep copy according to our needs)?
Also which is the recommended way (java standard way) of creating clones of the object? Using clone() method or creating copy constructor just like C++ which is mentioned in Andreas dolk's answer to this question?
The clone situation is unique and is rather anti-java-like - there's a reason its not recommended to use it in the first place. The way Cloneable is used in the JDK is not something you should be taking notes on - this isn't how to design APIs, nothing else in the java ecosystem works this way.
Weirdly, this is a common thing: The core parts of java often aren't java-like. For example, nobody in their right mind would make an API that defines an application by 'it has a method with the signature public static void main(String[] args). The obvious design principle would be to make an abstract class or interface with an abstract start() method, and to make a java app you write a class that has a no-args constructor and implements/extends that interface/class. Same story for arrays: They are weird - their toString, equals, and hashCode implementations are surprising, to say the least. They aren't entirely type-safe either.
The reasons for all of this are historic: To explain them, you need to know about all sorts of things that were relevant at the time, but aren't important anymore and haven't been for decades.
Cloneable is no different. Let me explain why it works that way:
The 'system' of cloning is offered by the JDK itself, it's a built-in thing that an ordinary library could not easily make. Kinda how "java SomeClass invokes its main method" is part of java itself.
The system, however, needs an opt-in mechanism: The act of cloning may not make sense (what does it mean to 'clone' an InputStream representing a TCP network connection's incoming bytes? What does it mean to 'clone' the value of an enum which tries to guarantee that only one instance ever exists? What does it mean to 'clone' a singleton?)
Thus, 'just make all objects cloneable' is dangerous, so java didn't want to do that: They want you to opt in to it. Java wants the author of a class to explicitly say: Yup. I am clonable, using the standard mechanism (which deep-copies all fields, if memory serves).
That is what Cloneable is for! - that's how you say: Yup. I'm good with it. By implementing that. It's a flag.
Java could also have decided to do something like:
/** #cloneable */
public class Something {}
instead, but they didn't. If it had been designed in this more modern age, perhaps it would have looked like:
#Cloneable
public class Something {}
But annotations were introduced in java 1.5 as a demo feature in 1.6 properly. The cloneable interface is as old as java 1.0 - over a decade earlier. "add an interface that defines nothing" was the standard way to flag class properties back then, even if it isn't now.
NB: You don't just implements Cloneable, you also make a public clone method. The implements Cloneable part tells the cloning system: You may clone this class, for example even if it is part of the deep structure of an encompassing object that is being cloned. Making a clone method that invokes the protected JVM-provided clone() method that j.l.Object has is how you expose the API. Maybe you want to name it copy instead, or maybe you want cloning but not as part of your public API. Your question isn't about how to use clone, but why it works like it is - my advice if you want to use it is simple. Don't, write clone code yourself, or better yet, design your API with more immutables so that cloning is no longer neccessary.
clone() method has no implementation in Object and does nothing. To make it work, your class has to implement Cloneable. This is a marker interface and adds some methods to any class inheriting it so that you can clone an object of that class.
I made my class immutable by following all java standards
A. Defined class as final
B. declared all fields as private and final
C. No setter method
D. No method changes the state of object
E. declared all method as final
F. Safer/defencieve copying of collection/ non mutable object fields.
These are the priliminary checkpoints I made when desigining immutable class.
But one question left, my object can still be modified by java reflection, am I right?
Or is there any point I missed in the class?
Thanks in advance.
There's no hiding from reflection - even immutable classes are not immune. There is nothing you can do about it, though, so "cannot be modified through reflection" is not one of the criteria of immutability.
Yes. Reflection can still access / change it. You can't really plan against that. If someone's altering your object with reflection, I would doubt the quality of code they're writing.
Immutable classes are fantastic to ensure thread safe applications. Immutable objects are ALWAYS thread safe. If you're looking for more great information, please read Effective Java. It's a MUST READ for any Java developer.
Yes, still it can be modified through reflection. Apart from that it seems you took required care to make it immutable.
I'm a rubyist and have started learning java. Came across some dialog that says not to use clone() method in java or if I do, make sure to know what I'm doing with it.
Java clone method seems to be a popular topic on stackoverflow but most questions have been about advanced topics related to why cloning is not working or shallow or deep copy etc. Don't know what to make of that. What about a few simple examples of how to use clone the right way and the wrong way?
It looks like clone is in the interface of an object but has absolutely no implementation. If there is no implementation why do I have to throw the cloneNotsupported exception? Could someone provide a comprehensive list of examples of how clone can be used the right way as well as the wrong way?
thank you in advance.
I think clone() could maybe used with your own, well defined, final data structure (or record) that is not exactly a class (has all public fields and no methods). Also, these fields should be either primitive data types, or immutable types (like Strings) so could be shared without problems.
Cloning such a structure by assigning all fields manually simply means more code, makes the maintenance more difficult (more changes after you add or remove a field) and I really do not understand what exactly benefits this brings.
C / C++ has an assignment statement for the structures to copy all fields in one go and in some cases does this transparently ("structure passed by value"). Java could use clone for the similar goal. After all, simply assigning a double value to a variable is a kind of cloning: all fields of the IEEE data structure (sign bit, exponent, fraction) are copied. Never used to be any fundamental problems with this. How this is different from cloning a final Point class with two public integer fields, x and y?
Most of arguments against clone() are valid for cases when the exact class of the instance in use is not known or it may be unknown invisible fields that may not get initialized correctly.
This question already has answers here:
clone() vs copy constructor vs factory method?
(10 answers)
Closed 8 years ago.
clone method vs copy constructor in java. which one is correct solution. where to use each case?
Clone is broken, so dont use it.
THE CLONE METHOD of the Object class
is a somewhat magical method that does
what no pure Java method could ever
do: It produces an identical copy of
its object. It has been present in the
primordial Object superclass since the
Beta-release days of the Java
compiler*; and it, like all ancient
magic, requires the appropriate
incantation to prevent the spell from
unexpectedly backfiring
Prefer a method that copies the object
Foo copyFoo (Foo foo){
Foo f = new Foo();
//for all properties in FOo
f.set(foo.get());
return f;
}
Read more
http://adtmag.com/articles/2000/01/18/effective-javaeffective-cloning.aspx
Have in mind that clone() doesn't work out of the box. You will have to implement Cloneable and override the clone() method making in public.
There are a few alternatives, which are preferable (since the clone() method has lots of design issues, as stated in other answers), and the copy-constructor would require manual work:
BeanUtils.cloneBean(original) creates a shallow clone, like the one created by Object.clone(). (this class is from commons-beanutils)
SerializationUtils.clone(original) creates a deep clone. (i.e. the whole properties graph is cloned, not only the first level) (from commons-lang), but all classes must implement Serializable
Java Deep Cloning Library offers deep cloning without the need to implement Serializable
clone() was designed with several mistakes (see this question), so it's best to avoid it.
From Effective Java 2nd Edition, Item 11: Override clone judiciously
Given all of the problems associated with Cloneable, it’s safe to say
that other interfaces should not extend it, and that classes
designed for inheritance (Item 17) should not implement it. Because of
its many shortcomings, some expert programmers simply choose never to
override the clone method and never to invoke it except, perhaps, to
copy arrays. If you design a class for inheritance, be aware that if
you choose not to provide a well-behaved protected clone method, it
will be impossible for subclasses to implement Cloneable.
This book also describes the many advantages copy constructors have over Cloneable/clone.
They don't rely on a risk-prone extralinguistic object creation mechanism
They don't demand unenforceable adherence to thinly documented conventions
They don't conflict with the proper use of final fields
They don't throw unnecessary checked exceptions
They don't require casts.
All standard collections have copy constructors. Use them.
List<Double> original = // some list
List<Double> copy = new ArrayList<Double>(original);
Keep in mind that the copy constructor limits the class type to that of the copy constructor. Consider the example:
// Need to clone person, which is type Person
Person clone = new Person(person);
This doesn't work if person could be a subclass of Person (or if Person is an interface). This is the whole point of clone, is that it can can clone the proper type dynamically at runtime (assuming clone is properly implemented).
Person clone = (Person)person.clone();
or
Person clone = (Person)SomeCloneUtil.clone(person); // See Bozho's answer
Now person can be any type of Person assuming that clone is properly implemented.
See also: How to properly override clone method?. Cloning is broken in Java, it's so hard to get it right, and even when it does it doesn't really offer much, so it's not really worth the hassle.
Great sadness: neither Cloneable/clone nor a constructor are great solutions: I DON'T WANT TO KNOW THE IMPLEMENTING CLASS!!! (e.g. - I have a Map, which I want copied, using the same hidden MumbleMap implementation) I just want to make a copy, if doing so is supported. But, alas, Cloneable doesn't have the clone method on it, so there is nothing to which you can safely type-cast on which to invoke clone().
Whatever the best "copy object" library out there is, Oracle should make it a standard component of the next Java release (unless it already is, hidden somewhere).
Of course, if more of the library (e.g. - Collections) were immutable, this "copy" task would just go away. But then we would start designing Java programs with things like "class invariants" rather than the verdammt "bean" pattern (make a broken object and mutate until good [enough]).
What is the advantage of having constructor simillar to the one mentioned below:-
class A{
public A(A a){}
public A(){}
}
If you mean the one with the parameter, there's no reason for having that at all, given that it completely ignores the parameter, and there's already another constructor with the same effect.
If you can give a more realistic example, we may be able to give more useful information...
A(A a){/*do something*/} Can be helpful as copy constructor.
As others have said, you have a copy constructor. There are a number of reasons why you may want a copy constructor. Some of those are:
You can provide an alternative to the clone method. (Which is implemented via the Clonable interface.)
Copy constructors are easily implemented.
You can use another constructor to build the copy (by extracting data from the original object and forwarding to a regular constructor).
Check out the link I added to this post for more information about copy constructors and why you would want to use them (if you need them).
There is no advantage unless you need to have a copy constructor. I would suggest using the clone() method if this object should be clonable rather than using a copy constructor semantic.
You're question is very unclear, but basically if you hava a class, that has a constructor, that takes an instance of the same class, then you have a copy constructor. i.e. a constructor that creates a new instance with the same internal values as the original.
Edit -- assuming of course that your constructor does something other than just create a new instance.
It could also be useful in a number of delegation-based design patterns such as decorator or proxy etc.
Providing a default constructor might still be considered good practice, especially in scenarios where dependency injection or serialization are considered.