What's the best way to copy one Java object of a class to another object of the same class? I tried BeanUtil.copyProperties but it didn't work for some reason. The class is a complex class. (class contains another class objects etc)
My aim is to populate values in order through hibernate function
Public Response getOrder(Order order, Ticket ticket) {
order = OrderManager.getOrderByTicket(ticket); //Hibernate function This doesn't work, order object gets a new reference
}
Tried doing this
Public Response getOrder(Order order, Ticket ticket) {
Order temp = OrderManager.getOrderbByTicket(ticket);
//Now I want to copy temp to order
}
To do a deep copy using Serialize / DeSerialize, you can use the code like below,
public Object deepCopy(Object input) {
Object output = null;
try {
// Writes the object
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
objectOutputStream.writeObject(input);
// Reads the object
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
output = objectInputStream.readObject();
} catch (Exception e) {
e.printStackTrace();
}
return output;
}
If all the fields are serializable then you can use ObjectOutputStream and ObjectInputStream.
If You need special handling during the serialization and deserialization process then implement special methods writeObject() and readObject().
Please have a look at IO: Custom Reading and Writing with Serializable .
Sample code:
class MyClass implements Serializable {
private static final long serialVersionUID = 1L;
String str;
List<Integer> list = new ArrayList<Integer>();
public MyClass(String str) {
this.str = str;
}
}
MyClass obj1 = new MyClass("abc");
obj1.list.add(1);
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(buffer);
oos.writeObject(obj1);
oos.close();
byte[] rawData = buffer.toByteArray();
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(rawData));
MyClass obj2 = (MyClass) ois.readObject();
System.out.println(obj2.str);
System.out.println(obj2.list.get(0));
I suppose you could use reflection if it was REALLY important or time consuming, but as I see it, there are two main choices
One
If you have access to the class, just implement Clonable and have the clone method produce a deep copy of the object and all its subobjects.
Two
Code it by hand. It may be time consuming and boring, but it works in all cases.
I believe you are talking about a 'deep' copy.
A similar question and various solutions are detailed here:
How do you make a deep copy of an object in Java?
The easiest way seems to be serialising the object and then deserialising it.
Better do it like this:
Public Response getOrder(Request request) {
Order temp = OrderManager.getOrderbByTicket(request.getTicket());
request.setOrder(temp);
//process the response
}
This will solve the problem of getting back the Order to the caller of the function. If you want that the caller gets a deep copy than serialize and deserialize it before seting it to the request
Related
There are methods to serialize or deserialize java objects...
Prepare bytes to send:
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutput out = null;
try {
out = new ObjectOutputStream(bos);
out.writeObject(yourObject);
out.flush();
byte[] yourBytes = bos.toByteArray();
bos.close();
}
catch(Exception ex)
{
}
Create object from bytes:
ByteArrayInputStream bis = new ByteArrayInputStream(yourBytes);
ObjectInput in = null;
try
{
in = new ObjectInputStream(bis);
Object o = in.readObject();
if (in != null)
{
in.close();
}
}
catch (Exception ex)
{
}
}
However, if someone wants to send different types of objects over the net is there a way to know which type of object has been sent. I guess there is the option to create a class and then serialize and deserialize it.
class SerialObject
{
String type;
Object object;
}
I think the only way to know the type of object being sent is when you use the InstanceOf keyword in java . The java instanceof operator is used to test whether the object is an instance of the specified type (class or subclass or interface). The instanceof in java is also known as type comparison operator because it compares the instance with type. It returns either true or false.
class Demo{
public static void main(String args[]){
Demo s=new Demo();
System.out.println(s instanceof Demo);//true
}
}
this code return true. just use the InstanceOf keyword .it will really help
When you are Serializing you can store the types somewhere - map or cache or somewhere, but still not sure why you want that?
One option is to check with instanceof operator during deserialized . I am not sure if (why?)should there be more?
Object deserialized = in.readObject();
if (deserialized instanceof TypeAbdClass) {
// do something with ..
} else if (deserialized instanceof SomethingElse) {
...
} else if (...) {
...
}
You can use
Object.getClass()
This will return runtime class of an object
Refer java doc
https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html
My teacher said that in file server program ObjectInputStreamReader is compulsory to write. When I asked the reason then he said me it is comfortable for file server program. I am thinking that it is not necessary reason. Why InputStreamReader or other alternatives can not be used? what is the advantage of ObjectInputStreamReader over InputStreamReader.
Here code for client/server:
public class Client {
public static void main(String[] args) {
Socket s = null;
ObjectInputStream ois = null;
ObjectOutputStream oos = null;
Scanner sc = new Scanner(System.in);
String data = "";
try {
s = new Socket("localhost", 1234);
System.out.println("client is connectd");
ois = new ObjectInputStream(s.getInputStream());
String jai = (String) ois.readObject();
System.out.println("DATA from SERVER:" + jai);
oos = new ObjectOutputStream(s.getOutputStream());
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("Enter file name:");
try {
String fil = (String) sc.next();
OutputStream pw = new FileOutputStream(fil + ".new");
oos.writeObject(fil);
data = (String) ois.readObject();
pw.write(data.getBytes());
} catch (Exception e) {
System.out.println(e.getMessage());
}
System.out.println("Content of file:" + data);
}
}
Can any one say what is actual reason ?
I think you mean ObjectInputStream and BufferedInputStream (not readers).
ObjectInputStream wraps input stream and provides typed methods that allow reading data of certain type from the stream. For example readDouble(), readObject() etc.
BufferedInputStream does not provide additional API (comparing to regular InputStream). The only thing it does is buffering of data, i.e. it reads data chunk-by-chunk that is much more efficient way than reading byte-by-byte.
An InputStream is an abstract class that can be used to define any type of input stream, including reading from file systems, URLs, sockets, etc.
You don't actually create an InputStream, as it doesn't mean anything by itself. Rather, you create a type of InputStream that defines how to read/write a particular type of data, such as the suggested ObjectInputStream. This class defines that the data being written is a Java Object (that implements Serializable or Externalizable). There are other InputStreams that are used for generic file data, images, audio, and a whole range of other types.
There is no such thing as an ObjectInputStreamReader, unless you write a class like this yourself that has the purpose of writing to an ObjectInputStream.
Refer to the ObjectInputStream and InputStream Java docs for more enlightenment
Is there a reliable way to convert any object to a String and then back again to the same Object? I've seen some examples of people converting them using toString() and then passing that value into a constructor to reconstruct the object again but not all objects have a constructor like this so that method wont work for all cases. What way will?
Yes, it is called serialization!
String serializedObject = "";
// serialize the object
try {
ByteArrayOutputStream bo = new ByteArrayOutputStream();
ObjectOutputStream so = new ObjectOutputStream(bo);
so.writeObject(myObject);
so.flush();
serializedObject = bo.toString();
} catch (Exception e) {
System.out.println(e);
}
// deserialize the object
try {
byte b[] = serializedObject.getBytes();
ByteArrayInputStream bi = new ByteArrayInputStream(b);
ObjectInputStream si = new ObjectInputStream(bi);
MyObject obj = (MyObject) si.readObject();
} catch (Exception e) {
System.out.println(e);
}
This is the code:
try {
ByteArrayOutputStream bo = new ByteArrayOutputStream();
ObjectOutputStream so = new ObjectOutputStream(bo);
so.writeObject(stringList);
so.flush();
redisString = new String(Base64.encode(bo.toByteArray()));
}
catch (Exception e) {
e.printStackTrace();
}
try {
byte b[] = Base64.decode(redisString.getBytes());
ByteArrayInputStream bi = new ByteArrayInputStream(b);
ObjectInputStream si = new ObjectInputStream(bi);
List<String> stringList2 = (List<String>)si.readObject();
System.out.println(stringList2.get(1));
}
catch (Exception e) {
e.printStackTrace();
}
Serialize to byte array, convert to Base64. Then decode Base64 back to byte array and deserialize.
None will work in all cases. An object may, e.g., contain references to other JVMs handling their state, and this state may be not available for you to restore.
Additional problems you're going to meet will include open streams, listening sockets, and almost anything else from the outer world.
There's no need to repeat that most at least two of Java core engineers say that serialization was one of the greatest mistakes a single worst feature in Java, that is, after finalization. (I do love serialization nevertheless, it's handy. But it won't always work.)
One way is to use JSON. For implementation specific in Java, the answer might be given in this post:
java code corresponding to Newtonsoft.Json.JsonConvert.SerializeObject(Object source,Newtonsoft.Json.JsonSerializerSettings()) in .net?
Using JSON is reliable enough that it's used for web application development (Ajax).
Yes, it is Serialization You can use, ObjectInputStream.readObject and ObjectOutputStream.writeObject. Please see below example:
MyClass myClass = new MyClass();
FileOutputStream fileStream = new FileOutputStream("myObjectFile.txt");
ObjectOutputStream os = new ObjectOutputStream(fileStream);
os.writeObject(os);
os.close();
FileInputStream fileInStream = new FileInputStream("myObjectFile.txt");
ObjectInputStream ois = new ObjectInputStream(fileInStream);
MyClass myClass2 = ois.readObject();
ois.close();
You can use SerializationUtils from org.apache.commons.
It provides the methods serialize and deserialize
So I am using a proprietary java library in a project which I don't have access to source code.
It throws a Message object, and obviously I can't implement Serializable. It's generated throughout runtime.
what are my options? Is there a way to serialize the Message object into a byte array and back into the object?
UPDATE: I was able to serialize the object to JSON (http://code.google.com/p/json-io/) but couldn't convert it back to an object as it returns null. So I am trying to convert it to byte array using the code below. Still not working.
public byte[] toByteArray (Object obj)
{
byte[] bytes = null;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(obj);
oos.flush();
oos.close();
bos.close();
bytes = bos.toByteArray ();
}
catch (IOException ex) {
//TODO: Handle the exception
}
return bytes;
}
public Object toObject (byte[] bytes)
{
Object obj = null;
try {
ByteArrayInputStream bis = new ByteArrayInputStream (bytes);
ObjectInputStream ois = new ObjectInputStream (bis);
obj = ois.readObject();
}
catch (IOException ex) {
//TODO: Handle the exception
}
catch (ClassNotFoundException ex) {
//TODO: Handle the exception
}
return obj;
}
You could write a wrapper that is serializable and stores everything you need to recreate the Message object.
XStream is one way to go.
Sure, you just can't use the java.lang.Serializable mechanism.
Choose any format: XML, JSON, protocol buffer, or something else that might work for you.
Now you're responsible for both ends of the conversation: serialization and deserialization.
If the object is a Java bean, you can use java.beans.XMLEncoder and java.beans.XMLDecoder for serialization.
I'm a newbie in Java so I'm not sure if this is possible. Basically I need to de-serialise a file into an object of a given type. Basically the method will do this:
FileInputStream fis = new FileInputStream(filename);
ObjectInputStream in = new ObjectInputStream(fis);
MyClass newObject = (MyClass)in.readObject();
in.close();
return newObject;
I would like this method to be generic, therefore I can tell it what type I want to in.readObject() to cast its output into, and return it.
Hope this makes sense...then again, I probably didn't understand generics properly and this is not actually possible, or advisable.
Thanks,
D.
I'm not sure about Android (or any limitations it might have), but in Java you can do something like this:
public static <T> T getObject(String filename) throws IOException, ClassNotFoundException {
FileInputStream fis = new FileInputStream(filename);
ObjectInputStream in = new ObjectInputStream(fis);
T newObject = (T) in.readObject();
in.close();
return newObject;
}
and then call it like
MyClass myObj = getObject("in.txt");
This will give you an unchecked cast warning though, since the compiler can't be sure you can cast the object received to the type provided, so it's not exactly type safe. You need to be sure that what you're getting from the input stream actually can be cast to that class, otherwise you will get a ClassCastException. You can suppress the warning by annotating the method with #SuppressWarnings("unchecked")
Having just seen this How do I make the method return type generic? I am going to try the following:
public <T> T deserialiseObject(String filename, Class<T> type)
throws StreamCorruptedException, IOException,
ClassNotFoundException {
FileInputStream fis = new FileInputStream(filename);
ObjectInputStream in = new ObjectInputStream(fis);
Object newObject = in.readObject();
in.close();
return type.cast(newObject);
}