InvalidClassException thrown in deep cloning

We are trying to deep-clone an object by using serialization. We want to read the object bytes to create a String ( using new String(byte[]) ), store that String in a memory cache for later retrieving, get its bytes (using string.getBytes() ) and rebuild the original object with an ObjectInputStream.
We are using ByteArrayInput/Output Streams to read and write the bytes from and to byte arrays, but when we call objectInputStream.readObject() we get an IllegalClassException. We have found that the byte arrays have in fact a couple of different elements after and before the retrieval. Here is the code we are using:
public class ObjectCloner {
public ObjectCloner(){}
static public Object deepCopy(Object oldObj) throws Exception
ObjectOutputStream oos = null;
ObjectInputStream ois = null;
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(bos);
// serialize and pass the object
oos.writeObject(oldObj);
byte[] b = bos.toByteArray();
oos.flush();
String s = new String(b); //turn byte array into String
byte[] b2 = s.getBytes(); //read bytes again
ByteArrayInputStream bin = new ByteArrayInputStream(b2);
ois = new ObjectInputStream(bin);
catch(Exception e){
System.out.println("Exception in ObjectCloner = " + e);
finally{
oos.close();
ois.close();
return ois.readObject(); //recreate the object
We make a call from a client class, like this:
Integer inte = (Integer)ObjectCloner.deepCopy(new Integer(7));
Any comments will be very helpful. Thanks.

The reason is this, you create a new String with the byte array and use getBytes() to get a new byte array using the default encoding. First I don't understand why you use these two statements, because you can apply the bytearray b directly to your ByteArrayOutputStream.
If you want to make a copy of b, then use System.arraycopy instead of creating a String and extract the bytes from that.
It would have worked if you used getBytes("8859_1"), that is the ISO 8859-1 encoding, which maps characters 0-255 to the same values. But UTF-8 will only map 0-127 to 0-127, and 128-255 will be mapped to at least two bytes.
One more comment, you shouldnt try to read from your ObjectInputStream after you closed it. Move that line to just before you exit the try block, and in your exception block you should return null or throw an exception. The finally block will still be executed, so dont worry about that (remove the return statement from finally).

Similar Messages

  • Deep Cloning problem

    I am having problems deep cloning a LinkedList object which contains serializable objects. I have tried using hand coded deep cloning and using the byteArray output and input streams.
    But nothing is working :(.
    My code currently looks like this:
    public LinkedList clones(LinkedList list){
       LinkedList deepCopy = new LinkedList();
       for(int x = 0; x < list.size(); x++){
          myClasstemp = new myClass((materials)list.get(x));
          deepCopy.add(new myClass(temp));
       return deepCopy;
    }cloning using just new myClass works when I am using individual objects, but when I try applying this to the new linkedlist, nothing happens. Is my error in the fact I am using .get? Or is it somewhere else in my code?
    My problem is that when I remove an object from the original LinkedList, the deepclone is changed as well.
    Message was edited by:
    DocterJ0208

    to be as detailed as possible, my problem is that I actually have 2 classes. One class is a structure object which contains basic properties like doubles and strings. And the other has doubles and strings as well and includes a LinkedList containing objects from the first class. To for an example, I have a student and School class where a School object contains a LinkedList holding all the students at the school.
    What I am trying to do is make a Cancel button. So, what I want is to make a copy of the original school, so if while editing the school, I decide I want to revert back to my original settings, I can by pressing the cancel button. So far, I can only accomplish this with the student class but not the School class. Does that make sense?

  • Deep Cloning of resultset object

    Hi, Is it possinble? Deep Cloning of resultset object?
    Resltset rs = pstmt.execute()
    Anyway to assign rs2 = rs1
    Because I am passing my resulset to a legacy application's method, that does a rs.close(). I need to use the same resultset later. JDK 1.4

    Write a dynamic proxy to the ResultSet where theclose() method does >nothing.
    What if the OP discovers that the app does a rs=null
    as well?How can that affect your code? Presumably the ResultSet is passed as an argument to a legacy method so the legacy method might set it's local reference to null it will not affect the reference held by the caller of the method.
    The op then runs thru hoops to get permission to
    modify a line in legacy code and is too distressed to
    post.He does not need to! You need to learn about Java argument passing.
    Anyway, thanks for the classrom solution. but i cant
    create another class file for extending rs.You have not presented any reason why not! This can be an inner class in the code you are writing and has no influence what so ever on the legacy application.
    >
    If you are too distressed by the posts here, you are
    under no obligation to reply to every one. Anyway , i
    found the postI replied because I had a viable solution to a problem you were having. Nothing you have said so far stops it being viable. Look at my posting history - I do not try to reply to everyone.
    >
    A Resultset is mainly a Java front end for adatabase
    cursor (which exists on the database server). When
    the ResultSet is closed, the cursor will be closed
    too so, even if you could copy everything in the
    ResultSet object, the handle for the cursor wouldno
    longer be valid.
    Which is why you use a Proxy so that you can control exactly what happens.
    >>
    To truely "deep copy" a resultset the depth would
    have to extend accros the database connection to
    cloning the cursor.I still don't see why you need to clone the ResultSet rather than use a proxy!
    >
    very much useful than the self pity expressed by
    you.No self pity! I just expressed annoyance at the lack of feedback from you and many others.
    No offence, none taken and none dealt.I still find it offensive when people don't bother with a simple acknowledgement. I don't ask many questions myself but when I do I make sure I track the responses and acknowledge those who try to help.
    I still think you should re-think your solution but you are free to totally ignore my very simple solution. I expect you will ignore it so the best of luck.

  • Problem in deep cloning

    Hai Friends,
    I am trying to use deep cloneing for copying objects and then setting the appropriate values to the properties of copied object. When we make deep clone copy, it is supposed to retain original property values. But in the example I tried, it shows only zeros. The source code and the output is given below. i seek your expertise and my advance thanks for any help to resolve my problem.
    * This class extends the class of Javas Point2D.Double
    import java.awt.geom.Point2D;
    import java.awt.Rectangle;
    import java.io.Serializable;
    import java.awt.Graphics2D;
    import javax.swing.JFrame;
    import java.awt.Graphics;
    import java.awt.Color;
    import java.awt.geom.AffineTransform;
    import java.util.ArrayList;
    import java.io.Serializable;
    import java.io.ObjectInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.ObjectOutputStream;
    import java.io.ByteArrayInputStream;
    import java.lang.ClassNotFoundException;
    import java.io.IOException;
    public class point2D extends Point2D.Double implements Cloneable, Serializable{
    // Properties
         Color drawColor =Color.red;
    * Constructor
    point2D(){ }
    point2D( double xx, double yy){ super(xx,yy); }
    public void setLocation( double xx, double yy){
         super.setLocation(xx,yy);}
    public void setDrawColor( Color drawColor){
         drawColor = this.drawColor;}
    * Draw a rectangle around through point.
    public Rectangle getPointRect(){
    int width = 4;
    return new Rectangle( (int)x-width/2,(int)y-width/2, width, width);
    * Check for a given point coinciding with point2D
    * location check is true, if it contains the point
    public boolean locationCheck( double x, double y){
         return getPointRect().contains((int)x,(int)y);
    * Draw method.
    public void draw( Graphics2D g2d ){
         g2d.setColor(drawColor);
    g2d.fill( getPointRect());
    public Object deepClone()
    try{
    ByteArrayOutputStream b = new ByteArrayOutputStream();
    ObjectOutputStream out = new ObjectOutputStream(b);
    out.writeObject(this);
    out.close();
    ByteArrayInputStream bIn = new ByteArrayInputStream(b.toByteArray());
    ObjectInputStream oi = new ObjectInputStream(bIn);
    oi.close();
    return oi.readObject();
    catch (IOException e)
    { System.out.println("exception:"+e.getMessage());
    e.printStackTrace();
    return null;
    catch( ClassNotFoundException cnfe){
    System.out.println("exception:"+ cnfe.getMessage());
    cnfe.printStackTrace();
    return null;}          
    public static void main( String[] args){
         point2D pp = new point2D();
         pp.setLocation( 100.,150.);
         System.out.println( pp.locationCheck(100.5, 149.5));
    System.out.println( pp.getX() + " " + pp.getY());
         point2D ppp = (point2D)pp.deepClone();
    System.out.println( ppp.getX() + " " + ppp.getY());
    The output:
    true
    100.0 150.0
    0.0 0.0

    Hai sztejkat,
    I tried with adding methods to save and restore the state of the non-serializable class and it works.
    What is the reason to implement deep clone in point2D - this class does not contain any references >except Color, which is an immutable class and can be safely shared by multiple objects. In this case the >shallow copy will work fine. In my opinion the method you have choosen to implement deep copy is one >of the worst possible, looking from performance point of view. Shallow copy makes a new reference but pointing to the same object. My intension of deep copying was to create a new object. However, I fully agree with you that for simple instances of Point2D.Double, it is better to create a new onject using " new" operator than deepcopying.
    With best regards,
    Chinnaswamy

  • Generic class for deep cloning

    How can I write generic class for deep cloning instead of implementing cloneable for each and every object

    Yes, probably you'd need to use reflection. Though, generic deep copy brings up some issues not readily resolvable at run-time, such as, for example, does the object you want to copy refer to a shared or synchronized resource, such as a db connection? If so, by making a new, say, DBConnection object, you then take up a db connection that you really don't need or want to take up (db conns being scarce in many I.T. shops that own a limited number of Oracle or SQL Server, etc. db conn. licenses). Also, many classes these days are getting written that use "obj = classname.newInstance()" (with their constructors made private so you can't use "new SomeObject()") instead of the more commonsense and traditional "obj = new SomeObject()". [Hey, can anyone explain why it might be preferable to use "classname.newInstance()" at times over "new SomeObject()"?  I can't to this day tell why it might be better or why some hacks have started doing this.]
    I am not saying either that you couldn't do it or that you shouldn't. In fact, if you wrote a really good generic deep copy class, it may very well suit your needs 95+% of the time. It'd be a great programming exercise that would likely result in something very useful to someone somewhere (yourself included), and would get you to really learn the reflect package, time generally well-spent. I also can see how it'd be a great exercise in writing recursive calls (if for example you'd like no limit to the depth of objects created within your deep-copied object). You may need to supply a few caveats for use, such as that there's no guarantee that objects within the object to be copied that don't have public constructors can be copied, and that objects that hold other objects that are limited in availablity due to their very natures, such as db connections, may not get fully copied. Another one may be that no object can be copied as long as a thread created and run from it is executing at the time the copy is done (because you couldn't guarantee the to-be-copied object instance's data or object reference state), or that perhaps in some cases, certain kinds of method-level (ie, what's officially called by Sun, "automatic") variables declared and used within, for example, blocks of code within methods, may not have their values copied correctly if they are not visible to the reflect pkg objects (though I'd have to look into that one myself to be sure it would be an issue).
    Doing a search on "deep copy" or "deep clone" on java.sun.com as well as on the 'net reveals surprisingly little except suggestions for using object serialization to do all the dirty work for you.
    I am surprised there isn't a kind of virtual working group trading ideas on the topic and trying collaboratively to come up with a good, solid generic deep copy class as a public service for all the Java brethren. Does anyone know of one? And if not, wanna start one?

  • Deep cloning

    Hi i need to know how can I make deep cloning of own created array which will store the same array as well as other objects like Integer class and then array at element of array will again store another array or some other objects and then again at any element store array can store objects or array . I need to know how should i make deep cloning recuresively . and how should i write hash code and equals method for that class . please help me. I m feeling fustrated

    As a supplementary issue on this subject I am interested how to choose between the Arrays and the
    ArrayList classes. This thread suggests that Arrays is more versatile, although I usually use an
    ArrayList. Should I review this practice?Sorry. You read the thread incorrectly. :-)
    Arrays and ArrayList are completely different. java.util.Arrays has static methods for dealing with arrays. java.util.ArrayList is like a resizable array. java.util.Collections has static methods that can be used on java.util.ArrayList. Read the APIs, and you will see the difference.

  • Deep cloning a Binary Tree

    Hi, I have a class called DigitalTree that acts like a binary tree, storing nodes that each have a "key" which is a long value, and then puts each node into the tree in its correct place, binary tree style. I am trying to deep clone the tree, but for some reason my recursive cloning method isn't working. If anyone can see a problem in my code or has any tips for me, it would be greatly appreciated. Thanks.
    public Object clone()
           DigitalTree<E> treeClone = null;
           try
               treeClone = (DigitalTree<E>)super.clone();
           catch(CloneNotSupportedException e)
               throw new Error(e.toString());
           cloneNodes(treeClone, this.root, treeClone.root);
           return treeClone;
       private void cloneNodes(DigitalTree treeClone, Node currentNode, Node cloneNode)
           if(treeClone.size == 0)
               cloneNode = null;
               cloneNodes(treeClone, currentNode.left, cloneNode.left);
               cloneNodes(treeClone, currentNode.right, cloneNode.right);
           else if(currentNode != null)
               cloneNode = (Node<E>)currentNode.clone();
               cloneNodes(treeClone, currentNode.left, cloneNode.left);
               cloneNodes(treeClone, currentNode.right, cloneNode.right);
       }In the Node class:
    public Object clone()
              Node<E> nodeClone = null;
              try
                   nodeClone = (Node<E>)super.clone();
              catch(CloneNotSupportedException e)
                   throw new Error(e.toString());
              return nodeClone;
           }

    Hello jssutton
    Your question inspired me to try my own binary tree and cloning. My cloning algorithm is similar to yours but with one difference.
    In my class Tree defined as:
    class Tree<T extends Comparable>
    I have:
        private void deepCopyLeft(TreeNode<T> src, TreeNode<T> dest) {
            if (src == null) return;
            dest.mLeft = new TreeNode<T>(src.mValue);
            deepCopyLeft(src.mLeft, dest.mLeft);
            deepCopyRight(src.mRight, dest.mLeft);
        private void deepCopyRight(TreeNode<T> src, TreeNode<T> dest) {
            if (src == null) return;
            dest.mRight = new TreeNode<T>(src.mValue);
            deepCopyLeft(src.mLeft, dest.mRight);
            deepCopyRight(src.mRight, dest.mRight);
        public Tree<T> deepCopy() {
            if (root == null) return new Tree<T>();
            TreeNode<T> newRoot = new TreeNode<T>(root.mValue);
            deepCopyLeft(root.mLeft, newRoot);
            deepCopyRight(root.mRight, newRoot);
            return new Tree<T>(newRoot);
        }Its a similar recursive idea, but with 2 extra functions. I hope that helps. I don't have time right now to pinpoint the problem in your routine. Good luck.

  • Deep Cloning of Arrays

    Hello, I am stuck with this problem...
    I am trying to clone an Array object of type MajorCat. Each MajorCat contains another Array of type MinorCat.
    MajorCat[] contains n MajorCat
    MajorCat[0] contains MinorCat[], of length m
    I wanna clone MajorCat[], which will in turn clone MinorCat[] embedded within it.
    Tried the method given in Section "CloneDemo5" within:
    http://developer.java.sun.com/developer/JDCTechTips/2001/tt0306.html
    The result is strange, and I need a solution...
    Result:
    1) MajorCat[] after cloning gives another copy
    2) MinorCat[] after cloning gives another copy
    3) the orginal MajorCat[] remains the same Object
    4) BUT THE ORIGINAL MinorCat[] points to the Object at 2) !!!!!!!
    Please see this System.out:
    Original MAJORCAT starting off is [LMajorCat;@59ac7b [LMinorCat;@e2ae8   <--- 1)
    Minor Cat before cloning: [LMinorCat;@e2ae8
    Minor Cat after cloning:  [LMinorCat;@489bb6
    New MAJORCAT afterward is  [LMajorCat;@487a3a [LMinorCat;@489bb6
    Original MAJORCAT is   [LMajorCat;@59ac7b [LMinorCat;@489bb6
    Here is the code:
    MajorCat[] tempcat = (MajorCat[])(majorcat.clone());
    for ( int i=0; i<majorcat.length; i++ ) {
    if ( majorcat.minorcat != null ) {
    tempcat.minorcat = (MinorCat[])(majorcat.minorcat.clone());
    What have I done wrong? A million thanks in advance!!!!

    Hello, I put the overloading clone() method back into MajorCat and MinorCat. Again, they are never called...
    Here is the code:
    public class CatelogueSingleton extends ConnectionBase {
        protected MajorCat[] majorcat = null;
        public MajorCat[] getCatelogue() {
            if ( majorcat == null ) {
                renewAllObjects();
                System.out.println("majorcat erased!");
            MajorCat[] tempcat = (MajorCat[])(majorcat.clone());
            System.out.println("original object is   " + majorcat + " " + majorcat[0].minorcat + " " + majorcat[0].minorcat[0].itemgroup + " " + majorcat[0].minorcat[0].itemgroup[0].item);
    // clone each Object in majorcat[]
            for ( int i=0; i<majorcat.length; i++ ) {
                if ( majorcat.minorcat != null ) {
    tempcat[i].minorcat = (MinorCat[])(majorcat[i].minorcat.clone());
    for ( int j=0; j<majorcat[i].minorcat.length; j++ ) {
    if ( majorcat[i].minorcat[j].itemgroup != null ) {
    tempcat[i].minorcat[j].itemgroup = (ItemGroup[])(majorcat[i].minorcat[j].itemgroup.clone());
    for ( int k=0; k<majorcat[i].minorcat[j].itemgroup.length; k++ ) {
    if ( majorcat[i].minorcat[j].itemgroup[k].item != null ) {
    tempcat[i].minorcat[j].itemgroup[k].item = (Item[])(majorcat[i].minorcat[j].itemgroup[k].item.clone());
    System.out.println("cloned object is " + tempcat + " " + tempcat[0].minorcat);
    System.out.println("after cloning the original object is " + majorcat + " " + majorcat[0].minorcat);
    return tempcat;
    Here is the code for MajorCat...
    public class MajorCat extends ConnectionBase implements java.io.Serializable, Cloneable {
        public MinorCat[] minorcat = null;
        public Object clone() {
            try {
                System.out.println("Cloning majorcat");
                MajorCat aobj = (MajorCat)super.clone();
                aobj.minorcat = (MinorCat[])(this.minorcat.clone());
                return aobj;
            catch (CloneNotSupportedException e) {
                throw new InternalError(e.toString());
        public MajorCat() {
    }here is the code for MinorCat...
    public class MinorCat extends ConnectionBase  implements java.io.Serializable, Cloneable {
        public ItemGroup[] itemgroup = null;
        public Object clone() {
            try {
                MinorCat aobj = (MinorCat)super.clone();
                aobj.itemgroup = (ItemGroup[])(this.itemgroup.clone());
                return aobj;
            catch (CloneNotSupportedException e) {
                throw new InternalError(e.toString());
        public MinorCat() {
    }The result is:
    original object is [LMajorCat;@572085 [LMinorCat;@180b94
    cloned object is     [LMajorCat;@148656 [LMinorCat;@180b94
    after cloning the original object is  [LMajorCat;@572085 [LMinorCat;@180b94
    The original MinorCat within MajorCat now points to the new clone, and the clone() within MajorCat and MinorCat aren't called.... as there is no System.out statements.
    What have I done wrong in clone() within MajorCat and MinorCat?                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       

  • Clarification regarding deep cloning/deep copy

    Hi,
    While performing deep copy of an object should all the subobject that the parent object constitute also constitute the clone method.
    For Eg:
    I have a class called Document and a class called Field. Document constitutes of List<Field> fields. Field class has a String fieldName as its member variable.
    I need to perform a deep copy of Document object. Should Field class also implement the clone method or can I create field objects in the documents clone method and fill these fields with values from the existing field list to form a new Document with these new fields.
    Or do I call clone() method on each field to get a new field object and
    add it to the new Document object that I am creating in the clone() method .
    //First approach
    public Document clone(){
    Document doc = new Document();
    List<Field> fields = doc.getFields()
    Field newField = null;
    for(Field f: fields){
        newField = new Field();
        newField.setName(f.getName());
       doc.addField(newField);
    return doc;
    //Second Approach
    public Document clone(){
    Document doc = new Document();
    List<Field> fields = doc.getFields()
    Field newField = null;
    for(Field f: fields){
        newField = f.clone()
       doc.addField(newField);
    return doc;
    }Please let me know which is a better approach and the standard coding
    practise.
    Thanks

    the second method is better, because it lets you the possibility to create a subclass of Field with a specific clone method, integrate some instances in a Document object; without changing the Document.clone method.

  • Cloning problem with Tool Tip Manager

    Hi,
    I am using JDialog which has got JTabbedPane. Inside the JTabbedPane I am using JTable.
    I want to clone JDialog object, for which I am using deep cloning technique. When I call my overloaded clone method it throws "NotSerializableExcpetion" for javax.swing.ToolTipManager class.
    I checked out the ToolTipManager Class which does not implements java.io.Serializable interface.
    I will create a new class which will extend ToolTipManger and implements java.io.Serializable interface. How can I override the default ToolTipManager using my new class.
    Thanks in advance,
    Deep Shah

    Hi,
    I am using JDialog which has got JTabbedPane. Inside the JTabbedPane I am using JTable.
    I want to clone JDialog object, for which I am using deep cloning technique. When I call my overloaded clone method it throws "NotSerializableExcpetion" for javax.swing.ToolTipManager class.
    I checked out the ToolTipManager Class which does not implements java.io.Serializable interface.
    I will create a new class which will extend ToolTipManger and implements java.io.Serializable interface. How can I override the default ToolTipManager using my new class.
    Thanks in advance,
    Deep Shah

  • Help with encapsulation and a specific case of design

    Hello all. I have been playing with Java (my first real language and first OOP language) for a couple months now. Right now I am trying to write my first real application, but I want to design it right and I am smashing my head against the wall with my data structure, specifically with encapsulation.
    I go into detail about my app below, but it gets long so for those who don't want to read that far, let me just put these two questions up front:
    1) How do principles of encapsulation change when members are complex objects rather than primitives? If the member objects themselves have only primitive members and show good encapsulation, does it make sense to pass a reference to them? Or does good encapsulation demand that I deep-clone all the way to the bottom of my data structure and pass only cloned objects through my top level accessors? Does the analysis change when the structure gets three or four levels deep? Don't DOM structures built of walkable nodes violate basic principles of encapsulation?
    2) "Encapsulation" is sometimes used to mean no public members, othertimes to mean no public members AND no setter methods. The reasons for the first are obvious, but why go to the extreme of the latter? More importantly HOW do you go to the extreme of the latter? Would an "updatePrices" method that updates encapsulated member prices based on calculations, taking a single argument of say the time of year be considered a "setter" method that violates the stricter vision of encapsulation?
    Even help with just those two questions would be great. For the masochistic, on to my app... The present code is at
    http://www.immortalcoil.org/drake/Code.zip
    The most basic form of the application is statistics driven flash card software for Japanese Kanji (Chinese characters). For those who do not know, these are ideographic characters that represent concepts rather than sounds. There are a few thousand. In abstract terms, my data structure needs to represent the following.
    -  There are a bunch of kanji.
       Each kanji is defined by:
       -  a single character (the kanji itself); and
       -  multiple readings which fall into two categories of "on" and "kun".
          Each reading is defined by:
          -  A string of hiragana or katakana (Japanese phoenetic characters); and
          -  Statistics that I keep to represent knowledge of that reading/kanji pair.Ideally the structure should be extensible. Later I might want to add statistics associated with the character itself rather than individual readings, for example. Right now I am thinking of building a data structure like so:
    -  A Vector that holds:
       -  custom KanjiEntry objects that each hold
          -  a kanji in a primitive char value; and
          -  two (on, kun) arrays or Vectors of custom Reading objects that hold
             -  the reading in a String; and
             -  statistics of some sort, probably in primitive valuesFirst of all, is this approach sensible in the rough outlines?
    Now, I need to be able to do the obvious things... save to and load from file, generate tables and views, and edit values. The quesiton of editting values raises the questions I identified above as (1) and (2). Say I want to pull up a reading, quiz the user on it, and update its statistics based on whether the user got it right or wrong. I could do all this through the KanjiEntry object with a setter method that takes a zillion arguments like:
    theKanjiEntry.setStatistic(
    "on",   // which set of readings
    2,      // which element in that array or Vector
    "score", // which statistic
    98);      // the valueOr I could pass a clone of the Reading object out, work with that, then tell the KanjiEntry to replace the original with my modified clone.
    My instincts balk at the first approach, and a little at the second. Doesn't it make more sense to work with a reference to the Reading object? Or is that bad encapsulation?
    A second point. When running flash cards, I do not care about the subtlties of the structure, like whether a reading is an on or a kun (although this is important when browsing a table representing the entire structure). All I really care about is kanij/reading pairings. And I should be able to quickly poll the Reading objects to see which ones need quizzing the most, based on their statistics. I was thinking of making a nice neat Hashtable with the keys being the kanji characters in Strings (not the KanjiEntry objects) and the values being the Reading objects. The result would be two indeces to the Reading objects... the basic structure and my ad hoc hashtable for runninq quizzes. Then I would just make sure that they stay in sync in terms of the higher level structure (like if a whole new KanjiEntry got added). Is this bad form, or even downright dangerous?
    Apart from good form, the other consideration bouncing around in my head is that if I get all crazy with deep cloning and filling the bottom level guys with instance methods then this puppy is going to get bloated or lag when there are several thousand kanji in memory at once.
    Any help would be appreciated.
    Drake

    Usually by better design. Move methods that use the
    getters inside the class that actually has the data....
    As a basic rule of thumb:
    The one who has the data is the one using it. If
    another class needs that data, wonder what for and
    consider moving that operation away from that class.
    Or move from pull to push: instead of A getting
    something from B, have B give it to A as a method
    call argument.Thanks for the response. I think I see what you are saying.. in my case it is something like this.
    Solution 1 (disfavored):
    public class kanjiDrill{ // a chunk of Swing GUI or something
         public void runDrill(Vector kanjiEntries){
              KanjiEntry currentKanjiEntry = kanjiEntries.elementAt(0); // except really I will pick one randomly
              char theKanji = currentKanjiEntry.getKanji();
              String theReading = currentKanjiEntry.getReading();
              // build and show a flashcard based on theKanji and theReading
              // use a setter to change currentKanji's data based on whether the user answers correctly;
    }Solution 2 (favored):
    public class kanjiDrill{ // a chunk of Swing GUI or something
         public void runDrill(Vector kanjiEntries){
              KanjiEntry currentKanjiEntry = kanjiEntries.elementAt(0); // except really I will pick one randomly
              currentKanji.buildAndShowFlashcard(); // method includes updating stats
    }I can definitely see the advantages to this, but two potential reasons to think hard about it occur to me right away. First, if this process is carried out to a sufficient extreme the objects that hold my data end up sucking in all the functionality of my program and my objects stop resembling natural concepts.
    In your shopping example, say you want to generate price tags for the items. The price tags can be generated with ONLY the raw price, because we do not want the VAT on them. They are simple GIF graphics that have the price printed on a an irregular polygon. Should all that graphics generating code really go into the item objects, or should we just get the price out of the object with a simple getter method and then make the tags?
    My second concern is that the more instance methods I put into my bottom level data objects the bigger they get, and I intend to have thousands of these things in memory. Is there a balance to strike at some point?
    It's not really a setter. Outsiders are not setting
    the items price - it's rather updating its own price
    given an argument. This is exactly how it should be,
    see my above point. A breach of encapsulation would
    be: another object gets the item price, re-calculates
    it using a date it knows, and sets the price again.
    You can see yourself that pushing the date into the
    item's method is much beter than breaching
    encapsulation and getting and setting the price.So the point is not "don't allow access to the members" (which after all you are still doing, albeit less directly) so much as "make sure that any functionality implicated in working with the members is handled within the object," right? Take your shopping example. Say we live in a country where there is no VAT and the app will never be used internationally. Then we would resort to a simple setter/getter scheme, right? Or is the answer that if the object really is pure data are almost so, then it should be turned into a standard java.util collection instead of a custom class?
    Thanks for the help.
    Drake

  • Java.util.Hashmap doesn't work for a custom object

    Hi,
    i have created a class named ID. I am trying to test it on a Hashmap, but the the "containsKey" and "get" operations do not work. Every operation of the main method returns as if the ID objects have not been inserted. Ideas?
    package swarm.sys.id;
    import java.util.*;
    import java.io.*;
    import swarm.sys.common.*;
    import swarm.sys.interfaces.*;
    public class ID implements IDInterface, Cloneable, Serializable
        String type;
        int body;
        String id;
        private static int idCounter=0;
        public ID(String type, int body)
          this.type=type;
          this.body=body;
          id=type+Ids.padWithZeroes(body);
        public String getType()
          return type;
        }//getType
        public String getBody()
          return Ids.padWithZeroes(body);
        }//getBody
        public int getIntBody()
          return body;
        }//getIntBody
        public boolean equals(Object o)
          if (!(o instanceof ID))
            return false;
          else
              ID id=(ID)o;   
              return (this.getType().equals(id.getType()) && 
                      this.getIntBody()==id.getIntBody());        
        }//equals
        /* factory method, which produces new IDs and afterwards
         * increments the body part
        public static ID newID(String type)
            return new ID(type,idCounter++);
        }//newID
        //implements deep cloning
        public Object clone()
            return new ID(new String(this.type),this.body);
        }//clone
        public String toString()
          return id.trim();
        }//toString
        public static void main(String[] args)
            Hashtable<IDInterface,String> table=new Hashtable<IDInterface,String>();
            table.put(new ID("PEER_",1),"x1");
            table.put(new ID("PEER_",2),"x1");
            table.put(new ID("PEER_",3),"x2");
            table.put(new ID("PEER_",4),"x3");
            table.put(new ID("PEER_",5),"x3");
            ID id1=new ID("PEER_",1);
            ID id14=new ID("PEER_",14);       
            System.out.println("table.containsKey(new ID(PEER_,1)): "+table.containsKey(id1)); //should be true
            System.out.println("table.containsKey(new ID(PEER_,14)): "+table.containsKey(id14)); //should be false
            System.out.println("table.get(new ID(PEER_,1))"+table.get(id1)); //should be x1
    }

    You need to override the hashCode() method.
    http://www.javapractices.com/Topic28.cjp

  • RE: (forte-users) tabfolder

    No, but to ask the obvious, are you deep cloning it??
    -----Original Message-----
    From: Aissa Amazzal [mailto:aamazzalaxialog.fr]
    Sent: Wednesday, July 19, 2000 5:06 AM
    To: forte-userslists.xpedior.com
    Subject: (forte-users) tabfolder
    hi,
    When i want to add the same panel to a tabfolder i used a cloned object.
    This way allow me to add dynamically the same panel several times.
    The problem is that the widgets attributes in the panel cloned have all a
    nil value.
    Any idea to resolve this problem will be appreciated.
    Aissa AMAZZAL
    Axialog Lille
    France.

    Hi Jean-Paul,
    As described in the Technote 10981 some Forte programs (Nodemanager and
    router) handle correct the high-file descriptor-use problem. It is possible
    that Forte interpreter do it correct too.
    Zenon
    -----Original Message-----
    From: Jean-Paul Gabrielli [SMTP:Jean-Paul.Gabriellisema.fr]
    Sent: Monday, September 25, 2000 12:11 PM
    To: Adamek, Zenon
    Cc: Forte-userslists.xpedior.com
    Subject: RE: (forte-users) [UNIX] "Too many open files" 3.0.M2
    question
    Actually, the stuff works in interpreted mode.
    It's only when having the server partition compiled that this happen.
    j-p
    -----Message d'origine-----
    De: Adamek, Zenon [mailto:ZAdamekpurolator.com]
    Date: lundi 25 septembre 2000 17:13
    &Agrave;: 'Jean-Paul.Gabriellisema.fr'
    Cc: Forte-userslists.xpedior.com
    Objet: RE: (forte-users) [UNIX] "Too many open files" 3.0.M2 question
    see Technote 10981
    -----Original Message-----
    From: Jean-Paul Gabrielli [SMTP:Jean-Paul.Gabriellisema.fr]
    Sent: Monday, September 25, 2000 11:02 AM
    To: zeForte-users
    Subject: (forte-users) [UNIX] "Too many open files" 3.0.M2 question
    Hi,
    running a server partition that reads a configuration file,
    and apparently doen't close it after, I have that exception:
    SYSTEM ERROR: System Error: Too many open files, opening '....'with mode
    'r'
    Class: qqos_FileResourceException
    1) Is there such a limit, or does this rely only on the OS one ?
    2) How is this error not trapped, as I only got itinteractively, whereas
    my server log does a exception trap/segmentation fault,
    thanlks
    j-p
    For the archives, go to: http://lists.xpedior.com/forte-users and use
    the login: forte and the password: archive. To unsubscribe,send in a new
    email the word: 'Unsubscribe' to:
    forte-users-requestlists.xpedior.com
    >
    For the archives, go to: http://lists.xpedior.com/forte-users and use
    the login: forte and the password: archive. To unsubscribe, send in a new
    email the word: 'Unsubscribe' to: forte-users-requestlists.xpedior.com

  • Difference between Synchronization Wrappers and Unmodifiable Wrappers

    Hi,
    I am not clear abt. the "Difference between Synchronization Wrappers and Unmodifiable Wrappers" in Collection implementation.
    How Unmodifiable Wrappers make read-only access to your data structures?
    Is it thru deep cloning of objects? If that is the case where this is mostly being used?

    You might find it useful to look at the Collections class source code in src.zip.
    It will answer both questions.
    The Unmodiferable wrapper just a wrapper, no cloning occurs. Only the collection wrapped is protected. If you have collections inside collections they will not be protected.
    The unmodifiable wrapper would be used to ensure a collection is not modified by third party code. It could be used if you return a Collection to ensure the caller does not 'accidently' modify it.

  • Getting separate copy

    I have a class that loads data from a file into a hashmap.
    The key for the hashmap is the id and the value is a object.
    As for example...following scenario
    public class Uploader(){
          private Map<String,ValueObject> map = new HashMap<String,ValueObject>();
          public Uploader(String filename){ uploadData(filename);}
          public Map get Map(){
                  return this.map();
          private void uploadData(String filename){
                 //this method uploads the data into map
    public class ValueObject(){
           //fields and methods excluded
    public class Foo implements Runnable{
          private Map<String,ValueObject> map;
          public Foo(Map map){ this.map = map};
          public void run(){  //excluded }
    public class Starter{
          public static void main(String[] args){
                 Uploader uploader = new Uploader("filename");
                 Thread foo1 = new Thread(new Foo(uploader.getMap()));
                  foo1.start();
                  Thread foo2 = new Thread(new Foo(uploader.getMap()));
                  foo2.start();
    }In the structure like above, in my main method im creating the uploader
    object once. As the uploader reads the file, i only wanna read the file once.
    And then I am creating two thread (foo1,foo2) which takes Map as parameters.
    The thread modifies the map values, however, I want the two thread to
    have a separate copy of map, so that changes mady by one thread doesnt affect the other thread map.
    How can i achieve that.
    I tried return a clone of a map from Uploader class but the clone method
    of HashMap returns a shallow copy. I tried returning like return new HashMap(map) but didnt work.
    Any help would be appreciated. Thank you.

    Well, since your requirement is to create a copy of a map that contains references to objects, where both the contents of the map and the contents of the referenced objects need to be modified independent of the original map, this is usually achieved through deep cloning.
    You can of course just create completely new objects that have the same state as the original objects and not use actual "cloning" (through Object.clone()/Cloneable interface) at all.

Maybe you are looking for