albertlee Posted July 21, 2006 Posted July 21, 2006 import java.io.*; class Food {Food(){System.out.print("1");}} class Fruit extends Food implements Serializable{ Fruit(){System.out.print("2");} } public class Banana2 extends Fruit { int size = 42; public static void main(String[] af){ Banana2 b = new Banana2(); try{ ObjectOutputStream oob = new ObjectOutputStream(new FileOutputStream("bla.txt")); oob.writeObject(b); oob.close(); ObjectInputStream oib = new ObjectInputStream(new FileInputStream("bla.txt")); Banana2 b1 = (Banana2) oib.readObject(); oib.close(); System.out.println(" restored "+b.size+" ");} catch(Exception e){System.out.println(e);} } } 1, why does the above code give me "121 restored 42" as the result instead of "12 restored 42" which is what I expected? Given: void wfs(){ Object o = new Object(); synchronized (Thread.currentThread()){ o.wait(); o.notify();; } } 2, what exception maybe thrown from the above code? this is actually a Java exam question. The possible answers are: a) IllegalStateException b) TimeoutException c) InterruptedException 3, what does the extra ";" symbol after the o.notify() method stand for? please help thanks
Aeternus Posted July 22, 2006 Posted July 22, 2006 1) I think this is because, it can't technically serialise the parts of the object belonging to the super class Food (even though it can serialise the fields, the constructor Food() might have to set certain things up that aren't carried over and are needed for Fruit, Banana2 etc to work once deserialized), therefore it must call the Food constructor to setup anything that wasn't serialized and so on inherited from Food. You'll notice that the problem goes away when you do - class Food implements Serializable { Food() {System.out.print("1");} } class Fruit extends Food { Fruit(){System.out.print("2");} } public class Banana2 extends Fruit { int size = 42; public static void main(String[] af){ Banana2 b = new Banana2(); try{ ObjectOutputStream oob = new ObjectOutputStream(new FileOutputStream("bla.txt")); oob.writeObject(b); oob.close(); ObjectInputStream oib = new ObjectInputStream(new FileInputStream("bla.txt")); Banana2 b1 = (Banana2) oib.readObject(); oib.close(); System.out.println(" restored "+b.size+" ");} catch(Exception e){System.out.println(e);} } } 2) The only exception I can see that could be thrown there is InterruptedException, although the TimeoutException would be nice considering as far as I can see notify will never be called and it'll get stuck like that (unless there are other threads elsewhere in the code calling notify(). 3) somestatement;; is just - somestatement; {anemptystatement}; Ie, just imagine there were actually a command/statement inbetween the two, but it didn't actually do anything, that is what that is. You can add as many extra ;'s as you want, each one just finishes an empty statement.
Aeternus Posted July 22, 2006 Posted July 22, 2006 A more illustrative example for (1) - import java.io.*; class Food { public String booga = "booga"; Food() {System.out.print("1");} } class Fruit extends Food implements Serializable { Fruit(){System.out.print("2");} } public class Banana2 extends Fruit { int size = 42; Banana2() { }; public static void main(String[] af){ Banana2 b = new Banana2(); b.booga = "cheese"; try{ ObjectOutputStream oob = new ObjectOutputStream(new FileOutputStream("bla.txt")); oob.writeObject(b); oob.close(); ObjectInputStream oib = new ObjectInputStream(new FileInputStream("bla.txt")); Banana2 b1 = (Banana2) oib.readObject(); oib.close(); System.out.println(" restored "+b.size+" "+b1.booga); } catch(Exception e){System.out.println(e);} } } gives - 121 restored 42 booga NOT 121 restored 42 cheese Because the fields inherited from Food (which doesn't implement serializable, are not serialized and when they are created from readObject, they gain their default value and the constructor's of the parents further up the tree are run, allowing these fields to be initialised again to sane values (especially useful if you inherit from things involving files or network connections which can't easily be serialised.
Karnage Posted July 22, 2006 Posted July 22, 2006 I'm gonna take a look at your code and try to figure it out. Sorry I'm not extremely good at Java (I never paid much attention in class) but nevertheless, I took the AP and i'll try my best to help you out if i can of course.
Karnage Posted July 22, 2006 Posted July 22, 2006 OMG i could understnad wht it does, ut i cant get much of a good understanding cuz im not sure what some of the methods do ie(serialization)
Aeternus Posted July 23, 2006 Posted July 23, 2006 OMG i could understnad wht it does, ut i cant get much of a good understanding cuz im not sure what some of the methods do ie(serialization) http://java.sun.com/developer/technicalArticles/Programming/serialization/ and http://java.sun.com/j2se/1.5.0/docs/api/java/io/Serializable.html Should give you some idea. The basic idea is that you can save the state of the object as a byte stream by "serializing" it, that can be saved to a file, or sent over a network and then you can then "deserialize" it later on or at the other end. Java does most of this automatically but there are some complications, and so to show that your class/object should be able to do this (ie you have checked that there aren't any problems*) you implement the Serializable interface, which doesn't actually include any methods for you to implement, it just acts as a check that the object is ok to be serialized. * Some things like network connections or file connectors might not make sense to be serialized as part of the serialized object being saved to file or sent over a network or a variety of other things. So you can provide certain methods with your class that can be called instead of the default Java serialization stuff so you can do certain things when the object is serialized or deserialized and reset certain variables to sane defaults or new values (these are discussed in the links above) and certain fields can be set to "transient" so that their values/state won't be saved when you serialise the object. My explanation might be a bit dodgy and perhaps a little wrong/broken in some places but the links above should provide more info.
albertlee Posted July 27, 2006 Author Posted July 27, 2006 thanks for ur response, Aeternus... Well, only 1 problem left... for the second question, the real answer is IllegalStateException.... can any one of you give me some examples when EXACTLY an IllegalStateException is fired? I searched through the Java offical site, and it only briefly defines it as an exception for an object or thread having an illegal state..... please help here thanks
Aeternus Posted July 27, 2006 Posted July 27, 2006 The only exception similar to what you are talking about that is actually thrown by Object.wait() (or notify() but that isn't really important as it won't reach that in this example) in this example is IllegalMonitorStateException which is thrown in this case when wait() is called on Object o, because whatever object the wfs method is a part of, hasn't grabbed the monitor/lock for Object o and so can't call wait() on it, hence it throws the IllegalMonitorStateException. The example currently synchronizes on the current thread (and hence gains a lock/monitor on the current thread object) but that isn't that same as having ownership of the monitor/lock of the Object o. To gain ownership of it's monitor and the ability to call wait() on it you have to do - public void wfs() { Object o = new Object(); synchronized (o) { o.wait(); o.notify();; } } That way you are synchronizing on o, gaining it's lock/monitor in the process and therefore you are allowed to call wait() on it and an IllegalMonitorStateException can't be thrown. I'm not sure whether an IllegalStateException can also be thrown somehow (and I can't see IllegalMonitorStateException extending to IllegalStateException) but I'm guessing maybe it was just a typo or something similar? I could be wrong on some of this, this is just how I see it.
albertlee Posted July 27, 2006 Author Posted July 27, 2006 Aeternus, regarding the code sample you provided, I tried it, and it did not throw IllegalMonitorStateException at runtime..... yes, the program simply stops working because the current thread, main, which is the only reachable thread becomes not runnable as it cannot regain the object lock, but there is NO IllegalMonitorStateException.... please illustrate thanks
Aeternus Posted July 27, 2006 Posted July 27, 2006 The code sample I provided was meant to illustrate how to avoid getting an IllegalMonitorStateException. The code you originally provided generates an IllegalMonitorStateException when you chuck it in a class and try to run it (or at least it did with me. For instance I put your original code segment into a class and compiled like so - public class Thread2 { public void wfs() throws InterruptedException { Object o = new Object(); synchronized (Thread.currentThread()){ o.wait(); o.notify();; } } public static void main(String args[]) throws InterruptedException { Thread2 t = new Thread2(); t.wfs(); } } and when run (on 1.4 and 1.5) this gives - Exception in thread "main" java.lang.IllegalMonitorStateException: current thread not owner at java.lang.Object.wait(Native Method) at java.lang.Object.wait(Object.java:474) at Thread2.wfs(Thread2.java:9) at Thread2.main(Thread2.java:18) I altered the code to change - synchronized (Thread.currentThread()){ to synchronized (o) { which when run works ok, but as expected will simply sit there indefinitely waiting for a notify() call that never comes. Basically my code segment was simply to illustrate how one would do things to avoid that exception. Sorry if this was a little unclear.
albertlee Posted July 27, 2006 Author Posted July 27, 2006 thanks... I finally get it.. end of Some Java Questions thread
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now