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);
}
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
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
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
I am trying to read 2 arraylists using the following methods.
public static ArrayList<Contestant> readContestantsFromFile() throws IOException, ClassNotFoundException {
FileInputStream fis = new FileInputStream("minos.dat");
ObjectInputStream ois = new ObjectInputStream(fis);
ArrayList<Contestant> contestants = (ArrayList<Contestant>) ois.readObject();
ois.close();
return contestants;
}
public static ArrayList<Times> readContestantsFromFile() throws IOException, ClassNotFoundException {
FileInputStream fis = new FileInputStream("minos.dat");
ObjectInputStream ois = new ObjectInputStream(fis);
ArrayList<times> times = (ArrayList<Times>) ois.readObject();
ois.close();
return times;
}
Bit this doesn't work. It cannot cast to the the second arraylist type i've saved. So how can I access this? The exact error I got was this:
Exception in thread "main" java.lang.ClassCastException: com.deanchester.minos.model.Contestant cannot be cast to com.deanchester.minos.model.Times
at com.deanchester.minos.tests.testAddTime.main(testAddTime.java:31)
The line that this is referring to is:
ArrayList<times> times = (ArrayList<Times>) ois.readObject();
So how can I read 2 different arraylists from one file?
Use FileOutputStream fos = new FileOutputStream("minos.dat", true); when writing the second file. true is a value of argument "append". Otherwise you override the file content. This is the reason that you read the same collection twice.
When you are reading the second collection from the file you have to skip to the beginning of the second collection. To do this you can remember how many bytes have you read on first phase and then use method skip().
But better solution is to open file only once (I mean call new FileInputStream and new FileOutputStream) only once and then pass it to methods that read collections.
You can read two different objects from a file using a ObjectInputStream, but your problem comes from the fact that you reopen the stream so it starts at the beginning of the file where you have the ArrayList<Contestant> and then you ArrayList<Times>. Try doing everything at once and returning both lists:
public static ContestantsAndTimes readObjectsFromFile() throws IOException, ClassNotFoundException {
FileInputStream fis = new FileInputStream("minos.dat");
ObjectInputStream ois = new ObjectInputStream(fis);
ArrayList<Contestant> contestants = (ArrayList<Contestant>) ois.readObject();
ArrayList<Times> times = (ArrayList<Times>) ois.readObject();
ois.close();
return new ContestantsAndTimes(contestants, times);
}
How do I return a vector in a java function. I want to unserialize a vector loaded from a file and return in a function but I get errors. This is what code I currently have.
private static Vector<Countries> loadOB(String sFname) throws ClassNotFoundException, IOException {
ObjectInputStream oStream = new ObjectInputStream(new FileInputStream(sFname));
Object object = oStream.readObject();
oStream.close();
return object;
}
You need to cast the object that you read from the file to Vector:
private static Vector<Countries> loadOB(String sFname) throws ClassNotFoundException, IOException {
ObjectInputStream oStream = new ObjectInputStream(new FileInputStream(sFname));
try{
Object object = oStream.readObject();
if (object instanceof Vector)
return (Vector<Countries>) object;
throw new IllegalArgumentException("not a Vector in "+sFname);
}finally{
oStream.close();
}
}
Note that you cannot check if it is really a Vector of Countries (short of checking the contents one by one).
This is a wild guess, but try return (Vector<Countries>) object;