Archive-name: computer-lang/java/programmers/faq
Posting-Frequency: twice-weekly
Last-modified: 1998/2/28
URL: http://www.afu.com/javafaq.html
Copyright: (c) 1997,1998 Peter van der Linden
Maintainer: Peter van der Linden
_____________________________________________________
________| |________
\ | Java Programmers FAQ http://www.afu.com | /
\ | Copyright (c) 1997-98 Peter van der Linden | /
/ |_____________________________________________________| \
/___________) (__________\
The Java FAQs here are intended for people who already know how to program
in some language (not necessarily Java though).
The most up-to-date copy of this FAQ is available at: http://www.afu.com/ in both HTML and text forms. It reflects the latest and most current FCS version of Java: JDK 1.1.5.
The contract in which Sun licensed its Java source code to Microsoft requires Microsoft's derivative product to pass the Java compatibility test suite. Sun charges Microsoft with breaking this contract, and is suing Microsoft. The contract clause that Microsoft is alleged to have broken is described at http://www.afu.com/contract.html
Here is a link explaining why Java portability is important. The best way for programmers to support portable Java is to reject non-standard tools. Please avoid Microsoft near-Java tools.
Free standard Java compilers can be downloaded from
http://java.sun.com.
Free standard Java Virtual Machines can be downloaded from
http://www.kaffe.org.
and
http://www.redhat.com/linux-info/jolt
Free Java AWT software can be downloaded from
http://www.biss-net.com/biss-awt.html and the
files are all at ftp.blackdown.org (the linux site) too.
Free Java software can be downloaded from
http://www.gnu.org/software/java/java.html
5. CORE LIBRARIES
6. I/O
7. NETWORKING & DISTRIBUTED
OBJECTS
8. MULTI-MEDIA
9. SECURITY
10. Java IDIOMS
11. FOR C and C++ AFFICIONADOS
12. FURTHER RESOURCES
13. TOP TEN NOVICE PROBLEMS
-------------------------------------------------------------------------
"Just Java 1.1" Programming in Java, for people who can already program in another language. More info at http://www.amazon.com/exec/obidos/ISBN%3D0137841744
"Not Just Java" Java explained for managers. More info at http://www.amazon.com/exec/obidos/ISBN=0138646384
Further, by submitting Java specifications to be ISO/IEC standards, Sun is giving up some control in exchange for the world being able to refer to a Java specification that is guaranteed to be open by ISO/IEC's charter and rules.
Sun Microsystems has invested significant time and money to create a Java implementation. It has licensed, for a fee, the results of this work (the source code for the implementation) to 117 companies and organizations who have asked for it, including competitor Microsoft. Sun has also allowed free download and use of the Java implementation (binary executables) by anyone. Over 2 million computer users have downloaded the JDK binaries for free in the twelve month period to December 1997.
1.1 What
is the best way to refer someone to the FAQ when they ask question I know
is answered there?
This gives them the answer, and shows them where to go for future questions It also demonstrates that the FAQ can answer their questions, supplying an incentive to go there next time. It's regarded as elementary politeness to look for the FAQ of a newsgroup and read it, before posting any questions.
In general, FAQS for any newsgroup are available by looking at past postings in a group, or by searching Deja News (see Q 1.4), or via anonymous FTP at directories under ftp://rtfm.mit.edu/pub/usenet/.
If you do not have anonymous FTP access, you can access the
rtfm.mit.edu archives by mail server as well. Send an E-mail
message to mail-server@rtfm.mit.edu with "help" in the body
for more information. "RTFM" stands for "Read The F*ing Manual" -- you
must expect to put in some time and effort to master a new area of study.
1.2
Where can I look at the definitive Java Language Specification?
1.3 Where can I find a full list of Java books and book reviews?
1.4 How do I search Deja News for past postings on Java topics, e.g. the FAQ?
nnn Documents (nnn is some number).
Also look at http://sunsite.unc.edu/java/cgi-bin/query
and look at http://asknpac.npac.syr.edu/
for Java newsgroup search
http://www.javaworld.com/search.html
can search the Javaworld newspaper
Note that only bugs that Sun deems "important" are listed there. The criteria for "important" are not published.
After you have checked whether the bug is already listed, you can submit
a bug report through:
http://java.sun.com:80/cgi-bin/bugreport.cgi
You can even send in an RFE or ease-of-use issue there!
You can even vote on the priority you would assign to a particular bug fix! Join the Java developer connection (it's free!) by going to http://java.sun.com and then searching for "Developer Connection". Then browse webpage http://developer.javasoft.com/developer/bugParade/#votes
If you go to the JDC (that's the Java Developer's Connection) you can do a keyword search against the internal Javasoft bugtraq database, looking by keyword or bug number. JDC has free registration.
1.6 Is there a Java port to Windows 3.1?
You could also consider JavaSoft's JavaPC $100 kit that converts a PC into a thin client Java system. Details are sparse as yet, but this is probably more for business users than personal PCs.
1.7 I see a lot of postings from magazines soliciting Java articles. Are these legitimate?
Another programmer reported that he was not paid by Sys-Con for an article for their Delphi magazine. There is a pattern of programmers complaining that SYS-CON has not paid them.
The issue is that Sys-Con will only pay for articles that it actually prints, even when it explicitly commissioned the article from you. Programmers expect publishers to pay a cancellation or "kill" fee when they don't run a work they have commissioned. Programmer beware, and please don't support magazines that are in conflict over payment with their programmer contributors.
1.8 What are the good folks at project Gnu doing with Java?
1.9 Where can I find information about Java Certification?
1.10 I'm looking for a Java style guide on naming conventions.
1.11 Where can I find information about future Java APIs?
1.12 How can I find links to recent news about Java?
This site is a source of independent news and commentary on the computer industry, including Java. http://www.pjprimer.com/media.html. (You have to subscribe ($10/year, 30 day free trial).
1.13 What computers have Java ports?
1.14 What IDEs (Integrated Development Environments) are there?
| Apptivity 2.0 (Progress) | http://www.apptivity.com |
| Java WorkShop 2.0 (Sun) | http://www.sun.com/workshop/java |
| Javelin 5.03.7 (Step Ahead SW) | http://www.ozemail.com.au/~stepsoft |
| JBuilder (Borland) | http://www.borland.com/jbuilder |
| Kawa 2.52.01 (Webcetera) | http://www.tek-tools.com/kawa |
| PARTS alpha (ObjectShare) | http://www.objectshare.com |
| PowerJ ? (Sybase) | http://www.sybase.com/products/powerj |
| Super Mojo 1.2r2.4811 (Penumbra) | http://www.penumbrasoftware.com |
| SuperCede 2.0 (Asymetrix) | http://www.supercede.com |
| teikade 1.8R2 (PFU Ltd) | http://www.pfu.co.jp/teikade |
| Together Java ? (?) | http://www.oi.com |
| Visaj 1.0.1 (Imperial SW Tech) | http://www.imperial-software-tech.co.uk |
| VisualAge 1.0 (IBM) | http://www.software.ibm.com/ad/vajava |
| Visual Cafe 2.1 (Symantec) | http://cafe.symantec.com |
| Visual J++ (Microsoft) | (non-standard; not recommended) |
| Xelfi 0.94 | http://www.xelfi.com |
| GRASP | http://sw-eng.falls-church.va.us/public/PAL/ada/swtools/grasp/ |
1.15 Where can I find information on Java 3D?
Also see the Runtime methods freeMemory() and totalMemory().
2.2 Why do I get a "Statement not reached" error from javac for no apparent reason?
2.3 Is there a lex and yacc or preferably a flex and bison equivalent for Java?
LALR(1) parser
2.4 Where can I find a byte code obfuscator?
Some people have reported problems using these with JDK 1.1.
This obfuscator has been updated to be fully compatible with JDK 1.0 and 1.1:
2.5 Which program is used to create .zip files compatible with the java* programs? (eg classes.zip, moz3_0.zip)
On Unix you can also use:
Netscape's command line version of its JAR packager and signing tool is called "zigbert". They also have a signing tool with GUI written in Java. More info at:
3. Put the archive in the same directory as the .html page;
4. Put something like the following tag in the .html file:
2.6 Can I compile a Java .class file to a binary executable, .exe on a PC?
C is much simpler. The only question here is how structures are "packed" (i.e., are integers aligned on four-byte bounds?). All the C++ compilers can interact with C code, thanks to 'extern "C"' declarations.
Consider carefully why you want to compile to a native executable, and whether there is a Java way to accomplish your goal. There may be a good reason for compiling to native code, but it needs to be thought through.
2.7 How can I performance profile my Java code?
produces some basic output in a file called java.prof, showing the
number of times methods were invoked. The output lines are of the form:
| # of calls | method called | called by | time spent |
2.8 When I use javadoc and I click on any java
class included in the jdk why do I get this message?
Netscape
is unable to find the file or directory named:
A. References to the JDK classes assume that *all* generated html files are in the same directory and, in fact, that all files for all classes referenced are generated at the same time. There is no way to generate files incrementally and have them all reference each other, as you would like.
As long as you have source for everything involved (including the JDK and all third-party classes), you can list all of your packages and all of the others on the javadoc command line and generate the whole set at once, but it is burdensome. Of course, if you receive any libraries as .class files, even this workaround will not suffice.
Also javadoc will not generate the image files - you need to get them from the images directory under the JDK API documentation files. You can just copy the entire directory into your own doc directory. javadoc is a very nice concept, with a few implementation flaws.
Without the "-depend" option, the standard "javac files" doesn't look beyond the immediately adjacent dependencies to find classes lower down the hierarchy where the source has changed.
The -depend options searches recursively for depending classes and recompiles it. This option doesn't help when you have dynamically loaded classes whose names cannot be determined by thecompiler from the dependency graph. E.g. you use something like
Class.forName(argv[0]);The author of the code using those classes should make sure that those classes are mentioned in a Makefile.
2.10 Why do I get the java.lang.UnsatisfiedLinkError when I run my Java program containing Native Method invocations?
On Windows 95/NT, make sure that the DLL exists in a path that is included within the PATH environment variable.
On Solaris, make sure that the environment variable LD_LIBRARY_PATH includes the path of your shared library.
public class MyDialog {
void Setup() {
addWindowListener( new WindowAdapter() {
public void windowClosing(WindowEvent e) {
myCloseWindow(); } }
); // anon inner class
}
void CloseWindow() { // outer method
dispose();
}
}From JDK 1.1.2 on, it is generally an ERROR if the user sets the CLASSPATH to include classes.zip. CLASSPATH is still needed to point to the roots of the programmers own packages, and the use of rmic apparently still requires it, too.
Java does not have pointer arithmetic or untyped casting. By removing the ability for programmers to create and modify pointers in arbitrary ways, Java makes memorymanagement more reliable, while still allowing dynamic data structures. Also note that Java has NullPointerException, not NullReferenceException.
A linked list class in Java might start like this:
public class linkedlist {
public linkedlist head;
public linkedlist next;
public Object data;
public linkedlist advanceToNext(linkedlist current) { ...
... }
Another choice for a linked list structure is to use the built-in class
java.util.Vector which accepts and stores arbitrary amounts of Object data
(as a linked list does), and retrieves it by index number on demand (as
an array does). It grows automatically as needed to accommodate more elements.
Insertion at the front of a Vector is a slow operation compared with insertion
in a linked list, but retrieval is fast. Which is more important in the
application you have?
3.3 What
is the true story about how parameters are passed in Java? Is is by value
or by reference?
Bottom line: primitive type arguments (int, char, etc) _do not_ change when the corresponding parameter is changed. The fields of object type arguments _do_ change when the corresponding parameter fields are changed.
The second alternative is a clearer variant of this. Pass in a single element array. Since arrays are objects, this works.
void jfoo(Object ref[]){
ref[0] = new Object();
}
...
Object kludge[] = new Object[1];
kludge[0]= myObj;
jfoo(kludge);
if (kludge[0] == myObj) ...
else ...
3.5 Why
is String a final class? I often want to override it in some way.
The simplest is that being final guarantees that instances of String
are immutable. (The String class implements immutable objects, but if it
were not final it would be possible to write a subclass of String which
permitted instances to be changed.) But that's an unsatisfying answer,
because the real question is "Why must Strings be immutable?"
One reason is efficiency. It's easier to optimize accesses to an object
that is known to be immutable. Strings are very commonly used, even used
behind the scenes by the Java compiler. Efficiency gains in the String
class can yield big dividends. If no one can change a String, then
you never have to worry about who else has a reference to your String.
A more compelling reason is security. Before String was changed to be final (while Java 1.0 was still in beta) there was a race condition which could be used to subvert security restrictions. It had to do with having one thread change a pathname while another thread was about to open it.
There are other ways to solve these problems, but making String final is the one that the designers chose.
3.6 What happened to "private protected"?
The official story is that it was a bug. That's not the full story. Private protected was put in because it was championed by a strong advocate. It was pulled out when he was overruled by popular acclamation.
3.8 Why does <unexpected> happen in Java floating point?
If you seem to be having problems with floating point, your problem probably stems from the fact that floating-point arithmetic is inherently imprecise. You can expect up to 7 digits of precision with floats and 16 digits with doubles. However, that does not mean that a number that can be exactly represented in 7 digits decimal, can be exactly represented as a binary floating point number. On the contrary, that is usually not the case.
Additionally, when Java converts floating point numbers to a String, as is done when they are output, enough digits are printed so the number can be read back in with no loss of precision. For this reason, you may see more "inaccuracies" in floating point output than you are used to. This policy actually gives you more consistent results than on a system where floating point output is deliberately rounded to make the output "pretty".
There is a limitation of FP in JDK 1.0 (fixed in JDK 1.1). Namely, when you output a floating point number in Java 1.0, the result is system-dependent and contains no more than six digits after the decimal point. This bug is fixed in Java 1.1.
For more information and detailed specifications on how Java deals with floating point, see the following URLs:
3.9 Why do I get the compiler error message
URL test;
try { test = new URL("http://osprey.avs.dec.com");
} catch (MalformedURLException e) {
System.out.println("bad URL:" + e.getMessage());
}
System.out.println("this is url " + test);
A. If an exception is raised in the try clause,
test will not be given a value, yet you are using it in the catch clause.
The solution is to declare test with an explicit initial value of null.
3.10 Why do I get this compiler error message?
public static void main(String[] args) {
^
Statement expected.
public static final float Conversion_Factor = 39.37;
^
Type expected.
A. A. Argument declarations and variable declarations
inside methods are never given the "public", or "static" keywords. They
are not public or static because they are local to a method. (They used
not to be allowed the "final" keyword either, but there was not good reason
for that restriction and it was dropped in JDK 1.1). Move your public or
static declarations outside the method. They are usually put at the beginning
of the class.
3.11 Why do I get this compiler error message?
MyApplet.java:11: No constructor matching MyCheckbox(myApplet) found in class MyCheckbox. bp1 = new MyCheckbox(this); ^ 1 errorA. The first thing to check is whether you gave a return value to the constructor, like this:
public void MyCheckbox( Container parent )If you did, the compiler will think it is an ordinary method, not a constructor. This is a very common mistake, and quite hard to spot. 3.12 Why do I get the compiler error message
T.java:96: Can't access protected method clone in class java.lang.Object. OtherT is not a subclass of the current class.
This means that a method can clone its own objects, but a method cannot clone objects of another class, unless you do something like:
class SomeObject implements Cloneable {
public Object clone()
throws CloneNotSupportedException {
return super.clone();
}
}
[i.e. override clone to make it public, and call the superclass clone].
class Foo {
Bar bar;
Foo (Bar b) {
try {bar = (Bar) b.clone();}
catch (Exception e) {}
}
...
class Bar implements Cloneable {
public Object clone()
throws java.lang.CloneNotSupportedException{
return super.clone();
}
}
3.13
How
do you transform a char into the corresponding int value, that represents
the code value of the char?
Going the other way is just
c = (char) i;This question crops up so frequently because the BASIC language uses functions to map characters into ints, ASC( 'A' ) => 65 causing BASIC programmers to seek the corresponding Java functions. Pascal and Ada have similar functions, and no doubt other languages too. 3.14 If I extend a class with a subclass, are the constructors inherited?
If you don't give your child class any constructors, a default no-arg constructor that invokes the superclass' constructor is provided for you. If the superclass doesn't have a no-arg constructor, see 3.7
3.15 How do I allocate a multidimensional array?
int arr[][] = new int[4][5];If you want each row to have a different number of columns, you can use the fact that a two-dimensional array is actually an array of arrays. The following code allocates a triangular array:
int arr[][] = new int[4][]; // allocate the four row arrays for (int i = 0; i < 4; i++) // initialize each of the four rows arr[i] = new int[i + 1]; // row i has i + 1 columnsNote that if you allocate an array of any kind of object (as opposed to primitive type), all the references will be null by default. These null references can result in NullPointerExceptions if you try to dereference them.
In other words, after doing:
int arr[] = new int[4];you can say "if (arr[2] == 0)"
But after doing
Integer Iarr[] = new Integer[4];you must fill in the object reference before using it, with e.g.
Iarr[2] = myInt;or
Iarr[2] = new Int(27);before you can say "if (Iarr[2].equals(myInt))"
3.16 Does it make a difference to the class file in any way, if I import a package, versus use the full name, i.e.
import java.rmi.server.*; RemoteObject ro;versus:
java.rmi.server.RemoteObject ro;A. No, it makes no difference to the class files. Import is just a shorthand for quoting the full name package and class name (as in the examples in the question). Importing a class does not cause the class to be loaded at run time. There is no run time penalty for using the * form of import. The class file will contain the name of the packages it uses, and the loader will look for those classes as needed at runtime.
The different forms of import may or may not make a difference to compile time. Such a difference is likely to be negligible, and should not be a factor in which form of import you use.
Some people say that stating which classes you are importing can help
program readability. In a program with many * import statements, it may
take a programmer time to find which package an obscure class is imported
from. If you explicitly list each class you import at the top of the
program, you document which package each class you use comes from.
These people suggest that you use
import java.rmi.server.RemoteObject;in preference to:
import java.rmi.server.*;Other people say that it is clearer still to use the full package and class name, at the point where you use classes in other packages. These people suggest that you use:
java.rmi.server.RemoteObject ro;But that gets a little lengthy when you instantiate:
java.rmi.server.RemoteObject ro = new java.rmi.server.RemoteObject();You always have the option of stating the full package and class name, whether you use import or not.
Another good reason not to use the * form is when you are importing two packages that have classes of the same name and you want to use only one of those classes. E.g.
import com.sun.*; import com.ms.*;where there is a class called SerialPort in both those packages. If you use the * form of import, you import both of the SerialPort classes and then must fully qualify the class each time you use it, to say which of the two you mean.
In Java 1.0, if you import a class that has the same name as a class defined in that source file, you will get an error that the class names clash. In Java 1.1, the local class will be used when the package name is not given; use the package name of the imported class to use it.
The best advice is to write the program so that it is as readable as possible. Where you have a group of well known classes, as in java.awt, there is no reason not to use "import java.awt.*;"
3.17 What are "class literals"?
Class myCl1 = Character.class; Class myCl2 = Void.class; Class myCl3 = Object.class; Class myCl4 = String[].class; Class myCl5 = int[][].class;You might use it like this:
Class cl = thing.getClass();
if (cl.equals(myCl1))
System.out.println("It's a Character class");
A class literal
Component.classis the equivalent of
Class.forName("java.awt.Component")
The second can throw an exception, but the first cannot. If you don't know
the name of the class when you write the code, you cannot use the first
form.
3.18 How do I copy the contents of an array (with primitive type contents) to another array?
Note that there is no corresponding method to clear an array to 0.0, 0, null, false, '\u0000' etc (except for allocating a new array, which will have the default initializations). This has lead several people to suggest the old COBOL trick of "initialize by rollup". In initialize by roll-up, the programmer sets the first element of the array to the desired value, and then moves elements array[0 to n-1] to array[1 to n]. Under some old IBM COBOL compilers, code was generated to move element 0 to 1, then 1 to 2, and so on, "rolling up" the desired value through the array. It was always a terrible idea, as it went outside the boundaries of defined behavior in COBOL, and was subject to being broken in any compiler release.
In any event, intialization by roll-up is defined not to work in Java. If the src and dst arguments refer to the same array object, then the copying is performed as if the components at positions srcOffset through srcOffset+length-1 were first copied to a temporary array with length components and then the contents of the temporary array were copied into positions dstOffset through dstOffset+length-1 of the argument array.
If you simply want to clear the same array to the same value many times, create two arrays. Fill one with the reset value, then use System.arraycopy to copy it into the work array each time you need to clear the work array.
3.19 What is a fast way to set all elements of an array to a given value without duplicating the (possibly large) array?
A fast way on many VM's is to set the first byte of the array, then
use System.arraycopy repeatedly to fill the next byte, the next two bytes,
the next four bytes, the next eight bytes, etc. (Note these are not overlapping
slices, so the issue raised in Q3.18 does not
arise).
public static void bytefill(byte[] array, byte value) {
int len = array.length;
if (len > 0)
array[0] = value;
for (int i = 1; i < len; i += i)
System.arraycopy( array, 0, array, i,
((len - i) < i) ? (len - i) : i);
}
This is faster on Sun's VM than a simple loop, and probably faster even
under JITCs because it only performs log2(array.length) bounds-checks at
most. This is a clever code idiom applying the binary chop algorithm to
arrays whose size is not a power of 2.
3.20 Is there some declaration that I can use to make "acos", "cos", "sin", etc. (from java.lang.Math) recognizable in my own class, so I don't have to prefix "Math." to them?
double sin(double x) {
return Math.sin(x);
} // etc. for each function
If your class does not extend another class, you could make it extend Math,
to bring the namespace in, but this is very poor OOP style.
If the Math class provided a public constructor -- which it does not -- you could instantiate a local copy of Math with a shorter name, e.g. "M". There is a cheating way to do this which works because all the methods are static. Declare
java.lang.Math M = null;
angle = M.cos(i);
If java.lang.Math were not final and your class did not extend another class, you could have your class extend Math, to bring the namespace in. However, the final prevents this and it is very poor OOP style to use inheritance to obtain a trivial name abbreviation (rather than to express a type hierarchy). The import stament only imports packages, subpackages, and classes. Members of classes are not imported, so
import java.lang.Math.*;doesn't work.
3.21 Why does b >>>= 1 give me the same result as b >>= 1?
The ">>>" operator is an "unsigned" or "logical" shift; it does a shift right and zero fill. However, there are a couple of places where ">>>" looks like it does a signed shift!
The issue occurs when you have a non-canonical type, byte, or short, with a negative value, e.g.
byte b = -15; // 0xF1 b = (byte) b >>> 4; // why isn't b 0x0f ?The initial expectation is that an unsigned shift right of 0xF1 would successively be (in binary) 0111_1000 then 0011_1100 then 0001_1110 then 0000_1111
But that doesn't happen. The rules of arithmetic in Java say that all operands are converted at least to int before the operation (and possibly to a more capacious type). That means our byte is promoted to an int, so instead of shifting 0xf1, we are shifting 0xfffffff1. If you shift right unsigned 4 places, you get 0x0fffffff. When you cast that to a byte it becomes 0xff, or -1.
The bottom line is that the final result is the same as if you'd performed the signed shift because the unsigned shift applied to the intermediate int, not to the original byte. This anomaly means that ">>>" is useless for negative bytes and shorts. It is probably safer and clearer not to use it at all, but to mask and shift like this:
// not recommended
byte b = -15;
b = (byte) (b>>>4);
System.out.println("b= "+Integer.toHexString(b) );
// recommended
b= -15;
b = (byte) ( (b & 0xFF) >> 4 );
System.out.println("b= "+Integer.toHexString(b) );
3.22 How do I compare two Strings together?
if (s1 == s2)is giving me funny results.
A. The comparison using "==" on objects, like Strings, is asking the question "do these two objects have the same reference?". That is, do they have the same address, and hence are the same object? What you really want to do is ask "do these two Strings have the same *contents*?"
You do that with any of (and there are others too)
if (s1.equals(s2) )
or if (s1.equalsIgnoreCase(s2) ) or if (s1.startsWith(s2) ) or if (s1.endsWith(s2) ) or if (s1.regionMatches(s1_offset, s2, s2_offset, length) ) or if (s1.compareTo(s2) < 0)Note that you can do this with literals:
if ("apple".equals(s2) ) ...
If you compare these the other way round, like this:
if ( s2.equals("apple") ) ...
and s2 is null, you will get a null pointer exception. Be alert to this.
3.23 How can I be type-safe without having to create a multitide of subclasses (IntegerLinkedList, StringLinkedList, etc.)?
A. Generic programming in java (the rough equivalent of C++'s templates) works reasonably well since all java classes are subclasses of Object. There is, however one potential problem - there is always a possibility that a generic container may contain different classes of objects.
This naturally leads to the question of how to do this in a type-safe way. If you've created a generic LinkedList class, how can you be type safe without having to create a multitide of subclasses (IntegerLinkedList, StringLinkedList, etc.)?
One way to handle this would be to offer up an additional constructor in your generic class that takes a parameter of type "Class" and uses that parameter along with Class's "isInstance" method to guarantee that Objects added to the container are the expected type.
public class LinkedList
{
protected Class type = Object.class;
public LinkedList(Class type) { this.type = type; }
public void addElement(Object element) throws Exception
{
if(!type.isInstance( element ))
throw new Exception(
"Expected element of type (" + type +
") got element of type (" + element + ")");
...
}
}
Note that the comments in the source for isInstance() refer to
a "specified Class parameter", suggesting that you are supposed to
write something like:
public void addElement(Object element) throws Exception
{
Class c = element.getClass();
if(!type.isInstance(c))
This works, but the
documentation for isInstance is clear that
the parameter should be an Object rather than a Class.
Also, be aware of "Collections" that are coming in JDK 1.2. More
information about this is available at the Java Developer Connection
at the Java website http://java.sun.com.
3.24 Why is there a standard JNI?
A. JNI is the Java Native Interface. It defines the way that a Java program can call C programs. The industry has agreed on, and Sun has codified, JNI as the standard. Microsoft shuns the standard and uses a protocol of its own called Raw Native Interface, RNI.
You might think that once a Java program uses JNI, portability is lost, and hence it doesn't matter if vendors diverge from the JNI standard. However, it does affect programmers and especially end-users. When you use native code, you lock your program into one platform (and other platforms if you port the native code). But programs that use native code should still be able to use a JVM, and other Java tools and libraries from any vendor. This is possible when everyone uses the same native code interface.
Microsoft's non-standard RNI is the reason that programs using the Microsoft JVM cannot use the standard Java jdbc-odbc library. That library has a piece written in C. It works for all JVM's except Microsoft's.
JNI thus has two purposes:
3.25 What are the naming conventions in Java?
A. The naming conventions are straightforward:
3.26 What are the differences between an interface and an abstract class?
A. The principal difference is that an abstract class is used when you have a type/subtype relationship. An interface does not imply a type/subtype hierarchy; it merely forces a class to have some methods with a given signature. That allows some other code to rely on being able to call those methods.
You want to subclass abstract classes when you are making subtypes that define the abstract behavior. The subclass should have a "kind of" relationship to the superclass. A user record is a kind of record, a dog is a kind of mammal, etc. Inheritance provides a "kind of" relationship.
By way of contrast, an interface provides a "plays the role of" relationship. An image loader could play the role of an Observable thing. Just about any class could play the role of a "sortable thing". Interfaces therefore often have a name that is a "something-able thing". A class may only extend one other class, but it can implement an arbitrary number of interfaces.
Abstract classes can have abstract methods and they can also have fully defined members. Interfaces can't have any code in them at all, though they can have final data. Another minor difference is that calls to a subclass method are faster than calls to an interface method (because the interface method involves a bit more lookup at runtime about what is actually being called).
A. Static (per-class, rather than per-object) methods do not participate in overriding (choosing the right method at runtime based on the class of the object). Probably the best and simplest way to think about this (and to write your code) is to write every invocation of a static method using the fully qualified class name so:
class A {
public static method1() {
A.method2();
}
public static method2() {
}
}
class B extends A {
public static method3() {
A.method1();
}
public static method2() {
}
}
Now it is perfectly clear that the static method2() that is called is
A.method2(), not B.method2(). This is true regardless of whether you use
the fully-qualified class name or not, but the use makes it obvious to all.
3.28 How do I get unsigned ints in Java?
A. Java doesn't have unsigned ints. The reason is that this is a very murky area of C -- the rules for what type you end up with when you mix signed and unsigned in expressions are horribly complex in C -- and they changed between K&R and ANSI C. (you might have heard this under the soubriquet "unsigned preserving vs. value preserving"). And, they depended on the underlying hardware, so they *varied* from platform to platform, causing bugs in all kinds of unexpected places. The book "Expert C Programming" has some examples (pages 25-29). All that horror is behind us now, with Java.
Use type char if you are ok with 16-bit unsigned quantities. Otherwise go to the next larger type and use masking. Specifically, to convert an int to its unsigned representation, use:
((long)i) & 0xFFFFFFFF
This promotes the signed int to long and chops off the sign-extension,
leaving it as an unsigned 32-bit quantity.
Also worth noting is that if you're going to work with unsigned bytes, int is a more efficient larger type to use than short or char, since smaller values have to be promoted to int to do any arithmetic or testing on them.
3.29 How do I send a variable number of arguments to a method, or get multiple return values back?
A. (Easy) Use method overloading to support different parameters. This makes things easy on the caller but can get out of hand if you want to support a wide number and variety of parameter types. You should ask yourself if your code design is well-organized if you need to do this.
(More complicated) Use arrays. It's possible to declare arrays inline as shown below:
foo("A param", new Object[] {"param3", "param4", new Integer(5)} );
// ...
void foo(String param1, Object param2[]) {
System.out.println(param1);
for (int i = 0; i < param2.length; i++) {
System.out.println(param2[i].toString());
}
}
You can even pass arrays of arrays using this method. Of course,
inside the method you need to be able to decode what the arguments are
and how you use them. Alternatively you can invent a class that
just contains all the possible fields you might want to pass into a
method (plus booleans to say if each field is set or not), and make
an object of that class be a parameter to the method.
You can return multiple values from a method the same ways; either have the method return an array or a wrapper object.
Remember the wise words of Prof Alan Perlis however, "if your procedure has more than about half a dozen parameters, you probably forgot a few." Perlis meant that passing large numbers of arguments into a function suggests that your function is badly-organized.
java.lang.NullPointerException at sun.awt.motif.MFramePeer.<init>(MFramePeer.java:59) at sun.awt.motif.MToolkit.createFrame(MToolkit.java:153) at java.awt.Frame.addNotify(Frame.java) at java.awt.Window.pack(Window.java)A. There's a missing font on your system. Move font.properties from the "lib" subdirectory aside to font.properties.bak Then it won't look for the font and fail to find it.
The problem occurs because the Motif AWT libraries use the Font "plain
Dialog 12 point" as a fall-back default font. Unfortunately, when using
a remote X server sometimes this font isn't
available.
On an X-terminal, the diagnostic may be slightly different, a segv
% appletviewer HelloWorldApplet.html SIGSEGV 11* segmentation violation si_signo [11]: SIGSEGV 11* segmentation violation si_errno [0]: Error 0 si_code [1]: SEGV_ACCERR [addr: 0x14]To determine which fonts you have, issue a command such as
SpringLayout was to be introduced as part of the Java Foundation Classes with JDK 1.2, but it was dropped from the beta release as the code was not ready in time. Javasoft generously made the preliminary code available and invited programmers to hack on it and submit the results.
4.0.3 How do you change the font type and size of text in a TextArea?
On both Windows 95 and Solaris 2.6, these fonts
import java.awt.*;
class foonly {
static public void main(String s[])
{
String n[]= new Frame().getToolkit().getFontList();
for (int i=0;i<n.length; i++)
System.out.println(n[i]);
System.exit(0);
}
}
In other words, You can get a String array of the names of the fonts by
String[] fonts = Toolkit.getDefaultToolkit().getFontList()4.0.7 Is it possible to draw a polygon or a line more than 1 pixel wide?
There is a useful class at http://www.apl.jhu.edu/~hall/java/GraphicsUtil.html It extends the drawxxx and fillxxx methods of java.awt.Graphics. It adds a Line Width argument to most of the drawxxx methods, a Color argument to most of the drawxxx and fillxxx methods, and a Font argument to draw String and drawChars.
In JDK 1.1 the z-order of components ("z-order" means "front-to-back" order, i.e. which window is in front of which) can be controlled by using the the method add(Component comp, int index). By default, components are added 0 to N. The method paint of class Container paints its visible components from N to 0.
4.0.10 What is the difference between
If you are in a constructor or an event handler (e.g. "click here to turn the canvas blue") you have a Component and should use the setForeground() method. If you are in a paint() method, that takes a Graphics context as its argument so you will typically use g.setColor(c).
Unlike a Component, a Graphics object doesn't have a background color
and a foreground color that you can change independently. A Graphics object
arrives in the color(s) inherited from the drawing surface. From then on,
any rendering (drawLine(), drawRect(), fillOval(), etc.) will be
done in the setColor() color. Because they do different things, the
Component and Graphics methods have different names.
4.0.11 When I start a mouse drag inside a Component, and go outside the Component, still dragging, the mouse events still get sent to the Component, even though I am outside it. Is this a bug?
4.0.12 What's all this about subclassing Canvas and overriding paint() ? Can't I just do a getGraphics() for a component, and draw directly on that?
4.0.13 But couldn't the AWT just remember what has been drawn to a Graphics context, and replicate that instead of calling paint()?
4.0.14 How can I get the dimensions and resolution of the screen?
Screen resolution is in dots-per-inch.
Take a look in the Toolkit class for other useful methods.
Toolkit.getDefaultToolkit().getColorModel().getPixelSize() gets you the color model in terms of bits per pixel.
Math.pow(2,Toolkit.getDefaultToolkit().getColorModel().getPixelSize())
4.0.15 How do I allow for the size of the title bar and border when I draw a Frame?
If you are doing this in the constructor you need to ensure that the Frame's peer object is created first. Otherwise the Insets object returned by getInsets() will have all zero values. Make a call to Frame.addNotify() to have the peer created.
4.0.16 When I run the Swing demo on Win95 I get an error "Out of environment space"
4.0.17 How do I resize a List? I had a List defined as
List tlist = new List(10);but the Strings in the list were 80 characters long and only the first 15 were being shown. I was not able to resize the List to display the contents without using the scroll bar.
public void paint (Graphics g) {
tlist.setSize(200,200);
}
Then before showing panel/frame with the List:
tlist.resize(400,400);4.0.18 How can my program tell when a window is resized?
Note the new APIs call the deprecated APIs instead of the other way round. For example, Component.setBounds calls Component.reshape, instead of reshape calling setBounds.
4.0.19 Why doesn't my window close when I click on the X in the title bar?
JDK 1.1:
a) Listen for WindowEvent and do hide(); dispose(); in
windowClosing() - this really ought to be the "default" behaviour. Or
b) enable AWTEvent.WINDOW_CLOSING and do the hide() and dispose() in
processWindowEvent().
4.0.20 How do I clear the contents of a TextArea?
area.setText("");
4.0.21 What are those
preferredSize() and minimumSize() methods in Component?
AnyComponent.getToolkit().sync();
4.0.23 How do I plot a single pixel to the screen?
4.0.24 How can I tab between components?
4.0.25 What is the difference between "low level" and "semantic" events?
To the programmer, the important difference is that you can change a low level event such as the key value in a keypress, and it will display the new value. You can also consume low level events so that they do not appear in the widget. You can't do these things with semantic events - they have already "occurred" to the widget.
Semantic events: Use the method addXListener() to add a listener object which implement the XListener interface, to get XEvent objects delivered (usually via the AWTEventMulticaster). Low level events: use the method enableEvents() and override performX() to grab those events in the object itself.
On Mac, a Window object is either layered in with other windows, just like a Frame is, or else it is entirely modal -- depending on which VM you use. In Java -- there appears to be no easy way to get floating behavior. If anyone knows otherwise, please send in your comments.
Dimension screen = Toolkit.getDefaultToolkit().getScreenSize(); my_window.move( ( screen.width - window.size().width ) / 2, ( screen.height - window.size().height ) / 2 ); my_window.show().In a related fashion, you can center something on its parent like this. Note the intelligent use of APIs like translate() to do the work for you.
void centre(Component parent) {
pack();
Point p = parent.getLocation();
Dimension d = parent.getSize();
Dimension s = getSize();
p.translate((d.width - s.width) / 2, (d.height - s.height) / 2);
setLocation(p);
}
4.0.28 How do I get back to a normal
echo after I have used TextField.setEchoChar('*');
There is only one good solution, and that is to make two TextFields on top of each other, one normal, and one with .setEchoChar('*'), and switch between them.
4.0.29 How can I get the absolute mouse coordinates?
The approach is to sum up the event's (x,y) and the locations of the target and its parents until there is no parent. Though on some browsers, it seems this is not reliable. [Better suggestions are solicited.]
4.0.30 How can iconify/deiconify a window in Java?
4.0.31 How can I write text at an angle?
Also, in JDK 1.2 on, the Java 2D API handles arbitrary shapes, text, and images and allows all of these to be rotated, scaled, skewed, and otherwise transformed in a uniform manner.
4.0.32 How do I know which mouse button was pressed, and how often?
public void mouseClicked(MouseEvent m) {
boolean leftButtonPush =
(m.getModifiers() & java.awt.event.InputEvent.BUTTON1_MASK) != 0;
boolean centerButtonPush =
(m.getModifiers() & java.awt.event.InputEvent.BUTTON2_MASK) != 0;
boolean rightButtonPush =
(m.getModifiers() & java.awt.event.InputEvent.BUTTON3_MASK) != 0;
int click = m.getClickCount(); // might be 1,2,3 clicks or more
You can also call at m.isPopupTrigger().
If it returns a true value, the user has asked for a pop-up menu.
On a lot of window systems,
the right mouse button is the trigger for pop-up menus.
4.0.33 How do I detect a resize of a Frame?
import java.awt.*;
import java.awt.event.*;
class MyFrame extends Frame {
public MyFrame() {
addComponentListener(new CmpAdapter());
}
class CmpAdapter extends ComponentAdapter {
public void componentResized(ComponentEvent evt) {
//doSomething();
}
}
}
Alternatively, the same effect can be achieved like this:
class MyFrame extends Frame implements ComponentListener {
public MyFrame() {
addComponentListener(this);
}
public ComponentHidden(ComponentEvent evt) { }
public ComponentMoved(ComponentEvent evt) { }
public ComponentShown(ComponentEvent evt) { }
public ComponentResized(ComponentEvent evt) {
//doSomething
}
}
A servlet is a java program whose input comes from a server and whose output goes to a server. Other than that it is virtually no different to a regular Java program. Think of a servlet as an application, but one that (like an applet) requires a context in which to run, namely web-server software. Servlets are used like CGI, and they allow the server end to be written in Java as well as the client.
The Web Server starts up a servlet when the URL is referenced, and now your applets have something that they can talk to (via sockets) on the server that can write files, open connections to other servers, or whatever.
There is also a software technology from IBM called an "Aglet". An aglet is a mobile agent that can go from machine to machine, performing tasks, serializing data collected, and "shipping itself" (code and data) to the next machine. It's too early to say if aglets are a flash in the pan or or a dawning technology. Read about aglets at http://www.trl.ibm.co.jp/aglets/
Don't confuse Sun's JWS "Java Web Server" with JWS "Java Workshop". Java Web Server supports servlets as does the lightweight and free server at Acme.com:
Be careful of the following things:
drawImage(img, 0, 0, size().width, size().height, this);You can set the background color to match the background color of the browser by passing the value in as a parameter, like this:
In the HTML applet tag:
String colparam = getParameter("BrowserColor");
int col = Integer.valueOf(colparam,16).intValue();
setBackground( new Color(col) );
An applet cannot override the size imposed by the HTML. If you make the
applet larger, the browser will still clip to the origional size. If you
need more room, open up a new Frame, Window or Dialog to show your output.
4.1.4 How do you make the applet's
background transparent?
Lightweight components (new in JDK 1.1) have a transparent background.
Or get the parent Frame like this:
Container parent = getParent(); while (! (parent instanceof Frame) ) parent = parent.getParent(); Frame theFrame = (Frame) parent;This second suggestion probably won't work on Macs (where would the menubar go?) or in some browsers. In JDK 1.1, just use a popup menu, which isn't attached to a Frame. 4.1.7 Can I get rid of the message "Warning:Applet Window" along the bottom of my popup windows in my Applet?
In Netscape (only), using the Capabilities API to make the call
PrivilegeManager.enablePrivilege("UniversalTopLevelWindow");
before creation of the Frame eliminates the message, if the security manager
passes it.
4.1.8 When
I subclass Applet, why should I put setup code in the init() method? Why
not just a constructor for my class?
String imageFileName = "foo.jpg"
URL imageURL = getClass().getResource(imageFileName);
Toolkit tk = Toolkit.getDefaultToolkit();
Image img = null;
try {
img = tk.createImage((java.awt.image.ImageProducer)
imageURL.getContent());
}
catch (java.io.IOException ex) {
System.out.println(ex);
}
(Like anything involving Jar files, this is from JDK 1.1 on).
In this scenario the following code will tell you which environment you're running in:
public boolean isRunningInBrowser() {
Component p = getParent();
while(p != null && !(p instanceof Frame)) {
p = p.getParent();
}
return (p == null);
}
4.1.11 How do I print a page with an applet?
Point p = parent.getLocation();
Dimension d = parent.getSize();
Dimension s = getSize();
p.translate((d.width - s.width) / 2, (d.height - s.height) / 2);
Inter-applet communication sometimes arises when you have a multi-screen type program and you don't want to force the user into downloading everything at once. Try to avoid the need for applets to talk to each other. Also check the URL http://java.sun.com:81/products/hotjava/1.1/applet_environment.html which explains how it can be done in HotJava 1.1. Recommendation: stay far away from code which is browser-specific.
4.1.14 How can I resize an applet?
4.1.15 How do I read a text file stored in a JAR?
People who are obliged to use Internet Explorer 4.0, with its Microsoft proprietary changes to Java, can use Java Activator. Java Activator substitutes a standard Java virtual machine for Microsoft's in Internet Explorer. It allows you to use RMI, JavaBeans components, and Java Foundation Classes in Internet Explorer 3.02, 4.0, and 4.01. You can download Java Activator from http://java.sun.com/products/activator.
4.2.2 Is it possible to set and retrieve cookies from Java, in a manner that is compatible with all browsers supporting cookies?
The DevEdge site on Netscape's home page has a javascript-java example on getting cookies. Also http://www.geocities.com/SiliconValley/Vista/1337 has info on connecting an applet with JavaScript functions. It's quite involved. Stick to just Java if you can.
Flushing the network cache will make no difference; that isn't where the caching is taking place. Although applets are sometimes "pruned" and their ClassLoaders garbage-collected, this doesn't happen predictably, so restarting Netscape is the only reliable work-around at the moment.
A related question is "how do I make the browser reload from a URLConnection
instead of just getting the content from the local cache?" The answer is
to use
java.net.URLConnection.setUseCaches(false)
Browsers seem to vary in their conformance to this programmatic
request. Netscape caching varies depending on whether a proxy
server is in use, and which thread in the applet made the get request.
Some versions of Netscape reload the Applet if you hold down <Shift> while you click on reload. Until they fix it, use the appletviewer to test applets. And send them mail -- developers can only fix the bugs they know about.
CAB format is a Microsoft-only format. So do not use it as it destroys software portability.
JAR format is the Java standard format, based on PKZIP format including data compression. JARs were introduced with JDK 1.1
See http://www.ibm.com/java/community/viewarchive4.html for more information.
You should use the Java standard format JAR (Java Archive) files, not a vendor-specific format. JAR files are not just a Java standard, they are in industry-standard PKZIP format. One reader comments that both formats can be used with this tag:
Component c = this.getParent(); while (c!=null && !(c instanceof Frame)) c=c.getParent(); PrintJob pj = getToolkit().getPrintJob((Frame) c, "test", null); Graphics pg = pj.getGraphics(); printAll(pg); pg.dispose(); pj.end();This feature was introduced with JDK 1.1. A common place to put this is in the code that handles a button press. Printing from an untrusted applet is subject to a check from the SecurityManager.
To print in JDK 1.0.2, some people have suggested using Jentec's JENI. (The Java Enterprise Network Interface). JENI is a set of classes that provides applets with file, print, email, and directory services to lots of different protocols and locally without the applet having to change or even be aware which is being used.
JENI is free and available at http://www.jentec.com.
For an example of how to print, see http://www.jentec.com/live/jeni/PrintingAFile.html.
To save a file, see
http://www.jentec.com/live/jeni/CreatingAFile.html.
5.3 What
are the properties that can be used in a PrintJob?
The defaults are destination=printer, orientation=portrait,
paperSize=letter, and numCopies=1
You can search for info like this by joining the Java Developer Connection (it's free)
http://developer.javasoft.com/developer/index.html
Then do a search for "PrintJob".
Worst of all, those programs will not have the portability of true Java but will only run on Sun JDKs. For the same reason you shouldn't use classes outside the java.* packages when using JDKs from other vendors.
If you still insist on going ahead, check these URLs:
http://java.sun.com/products/api-overview/index.html
http://www.parmly.luc.edu/javaudio/
http://www.users.interport.net/~mash/javamidi.html
A. Environment variables are not used in Java, as they are not platform portable. The Mac doesn't have environment variables for example. A Windows 95 application not started from a DOS window does not have environment variables. Use properties instead. Create your own properties file (see java.util.Properties) or specify them with the -D option when you invoke the interpreter or JRE. Additionally, on some systems you can set a property from the command invocation line like this:
String env = System.getProperty("foo");
More simply, just put the environment variable on the commandline
5.8 How do you use the Date class to display the current time in my timezone? Date.toString() always uses PST. [jdk 1.1] (Pacific Standard Time -- the zone covering California).
DateFormat df = DateFormat.getDateInstance(); df.setTimeZone(TimeZone.getDefault());
If you want to see the properly formated version of your date, you shouldn't use getTime().toString(). That routine just returns the date info with respect to the timezone preference of your computer. To see the correct output, one possibility is to declare a GregorianCalendar and pull the fields out of that, as in this example:
import java.util.*;
...
GregorianCalendar g = new GregorianCalendar();
int year = g.get(Calendar.YEAR);
int mon = g.get(Calendar.MONTH);
int date = g.get(Calendar.DATE);
System.out.println(mon +"/" +date +"/" +year);
If you want fancy formats for printing/expressing the date, you should use the new internationalization routines. You will need to use the DateFormat and SimpeDataFormat classes in the java.text package. There is some sample code in the Java API documentation. As an example of how the new method should work jdk1.1/src/java/util/Date.java contains the method:
DateFormat formatter = new SimpleDateFormat (
"d MMM yyyy HH:mm:ss 'GMT'", Locale.US);
formatter.setTimeZone(TimeZone.getTimeZone("GMT"));
or even:
formatter.setTimeZone(TimeZone.getDefault());It should be reasonably straight forward to adapt this code for your preferred format (e.g. change string to "hh:mm" or other) and timezone, e.g. change "GMT" to "ECT", "JST" or other timezone.
5.9 How are dates represented in Java?
In JDK 1.1, Date was augmented by Calendar. Things didn't get any better. Instead of being ill-conceived and simple, it is now ill-conceived and complicated. The code was all licensed from Taligent. It didn't really improve matters. Dates are the lemon of Java, as Roedy Green truly notes.
So get your Date -- the current Date can be had by
Date now = new Date();Then construct a Calendar to do the translation:
Calendar mycal = Calendar.getInstance(); mycal.setTime(now);// Now read the Calendar's fields using get().
System.out.println("Year = " + mycal.get(Calendar.YEAR));
We hope all this junk will be fixed once and for all in a future release.
The Calendar, DateFormat, and even TimeZone classes will give you the timezone of your system (wherever you are). You can create a TimeZone object with the GMT offset of your choice like this:
bst_tz = new SimpleTimeZone( 1 * 60 * 60 * 1000, // 1 hour offset from GMT
"BST");
TimeZone.setDefault(bst_tz);
GregorianCalendar BritishSummerTime =
new GregorianCalendar(bst_tz);
5.11 What
kind of different date formats are allowed for the Date constructor with
the string parameter.
5.12 How do I get Java talking to a Microsoft Access database?
Note that the Microsoft version of the Java kit does not support JDBC-ODBC access because it uses a non-standard native code interface. Also check the JDBC FAQ listed at the end of this document.
int i =7; Vector holdsInts = new Vector(5,1); holdsInts.addElement(new Integer(i)); int j = ((Integer)holdsInts.elementAt(0)).intValue();5.15 I have several worker threads. I want my main thread to wait for any of them to complete, and take action as soon as any of them completes. I don't know which will complete soonest, so I can't just call Thread.join on that one. How do I do it?
double myrandom = Math.random(); // [0,1)The notation "[0,1)" is common math notation for "zero to .9999999 etc" The Sun documents say this returns 0.0 to 1.0, but inspection of the source shows they are wrong. However, due to the inherent inaccuracies of floating point arithmetic, multiplying N by 0.999999 etc can result in an answer of N, not N * .999999 . So watch out when N is big.
Where things get even trickier is in the case where you want an int within a certain range, say 1 to 6 to simulate the throw of a die or 1 to 52 to represent a playing card. Class Random has a nextInt method that will return any integer:
Random r = new Random(); int i = r.nextInt();However, that has an (almost) 50% chance of being negative, and it doesn't come from the right range. So you just take the abs() value and then mod it into the right range:
int dice_throw = 1 + Math.abs(i) % 6;Except, the abs() method fails gracefully in the presence of the Integer.MIN_VALUE (it returns the same, negative, result!). So it is better to AND to get the non-negative value: In general, to get a random int between high and low limits (incl.):
Random r = new Random(); int j = (Integer.MAX_VALUE & r.nextInt()) % (high-low+1) + low;The sentence states "(almost) 50% chance" because there is one more value in the negative integers than in the positive integers in two's complement arithmetic as used by Java. For most purposes, the bias introduced will be insignificant.
A worse problem is that with the algorithm used, the low order bits are significantly less random than the higher order bits. And the low order bits are precisely the ones you get when you do the remainder operation.
5.17 What does "deprecated" mean? I got this in a compiler error message.
An example of using a deprecated API is calling component.size(). That has been replaced by component.getSize().
Here's how you might look at every file in ZIP file:
ZipFile z = new ZipFile("foo.zip");
for (Enumeration e=z.entries(); e.hasMoreElements(); ) {
ZipEntry ze = (ZipEntry)e.nextElement();
System.out.println("got " + ze.getName() );
}
You should look for opportunities in your own data structures to implement
Enumeration, anywhere where the structure has repeated elements.
5.19 Which version of WinZip is compatible with java.util.zip?
5.20 What is the Model/View/Controller paradigm?
EasyIn easy = new EasyIn(); int i = easy.readInt(); // gets an int from System.in boolean b = easy.readBoolean(); // gets a boolean from System.in double d = easy.readDouble(); // gets a double from System.in... etc.
EasyIn is free, comes with source, and you can do what you like with it, including improve it, and send me back the results.
If, instead, you want to "roll your own" code (why?!) In JDK 1.0.2
java.io.DataInputStream in = new java.io.DataInputStream(System.in); String s = in.readLine();One way in JDK 1.1
java.io.BufferedReader in = new java.io.BufferedReader( new InputStreamReader(System.in)); String s = in.readLine();Once you have the token in a String, it is easy to parse it into one of the other types, as shown earlier in the FAQ. Yes, it is bone-headed, as it makes the simplest case of keyboard I/O unnecessarily complicated. A bug was filed with Javasoft to record this problem, but don't count on this being fixed any time soon. 6.2 Why do I have trouble with System.out.println()?
The name of the method stands for "print line", since it prints a String and goes to the next line, rather than staying on the same line as System.out.print() does. Yes, the name is yet another Java naming inconsistency, since the input equivalent is readLine(), not readln().
For systems prior to JDK 1.2, read on.
If the port exists as a pathname in
the filesystem, you can open it as a file and read/write. You can also
print text this way by writing to "prn" or "lpt1" on a pc, and "/dev/something"
on Unix.
Writing a formfeed at the end of the file is essential on Windows95.
//class that opens the printer as a file and writes "Hello World" to it
import java.io.*;
public class lpt {
public static void main (String[] argv) {
try {
FileOutputStream os = new FileOutputStream("LPT1");
//wrap stream in "friendly" PrintStream
PrintStream ps = new PrintStream(os);
//print text here
ps.println("Hello world!");
//form feed -- this is important
//Without the form feed, the text
//will simply sit in the print
//buffer until something else
//gets printed.
ps.print("\f");
//flush buffer and close
ps.close();
} catch (Exception e) {
System.out.println("Exception occurred: " + e);
}
}
}
The bigger problem is if you wish to change the characteristics of the port (e.g. baud rate, parity, etc). Java currently offers no portable way to do this. You will need to use a native method, or execute a system command. At least two companies have written a library to drive the port. See
In addition, there is a Unix serial port utility available with source at: http://jarvi.ezlink.com/rxtx/ and http://www.blackdown.org/Products.html. It's still free under the LGPL, and works on linux, irix, SunOS...
While not helpful to typical home users, there is an alternative portable COM port solution for Java 1.1 and even 1.0. Buy your COM ports in the form of "terminal servers". Using a COM port is now as easy as connecting to it with a Socket. Port parameters can be changed programatically using SNMP for most terminal servers (but this is never necessary when a modern modem or other fixed rate equipment is attached). Any networked box can serve as a terminal server - even Win95 - with a simple native server application for that box, but buying an actual firmware based hardware box is much easier.
Furthermore, your Win95 native applications can now share the COM ports (and any attached modems) via a Win95 product called "Dial-out IP": http://www.tactical-sw.com/
6.4 How do I append to a file?
public FileWriter(String fileName, boolean append) throws IOException public FileOutputStream(String name, boolean append) throws IOExceptionAnother way is to do this:
RandomAccessFile fd = new RandomAccessFile(file,"rw"); fd.seek(fd.length());Then write using fd. Note that the latter method does not take advantage of the "append" mode present in many operating systems (such as all Unixes). Such a difference may make a difference with multiple processes or threads appending to the same output file. This can happen frequently, even if not intended by the programmer, e.g. with logfiles in multitasking environments. With the lack of file-locking mechanisms in Java the issue becomes even more significant. 6.5 Is it possible to lock a file using Java ?
2. Use an atomic operation like file "renameTo()" and have all processes
(Java and non-Java) follow the same protocol: if the operation succeeds,
you have the lock, and you change the file back to give up the lock.
The FAQ previously recommended delete() or mkdir() as the primitive, but
there has been a report that these operations are idempotent (can be
repeated without error) in some JVMs. The suggestion of renameTo has been
proven to work in practice.
See
http://www.camb.opengroup.org/~sanfilip/FileLock/
for example locking class docs and source.
3. make calls to native code to issue the locking ioctls. This approach
is not portable, but gives you a shot at having your locks respected by
other programs using standard locking ioctls outside Java.
4. Push the work to a central server. Since socket connection requests arrive in a single queue on the server, this can be used to serialize lock requests. There might be some merit in copying the NFS lockd protocol for a general approach. Rolling your own simple version for a specific application is pretty easy. A database would be better off locking records or fields, not byte offsets. In theory, the server socket approach would make it easier to perform automatic cleanup of a lock on abrupt VM process failure, e.g. by asking "are you still alive?" to the lock holder occasionally.
System.out.print("\07");
System.out.flush();
should work, and works in JDK 1.0.2, too. That's the ASCII BEL character
(Java doesn't support the C abstraction of '\a' for an alert character).
6.7
How do I execute a command from Java? How do I do I/O redirection in Java
using exec() ?
The following suggestion is for server-side input.
- You can read a file on the server if you can create a URL referencing the file. Then open a stream, then use any of the stream-based methods to read.
This allows reading but not writing. It requires an http demon running on the server, which will usually be the case.
try{
URL url = new URL("http://somewhere.com/test.txt");
// or URL url = new URL( getDocumentBase(), filename);
DataInputStream dis = new DataInputStream(url.openStream());
String s = dis.readLine(); //read till you get a null line.
} catch(MalformedURLException e){System.out.println("URLException:"+e);}
catch(IOException e){System.out.println("IOException:"+e);}
You cannot write a file on the server this way.
The following suggestions are for server-side output.
It absolutely requires the cooperation of the server to allow an applet to write a file to the server. This cooperation may take any of several forms:
2. Or use a CGI script or servlet on the server to write when browsed. There is some source at ftp://ftp.oyster.co.uk/pub/java/fileIO/
The following suggestions are for client-side I/O.
3. Use a trusted applet (see section on security). This will permit local I/O without any of the restraints mentioned above. In this regard, the appletviewer and many other browsers regard applets loaded from a local filesystem (rather than across the net) as being more trustworthy, and perhaps even allowed to do I/O.
4. Or use a browser that has a security policy that is configured to allow file I/O (such as Sun's appletviewer).
Also see the answer to question 5.2 regarding the JENI library.
The following code will byte-swap little-endian integers into network standard order
public int swap(int i) {
int byte0 = i & 0xff;
int byte1 = (i>>8) & 0xff;
int byte2 = (i>>16) & 0xff;
int byte3 = (i>>24) & 0xff;
// swap the byte order
return (byte0<<24) | (byte1<<16) | (byte2<<8) | byte3;
}
Alternatively, the following code assembles bytes from
a byte array in big-endian order (as used by Java) into an int:
byte[] bytes = ... // whatever
int start_index = ... // wherever
int value = 0;
for ( int i = start_index; i < start_index+4; ++i ) {
value = ( value << 8 ) | ( bytes[i] & 0xFF );
}
If the bytes are in little-endian order, just change the "for":
for ( int i = start_index+3; i >= start_index; --i )6.10 How do I make I/O faster? My file copy program is slow.
Although many utilities claim to handle all varieties of C's printf, as far as has been found, this is the only one to correctly handle the equivalent of %e in printf.
import java.io.*;
public class ReadExponential {
public static void main(String argv[]) {
DataInputStream in = new DataInputStream(System.in);
StreamTokenizer st = new StreamTokenizer(in);
try {
while (st.nextToken() != StreamTokenizer.TT_EOF) {
switch (st.ttype) {
case StreamTokenizer.TT_NUMBER:
double num = st.nval;
int exp = 0;
st.ordinaryChars('\0', ' ');
st.nextToken();
st.whitespaceChars('\0', ' ');
if (st.ttype == StreamTokenizer.TT_WORD &&
Character.toUpperCase(st.sval.charAt(0)) == 'E') {
try {
exp = Integer.parseInt(st.sval.substring(1));
} catch (NumberFormatException e) {
st.pushBack();
}
} else if (st.ttype < 0 || st.ttype > ' ')
st.pushBack();
System.out.println("Num " + num * Math.pow(10, exp));
break;
case StreamTokenizer.TT_WORD:
System.out.println("Word " + st.sval);
break;
default:
System.out.println("Char '" + (char) st.ttype + "'");
break;
}
}
} catch (IOException e) {
System.out.println("IOException: " + e);
}
}
}
6.13 I'm trying to read in a character from a text file using the DataInputStream's readChar() method. However, when I print it out, I get ?'s.
FileInputStream fis = new FileInputStream("myfile.txt");
InputStreamReader isr = new InputStreamReader(fis);
char c3 = (char) isr.read();
The less-favored way (because it is not so portable, as the encodings translation
is not done) is just to read a byte and cast it into a character:
FileInputStream fis = new FileInputStream("myfile.txt");
DataInputStream dis = new DataInputStream(fis);
char c1 = (char) dis.readByte();
6.14 How
do I delete a directory in Java?
An alternative compression technology, LZW compression, is encumbered by Unisys's patent. LZW is used in GIF files and by the Unix compress command. Luckily, as well as being free from patent restrictions, LZ77 also gives better compression than LZW. LZW is the initial letters of the last names of the three computer scientists who developed the algorithm (Lempel, Ziv, Welch).
The basic classes (all in java.util.zip) that read LZ77 Zip format are Deflater and Inflater. These are used by the stream classes DeflaterOutputStream and InflaterInputStream. The java.util.zip classes GZIPInputStream and ZipInputStream inherit from InflaterInputStream.
PKZIP is a commercial program for DOS, Windows, and OS/2, sold by PKWARE Their FAQ (http://www.pkware.com/zipgfaq.html) specifically says
The "other people" PKZIP's FAQ refers to is the InfoZIP project, a group of public-minded programmers spread over the world producing free software that works on most ANSI C compilers and platforms. See
The article explains how to add fonts to Sun's JDK, using the font.properties file. [If anyone has summarised the information, please send it in].
When you instantiate a buffered input stream, you can specify the size of buffer it should use. Let's call this the internal buffer. When you call read() you can say how many bytes to read. Let's call this the request. If the request is smaller than the internal buffer and not a multiple of the internal buffer, then the last read returns only the odd bytes left in the internal buffer! The more reasonable and intuitive behavior would be for the internal buffer to be refilled, so that the whole request can be granted.
For example, if you create a BufferedInputStream with an internal buffer of 1000 bytes, and try to read 512 byte chunks, your first read will return 512 bytes, but your second read will only return (1000-512), or 488, bytes. (Assuming that the file has at least that many bytes in it). The following code illustrates the problem.
// troubleshooting by Tov Are JacobsenOf course, a valid reason for getting less than you asked for is that you asked for more data than is actually available in the Stream, e.g. you requested 512 bytes from a file that only contains 40 bytes. In general, there are no guarantees about how much data is returned for a given buffered input stream read request. To avoid this problem, push a DataInputStream on top of your buffered stream. Then you can call readFully() which will do what you want.import java.io.*; class filebug { public static void main(String args[]) throws FileNotFoundException,IOException { BufferedInputStream bis = new BufferedInputStream( new FileInputStream("test.txt"), 1000 ); byte[] buf = new byte[2000]; int numread; System.out.println( "Available: "+bis.available() ); while (true) { numread = bis.read(buf,0,512); if (numread<0) break; System.out.println( "got "+numread+", avail:"+ bis.available()); } } }
A similar "got less than I asked for" occurs when reading a socket. Network protocols frequently packetize data and send it across in bursts. Nothing is lost of course, and you are always told how many bytes you actually got. You will get the remaining bytes on a subsequent read. This happens regardless of the language used. Be sure to check the "amount of data returned" when using the read(byte[], int, int) method of BufferedInputStream, or when reading from a socket.
Another problem with java.io.InputStream.read(byte[], int, int) is that it catches and ignores IOExceptions. Instead, these exceptions should be passed on to the caller. Ace programmer Jef Poskanzer, jef@acme.com, has a version to do this at http://www.acme.com/jef/.
6.19
How do I get a directory listing
of the root directory C:\ on a PC?
6.20
How do I redirect the System.err stream to a file?
If you need to connect to C++ (or other language) systems or you need
CORBA-specific services, then CORBA is your choice.
In July 1997, Sun announced that it was aligning RMI to work more closely
with CORBA. Sun is simply adding an IIOP transport layer to RMI to support
interoperability with CORBA. Java programs can then
access CORBA-based objects through IIOP, the OMG's CORBA-based protocol.
This is very good news for those building heterogenous Enterprise systems,
although
it will take some additions to IIOP to support the pieces that RMI uses.
Microsoft spokespeople have tried to promote DCOM by
spreading misinformation that RMI is
changing or being dropped. That is totally wrong.
The RMI API continues unchanged in its current form.
Using DCOM would restrict your code to only ever run on Microsoft platforms
using Intel hardware, and negates the "write once, run anywhere" Java philosophy.
Non-portable, single vendor code should be avoided. You can sometimes minimize the Win95 problem by giving
your system another way to resolve
DNS names. Edit the hosts file for your system
so that localhost
and the full domain name are both mentioned.
On Windows 95 systems the hosts file is: %windir%\HOSTS
(for example, C:\WINDOWS\HOSTS)
So if my system is called
goober.best.com change the hosts file from
7.3 If I call the InetAddress.getByName() method
with an IP-address-string argument, like "192.168.0.1", I
get an UnknownHostException on some platforms, but not others. Code like
When InetAddress is instantiated with an IP address, a reverse DNS lookup
is done. If the IP address is not associated with a valid hostname, the
instantiation will fail. This is part of anti DNS-spoofing, and in JDK
1.1 works because the reverse lookup will not occur until the hostname
is asked for. So in JDK 1.1,
[Note: this info is still to be confirmed. Net gurus?]
7.4 I am using JDK 1.1.1 on Windows95, and
when I start jdb I get "Uncaught exception: java.lang.UnsatisfiedLinkError no
winawt in shared library path"
The same program works OK using jdk1.1
But actually the problem is the version of Microsoft's Visual C++ that
was used to build the product. VC++ 4.2 incorrectly generates code that
depends on MSCVRT.DLL or in the case of java_g, MSVCRTD.DLL. These DLLs
are not present in (some versions of) Win95. To make things even more interesting,
some versions of Win95 (yes, there are at least four different ones...)
ship with a broken MSVCRT.DLL (and MSVCRTD.DLL?) that seems to work, only
it doesn't, and after a while it dies.
Sun linked the winawt_g.dll with VC++ 4.2, which wrongly brought in
MSVCRTD.DLL, the debug version of the VC++ runtime. You have to get that
library from somewhere (like, say, VC++)
You'll hit this problem any time you try to debug 1.1.1 code with jdb
on a win95 system that doesn't have VC++ (or the MSVCRTD.DLL library from
some other source) installed. At least this is a problem you can solve
without waiting for the next release.
Some people say that the missing library has been seen at http://cag-www.lcs.mit.edu/curl/Binaries/PC/
Others say you need to buy VC++ to get it.
A. The obvious approach of calling
File.list("C:\"); does not work. There are two reasons why this
fails. First, slash is an escape character in Java, so if you want a
literal slash, you have to repeat it. Second, you need to give the
name of the directory, i.e. dot. Putting this together, either of
the following calls will work
File.list("C:\\.");
or
File.list("C:/.");
Note: a file separator of "/" works just as well as "\" in
most MS Windows programs and library calls. It is an artifact of DOS's
origin's as a ripped-off port of CP/M.
They changed the direction of the CP/M file separator,
so it looked different to a casual onlooker, but they
also made the old one continue to work in the shell and elsewhere.
That code has stayed there ever since.
A. You cannot assign a new FileOutputStream
to System.err, as it is final. Instead use the System.setErr() library
call, like this:
System.setErr(new FileOutputStream("myerrors.txt"));
This was introduced with JDK 1.1.
There is also a corresponding setIn() for redirecting standard in, and
a setOut() for standard out.
7. NETWORKING
& DISTRIBUTED OBJECTS
7.1 Should
I use CORBA in preference to RMI? Or DCOM? Or what?
A. If your distributed programs are all
in Java, then RMI provides a simpler mechanism that allows the transfer
of code, pass-by-value of real Java objects, and automatic garbage collection
of remote objects.
7.2 Why
does <my java debugger/IDE/other> hang for a couple of minutes if my
Windows PC is not dialed up to the Internet?
A. Java has networking support built in.
When the Java program starts the Winsock dll automatically gets loaded.
The first thing this does is to try to resolve the fully qualified domain
name for your machine under the name "localhost". If your system doesn't
have this name mapped, it will try to query a nameserver on the internet,
which is typically (on a PC) your dialup ISP. So it either prompts you
to connect to the ISP, or waits till the attempt times out.
On Windows NT systems the hosts file is:
%windir%\System32\DRIVERS\ETC\HOSTS
(for example, C:\WINNT\System32\DRIVERS\ETC\HOSTS)
127.0.0.1 localhost
to
127.0.0.1 goober.best.com localhost
or (showing more of the file) to
# Hosts file
127.0.0.1 localhost
129.146.77.177 goober
Another alternative is to dial up with a PPP connection to your ISP
whenever you want to run networking programs.
Fundamentally the experience of some people has been that networking
is not completely satisfactory on Windows95, and is subject to sporadic
unexplained failures. If this occurs to you, there is little choice
but to reboot and start again. Microsoft has several network-related
patches at its site http://www.microsoft.com
Socket sock = new Socket("155.152.5.1", 23);
triggers the exception. Why?
A. This is a platform difference that arises
out of different semantics in the underlying network libraries, and is
[said to be, but subject to confirmation] fixed in JDK 1.1. On Solaris
and Windows NT, the IP address string only works for IP addresses that
have an associated hostname. On Linux and Windows 95, the IP address string
works in all cases.
http://www.cdt.luth.se/~peppar/java/InetAddress/
has a workaround.
InetAddress in = InetAddress.getByName("155.152.5.1");
A. It *sounds* like your java\bin directory
is not on your PATH and so the system can't find the winawt DLL.
7.5 I
want to pass a class file to willing recipients who are using my applet.
Any ideas how?
in order to get jdb to run.
java.io.InvalidClassException: MacroData; Local class not compatibleA. You need to add a declaration such as
static final long serialVersionUID = 4021215565287364875L;in the modified class. The actual value of this long is supplied by the "serialver" utilitity suppied with the JDK. Any versions of a class other than the first version require this static to be defined
[comments from net gurus welcome]
String host = InetAddress.getByName("211.10.2.119").getHostName();
7.11 How
do I embed an anchor in a URL? Just putting it as part of the string in
the constructor doesn't work.
URL url = new URL("http://www.my_domain.com/my_page.html");
URL anchor = new URL(url, "#section2");
this.getAppletContext().showDocument(anchor);
7.12 RMI
seems to have stopped working for me in JDK 1.1. Why is this?
There are several very good sources available from Sun which cover many simple and advanced RMI problems. They are:
In addition there is currently a practical RMI connection limit imposed by the scalability of the VM and the performance of object serialization. In JDK 1.2 this is addressed. The actual number of active clients you will be able to support will depend on the workload mix you have (i.e. the number of clients, how often they talk to the server, and how much work must be done per call).
try { sock = new Socket(host, 80);
dock = new DataOutputStream(sock.getOutputStream());
dock.writeBytes("POST "+cgiloc+" HTTP/1.0\n");
dock.writeBytes("Content-type: text/html\n");
dock.writeBytes("Content-length: " +my_string.length() + "\n\n");
dock.writeBytes(my_string+"\n");
dock.close();
sock.close();
uresp = new URL(getDocumentBase(),"respond.html"); getAppletContext().showDocument(uresp); }The my_string contains the data you want to POST to the CGI script. The string should be encoded in the special way CGI expects. The class method java.net.URLEncoder.encode(my_string) will do it. The CGI has to write its output to respond.html so that it can be displayed by the browser. Even this won't really work, because respond.html could be overwritten by a subsequent request to the same CGI before the results of the first POST are read back.
To get an acceptable solution takes quite a lot of effort. There's a pretty good explanation at http://www.javaworld.com/javaworld/javatips/jw-javatip41.html In general you should prefer GET to POST for CGI access from Java. As it says on the Javaworld page, the answers to the question are really: you can't, don't POST (use GET), use a bean, or cheat.
Finally, if you request a url via the URLConnection/HttpURLConnection, the server sets the content type, and your applet can use URLConnection.getContentType() to get the type. Alternatively, use setRequestProperty to set it, like this:
url = new URL(cgiUrl);
urlc = url.openConnection();
urlc.setRequestProperty("Content-type", "application/x-www-form-urlencoded");
Search at www.yahoo.com for GoldWave for Win 95, sox for Unix and similar
conversion utilities for other systems. One conversion utility in Java
is at http://saturn.math.uaa.alaska.edu/~hursha
The source of a Java class to play linear PCM .WAV files is at: http://www.shef.ac.uk/~cs1mjp/Java/WhiteBoard/WavePlayer.html
It can be used in any Java application or applet.
The advantage of an animated GIF file is that there is only one file to download, and it is simple to do simple animations. The advantage of programmatic control over individual frames is that you control the rate and order of displaying them.
Here's a surprise: JDK 1.1 supports the animated display of animated GIFs. For simple animations animated GIFs are a lot easier and lighter-weight than coding an animation explicitly.
8.2.0 How do I create animated GIFs?
8.2.1 How do I prevent animated GIFs from flashing while displaying?
g.drawImage(img, ix, iy, this);You should change this to
g.drawImage(img, ix, iy, getBackground(), this);This will change all the transparent regions of the image to the background color before painting to the screen. If you paint transparent images directly to the screen they flicker.
public boolean imageUpdate(Image img, int flags, int x,
int y, int width, int height) {
if ((flags & (FRAMEBITS|ALLBITS))!= 0) {
repaint();
}
return (flags & (ALLBITS|ABORT)) == 0;
}
2. update is
public void update(Graphics g) {
paint(g);
}
If you have a background Image behind the partly transparent animated GIF
you will have to double buffer. You can crop the backgound image so you
won't have to double buffer the full app and waste too much memory.
8.3 Does
Java support transparent GIFs?
Even better, you can fill the transparent pixels with a color (so they appear non-transparent in Java). Just pass the fill color explicitly:
drawImage(img, x, y, w, h, fillcolor, this);Further, you can filter the pixels of an Image to turn any bits you wish transparent. However, the most you can do is reveal what is underneath the image. You cannot reveal what is underneath the applet (i.e. on the browser itself). By default applets have a plain grey background. 8.4 How do I play video in Java?
The spec can be found at
import sun.audio.*;
URL url; ... AudioStream audiostream = new AudioStream(url.openStream()); AudioPlayer.player.start(audiostream); ... AudioPlayer.player.stop(audiostream);b. Use the new Java Media Framework API, allowing a wide range of video and audio formats to be played back. See previous question for implementations of this. 8.6 How do I read in an image file, in an application?
Image img = Toolkit.getDefaultToolkit().getImage(fname);8.7 When I initialize a component, I call MyComponent.getImage() to get its image. createImage() returns null! I know the image works elsewhere. What's wrong?
If you override addNotify(), don't forget to call super.addNotify() in your overriding version.
URL url = null;
URLConnection con;
try {
url = new URL(getDocumentBase(),"image.jpg");
con = url.openConnection();
con.setUseCaches(false);
} catch (MalformedURLException e1) {System.err.println(e1.getMessage());}
catch (IOException e2) {System.er.println(e2.getMessage());}
Note: some programmers have reported that it caches anyway, even if that
do this. That is a browser bug.
One programmer reported that even after turning off caching and calling image.flush() before getImage(..), he was still seeing the same picture even though it had been changed on the server.
He worked out a solution: access the image via a cgi script that returned a URL. This redirects the browser, and he put in an Expires: header as well to force the reload. Painful and laborious, but it got the result. 8.9 How can I save an Image file to disk in jpg or gif format?
$ appletviewer m.html Premature end of JPEG file sun.awt.image.ImageFormatException: JPEG datastream contains no image at sun.awt.image.JPEGImageDecoder.produceImage(JPEGImageDecoder.java:133) at sun.awt.image.InputStreamImageSource.doFetch(InputStreamImageSource.java:215) at sun.awt.image.ImageFetcher.run(ImageFetcher.java:98)A. There's a known bug in early releases of the JDK which can cause the above failure when reading a JPEG across a slow connection. The failure only occurs if the JPEG contains a large application data block (APPn marker) --- the problem is that the JPEG decoder is trying to skip over the APPn and failing if not all of the APPn has been received yet. The quoted error message is only one of several possible complaints, but they all stem from the same root.
Photoshop is the most common source of JPEGs containing oversize APPn blocks. In particular, if you allow Photoshop 4 to save a thumbnail (preview) in a JPEG, the thumbnail plumps up Photoshop's private APPn marker to several K, which is usually enough to cause this problem.
There are several possible workarounds:
2. When making JPEGs for Web use from Photoshop, make sure you have
turned off the "save thumbnails" preference. (This is a good idea quite
aside from bug workarounds, because the thumbnail is just a waste of download
time as far as a Web browser is
concerned.) You might still have a problem if you've got verbose comments
or lots of paths being saved into the file, but 99% of the time, getting
rid of the thumbnail will make Photoshop's APPn small enough to not trigger
the Java bug.
3. Use a tool such as 'jpegtran' (from the Independent JPEG Group) to strip out the Photoshop APPn entirely without any loss of image quality. Recommended answer for the compulsive byte-trimmer.
4. (Last resort) Load and resave the image in a different image editor that won't insert any APPn or other overhead data. This implies a JPEG generational loss, so I don't recommend it if you are picky about image quality.
Any large overhead marker will cause the same problem; 4K of comment text, say, in a COM marker. So Photoshop is not the only source of tickling this bug.
There's hardly any overlap between the set of images that JPEG works well on and the set that GIF works well on. Sometimes, with enough care, you can get an acceptable conversion ... but most of the time gif<->jpeg conversion will just turn your image to mush. It's better to pick the right format in the first place.
If you're determined to convert formats anyway, try
the GBM (Generalized Bitmap Module).
The package is GNU licensed, in C and is very good.
Find it at
http://www.interalpha.net/customer/nyangau/
GBM does a good job converting to JPG, and
'lossiness' is adjustable to 0%.
It also converts to/from about 20 other formats, does
cropping, sizing, color mapping, gamma correction,
halftoning, everything you could want.
GBM source doesn't support jpeg directly, but utilizes
jpg source from IJG called jpeg-6a and found at
ftp://sun2.urz.uni-heidelberg.de/pub/simtel/graphics/jpegsr6a.zip
For more info see the JPEG FAQ at http://www.faqs.org/faqs/jpeg-faq/
Toolkit.getImage("localhost:8888/")
The thread will act as a stream-to-url adapter, and send back the data It saves you from having to read 200K of JPEG data before you can begin drawing anything.
It supports 8, 16-bit, stereo, mono, 11025, 22050, 44100 Hz record/play, load/save .WAV files.
You preconfigure your browser with a list of whose X.509 certificate you trust, and then applets arrive with X.509's attesting to their keys. It's easier than it sounds.
There has been mention of a "Java virus" called "BlackWidow" in the media (it was mentioned in Unigram in late 1996, and obliquely on the RISKS newsletter in February 1997). A request to the editor of Unigram for more information brought the answer that there was no more information, it was just a report of a rumor. As far as is known, this story exists *only* as rumors reported on by the press. There is no actual Java virus or blackwidow virus (there was a legitimate commercial product of that name, since renamed). If anyone has more concrete information about a virus that can attack a Java applet (again, this is thought to be impossible), please would they contact the FAQ maintainer with details.
A comprehensive and free crypto library (called Cryptix) is at
One commercial Java encryption source (from Ireland) is
Also, early access to Sun's Java Cryptography Extension (JCE) is available for JDK 1.1 at:
There's a Q&A archive at
An actual port of PGP v2.6.3i to Java is at http://tassun.math.nsc.ru
int i = Integer.parseInt(<String>);or
i = Integer.parseInt(<String>,<int radix>);Note: there are similar methods for Byte, Short, and Long.
int i = Integer.valueOf(my_str).intValue();also works but involves the creation of an extra object. Note: use this for floating point values, as there are no parseDouble or parseFloat methods.
float f = Float.valueOf(my_str).floatValue();10.2 How do I convert an int to a string?
String s = Integer.toString(i);or
String s = Integer.toString(i, radix);or
String s = "" + i; // briefer but may result in extra object allocation.Note: there are similar classes for Double, Float, Long, etc. 10.3How do I print the hex value of an int?
int i = 0xf1;
System.out.println("i is hex " + Integer.toHexString(i) );
10.4 How can you
send a function pointer as an argument?
public interface CallShow { public void Show( ); }
public class ShowOff implements CallShow {
public void Show( ) { .... }
public class ShowMe implements CallShow {
public void Show( ) { .... }
public class UseShow { CallShow callthis;
UseShow( CallShow withthis ) { callthis = withthis; }
void ReadyToShow( ) { callthis.Show( ); }
// in some other class that uses all this stuff:
UseShow use_1 = new UseShow( new ShowOff() );
UseShow use_2 = new UseShow( new ShowMe() );
and then the ReadyToShow() method on use_1 or use_2 will call the appropriate
method, as if you had stored a pointer to the method.
10.5 How
do I execute a command from Java?
String[] command = {"/bin/sh", "-c", "/bin/ls > out.dat"};
If you don't do this, and simply use a single string, the shell will see
the -c and /bin/ls and ignore everything else after that. It only expects
a single argument after the -c.
import java.io.*;
import java.util.*;
class IoRedirect {
public static void main(String Argv[]) {
try {
String[] command = {"/bin/sh", "-c", "/bin/ls > out.dat"};
Process p = Runtime.getRuntime().exec(command);
p.waitFor();
System.out.println("return code: "+ p.exitValue());
}
catch (IOException e) {
System.err.println("IO error: " + e);
}
catch (InterruptedException e1) {
System.err.println("Exception: " + e1.getMessage());
}
}
}
10.7 So why can't I exec common DOS commands
this way (as in 10.6)?
This occurs on any OS where some commands are actually interpreted directly by the shell.
BufferedReader pOut=
new BufferedReader(
new InputStreamReader(p.getInputStream()));
try {
String s = pOut.readLine();
while (s != null) {
System.out.println(s);
s = pOut.readLine();
}
} catch (IOException e) { }
Another possibility is to read chunks of whatever length as they come in:
p = r.exec(cmd);
InputStream is = p.getInputStream();
int len;
byte buf[] = new byte[1000];
try {
while( (len = is.read(buf)) != -1 ) {
String str = new String(buf,0,0,len);
System.out.println( "Process out: " + str );
}
}
catch( java.io.EOFException eof ) {
...
}
catch( java.io.IOException ioe ) {
...
}
10.9 How do I compile
code which has a cyclic dependency, i.e class pkg1.X contains a reference
to class pkg2.Y ?
indent (fails with "//" comments though)
cb (very few style choices though)
alias printjava 'vgrind -lC++ -t -w \!* | lp'
works pretty well too.
public synchronized void layout() {
LayoutManager layoutMgr = this.layoutMgr;
if (layoutMgr != null) {
layoutMgr.layoutContainer(this);
}
}
A. The code makes a local copy of a global
variable for one or both of two reasons.
The first reason is that accessing local variables can be faster than accessing (non final) member variables It's good for loops or where there are many references in the source.
The second reason is so that even if other threads update the global,
this.layoutMgr = someOtherLayoutMgr;this method will still have a pointer to the original layoutMgr.
If the local variable were omitted, and another thread used the setLayout() method to change layoutMgr to null between when the layout method checked for null and when it invoked layoutMgr's layoutContainer method, a NullPointerException would result.
Note that the synchronized keyword on the layout method doesn't help any, since setLayout (which could make such a dire change) isn't synchronized. Synchronized methods only lock out other synchronized methods on this object. (The unhelpful synchronized keyword on the layout method is gone in JDK 1.1.)
There are two alternative solutions. One would be to make setLayout synchronized and make layoutMgr private, so that it can't be set other ways. This provides a stronger form of thread serialization, in that you would never be able to see an old layout manager being used after it had been replaced. However, it is slower. Another option that provides no increase in thread serialization over the original would be to catch the NullPointerException.
Threads programming is hard! This idiom was probably put in place by someone who got really bitten by this in the past. 10.13 What is the difference between "a & b" and "a && b" ?
"a && b" is a "conditional AND" which only takes boolean operands. It always avoids evaluating its second operand if possible. If a is evaluated to false, the AND result must be "false" and the b operand is not evaluated. This is sometimes called "short-circuited" evaluation. "||" is the corresponding short-circuited OR operation.
Possible mnemonic: The longer operators "&&" or "||" try to shorten themselves by not evaluating the second operator if they can.
Thread t = new Thread( my_runnable_obj ); t.start(); ... t = null; // what happens to the thread?The answer is that *you* may no longer have a reference to the thread, but the JVM still does. Once a thread is started, and as long as it keeps running, it is a root object. Root objects are the starting points for "things in use" that the garbage collector uses. 10.15 How do I calculate the number of days between two dates?
Calendar earlierDate = new GregorianCalendar();
Calendar laterDate = new GregorianCalendar();
earlierDate.set(1997, 1, 1, 0, 0, 0); // Jan 01, 1997
laterDate.set(1998, 1, 1, 0, 0, 0); // Jan 01, 1998
// the first getTime() returns a Date, the second takes
// that Date object and returns millesecs since 1/1/70.
// The API has misleading and horrible naming here, sorry.
long duration = laterDate.getTime().getTime()
- earlierDate.getTime().getTime();
long nDays = duration / (24 * 60 * 60 * 1000);
System.out.println("difference in days: " + nDays);
10.16 How can
a Java program determine the level of JDK support given by the underlying
VM? I.e. is it running in a JDK 1.0.2 or 1.1 VM?
String ver = System.getProperty("java.version");
There isn't a lot of standardization on the string contents however.
Another possibility is to try { ... } a library method that didn't exist in
JDK 1.0.2, such as SomeComponent.setSize(), and catch the exception.
If you got an exception, it's a 1.0 implementation. In 1.0 setSize()
was known as resize().
There's a product to convert Visual Basic to Java. Details at
Every object has a routine called finalize() which will be called before the object is collected. This is Java's nearest equivalent to C++'s destructor. However, it is not a good idea to rely on finalization for the timely freeing of resources.
This is because garbage collection and hence finalization may be arbitrarily
delayed, and may never happen at all if the program terminates before it
runs out of memory. You should instead provide your objects with methods
similar to Graphics.dispose() to free resources, and call the
dispose() method explicitly when you have finished using them - typically
within the "finally" clause of a "try/catch" block. You may then call your
dispose() method from within your finalize() method as a last-ditch attempt
to free the resource if someone forgets.
Alas, all this means the C++ idiom of "object construction is resource aquisition" does not translate well to Java. However, note that 90% of destructors in C++ are there to free memory, and the GC means you don't need to do that in Java. As well as fixing an important source of bugs, the GC is essential to Java's security model; without it you could forge object references by preserving the reference after the object has been deleted.
If your program appears to be crashing due to running out of some system
resource (like File, Window or Graphics handles), it probably because the
system is running out of handles before it has run out of memory. Check
that you have called the dispose() method (or equivalent) on every object
that uses system resources. You can help the GC a little bit more by explicitly
NULLing out references that you've finished with.
2) In memory allocation (i.e. malloc (32 * (sizeof(int));) In Java you always allocate a specific type of object, rather than a block of raw memory that you will fill as you like. The system always knows the size of the kind of objects you are allocating. So sizeof is not needed.
3) in pointer arithmetic (i.e. p += sizeof (int)) Pointer arithmetic of this type is not allowed in Java, so this isn't necessary, either.
For all these reasons, there is no need for a Java sizeof() operator. If you absolutely must know the size of an object, you can create a ByteArrayOutputStream, and have the object serialize itself to the stream using the object serialization that is available with JDK1.1. After it is serialized, get the byte array that the ByteArrayOutputStream built and look at its .length property (the bytearray.length). Now you have the object in a form you can read/write to any I/O stream, and you also know its size. Only use this knowledge for good, never for evil purposes.
void foo(final MyClass c, final int a[]) {
c.field = 7; // allowed
a[0] = 7; // allowed
c = new MyClass(); // final means this is NOT allowed
a = new int[13]; // final means this is NOT allowed
}
is roughly equivalent to the following C/C++ code:
void foo(MyClass * const c, int * const a) {
c->field = 7; // allowed
a[0] = 7; // allowed
c = new MyClass(); // const means this is NOT allowed
a = new int[13]; // const means this is NOT allowed
}
Java does not have any equivalent to the following C/C++ function declarations:
void foo(const MyClass *c); // a pointer to a const class void foo(const int *a); // a pointer to a const int void foo(const int a[]); // a pointer to an array of const ints11.5 Are there any hacks around this?
public interface ConstFoo {
int getValue();
}
public interface Foo extends ConstFoo {
int getValue();
void setValue(int i);
}
Then when you want to receive a parameter that cannot be modified you have:
void noChange(ConstFoo foo);For a parameter that can be modified
void change(Foo foo);11.6 How can I write C/C++ style assertions in Java?
With a good optimizing compiler there will be no run time overhead for many uses of these assertions when Assert.enabled is set to false. However, if the condition in the assertion may have side effects, the condition code cannot be optimized away. For example, in the assertion
Assert.assert(size() <= maxSize, "Maximum size exceeded");the call to size() cannot be optimized away unless the compiler can see that the call has no side effects. C and C++ use the preprocessor to guarantee that assertions will never cause overhead in production code. Without a preprocessor, it seems the best we can do in Java is to write
Assert.assert(Assert.enabled && size() <= maxSize, "Too big");In this case, when Assert.enabled is false, the method call can always be optimized away, even if it has side effects. However, an opposing view holds that even this might not work in the face of java's late binding. If the Assert class is in a package, and if the computer the applet/application is running on has a different version with Assert.enabled being true, then it's possible that assertions *should* be enabled in that case. Therefore, the compiler can't assume that enabled is *false* at runtime just because it *is* false in the compilation environment. This may be thought perverse, but it could happen.
public class AssertionException extends Error {
public AssertionException(String s) {
super(s);
}
}
public final class Assert {
public static final boolean enabled = true;
public static final void assert(boolean b, String s) {
if (enabled && !b)
throw new AssertionException(s);
}
}
11.7 How
do I do stuff like scanf and sscanf in C/C++? And how do I do stuff like
sprintf, e.g.
float x = 12345.6789;
printf("%6.3f/n", x);
A. You can break a string like "5 loaves 2
fishes" into its parts by using java.util.StringTokenizer. This is the
Java equivalent of sscanf().
StreamTokenizer does a similar thing on a file or any stream (i.e, what scanf() and fscanf() do in C).
To do formatted character output, create a format string, and then use that to format your binary value, e.g.
import java.text.*; float fi = 1234.56789F; DecimalFormat df2 = new DecimalFormat( "0.000" ); System.out.println( df2.format(fi) );gives:
11.8 What is the Java equivalent of C++ friend"?
11.9 Does anything like the C++ Standard Template Library exist for Java ?
It includes about a dozen nice data structures (including sets and bags) and algorithms like unions, searching, and sorting.
[Some Java vendors are bundling it with their next release]
Other Java resources:
The Java "Hall" of Fame: http://www.apl.jhu.edu/~hall/java/
good glossary: http://oberon.ark.com/~roedy
conversions: http://oberon.ark.com/~roedy/convert.html
good JDBC FAQ: http://www.yoyoweb.com/Javanese/JDBC/FAQ.html
general Java: http://java.miningco.com/
Tutorial:
http://java.sun.com:80/nav/read/Tutorial/index.html
http://www.phrantic.com/scoop/onjava.html
Java Book lists:
http://www.netcharts.com/majug/reviews.html
Javasoft site: http://java.sun.com
General sharing and exchange of Java info:
http://www.gamelan.com
http://www.JavaShareware.com
comp.lang.java.help
simple programming and setup questions
comp.lang.java.announce
(moderated) announcements
comp.lang.java.advocacy
for arguments: no it isn't, yes it is
comp.lang.java.programmer
programming in Java
comp.lang.java.security
security issues
comp.lang.java.machine
JVM and native interfaces
comp.lang.java.databases
JDBC,ODBC, java access to DBs.
comp.lang.java.softwaretools
IDES, editors, compilers, tools, etc
comp.lang.java.gui
AWT, IFC, JFC, AFC, Vibe, etc etc
comp.lang.java.beans
Software components in Java
comp.lang.java.corba
(newsgroup added Dec 3 1997) interaction between Java and CORBA.
Please make an effort to post only to the single most appropriate group.
As with the other language groups on Usenet (comp.lang.c, comp.lang.c++, etc) questions about products from specific vendors that only work on one specific platform are best posted to other newsgroups. For example, questions about ActiveX belong in comp.os.ms-windows.programmer.ole, not the Java groups. For questions about J/Direct try the group microsoft.public.java.visualj++ or microsoft.public.java.sdk. These are available from Microsoft's news server msnews.microsoft.com .
See "QuickSort", "HeapSort" and "RadixSort" in the Java glossary at http://oberon.ark.com/~roedy/index.html .
Also, try the Java Generic Library. This library (JGL) is freely downloadable from http://www.objectspace.com/
Also Visual Engineering has JChart at: http://www.ve.com. No licensing fees.
13.2 How do I do keyboard (interactive) I/O in Java?
13.3 How do I do file I/O in an applet?
13.4 How do I do I/O to the serial port on my computer?
13.5 How do I do formatted I/O like printf and scanf in C/C++?
13.6 I have spent more debugging time finding case (upper vs lower) typos than everything else put together and squared!
13.7 Why do I get a compiler error with this statement: "double y = sin(90);"?
double cvtDegToRad = Math.PI/180; double x = 90*cvtDegToRad; double y = Math.sin(x);
This is because the Math package works in radians, not degrees. 360 degrees = 2 pi radians. You need to use the "Math" classname, e.g. Math.sin instead of plain sin, because you have to say what class or object these methods belong to. These are static methods of the Math class, so you give the name of the class in invoking them.
13.8 Why do I get this compiler error: "Can't make static reference to method..."?
class myclass {
public static void main(String args[]) {
myMethod();
}
public void myMethod() { //some code
}
}
The issue is this: a static method means it belongs to the class,
not each individual object. If you leave the static keyword off
(the usual case) as is done here with the method "myMethod()", it means
that method can only be invoked on an object. But your call from
main() has not told myMethod() which object it is to be invoked on.
Inside a non-static method, you don't have to provide this information,
as it assumes you mean the same object on which it was invoked.
When calling from a static method, you must provide the information.
A common fix is to instantiate a member of the class, on which to invoke myMethod(), like this:
public static void main(String args[]) {
myclass m = new myclass();
m.myMethod();
}
This problem is especially common when you are writing code that
you want to run as an applet and as an application. Naturally, you
call init() and start() from main. What you really need to do is:
public static void main(String[] args) {
Applet ma = new myApplet();
ma.init();
ma.start();
}
13.9 How do I close a Java window by using the icon in the upper right hand corner of a window?
public class MyFrame extends Frame extends WindowAdapter {
public void windowClosing(WindowEvent e)
{
// Do any other cleanup here
hide();
dispose();
// possibly also System.exit(0);
}
// do your other Frame stuff
}
Somewhere in your initialization code, put:
addWindowListener(this);
See also the answer to Q.4.0.30, and 4.0.19.
See also "The 10 Most Common Java Programming Mistakes": http://webreview.com/wr/pub/97/12/19/feature/sidebar.html
FAQ copyright 1997, 1998 by Peter van der Linden. Contributions and help from:
Matt Kennel, Patric Jonsson, Brad Van Tighem, Tony Hursh , Glenn L Vanderburg, Peter Jones, John McDowall, Jim Driscoll, Uday, Dave Harris, Bill Wilkinson, Tom Valesky, Dan Drake, Giles Thomas, Mitch Baltuch, Guy Ruth Hammond, Gordon Keith, Jason Brome, Shani Kerr, Steve Chapel, Timothy Wolters, Robert Lynch, Jake Cormier, Sean C Sullivan, Joseph A. Millar, Jim Frost, Jim Balter, Jeff Bauer, John Kochmar, Carl Burke, William Stubbs, Mark Smith, Volker Turau, Real Gagnon, Russell Gold, Max Hailperin, Bill Tschumy, Marco Nijdam, Marc Pawlowsky, Laurence Vanhelsuwe,Ian Macgregor, Mike Faulkner, Rich Koch, Will Clark, Govind Seshadri, Rich Simkin, Ian Stiles, Kieren, Darren Christie, Tom Lane, Michael Jungmann, Rob Mayoff, George Ruban, Tom McCann, David Hopwood, Thomas Phan, Kai Stuke, Rolf Howarth, Derek Snider, David Boydston, Andy Godwin, John F. Dumas, Doug Bell, David J. Biesack, Tiger Quimpo, Martin Hugh Rogers, Brian Krahmer, Ian Burrell, Nikki Locke, Bin Li, Jackson Thompson, Steve Odendahl, Greg Smith, Jeffrey C. Ollie, Mark Halvin, Jeremy Cook, Lak Ming Lam, Peter S. Morris, Mark Halvin, Juergen Keil, Alex Stewart, Mike Abney, Rodney Stephenson Mark Gritter, Satish Talim, Tamminen Eero, Alexander Gridnev, Eric Hodges, Jamey Graham, Will Lockhart, Scott Plante, Tom Sanfilippo, Jan Newmarch, Sean Breslin, Stuart D. Gathman, rhino@wwdc.com, C Matthew Curtin, Tor Iver Wilhelmsen, A.N.Pryke, Phil Race, David Holmes, David Rodal, Dominique Plante, Trent Jarvi, Ingrid Biery, Gopal Unni Krishnan, Grant Lewis, Tov Are Jacobsen, Gary McGath, Marty Hall, Will Forster, Colin Mummery, Darin McBride, Mayank Shah, Jens Alfke, Glen Stampoultzis, Philip Brown, Peter Steiner, Kurt Spaugh, Rasmus Ekman
I am maintaining a FAQ list to address specifically programming issues
(not a general tutorial on Java). Please feel free to mail
suggestions to me at pvdl@best.com.
Question with answer gets you a credit in the FAQ.
Peter van der Linden, Sun Certified Java Programmer.
-- end --