home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 31
/
CDASC_31_1996_juillet_aout.iso
/
internet
/
javnl006.zip
/
JAVNL006.TXT
< prev
Wrap
Text File
|
1996-06-05
|
15KB
|
440 lines
Issue #006
June, 1996
Contents:
JavaDoc
Comparing C/C++ to Java Part 6 - Method Overloading
Introduction to Applet Programming Part 2 - Drawing
Performance - Primitive Types vs. Wrappers
JAVADOC
You may have heard of the term "JavaDoc" in relation to Java. What is
this? JavaDoc is a tool that comes with the Java Development Kit.
It's used for preparing HTML (the language of the Web) documentation
for Java classes. That is, it generates HTML code that documents a
class or package (set of related classes), including their methods,
interfaces, exceptions, class hierarchy, and so on.
JavaDoc extracts structured comments from a Java source file. For
example:
/**
* Create a hash table.
*
* @param sz initial table size in hash slots (>= 1)
* @param load_factor (average elements per slot)
* (0.25 - 10.0)
* @param growth_factor (how much to grow the table
* when load factor is exceeded) (1.1 - 2.0)
* @exception IllegalArgumentException for invalid arguments
*/
public Hash(int sz, float load_factor, float growth_factor)
{
// stuff
}
This is documentation for a constructor for a hash table class.
JavaDoc keys off of "/**" and tags like "@param". Page 182 of David
Flanagan's "Java in a Nutshell" (O'Reilly) describes the tags that can
be used.
You can run JavaDoc on individual Java source files, or on whole
packages. It generates a set of HTML files that can be used on a Web
page or with a Web browser whether connected to the Web or not. The
files have hyperlinks between related classes and methods, so that a
user can navigate easily through the documentation.
COMPARING C/C++ TO JAVA PART 6 - METHOD OVERLOADING
In both C++ and Java it's possible to have functions/methods with the
same name as other functions. For example, in C++ you can say:
class A {
public:
void f(int i) {}
void f(char* s) {}
};
and the compiler will choose the right function based on the type of
the argument given to f(). Java has a similar facility.
One question that naturally arises is how to choose the proper
function or method to call. For example, with this C++ code:
void f(short s) {}
void f(long l) {}
and a call:
char c = 0;
f(c);
it's not clear which of these functions to call, because a char could
be promoted to either a short or a long (this particular call is in
fact ambiguous in C++).
Java uses what is known as a "most specific" algorithm to figure out
which method to call. Before we explain what is meant by this, we
need to talk a bit about assignment, namely, what sorts of types can
be assigned to other types in Java. Here is an example to illustrate
this point:
public class test1 {
public static void main(String args[])
{
short s = 0;
int i = 0;
float f = 0.0f;
i = s; // OK
f = i;
s = i; // error
i = f;
s = (short)i; // OK but have to be careful
i = (int)f;
}
}
We can assign shorter primitive types to longer ones, for example
short (16 bits) to int (32 bits). We can assign an int to a float.
We cannot assign a longer type to a shorter or a float to an int,
unless we use a cast. With casting one has to be careful, because of
potential loss of precision, for example, in stuffing 32 bits into 16.
Similarly, we can assign class object references to references to a
base class, but not the other way around without casting.
Given this notion of assignment, and an actual method call, how does
Java decide which method to call? First of all, it finds all methods
that have the correct name, the correct number of parameters, and
parameters that are of types that can be assigned the values of the
arguments. If only one method matches, then that is the method that
is invoked.
If there's more than one method in the set under consideration, then
the compiler goes through and finds methods for which all the
parameter types are assignable to another method's parameter types in
the set, and removes that other method from the set of methods being
considered. The method removed is considered "less specific".
If the result of this process is a single method, then that method is
invoked. If there's more than one method left, the call is ambiguous.
To illustrate these ideas, consider another example:
public class test2 {
public static void f1(int i, int j) {}
public static void f1(int i, short j) {}
public static void f2(long i, long j) {}
public static void f2(int i, int j) {}
public static void f3(short i, short j) {}
public static void f4(double i, float j) {}
public static void f4(float i, double j) {}
public static void main(String args[])
{
int i = 0;
short s = 0;
f1(i, s);
f2(i, s);
f3(i, s);
f4(i, s);
}
}
The f1() call invokes f1(int, short) and is an exact match.
The f2() call invokes f2(int, int) because f2(int, int) has parameter
types that are assignable to f2(long, long) and f2(long, long) is
therefore removed from the set.
The f3() call is an error because an int for the first parameter
cannot be assigned to a short.
The f4() call is ambiguous because both methods can be called and
neither can be removed from the set of possible methods to call
because neither has parameter types assignable to the other.
Coming back to C++ for a moment, it's fair to say that the equivalent
argument matching rules in that language are significantly more
complicated, reflecting a more complex language in general. For
example, consider a case like:
class String {
public:
String(char);
};
where a constructor is defined to create a String from a character.
In C++, usage like:
String s(37);
is valid, with the integer constant 37 being demoted to a char and
then the constructor invoked. Whether a user intended this or not is
not clear, given that usage such as:
String s(12345);
is a problem when chars are 8 bits.
There's no magic formula for avoiding problems with method
overloading, except perhaps to follow the general rule of avoiding
cleverness. If a reader of your code can't quickly tell which method
is invoked in a given case, then it might be worth reworking the code
or at least adding a comment about its operation.
INTRODUCTION TO APPLET PROGRAMMING PART 2 - DRAWING
In previous issues we gave a simple example of an applet, and talked
about the handshaking that goes on between an applet and the applet
viewer or Web browser. As you recall, an applet is not a standalone
Java program of the sort we've presented examples of here, but instead
is a program that runs in a particular context, invoked via a Web
browser or applet viewer program.
We will continue our discussion by talking about drawing in an applet,
things like lines and boxes and colors and fonts. To illustrate these
ideas, let's look at an actual applet:
import java.applet.*;
import java.awt.*;
public class test1 extends Applet {
public void paint(Graphics g)
{
g.setColor(Color.red);
g.fillOval(20, 20, 350, 200);
g.setColor(Color.green);
g.setFont(new Font("Helvetica", Font.ITALIC, 36));
g.drawString("This is a test", 80, 120);
//g.setColor(Color.blue);
g.setColor(new Color(0, 0, 223));
g.drawRect(20, 20, 350, 200);
}
}
that is invoked via a browser or applet viewer using the HTML code:
<html>
<body>
<applet code="test1.class" width=400 height=400>
</applet>
</body>
</html>
The parameters passed in to the applet set the bounding box (400 x 400
in this example) within which the applet will function.
As we've discussed previously, an applet has no main() method, and the
paint() method is part of the handshaking protocol for an applet.
paint() is called when the applet needs to be drawn.
The first thing that paint() does is to set a color for drawing. A
color like "red" is a static data member of the Color class found in
the Abstract Windowing Toolkit (AWT) in Java. It's also possible to
specify your own color, as we illustrate later in the example:
g.setColor(new Color(0, 0, 223));
where (0, 0, 223) are red/green/blue values 0-255. This particular
color is a dark shade of blue.
After setting the color, we draw a filled oval, starting at position
(20, 20) relative to the bounding box we've established. The oval has
a width of 350 and a height of 200.
We now have a red oval on the screen, and we change the drawing color
to green and draw some text. In this example, the Helvetica font is
used and the text is drawn in italics using 36-point letters. The
string originates at (80, 120) in the bounding box.
Finally, we draw a box around the oval, using the color we've created
from RGB values.
The Graphics class in java.awt has a variety of methods for drawing
lines, rectangles, ovals, polygons, and strings, with or without
filling. There are also various methods for getting and setting colors
and fonts.
The Color class has a set of standard colors defined, and methods for
creating your own colors or querying properties of existing colors.
The Font class has similar methods for fonts, and there is also a
FontMetrics class for determining the metrics of a specified font,
such as might be used to compute the width of a string displayed in a
given font.
PERFORMANCE - PRIMITIVE TYPES VS. WRAPPERS
In Java all class types are derived from the base class Object.
Primitive types such as int or double are not class types and do not
have this property. But they do have class type wrappers, that can be
used to represent the primitive type and hence plug in to the Object
hierarchy. For example, the wrapper for int is Integer:
Integer x = new Integer(37);
Object p = x;
In this example we've taken an integer constant (37) and created a
class object instance to represent this value. The object instance
can be assigned to an Object reference and manipulated in various ways.
Wrappers have some overhead associated with them. They offer
generality at the cost of inconvenience in digging out the value:
int i = ((Integer)p).intValue();
and there are some space costs as well. To more closely examine this
latter point, we can write a program that allocates a vector of ints
or int wrappers, and compute the size of each vector element:
public class test1 {
public static final int N = 25000;
public static long freemem()
{
System.gc();
return Runtime.getRuntime().freeMemory();
}
// ints without wrappers
public static void test01()
{
long start_mem = freemem();
int vec[] = new int[N];
for (int i = 0; i < N; i++)
vec[i] = i;
long end_mem = freemem();
long n = (start_mem - end_mem) / N;
System.out.println("bytes per element = " + n);
}
// ints with wrappers
public static void test02()
{
long start_mem = freemem();
Integer vec[] = new Integer[N];
for (int i = 0; i < N; i++)
vec[i] = new Integer(i);
long end_mem = freemem();
long n = (start_mem - end_mem) / N;
System.out.println("bytes per element = " + n);
}
// driver
public static void main(String args[])
{
test01();
test02();
}
}
This program uses a system method freeMemory() that returns the amount
of memory currently free. We force a garbage collection via
System.gc() to make the figure more reliable. As we mentioned in
issue #004, this technique for determining memory use per element
should be used cautiously.
When we run this program, it reports 4 bytes used per element without
wrappers, and 16 per element with a wrapper. A wrapped double reports
as 24 bytes per element, with the actual double value as 64 bits (8
bytes). The space overhead of wrappers goes to support things like
garbage collection.
Wrappers have considerable advantages in that primitive types can be
treated in a way similar to class types. See for example the
discussion on page 243 of Arnold & Gosling's book "The Java
Programming Language" (Addison-Wesley).
But they do take extra space and time, which may be an issue in some
circumstances.
ACKNOWLEDGEMENTS
Thanks to Thierry Ciot, Irv Kanode, Mike Paluka, and Alan Saldanha for
help with proofreading.
SUBSCRIPTION INFORMATION / BACK ISSUES
To subscribe to the newsletter, send mail to majordomo@world.std.com
with this line as its message body:
subscribe java_letter
Back issues are available via FTP from:
rmii.com /pub2/glenm/javalett
or on the Web at:
http://www.rmii.com/~glenm
There is also a C++ newsletter. To subscribe to it, say:
subscribe c_plus_plus
using the same majordomo@world.std.com address.
-------------------------
Copyright (c) 1996 Glen McCluskey. All Rights Reserved.
This newsletter may be further distributed provided that it is copied
in its entirety, including the newsletter number at the top and the
copyright and contact information at the bottom.
Glen McCluskey & Associates
Professional Computer Consulting
Internet: glenm@glenmccl.com
Phone: (800) 722-1613 or (970) 490-2462
Fax: (970) 490-2463
FTP: rmii.com /pub2/glenm/javalett (for back issues)
Web: http://www.rmii.com/~glenm