Archive for category Java

Problem With clone() if Object Has a Reference Type Attribute

You might have used the clone() method of Object class to get a clone of an object.But have you ever faced a problem if your object has reference type attributes? Well, I have, and thats what I am going to discuss in this post.
A class can have two types of class level variables,primitive type (as int,float) and reference type(as List).Here is an example:

class AClass
{
int i; //primitive type
List alist; //reference type
}
For more on types, click here

Well, lets return on the original topic.When we make a clone of an object, the primitive type variables are copied in the new clone object, but for the reference type variables,only the reference is copied, not the original instance.For example, if we create the clone of above class’s object,there will be only one List object, and both object will have a reference to this.Here is what I tried:

public class ClassToClone {
ArrayList list;
public ClassToClone(ArrayList list)
{
this.list=list;
}

protected Object clone()
{
try{
return super.clone();
}
catch(CloneNotSupportedException e)
{
return null;
}
}
}

To test it:
public class TestClone {
public static void main(String args[])
{
ClassToClone c1,c2;
ArrayList arraylist= new ArrayList();
arraylist.add("Hello");
c1= new ClassToClone(arraylist);
c2 = (ClassToClone)c1.clone();
c1.list.add("Hi"); //change contents of the list of c1
System.out.print(c1.list.toString());
System.out.print(c2.list.toString()); // prints the list of both objects
}
}

When you run this program, you will see that on changing the list of c1, list of c2 is also changed and they both have the same content.
To avoid this problem, you have to explicitly clone the reference type variables. In ClassToClone, replace clone() method by this:

protected Object clone()
{
try{
ClassToClone aobj = (ClassToClone)super.clone();
aobj.s = (ArrayList)list.clone();
//explicit call to clone() for arraylist
return aobj;

}
catch(CloneNotSupportedException e)
{
return null;
}
}

Here we have explicitly cloned the arraylist.Now a new list will be created for clone object.Now changes done in c1.list do not reflect in c2.list.You can try this by yourself.But remember,clone() can be called only if the class implements Cloneable interface, otherwise we get CloneNotSupportedException.Here class ArrayList implements this interface.
Here and here is a great article to read on object cloning.

Advertisements

Leave a comment

Cloning of Objects Using clone() in Java

java.lang.Object class provides a native method clone(). Calling this method on your object will return a clone of that object.”Clone” here means what in normal world the word “clone” means. A clone object is another object having same attribute values as the original object.Here is the how to do cloning of objects:

public class ClassToClone implements Cloneable {
int i;
public ClassToClone(int i)
{
this.i=i;
}
protected Object clone()
{
try
{
return super.clone();
}
catch(CloneNotSupportedException e)
{
return null;
}
} //end of clone method
}//end of class

clone() in Object has protected access. So we have to override the clone() and call super.clone() from it(As Object is superclass of every class). To ensure that our class is cloneable, i.e. it supports cloning functionality, it has to implement java.lang.Cloneable interface.Cloneable inteface does not have any method inside it.It is just a markup interface, used to tell other classes that our class supports cloning.
Now a small note on how it works.When clone() of Object class is called on an object, a new object is created of that class and all the attribute’s values are copied from original to new object.
Now because these two objects are different,calling (obj1==obj2) will give false.
Here and here is a great article about object cloning.

Leave a comment

“Code Too Large” problem in java

Today while browsing through the internet, I found a very strange thing. I am sure it will be a very new and unknown fact for most of the java programmers, even the well experienced ones. The reason is because while working on a project, problem of this type does not occur very often. Now what kind of problem am I talking about? Well, most of you must have had a slight idea by looking at the title of the post. It says something when we have written a very large code and the compiler produces the error. Here is the snapshot of what I tried myself after reading this thing on internet:

C:\Documents and Settings\chirag.jain\Desktop>javac LargeCode.java
LargeCode.java:3: code too large
void largeMethod()
1 error

So does the java compiler enforces any limitation on the size of the code? The answer is yes, and that boundary is 65536 Bytes. This limitation is not on the size of whole file, but on a single method.
Now lets us delve a bit in the details. When we compile a java source file(.java file), compiler produces the byte code in .class file. When the size of the byte code of a single method crosses 65536 bytes, the compiler is not able to compile that method, and gives “code too large” error for that particular method.
Now here is one thing to notice. The overall size of your class file can grow more than 65536 bytes, but the byte code for a single method should not be more than this. Notice that here I am getting this error for a method named largeMethod(), not for the whole file.
Now for the folks who want to try this by themselves. First thing is how would you generate such a large amount of code. Although there are some code generation tools like Groovy, but these are for large projects. To try it by yourselves, you can do what I did. Here is my code:

import java.io.*;

class WriteFile
{
public static void main(String args[])
{
BufferedWriter bw=null;
try{
File f= new File("LargeCode.java");
FileWriter fr= new FileWriter(f);
bw= new BufferedWriter(fr);
String s= "System.out.println(\"hello\");";
for(int i=0;i<10000;i++)
{
bw.write(s);
}

bw.close();
}
catch(Exception e) { }
}
}

Here I have generated a new file using java IO API. It writes the statement
System.out.println("hello");
10,000 times in a separate file. Now you can add other things (class name, method name) to compile the program. If you write the whole code in a single method and compile it, you will get the error.

,

Leave a comment

Ways of Creating Strings in java: String Literal Pool

    String Literal Pool:

String str=”hello”;
willl go to String literal pool managed by String class and will reuse the “hello” string if it is already present, otherwise creates new “hello” in pool.
String str=new String(“hello”)
every time creates new object in heap.

Garbage collector never looks in String literal pool. String literal pool is also a part of heap memory.

So:

String s1 = “hello”;
String s2 = “hello”;
System.out.println(s1==s2);
// true.

Object s2 is the same object with s1. But if you create using new operator:

String s1 = “hello”;
String s2 = new String(“hello”);
System.out.println(s1==s2);
//false
Here is a great article about Strings.

Leave a comment

Using Scanner class to get input from user in java

java.util.Scanner class provides a way to get input from user:

Scanner scanner = new Scanner(System.in);

If input is String:

String string= scanner.nextLine();//to read input as a whole line

or

String string= scanner.next(); // to read single word

To read integers:

int i= scanner.nextInt();

Here is an article helpful on Scanner.

,

Leave a comment

Narrowing: Typecasting to Subclass

    Case 1: (ALLOWED):

Super super = new Sub();
Sub sub = (Sub) super;

It is called Narrowing.

Use:
We have an object of subclass which is referenced by Superclass reference. We don’t have any other reference to that object. Now we want to get subclass reference to that object to get access to subclass methods. Then we can perform narrowing. Here object remains the same(of subclass), what narrowing does is gives a reference of subclass to that object.

Case 2: (Gives ClassCastException at run time):


Super super = new Super();
Sub sub = (Sub) super;

Reason:
If object itself is of superclass, we can not have a reference of subclass to it. The superclass object does not have subclass specific members in its scope. So if it is typecasted to subclass, it will still have the superclass members in its scope, so there is no use of narrowing it to subclass. So it is not allowed.
Why the error is at run time, not compile time: At compile time, the compiler does not know what object the super class reference is pointing to. Compiler knows about the reference variable only.
If it points to subclass,

Super super = new Sub();

Narrowing is allowed as in case 1 above.
But if it points to same(super) class, narrowing is not allowed.

Super super = new Super();

So not knowing what the actual case is,compiler does not take any action and leaves it to run time to handle it.

,

Leave a comment

Writing a file in java

Here is the code to write a string to a file in java:

import java.io.*;
class WriteFile {
public static void main(String args[]) {
try{
String s="data to write in file";
File f=new File("a.txt");
FileWriter fwr= new FileWriter(f);
Writer wr= new BufferedWriter(fwr);
wr.write(s);
wr.close();
}
catch(IOException ie) {
System.out.print(ie);
}
catch(Exception e) {
System.out.print(e);
}
}
}

First make a reference to file to which you want to write the data:
File f=new File("a.txt");
Here, in place of .txt, we can use any file extension as .srt,.xml,.doc etc

Then, create a file writer,
FileWriter fwr= new FileWriter(f);

Then, make a writer to write to the file:
Writer wr= new BufferedWriter(fwr);

then, call write function and pass the string:
wr.write(s);
Always remember to close the writer, otherwise it won’t write to the file:
wr.close();

We have to catch the exceptions thrown by the API methods also. To know more about exceptions, go to Java Exceptions

Leave a comment