worker bees can leave
even drones can fly away
the queen is their slave
- Fight Club
Wednesday, June 18, 2008
Completeness in Incompleteness
Everyday reminds me of my Incompleteness.
The more I try to complete it, the more incomplete it gets.
But I try and try and try,
Only to realize that the Incompleteness is just a part of my Completeness.
The more I try to complete it, the more incomplete it gets.
But I try and try and try,
Only to realize that the Incompleteness is just a part of my Completeness.
Tuesday, June 10, 2008
Forward Referencing
The following notes are taken from Java Language Specification in reference to forward referencing of variables.
The declaration of a member needs to appear before it is used only if the member is an instance (respectively static) field of a class or interface C and all of the following conditions hold:
1. The usage occurs in an instance (respectively static) variable initializer of C
or in an instance (respectively static) initializer of C.
2. The usage is not on the left hand side of an assignment.
3. C is the innermost class or interface enclosing the usage.
Example where it needs to be taken care of
public class ForwardReference
{
int j = i;
int i = 10;
}
Here in this example all the above three conditions are met because i is used in the instance variable initializer, i is not on the left hand side of the assignment and the usage of i belongs to the ForwardRef which is the innermost class holding the variable i.
Examples where it need not be taken care of:
Example1:
public class ForwardRef
{
int j;
ForwardReference()
{
j = i;
}
int i = 5;
}
Here the usage is in the constructor and not in instance varialble initializer or instance initializer so the first rule is violated.
Example2:
public class ForwardReference
{
{
i = 9;
}
int i = 8;
}
Here second rule specified in JLS is violated, so we need not worry about it appearing before it is defined. We should be worried if i is used on the right hand side of the assignment.
Example3:
public class ForwardReference
{
class InnerForwardRef
{
int j = i;
}
int i = 5;
}
Here the usage of i is in a inner class so the third rule is violated, so the compiler will not create a problem for this.
Now we come to a very strange example where forward referencing is allowed..
public class X
{
private static int x = getValue();
private static int y = 5;
private static int getValue()
{
return y;
}
public static void main(String args [])
{
System.out.print(x);
}
}
The code above prints..zero which is quite weird in fact. Here the compiler is tricked making it think that it is a valid forward reference.
The declaration of a member needs to appear before it is used only if the member is an instance (respectively static) field of a class or interface C and all of the following conditions hold:
1. The usage occurs in an instance (respectively static) variable initializer of C
or in an instance (respectively static) initializer of C.
2. The usage is not on the left hand side of an assignment.
3. C is the innermost class or interface enclosing the usage.
Example where it needs to be taken care of
public class ForwardReference
{
int j = i;
int i = 10;
}
Here in this example all the above three conditions are met because i is used in the instance variable initializer, i is not on the left hand side of the assignment and the usage of i belongs to the ForwardRef which is the innermost class holding the variable i.
Examples where it need not be taken care of:
Example1:
public class ForwardRef
{
int j;
ForwardReference()
{
j = i;
}
int i = 5;
}
Here the usage is in the constructor and not in instance varialble initializer or instance initializer so the first rule is violated.
Example2:
public class ForwardReference
{
{
i = 9;
}
int i = 8;
}
Here second rule specified in JLS is violated, so we need not worry about it appearing before it is defined. We should be worried if i is used on the right hand side of the assignment.
Example3:
public class ForwardReference
{
class InnerForwardRef
{
int j = i;
}
int i = 5;
}
Here the usage of i is in a inner class so the third rule is violated, so the compiler will not create a problem for this.
Now we come to a very strange example where forward referencing is allowed..
public class X
{
private static int x = getValue();
private static int y = 5;
private static int getValue()
{
return y;
}
public static void main(String args [])
{
System.out.print(x);
}
}
The code above prints..zero which is quite weird in fact. Here the compiler is tricked making it think that it is a valid forward reference.
Monday, May 26, 2008
Daemon threads in Java
Threads that work in the background to support the runtime environment are called daemon threads. For example, the clock handler thread, the idle thread, the screen updater thread, and the garbage collector thread are all daemon threads. The virtual machine exits whenever all non-daemon threads have completed.
public final void setDaemon(boolean isDaemon)
public final boolean isDaemon()
By default a thread you create is not a daemon thread. All the user applications are generally started off as non-daemon threads. However you can use the setDaemon(true) method to turn it into one.
public final void setDaemon(boolean isDaemon)
public final boolean isDaemon()
By default a thread you create is not a daemon thread. All the user applications are generally started off as non-daemon threads. However you can use the setDaemon(true) method to turn it into one.
Thursday, May 22, 2008
Covariant return type
A covariant return type means changing a method's return type when overriding it in a subclass. Covariant return types were allowed in the Java language since the release of JDK5.0. I will try to illustrate the use of covariant return type using the following example.
class A
{
public List test()
{
return null;
}
}
class B extends A
{
public ArrayList test()
{
return new ArrayList();
}
}
Here we can see that the return type of the method test() in subclass B is the subclass of the return type of method test() in the superclass A.
class A
{
public List test()
{
return null;
}
}
class B extends A
{
public ArrayList test()
{
return new ArrayList();
}
}
Here we can see that the return type of the method test() in subclass B is the subclass of the return type of method test() in the superclass A.
Wednesday, May 21, 2008
Contract between the subclass and superclass
The following is an excerpt from the book 'The Java FAQ' .. "An API (application programming interface) establishes a contract of intent, not just of form or interpretation. To borrow terminology from linguistics and philosophy, an API contract involves both extension and intension: the boundaries of the current state of the world (extension) as well as the intended boundaries for other possible states of the world (intension: possible future implementations). In object-oriented programming, a common source of "possible future implementations" is subclassing from an existing class in an API.
A method defines a contract for any subclass method that would override it; it constrains possible implementations that a subclass could provide. In Java, the bare minimum contract for a method's inputs and outputs is the following:
* A method's parameter list is fixed; an overriding method in a subclass must declare precisely the same number and types of arguments.
* A method's return type is fixed; an overriding method in a subclass must declare precisely the same return type.
* The set of checked exceptions a method can throw (the method's declared exception classes and all their subclasses) establishes an upper bound. An overriding method in a subclass cannot throw any checked exceptions outside of that; it can, however, throw fewer exception types, or even none at all.
Note that the contract on exceptions concerns only checked exceptions; errors and runtime exceptions (that is, Error, RuntimeException, and their subclasses) are always permitted.
If a method, such as Object's toString method, is declared as throwing no checked exceptions, any overriding method you define must live within those bounds. You cannot define your own subclass of Exception and have your toString method throw that. In such a case, if you really need some exception to be thrown, you can resort to a subclass of RuntimeException, which is not checked or constrained by the compiler."
This description basically covers all the rules that a subclass must follow when overriding a method from superclass.
A method defines a contract for any subclass method that would override it; it constrains possible implementations that a subclass could provide. In Java, the bare minimum contract for a method's inputs and outputs is the following:
* A method's parameter list is fixed; an overriding method in a subclass must declare precisely the same number and types of arguments.
* A method's return type is fixed; an overriding method in a subclass must declare precisely the same return type.
* The set of checked exceptions a method can throw (the method's declared exception classes and all their subclasses) establishes an upper bound. An overriding method in a subclass cannot throw any checked exceptions outside of that; it can, however, throw fewer exception types, or even none at all.
Note that the contract on exceptions concerns only checked exceptions; errors and runtime exceptions (that is, Error, RuntimeException, and their subclasses) are always permitted.
If a method, such as Object's toString method, is declared as throwing no checked exceptions, any overriding method you define must live within those bounds. You cannot define your own subclass of Exception and have your toString method throw that. In such a case, if you really need some exception to be thrown, you can resort to a subclass of RuntimeException, which is not checked or constrained by the compiler."
This description basically covers all the rules that a subclass must follow when overriding a method from superclass.
Tuesday, May 20, 2008
What does a constructor do?
The constructor helps initializing the state of the object. So initially the implicit or the defined no-argument constructor of the super class is called so that the parent gets initialized in a proper manner.
One more restriction that is being imposed when a constructor is being defined is that call to any explicit super class constructor must be the first statement of all the constructors. So this might sound like a weird restriction at first but this rule guarantees the parent object to be in a valid state before the child object gets operational. This would help in avoiding the situations like this :
class Date{
public Date(){ date = setDate... }
String date;
}
// what if?
class DateViewer extends Date{
public DateViewer(){
System.out.println("The Date: " + date);
super();
}
}
Another thing that must be kept in mind while dealing with the constructors is that once you define a non-default constructor with non-zero arguments then and there the implicit constructor's definition inserted is removed from the code. So now if you have two classes X and Y such that
class Y
{
Y(int x,int y)
{
}
}
class X extends Y
{
}
Now this will result in a compilation error in the class X..Because the JVM tries to call the super() method while initializing the child object but since there is not implicit constructor for the parent class, this results in a error. Also see this amusing thread on sun forum:
http://forum.java.sun.com/thread.jspa?threadID=731805&start=0&tstart=0
One more restriction that is being imposed when a constructor is being defined is that call to any explicit super class constructor must be the first statement of all the constructors. So this might sound like a weird restriction at first but this rule guarantees the parent object to be in a valid state before the child object gets operational. This would help in avoiding the situations like this :
class Date{
public Date(){ date = setDate... }
String date;
}
// what if?
class DateViewer extends Date{
public DateViewer(){
System.out.println("The Date: " + date);
super();
}
}
Another thing that must be kept in mind while dealing with the constructors is that once you define a non-default constructor with non-zero arguments then and there the implicit constructor's definition inserted is removed from the code. So now if you have two classes X and Y such that
class Y
{
Y(int x,int y)
{
}
}
class X extends Y
{
}
Now this will result in a compilation error in the class X..Because the JVM tries to call the super() method while initializing the child object but since there is not implicit constructor for the parent class, this results in a error. Also see this amusing thread on sun forum:
http://forum.java.sun.com/thread.jspa?threadID=731805&start=0&tstart=0
Subscribe to:
Posts (Atom)