I'm trying to figure out implementing the clone() method of Object. I have a class with a few data memebers that I thought I'd try it out on - a node class for a linked list.

So, here's the class:

public class HashListNode implements Cloneable
{

    private String data;
    private HashListNode nextNode;

/* other methods and such */

        public Object clone() throws CloneNotSupportedException
    {
        final HashListNode theClone = (HashListNode)super.clone();
        if( this.nextNode != null)
        {
            theClone.nextNode = (HashListNode)this.nextNode.clone();
        }
        
        return theClone;
    }
}

So, it seems that what's happening is when I call super.clone(), I'm calling Object's clone method, correct? What I don't understand, is will that method be able to deal with the String?

I can't seem to figure out if I have the hang of writing clone methods.

I am aware that it might not be too important to write one for this class, it just happened to be a simple class that was written recently.

Thanks for any help.

In this particular case it probably wouldn't make any difference as String is immutable.
If a member isn't and doesn't implement Cloneable you'll have to explicitly make a deep copy yourself.

There might be more to it, I've not used Cloneable extensively myself, but that's how I understand it to work.

In this particular case it probably wouldn't make any difference as String is immutable.
If a member isn't and doesn't implement Cloneable you'll have to explicitly make a deep copy yourself.

There might be more to it, I've not used Cloneable extensively myself, but that's how I understand it to work.

The code I posted is not thread safe, correct? Should it be made so and how would I go about doing that?

Thread safety isn't something of a single method, it's something for the entire class.
Without knowing the code for the rest of the class, it's impossible to tell whether this one is threadsafe or not.
It might be, but most likely it isn't. Just putting a "synchronized" keyword here and there isn't going to change that however, you'll need to make sure no update to one data member can happen while you're working on another one.
For example you have to ensure that noone changes that String while you're cloning the HashListNode (which also has to have thread safety in mind).

This is the entire class. I do think that it is close to being thread safe. Not that this has to be. This is just me trying to learn about thread safety. How close am I?

//GPL is here.  waste of forum space though.

/**
*A single element in a linked list specifically designed
*for hash tables
*of strings.
*
*@author    Metsfan147
*@version   1.0
*/
public class HashListNode implements Cloneable
{

    private String data;
    private HashListNode nextNode;
    
    /**
    *Constructor taking a string argument, setting the 
    *node data to that string.
    *@param x   The string to set the node to represent.
    */
    public HashListNode(String x)
    {
        this.data = x;
        this.nextNode = null;
    }

    /**
    *Sets the pointer nextNode to the next node in the linked list.
    *@param next    The HashListNode that this one should point to.
    */
    public void setNext(HashListNode next)
    {
        synchronized( this )
        {
            this.nextNode = next;
        }
    }
    
    /**
    *Accessor method that returns a pointer to the next node in the
    *linked list.
    *@return    nextElement The next node in the linked list;
    */
    public HashListNode getNext()
    {
        return this.nextNode;
    }
    
    /**
    *Changes the value of the String that this node holds.
    *@param newString   The string that the node should now represent.
    */
    public void setData(String newString)
    {
        synchronized( this )
        {
            this.data = newString;
        }
    }
    
    /**
    *Returns the string that this node represents.
    *@return data   The string contained in this node.
    */
    public String getData()
    {
        return this.data;
    }
    
    /**
    *Indicates wheter another HashListNode is 'equal' to this one.
    *@param object The object to check this one against.
    *@return Whether this node is equal to node by their String data.
    */
    public boolean equals( Object object )
    {
        boolean result = false;
        
        if( this == object )
        {
            result = true;
        }
        
        else if( object == null || this.getClass() != object.getClass() )
        {
            result = false;
        }
        
        else
        {
            final HashListNode other = (HashListNode) object;
            result = ( this.getData().equals(other.getData() ) );
        }
        
        return result;
    }
    
    /**
    * Returns a hash code value for the node.
    *@return The object's hash code value.
    */
    public int hashCode()
    {
        final int prime = 31;
        int result = 7;
        result = prime * result + ( null == data ? 0 : data.hashCode() );
        result = prime * result + ( null == nextNode ? 0 : nextNode.hashCode());
        return result;
    }
    
    /**
    *Creates and returns a copy of this object.
    *@return A clone of this object.
    *@throws CloneNotSupportedException if the clone interface 
    *is not supported.
    */
    public Object clone() throws CloneNotSupportedException
    {
        final HashListNode theClone = (HashListNode) super.clone();
        if( this.nextNode != null)
        {
            theClone.nextNode = (HashListNode) this.data.clone();
        }
        
        return theClone;
    }

}

Not even halfway there.
Different threads can still access data members at the same time, even if they can't change them at the same time.

One thread can call setData while another calls getData for example, potentially getting corrupted results.

This article has been dead for over six months. Start a new discussion instead.