I want to ask you how can i copy firstClass objects to secondClass objects?
Is this possible to figure it out by using clone()?
The situation looks like this:
I have a class f.x. firstClass. And I need to clone firstClass objects to secondClass objects (and these cloned objects must be stored into array)
Thanks
EDITED:
sorry for a little information. But my task looks like this:
Write a Garage class whose objects can hold up to some number of Vehicle objects in an
array. Make Garage a Cloneable type, and write a proper clone method for it. Write a Garage.main
method to test it.
It's not cloning. If you have two unrelated classes, the best you can do is write a constructor for SecondClass that takes FirstClass object as an argument and writes all the values into the proper fields:
public SecondClass (FirstClass source){
this.valueA = source.getValueA();
this.valueB = source.getBValue();
this.valueC = source.getProperCValue();
...
}
By convention, Object.clone() method and its overrides should always return an object of the original type.
x.clone().getClass() == x.getClass()
So it should be impossible to create an object of different type if clone() is properly implemented and used.
something like this?!
class Foo{
private String bar;
public Object clone(){
Foo f=new Foo();
f.setBar(this.bar);
//filling and copy the f attributes
guys.add(f);
}
///
private final static List<Foo> guys=new ArrayList<>();
///
}
Related
I have been working to upgrade my Java code baseline so that it follows good security practices and have run into an issue related to generics. Say you have the following:
public class SomeClass<T>
{
private T value;
public T getValue()
{
return value;
}
public void setValue(T value)
{
this.value = value;
}
}
I have not found a good answer on how to edit these methods so that value does not leak like it does in this example class for a generic object that does not implement Clonable and in some cases has no default constructor.
As I understand it, you want to make sure that nothing outside SomeClass can mutate the object value.
In C++, you could returns a const reference (avoid copying altogether), but Java does not have that. So let's look at copying...
First, know that some objects cannot be copied. For example, stream, gui elements, etc. Thus, trying to copy all objects is a hopeless endeavor from the start.
But what about objects that are copiable?
In Java, you cannot call the copy constructor (or any other constructor) of a generic (Calling constructor of a generic type).
There is the Cloneable interface, but that is really nothing more than a promise that clone works; it does not actually expose clone publically. Thus, for generics, you have to use reflection, as shown here.
Unfortunately, there is no good solution. The only viable one (except for changing the purpose or semantics of your class) is to use the clone method as shown in the link above, and realize that some objects cannot be copied.
Ultimately, the best thing to do is find a solution that does not require this. Make a (non-generic) read-only wrapper class that exposes the non-mutating methods. Or stipulate in documentation that mutating methods must not be called.
I can see three approaches:
Make copies. This of course would only work with types can can be copied (and that you know how to copy).
Only support immutable types.
Remove getValue(). Instead, provide methods that operate directly on this.value without exposing it outside the class. In this approach, setValue() can still be problematic (you need to make sure that the caller does not hold on to the object reference after calling setValue()).
If T can be arbitrary type that you have no control over, then options 1 and 2 won't be suitable.
I believe that i undestand you ... If you want to restrict a generic type you should use extends keyword that in generic type is not equals to general class. If you use only the class how implements Clonable are able to instantiate this class. One example:
public class Stack {
public static void main(String[] args) {
SomeClass<Animal> sc = new SomeClass<>(); //This generate an error because doesnt implements Clonable interface
SomeClass<Person> sc1 = new SomeClass<>();
}
}
class SomeClass<T extends Comparable> //Note that extends means implements or the common extends
{
private T value;
public T getValue()
{
return value;
}
public void setValue(T value)
{
this.value = value;
}
}
class Person implements Comparable<Person>{
#Override
public int compareTo(Person p){
return 0;
}
}
class Animal {
}
I wish i helped you.
:)
An object whose state is encapsulated in a mutable object should generally never expose to the outside world any reference to that object, and should avoid giving the outside world a reference to any mutable object (even a copy) which claims to encapsulate its state. The problem is that given code:
Foo foo = myEntity1.getFoo();
foo.bar = 23;
myEntity2.setFoo(foo);
foo.bar = 47;
myEntity3.setFoo(foo);
there is no clear indication whether or how the change to foo.bar would affect the various entities. If the code had instead been:
Foo foo = myEntity1.getFoo();
foo = foo.withBar(23); // makes a new instance which is like foo, but where bar==23
myEntity2.setFoo(foo);
foo = foo.withBar(47); // makes a new instance which is like foo, but where bar==47
myEntity3.setFoo(foo);
it would be very clear that the bar property of myEntity1's foo will be unaffected, that of myEntity2 will be 23, and that of myEntity3 will be 47. If foo is a mutable class, the pattern should be:
Foo foo = new Foo();
myEntity1.writeTo(foo); // Copy properties from myEntity1 to the supplied instance
foo.bar = 23;
myEntity2.readFrom(foo); // Copy properties from the supplied instance to myEntity2
foo.bar = 47;
myEntity2.readFrom(foo); // Copy properties from the supplied instance to myEntity3
Here, myEntity1 isn't giving the caller an object, but is instead copying data to an object supplied by the caller. Consequently, it's much clearer that the caller shouldn't expect the writes to foo.bar to affect the entities directly, but merely change what will be written in subsequent readFrom calls.
This question already has answers here:
How do I copy an object in Java?
(23 answers)
Closed 9 years ago.
I am having difficulties understanding the concept of "deep copy" in Java.
Assuming I had a class "myClass" with various parameters in it. I tried writing a method "copy" which was supposed to return a deep copy of such class as:
public myClass copy() {
myClass deepCopy = new myClass();
deepCopy.varA = varA;
deepCopy.varB = varB;
return deepCopy;
}
Can somebody confirm whether this is indeed "deep copying" or if I am doing something wrong?
Thanks!
If you don’t want to implement deep copy yourselves then you can go for serialization. It does implements deep copy implicitly and gracefully handling cyclic dependencies.
A nice article about Deep Copy, Clone and Shallow Copy can be found here.
Only If:
Class "myClass" only contains varA and varB.
Class "myClass" has no superclass.
Variables varA and varB are of an elementary type (ie. String, int, long, ....). Otherwise you'll have to apply the same copying process to them too.
In deep copy When the copied object contains some other object its references are copied recursively
see more at here
A deep copy occurs when an object is copied along with the objects to which it refers.
If suppose there is a MainObject1 of MainObject type having fields "field1" of int type, and "ContainObject1" of ContainObject type. When you do a deep copy of MainObject1, MainObject2 is created with "field3" containing the copied value of "field1" and "ContainObject2" containing the copied value of ContainObject1. So any changes made to ContainObject1 in MainObject1 will not be reflected in MainObject2.
In your implementation, if you are trying to simulate deep copy, then you should have only these two variables : varA and varB in your class of primitive type.
This would only be a deep copy if varA and VarB were primitive types. If they are reference types than your new object will point at the same instances of these classes as the original.
An easy way to implement deep copy is via serialization. Apache commons lang provides a utility method for this (SerializationUtils.clone( foo ) ).
It does however requires that all the objects are serializable.
If this is not the case for you XStream can be used for deep cloning with minimal development effort.
http://x-stream.github.io/
Observe output of following program.
1> See output without clone() method. Remove clone() method from following program. (example of shallow copy)
2> See output with clone() method. (Example Deep copy. See ArrayList object's output)
import java.util.ArrayList;
import java.util.List;
public class DeepCopy implements Cloneable {
private List<String> hobbiesList;
private int age;
private String name;
private float salary;
public static void main(String[] args) throws CloneNotSupportedException {
DeepCopy original = new DeepCopy();
original.name="AAA";
original.age=20;
original.salary=10000;
original.hobbiesList = new ArrayList<String>();
original.hobbiesList.add("Cricket");
original.hobbiesList.add("Movies");
original.hobbiesList.add("Guitar");
original.hobbiesList.add("Eating");
DeepCopy cloned = (DeepCopy) original.clone();
System.out.println("original:="+original);
System.out.println("cloned :="+cloned);
System.out.println("After adding two more hobbies in 'original' which untimately reflected in 'cloned'");
cloned.name="BBB";
cloned.age=27;
cloned.salary=18237;
cloned.hobbiesList.add("Trecking");
System.out.println("original :="+original);
System.out.println("cloned changed:="+cloned);
}
#Override
protected Object clone() throws CloneNotSupportedException {
DeepCopy clone = (DeepCopy)super.clone();
clone.hobbiesList = new ArrayList<String>(clone.hobbiesList);
return clone;
}
#Override
public String toString() {
return "My name is (String)"+name + " having age (int)"+age+". I earned (float)"+salary+" and hobbies are (ArrayList)"+hobbiesList;
}
}
I'm asking if I create a Custom Class object with say 100 integer values in it.
If I were to pass that variable into a method that contains and object of the same type I am only passing a refernce to the source object, I'm not making a duplicate of those 100's of variables, right?
class BigClass {
int A;
int B;
...
}
BigClass ThisClass = new BigClass();
private void DoSomething(BigClass b) {
BigClass ThatClass = b;
}
**************
DoSomething(ThisClass);
Correct, just the reference to the instance of your class will get passed/copied. The actual guts of your class will not be copied.
See Jon Skeet's article about parameter passing in Java, it does a good job of explaining things.
That is correct. When you pass objects to another class, you are simply passing a reference to it.
Hi I have a enum array and it is a field of my class. And I am implementing clone method of this class. But I have some ideas about copying array of enums but what is the formal way of copying an enum array ?
public enum StateEnum {
START, PLAY, PAUSE , STOP
}
class MyClass{
StateEnum[] stateEnums;
public Object clone(){
MyClass copyClass = new MyClass();
// copy enums
}
}
Enum values are (or should be) immutable, so you don't need to copy them.
You can just make a shallow copy of the array by calling System.arraycopy().
As said by SLaks, use the System.arraycopy to clone your array. Further, the
MyClass copyClass = new MyClass();
should be replaced by
MyClass copyClass = (MyClass)super.clone();
The reason for this is explained in this article in full detail, where the end of page 2 discusses the common pitfalls while implementing a clone method
I have a method called xyz which returns an object.
private XYZ xyz() {
return abc;
}
I want to use this method in 2 different places but I want to call the method only once.
I mean for the first time I am calling the method to get the object.
XYZ aaa = xyz();
Here I have an object 'aaa'. And I want to use the same object in different place, but I can't use this object as this is private. So what I want to do is to create a new object called 'bbb' from 'aaa' without calling the method.
Just like bbb = aaa;
Please help me how to create a new object from existing object or create a duplicate object with different name.
Thanks in advance
You could use the clone method by implementing the cloneable inteface:
http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Cloneable.html
I think he wants to clone XYZ object because it is private in his code (and so is the getter method) and not useable outside. One other idea is to make the getter public or write a public getInstance() method (for example) returning the Singleton.
http://en.wikipedia.org/wiki/Singleton_pattern
So you want only one instance - you can call the xyz() method twice, it won't create a new object.
And if you want two instances - you need cloning. Check this answer.
maybe you could try this out: (for deep cloing)
http://code.google.com/p/cloning/
What you are talking about can be done using a copy constructor:
example:
private field1;
private field2;
public XYZ(XYZ in)
{
this.field1 = in.field1;
this.field2 = in.field2;
}
So this constructor takes as a parameter an object of type XYZ called in and copies all of in's fields to this XYZ object.
I think it would be better if you just had a method called getXYZ() that returns a reference to an XYZ object.
public XYZ getXYZ()
{
return this;
}