Archive for category Java Basics

Method Overloading Ambiguity Problem

While going through an article about method overriding in OOP, I stumbled upon an ambiguity problem in overriding.

Here is the java code I wrote to test it:

public class OverLoadingTest {

static void testOverload(int i,double d) {
System.out.println("testOverload 1: int, double");
}

static void testOverload(double d,int i) {
System.out.println("testOverload 2: double,int");
}

public static void main(String[] args) {

testOverload(2,3.5);
testOverload(2.5,3);
testOverload(2,3); // Compilation error:  The method testOverload(int, double) is ambiguous for the type OverLoadingTest
  }
}

In the third call testOverload(2,3), there will be a compilation error, because:

First argument 2 is int, so java compiler will decide to call the method testOverload(int,double) because its first argument is int, so it is better match than .testOverload(double,int)

Second argument 3 is also int, so java compiler will decide to call the method testOverload(double,int) because its second argument is int, so it is better match than testOverload(int,double)

As compiler will not be able to decide the right overloaded version for call, compilation error occurs.

Happy Coding !

Advertisements

Leave a comment

Java Good Practices

Here is an article on java good practices.Have a look!

1 Comment

Private Fields of Reference Type

Hi, today I stumbled upon a strange problem while wriring some java code.
There is a class with a private field of reference type, say an ArrayList. Now,what is the use of private fields? They are used so that they can not be modified from outside the class like public fields. General practice is to provide getter methods in the class to return the values of private fields.It goes fine with the primitive type variables and Strings(because Strings are immutable). But when the field is of reference type, we can still change its value.Have a look at the code:

import java.util.*;

class Aclass
{

private ArrayList list;
private String s= "My string";

public Aclass()
{
list= new ArrayList();
list.add("Hello");
}

public ArrayList getList()
{
return list;
}

public String getString()
{
return s;
}
}

public class TestPrivate
{

public static void main(String args[])
{
Aclass ob= new a();
ArrayList alist= ob.getList();
System.out.println(l2);
alist.add("Hi");
ArrayList anotherList= ob.getList();
System.out.println(anotherList);

String s2= ob.getString();
System.out.println(s2);
s2="changed";
String s3= ob.getString();
System.out.println(s3);
}
}

When you run this code,the output is:
[Hello]
[Hello, Hi]
My string
My string

You can see that content of list has been changed, but for string, they are not changed.So you can change the list object even if it is private.It is because the getList() method returns the reference to the same list object, so we can modify the list even if it is private.Now if you think that it is some loophole or bug of java,the you are wrong.It is just a simple basic concept of reference type variables.

Now, what should you do to avoid this thing. You have to modify the getList() method so that it returns the clone of list, not the actual list object.Here is the solution:

public ArrayList getList()
{
return (ArrayList) list.clone();
}

clone() will return the clone of object, not the actual list. Return type of clone() is Object, so we have to typecast it to ArrayList. Any modification done from the reference returned by this method will not change the actual one.For more information on clone() method,
go here.

, ,

1 Comment

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.

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

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

Java Exceptions: Using Exception’s Sub Classes

Syntax of try-catch

try
{
//code which throws some exception
}
catch(XException xe)
{
}
where X is type of exception.

In catch, we have to pass type of exception which is thrown by the code in above try
block.If we know the exact type of excepton thrown, we should use it in catch, as:

catch(SQLException se) {}

But what if we are not sure about type of exception thrown? Here is the solution:

catch(Exception e){}

Exception is superclass of all Exception classes. So a reference of Exception can catch all type of exceptions.
So whatever is the exception type, it will catch it and will not give any error.
To know the type of exception, we can print it:

catch(XException e)
{
System.out.println("Exception type: "+e);
}

Caution: If we are using multiple catch blocks for a single try, always put superclass before subclass, as:

try
{
// code here
}
catch(XException xe){}

catch(Exception e) {}

where XException may be any exception as SQLException,ClassNotFoundException etc.

Putting Exception before XException will produce error.

try
{
// code here
}

// this will give compilation error
catch(Exception e) { }

catch(XException xe) { }

,

Leave a comment