I just finished reading "Concepts, Techniques, and Models of Computer Programming" by Peter Van Roy and Seif Haridi. If you are the kind of person who thinks that "The Art of Computer Programming" and "Structure and Interpretation of Computer Programs" are good books, then you owe it to yourself to check this book out.
There is a slightly-dated version of the book available online (PDF, 3.4 MB), if you want to preview some of the content before buying it. There is also an Indian edition of the book published by Prentice Hall of India (ISBN: 81-203-2685-7) and priced at Rs 450. The book's web site links to some reviews and you can also read my review of the book.
2007-01-21
2007-01-20
Local Variables in Java
The other day I was reviewing some Java code written by a colleague. I noticed that he was in the habit of declaring all the variables used by a method at the beginning of the method body rather than in the places where they were first used. I pointed out that declaring a variable only when it is first required makes the code more readable.
While he agreed to change the style of his code, he was still reluctant to move the declaration of a variable used only within a loop from outside it to inside it. For example, he was reluctant to change:
to:
He believed that only one variable is created in the former case while 10 variables are created in the latter - clearly it is more efficient to declare a single variable outside the loop and keep reusing it inside the loop!
I then pointed out the section in the JVM specification that says that a JVM uses a fixed-size array for storing the values of local variables used in a method and each local variable maps to an index in this array. A Java compiler calculates the size of this array during the compilation of a method and declares it in the generated bytecode for the method.
Since he was still sceptical, I compiled both the variants to bytecode, used
He was finally convinced.
On the other extreme, I have another colleague who is in the masochistic habit of introducing new scopes to isolate the local variables used only in a section of a method's body. That is, something like:
While he agreed to change the style of his code, he was still reluctant to move the declaration of a variable used only within a loop from outside it to inside it. For example, he was reluctant to change:
String s;
for( int i = 0; i < 10; i++)
{
s = String.valueOf( i);
}
to:
for( int i = 0; i < 10; i++)
{
String s = String.valueOf( i);
}
He believed that only one variable is created in the former case while 10 variables are created in the latter - clearly it is more efficient to declare a single variable outside the loop and keep reusing it inside the loop!
I then pointed out the section in the JVM specification that says that a JVM uses a fixed-size array for storing the values of local variables used in a method and each local variable maps to an index in this array. A Java compiler calculates the size of this array during the compilation of a method and declares it in the generated bytecode for the method.
Since he was still sceptical, I compiled both the variants to bytecode, used
javap -c
to produce the dissassembled code and used diff
to show that the generated code was the same in both the cases (except for the indices used for s
and i
). I then used a simple modification of using the JVM Emulator Applet written by Bill Venners as a standalone application to show the bytecode variants in execution and demonstrate that the size of the local variables array really remains constant throughout.He was finally convinced.
On the other extreme, I have another colleague who is in the masochistic habit of introducing new scopes to isolate the local variables used only in a section of a method's body. That is, something like:
{
Foo x = wombat.snafu( );
// Use x here.
...
}
{
Bar y = new Bar( a, b, c);
// Use y here.
...
}
Labels:
gyaan,
programming
2007-01-11
Generics in Java and Return Types
Consider a class
While the following is allowed:
the following is not:
In the first case, callers expect to get an object implementing the interface
Consider what happens if the compiler were to allow such code to compile. Callers can then add objects of another class
A better way to define the second case is:
(You can also return an
Thanks to Steve for clearing up my muddied thinking.
C
that implements an interface I
.While the following is allowed:
I foo( )
{
return new C( );
}
the following is not:
ArrayList<I> foo( )
{
return new ArrayList<C>( );
}
In the first case, callers expect to get an object implementing the interface
I
and therefore it is correct for foo( )
to return an object of class C
. In the second case, callers expect to get an ArrayList
containing objects implementing the interface I
and therefore it should again be correct for foo( )
to return an ArrayList
containing objects of class C
, right?Consider what happens if the compiler were to allow such code to compile. Callers can then add objects of another class
X
, which also implements the interface I
, to the returned ArrayList
with the result that the original ArrayList
, which is only supposed to contain objects of class C
, now also contains objects of an incompatible class X
!A better way to define the second case is:
ArrayList<? extends I> foo( )
{
return new ArrayList<C>( );
}
(You can also return an
ArrayList<I>
instead, but that loosens up the definition of the returned object.)Thanks to Steve for clearing up my muddied thinking.
Labels:
gyaan,
programming
Subscribe to:
Posts (Atom)