Archive-name: computer-lang/java/programmers/faq
Posting-Frequency: weekly
Last-modified: 1998/6/11
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 have some programming experience, though maybe not in Java.
Go to the FAQ home page at http://www.afu.com for other Java information and downloads, and the most up-to-date copy of the FAQ. Report FAQ updates to faqme at the address afu.com.
The biggest value of Java is its portability.
Speak to your management chain -- how comfortable do they feel using a Microsoft product that is embroiled in a legal dispute, that introduces deliberate incompatibilities, and whose stated goal is to lock you in to one platform? It is a safer choice to get standard Java from any other source than Microsoft. You can use these facts to move your company to standard Java.
The best way for programmers to support portable Java is to reject "polluted" non-standard tools from the only company pushing them: Microsoft. As a Java programmer please join the Java Lobby, an independent organization dedicated to representing non-vendor interests in Java. It's free, and you can sign up by visiting http://www.javalobby.org for details. Other ways to encourage portable java:
Free standard Java compilers and Java Plug-In can be downloaded from
http://java.sun.com.
Free standard Java Virtual Machines can be downloaded from
http://www.kaffe.org. and
http://www.oryxsoft.com/projects/gvm 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.java-linux.org (the linux site) too.
Free Java software can be downloaded from
http://www.gnu.org/software/java/java.html
Just for the record, the May 1998 Federal case against Microsoft has nothing to do with innovation, or product design. Microsoft is charged with
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. MOST COMMON JAVA NOVICE PROBLEMS
14. FOR WINDOWS USERS
15. Java GOTCHA'S
-------------------------------------------------------------------------
This Java FAQ is maintained as a service to the Java community. Please consider these books from the FAQ author when you are looking for a programming text.
"Not Just Java" Java explained for managers. More info at http://www.amazon.com/exec/obidos/ISBN=0138646384
Sample chapters are on Sun Microsystems webpage at http://www.sun.com/971124/cover-linden/.
Specifically, Sun includes a perpetual, irrevocable, free and royalty-free license in the front of the Addison-Wesley books containing the specification.
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 promised ISO that it will abide by ISO's rules for developing a standard, in particular it will take account of industry input. Just as with other ISO standards, "open" does not mean that anyone who suggests any new feature will get it into the Java standard; Sun has the casting vote in the future evolution of Java, but it does not own the specification nor the sole right to implement to it. On the spectrum of "single vendor proprietary technology" to "open to all to implement", Java lies much more towards the open end than the single vendor end.
Sun Microsystems has invested significant time and money to create its Java implementation. Sun has licensed its source code to more than 140 companies and organizations who want to build it into a commercial product of their own, 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.
The relative openness of Java contrasts with systems that are only available from one vendor, whose interfaces are developed in secret, without an open process for others to participate, and whose owners do not allow competing implementations of the same API. Typically, such systems also feature "private" APIs that are published late or not published at all, to allow the single vendor to gain a competitive advantage for their other products. Typically such proprietary systems do not make the source code available for inspection by all.
Some programmers want to see the Java source for free. They say that nothing is truly open without the source code. Sun allows this. If you aren't planning on incorporating Java into a commercial product, or doing any sort of external redistribution, there is an Internal Noncommercial Use Source License available at no charge. Please see URL http://java.sun.com/nav/business/source_form.html
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 The pathnames are called things like /pub/usenet-by-group/comp.lang.java.programmer/Java_Programmers_FAQ which may help you get to the right one directly, as it takes some time to get a directory listing there. Alternatively, you can look for newsgroup names on the same ftp site by going to the same site and looking under /pub/usenet-by-hierarchy/. That has subdirectories such as alt/, ba/, ca/, comp/, and subdirectories under them such as /pub/usenet-by-hierarchy/comp/lang/ and so on. This helps you explore the world of newsgroups with FAQs.
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 effing 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?
and the Java 1.1 inner classes spec at:
and the other Java 1.1 update at:
It is also available as a book in printed form (details at website). Also see the "Clarifications and Amendments" http://java.sun.com/docs/books/jls/clarify.html.
You can also see the virtual machine (execution environment) specification at http://docs.sun.com:80/ab2/java1/@Ab2CollToc?subject=java
1.3 Where can I find a full list of Java books and book reviews?
1.4 What if my question is not answered in this FAQ?
nnn Documents (nnn is some number).
The chances are that you will find several answers to your question. Some may not be complete or completely accurate however. That is the nature of Usenet, and free information. If you still don't have an answer, then post your question on the most appropriate of the newsgroups. Don't spam the newsgroups by posting to multiple groups. Knowledgeable posters tend to ignore questions like that.
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
1.5 How do I check on known bugs in JDK 1.1?
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 also send in an RFE (Request For Enhancement) 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/jdc Then browse webpage http://developer.javasoft.com/developer/bugParade/#votes
1.6 What computers have Java ports? Is there a port to Win 3.1?
There are several Java ports to Win 3.1. IBM's ADK1.02 is available at the following locations:
Netscape Navigator for Win3.1 has Java support. Java will never be well-supported under Win3.1 because Win3.1 lacks the basic features expected of a modern OS (primarily lengthy filenames and multithreading support).
You could also consider JavaSoft's JavaPC kit that converts a PC into a thin client Java system. Details are at http://java.sun.com/products/javapc/index.html. JavaPC is probably more for business users than personal PCs. However, unlike the 16-bit versions of Netscape Navigator and Microsoft Internet Explorer, which provide a Java Virtual Machine that is only compliant with the JDK 1.02 API, the JavaPC software allows IS managers to deploy JDK 1.1 compatible Java applications on PCs running DOS and Windows 3.x.
1.7 Where can I find information on Java 3D?
1.8 What are the folks at project Gnu doing with Java?
Kaffe (a JVM) can be found at
JCL is a free implementation of Sun's core Java libraries (v1.1), being developed for the GNU Project http://www.gnu.org. Information regarding JCL is at http://www.oryxsoft.com/projects/gvm/
See also http://www.oryxsoft.com/projects/gvm and http://www.hungry.com/products/japhar (Now one merged project).
1.9 Where can I find information about Java Certification?
and then search for "sun certified java". It costs $150 to sit the Java Programmer exam. It is not trivial to pass the Java certification exam. It requires understanding the objectives of the test, and the material that is tested for. These are given, along with sample questions, at the URL mentioned above.
1.10 I'm looking for a Java style guide on naming conventions.
Also take a look at Doug Lea's draft coding standard -
See also Q3.25 for some basic rules of thumb.
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 IDEs (Integrated Development Environments) are there?
IBM's SF project competes with products from companies like SAP and Baan. Of course, the SF project is multi-platform and uses Java beans and GUI interfaces. More information on SF is available at http://www.ibm.com/Java/Sanfrancisco
1.15 What large Office-style or other applications have been written in Java?
Yet another is Star Division's Client/Server Office. It is an office suite with the client part written in Java and able to run on JavaStations. The server part will run on Solaris, NT, OS/390 and AS/400. The older (non-Java) version is bundled with all Sun wokstations sold in Germany The Linux version is freely downloadable from http://www.stardivision.com.
However the niche for single user office productivity applications is pretty well already dominated by Microsoft products, and it is unrealistic to think that Java software will unseat shrink-wrapped software simply because it is written in Java. This is why Corel replanned its Java rewrite of Corel Office before taking it to FCS. When Corel did that, it also increased its investment in Java from 33% of R&D budget to 50%, at the expense of Windows.
Most of Java development is taking place for custom applications internal to a company. Most programmers of any kind have never worked on MS Office, but work on internal applications, and so it is with Java. These projects don't have the high profile of major vendor's products, but they are the mainstay of the industry.
Finally, note that Sun's Java compiler is written in Java. This is a really big application in widespread use on millions of platforms. The compile command "javac test.java" is equivalent to
java sun.tools.javac.Main test.javaIn reality, the javac script does a few extra things, like setting the heap size, etc. but nothing major, and nothing that isn't represented by a command line switch.
1.16 What Java User Groups are there?
If you can't find a user group in your area/school, it's easy and satisfying to start one.
to get a 32Mb extent.
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
LL(k) parser
2.4 Where can I find a byte code obfuscator?
This obfuscator has been updated to be fully compatible with JDK 1.1: http://www.monmouth.com/~neil/Obfuscate.html
Obfuscators are intended to foil decompilers. Decompilers translate byte
code back into Java source code. Mocha was the first and most well known
of the decompilers; it's no longer supported.
There is a decompiler (written
in C++) at
http://web.unicom.com.cy/~kpd/jad.html Because it is in C++, there are
different versions for every architecture (hah!) There are also commercial
products, such as SourceAgain from
http://www.ahpah.com
There's a very good Java Code Engineering and Reverse Engineering FAQ page at http://Meurrens.ML.org/ip-Links/Java/codeEngineering/.
2.5 Which program is used to create .zip files compatible with the java* programs? (eg classes.zip, moz3_0.zip)
E.g.:
creates a compressed archive
creates it fullsize (uncompressed) (note the 'O'-option used for JDK1.0.2)
On Unix you can also use:
Info-ZIP home page:
http://www.cdrom.com/pub/infozip/
Latest source code:
ftp://ftp.uu.net/pub/archiving/zip/src/zip21.zip
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 http://developer.netscape.com/software/signedobj/jarpack.html
If you zip your .class files for JDK 1.0.2 (for 1.1 you'll use a Jar)
2. Make sure the main class has no parent directory inside the archive, (in other words, don't build an archive with foo/bar/myMain.class, unless your myMain is in a package called foo.bar. Instead start it at myMain.class). Your packages must be placed in the archive using their corresponding filesystem pathnames.
3. Put the archive in the same directory as the .html page;
4. Put something like the following tag in the .html file:
From JDK 1.1 on, an example of the applet tag used with a jar file is
These lines will use an applet called myapplet that can be found in the jarfile myfile.jar. An example applet tag of a jar file used to hold classes in packages is
<APPLET ARCHIVE="myclasses.jar" CODE="linden.net.MyApplet.class" WIDTH=480 HEIGHT=120> </APPLET>
You can supply several jar filenames in a comma-separated list. Jar files are in compressed PKZIP format.
2.6 Can I compile a Java program to a binary executable, .exe on a PC?
Compiling to native code takes away the most significant benefit of Java: portability of executables. Further, if you want your Java DLL (or .exe) to interact with C++, you'll have to specify which specific C++ compiler and/or actually compile some sort of linkage via the appropriate C++ compiler. Because C++ does not have a standard ABI there is a big problem with interoperability. Every C++ compiler uses a different object model, a different way of laying out class members, and a different way of "mangling" names for the linker.
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 |
On a Unix system, you can sort the file with something like
More and better Java tools are a third party opportunity. One Java profiler is JProbe Profiler, available from http://www.klg.com/jprobe. JProbe is said to be easy to use. Another profiler is OptimizeIt, available from http://www.optimizeit.com. Each of these profilers has performance tuning, which shows which methods took how much time, and also memory tuning, which shows what objects are in memory and how they were allocated. Both are important things to know. The latest version of the CodeWarrior IDE http://www.metrowerks.com has a time-based profiler for Java code. Java Workshop from Sun also has a time-based profiler.
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.
2.9 I'm working on a project with lots of classes and I use the JDK. A recompile from scratch takes forever when I do it a class at a time. How do I recompile everything?
Another way is
where "tip.java" is a class "at the tip of the iceberg", i.e. that depends on (uses) all the other classes. Typically, this may be your main class. However, "-depend" is known to be buggy and cannot be relied upon. It also doesn't issue compile commands in parallel to make use of multi-processor systems.
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. (This need is true for both standard (untrusted) applications and trusted applets. At least, if you use the Java Plug-in to give yourself standard Java inside a browser).
On Solaris, make sure that the environment variable LD_LIBRARY_PATH includes the path of your shared library.
2.11 An anonymous class can't seem to access a private outer method. Why is that?
public class MyDialog { void Setup() { addWindowListener( new WindowAdapter() { public void windowClosing(WindowEvent e) { myCloseWindow(); } } ); // anon inner class } private void myCloseWindow() { // private outer method dispose(); } }
This code sends javac into an infinite loop. The workaround is to make the
private method non-private, or to make the inner class a named class.
Sun temporarily put a workaround in the compiler to
silently set the field to package access! Interesting.
2.12 What are the major Java releases and their contents?
jre.exe is the runtime stub that comes with the Java Runtime Environment (it's also in the JDK). It ignores the CLASSPATH environment setting in favor of its own internally generated default and whatever is supplied on the cmd line using -cp or -classpath. It's intended to be a bit simpler for those who are only ever running Java programs, not developing them.
java.exe is the runtime stub that only comes with the JDK. It uses the CLASSPATH environment setting as a starting point and then tacks on its own internally generated entries.
They both serve the same purpose and that's to start a Java VM, have it run a Java application, then terminate. The source for jre.exe is provided in the JDK. The source to java.exe is provided only in the JDK Source distribution.
In JDK 1.1, users are no longer required to set the CLASSPATH to point to the classes.zip file, and in fact the README advises users not to set it.
From JDK 1.1.2 on, it is generally an ERROR if the user sets the CLASSPATH to include classes.zip. CLASSPATH is only needed to
If you're not doing any of these, do not set CLASSPATH. If you have set it, unset it.
3.2 How can I program linked lists if Java doesn't have pointers?
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.
3.4 How, then, can I pass an object to a method, and have the method change the reference so it points to a different object back in the calling code?
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 ...
Note that changing a global variable/object inside a method is an egregious programming practice -- it usually violates basic OOP constructs.
3.5Why 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.7 I extended the class called Frotz, and the compiler is giving me an error message "No constructor Frotz()" in the child class. Why?
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:
http://java.sun.com/products/jdk/1.1/compatibility.html#incompatibilities
http://java.sun.com/doc/language_specification/javalang.doc.html#1466
http://java.sun.com/doc/language_specification/javalang.doc.html#5899
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. 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 error
A. 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(); } }Another refinement is to note that Object.clone() only throws a CloneNotSupportedException when the object doesn't implement Cloneable. Since you control what your classes do and don't implement, you can ensure that cloneable classes implement the interface and you don't need to make the overridden clone() throw the exception.
public class X implements Cloneable { public Object clone() { // no throws try { X c = (X)super.clone(); // in case members need cloning return X; } catch (CloneNotSupportedException e) { // should not happen, because of Cloneable throw new InternalError(); } } }
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 columns
Note 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.class
is 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. Although it went outside the boundaries of defined behavior in COBOL, on S/360 computers and their successors. this could compile into a single machine instruction. The roll-up behavior was documented by IBM, and the technique was common enough that it was worth optimizing the trick in microcode.
In any event, initialization 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);
Please don't do this.
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.)?
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?
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.
The standard JNI thus has two purposes:
3.25 What are the naming conventions in Java?
Also see Q1.10.
[Reference: Java Language Specification, section 6.8 Naming Conventions.]
3.26 What are the differences between an interface and an abstract class?
Interfaces allow you to treat an object as an abstraction without having to know anything about its particulars. If, for example, you wanted to have a bunch of persistent objects on which you need to provide persistence services, these objects of many varying kinds would all in their individual ways implement a Persistent interface that prescribes a save() method. The persistence service simply treats each different object as a Persistent and calls save() on it. Each object of all the unrelated classes knows how to save() itself when told to do so. The service has no need to worry about the actual class of each object.
You want to use abstract classes when you plan to have related 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).
3.27 How do static methods interact with inheritance?
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?
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 held in a 64 bit type.
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?
(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.
Finally, you can just have the function return a Vector. This is particularly convenient when you're not sure how much you are going to be returning, based on what occurs in the method. A Vector is essentially a dynamically-growable array. Regular arrays can't grow after you declare them - you have to declare a bigger array and move the old stuff into it.
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
Then pick through the long list of fonts to determine which ones you want to use. The xfd program will let you look at a font:
4.0.2 Why is GridBagLayout so hard to use?
Bottom line: nobody has to spend any effort on GBL, there are better alternatives available now, and it will be replaced by the SwingSet "SpringLayout" Springs & Struts style layout manager.
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?
4.0.4 Can you have different fonts for individual words in a TextArea ?
4.0.5 How much text can be put in a TextArea?
4.0.6 MyClass works fine except when I try to set a particular font. I just can't seem to get it to work in Win95, but I can get it to work on a MacOS and Unix.
On both Windows 95 and Solaris 2.6, these fonts
are revealed by this code:
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()
The font styles are now mapped into a system font name using the entries in one of the font.properties files in $JAVAHOME/lib. There are multiple font.properties files corresponding to different locales. If you wanted a quick hack for testing, you could modify the file or add to it so a different mapping is done to a new font you want to try.
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.
4.0.8 I use add(Component) to add Components to the Container. Is there any way toexplicitly set the z-order of these Components?
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.9When I call repaint() repeatedly, half my requests get lost and don't appear on the screen. Why is this?
4.0.10 What is the difference between
Component's setForeground(Color c)
and
Graphics's setColor(Color c) ?
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.
It is done for the convenience and ease of the application programmer. It allows you to handle all drags from the place of origin. If you don't want this, simply look at the coordinates of the mouseDrag Event, and if they are outside the Component, ignore them.
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.14How 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())
gets you the color model in terms of number of colors. Or use this:
1 << Toolkit.getDefaultToolkit(). getColorModel().getPixelSize()
That does a shift left to calculate the power of two.
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. This is because the AWT sometimes needs to call these for its own purposes. If it called the old one which then called the new one, and you overrode the new one, the AWT would (wrongly) not call your routine. By having the AWT call the new one (and then the new one call the old one), any overrides of the new one will correctly be called by the AWT as needed. If that didn't make sense, forget I mentioned it.
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, so was made so for
a Swing JFrame. Or
b) enable AWTEvent.WINDOW_CLOSING and do the hide() and dispose() in
processWindowEvent().
4.0.20How do I clear the contents of a TextArea?
area.setText("");
4.0.21 What are those preferredSize() and minimumSize() methods in Component?
4.0.22 How can I force a synchronization of the graphics state, e.g. of a cursor change, or an animation frame to be rendered?
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.
4.0.26Is it possible to have a Java window float above all other windows. for example a tool palette floats in a super-layer always above all the regular document windows on which you use the palette's tools?
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.
4.0.27How do I center a dialog box?
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.
You can overload processMouseEvent of your component.
public void processMouseEvent(MouseEvent e) { if (e.isPopupTrigger()) { // do what you want } else super.processMouseEvent(e); }The code above applies to JDK 1.1. You can also call java.awt.swing.SwingUtilities.isRightMouseButton(MouseEvent me). See also question 15.10.
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 } }
4.0.34 How do I get word-wrap in a TextArea?
Supply TextArea.SCROLLBARS_NONE or TextArea.SCROLLBARS_VERTICAL_ONLY to the TextArea constructor to get word wrap. By default, a TextArea is created with both horizontal and vertical scrollbars.
4.0.35 How can I make an offscreen image with
transparent pixels?
How can I grab the pixel values from an offscreen image?
How can I use AWT drawing primitives (e.g. drawString() or drawOval()) on
an image I created from an ImageProducer?
Despite the fact that there is only one class called Image in the AWT libraries, it suffers from a (currently undocumented) severe case of schizophrenia: there are really two unrelated types of Image. The first type are those created by the Component.createImage(int, int) call, known as "offscreen" images, and the second are those created by the Component.createImage(ImageProducer) call, or by the Toolkit/Applet.getImage() calls, which I will call "produced" images.
The only common ground between these kinds of Image is the following:
The differences between these objects are the following:
In these cases, "you may not" generally means "you may not successfully". Symptoms on attempting these range from Exceptions to garblings of the Image. Any or all of these restrictions may be removed in Java 1.2, which features a new 2d API. Wait and see.
There are some relevant bugs shown in the Java Developer Connection: Bug ID 4098505. Apparently, from the report from the Sun engineer, PixelGrabber is specified to work with offscreen images, just it is currently buggy, and invariably gets the wrong colour model. No fix has been scheduled yet.
Bug ID 4077718 reports that setting transparent Colors in offscreen images has been available since Java 1.2beta1. I am personally unable to verify this.
There is an incorrect answer from Sun to the third matter, of getGraphics() on produced images, in article 1501 in Questions&Answers.
4.0.36 How can I grab a pixel from an Image object?
import java.awt.image.PixelGrabber; import java.awt.Image; .... .... public static int pixelValue(Image image, int x, int y) { // precondition: buffer must not be created from ImageProducer! // x,y should be inside the image, // Returns an integer representing the color value of the x,y pixel. int[] pixel=new int[1]; pixel[0]=0; // pixel grabber fills the array with zeros if image you are // trying to grab from is non existent (or throws an exception) PixelGrabber grabber = new PixelGrabber(image, x, y, 1, 1, pixel, 0, 0); try { grabber.grabPixels(); } catch (Exception e) {System.err.println(e.getMessage());} return pixel[0]; }
By the way, one issue on working with images is that the Java VM will consume virtual memory pretty fast if you are loading lots of images without calling the Image.flush() method when done. The getImage() method probably caches old images so they aren't garbage collected.
4.0.37 How can I limit a TextField to no more than N characters, or to only allow numeric input?
A neat variation is to extend the basic AWT component, and in your subclass also include the handler that will look at the keystrokes. This bundles everything neatly in one place. The code may look like:
import java.awt.*; import java.awt.event.*; public class XCTextField extends java.awt.TextField implements java.awt.event.TextListener { public XCTextField(int columns) { super(columns); enableEvents(AWTEvent.FOCUS_EVENT_MASK); addTextListener(this); } // other constructors may be useful, too public void textValueChanged(java.awt.event.TextEvent event) { int col = this.getColumns(); int len = getText().length(); // int caret = getCaretPosition(); if (col > 0 && len > col) { // or if the char just entered is not numeric etc. String s = this.getText(); Toolkit.getDefaultToolkit().beep(); this.setText(s.substring(0,col)); this.setCaretPosition(col-1); // caret at end } } public void processFocusEvent(java.awt.event.FocusEvent e) { // this routine highlights according to focus gain/loss. super.processFocusEvent(e); int id = e.getID(); if (id==java.awt.event.FocusEvent.FOCUS_GAINED) this.selectAll(); else if (id==java.awt.event.FocusEvent.FOCUS_LOST) this.select(0,0); } }
Here is a much briefer example, which very cleverly does the work in the Listener. Oracle really dislikes the "tick" character in a data text fields, as it is interpreted as part of an SQL statement. Here is the code that James Cloughley wrote to suppress "ticks" in a TextField.
import java.awt.*; import java.awt.event.*; public class NoTick extends KeyAdapter { final char tick = '\''; public void keyPressed( KeyEvent event ) { TextComponent tc = ( TextComponent )event.getSource(); char C = event.getKeyChar(); if ( c == tick ) { event.consume(); } } }Use it like this:
TextField sometextfield = new TextField(); sometextfield.addKeyListener( new NoTick() );Brief and clever -- make the event handler consume unwanted characters.
Finally, check out iDate, iTime, and iNumeric from IBM's alphaworks javabeans, available free at http://www.alphaworks.ibm.com/alphaBeans. These beans do the kind of validation you want.
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/
Finally, there is the ticklet (Tcl/Tk) plugin for your browser (Netscape or Explorer) available at http://sunscript.sun.com/plugin/ 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:
4.1.2 My applet works on my machine, but fails when I put it on our web server. Why?
Be careful of the following things:
4.1.3 How do I use an image as the background to my applet? How do I set the background color of my applet the same as the browser?
(under AWT) Alternatively, the AWT can scale your background image to the
size of
the applet. The result quality will depend on the kind of image. Inside an
applet class, you can use:
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.
4.1.5 How do you do file I/O from an applet?
4.1.6 How do you get a MenuBar/Menu in an applet?
Or get the parent Frame like this (doesn't work in all execution environments):
Container parent = getParent(); while (! (parent instanceof Frame) ) parent = parent.getParent(); Frame theFrame = (Frame) parent;
This second suggestion definitely doesn't work in the appletviewer, and 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.8When I subclass Applet, why should I put setup code in the init() method? Why not just a constructor for my class?
4.1.9How do I pull a non-class file, such as a .gif, out of a jar file?
String imageFileName = "foo.jpg" URL imageURL = getClass().getResource(imageFileName); Toolkit tk = Toolkit.getDefaultToolkit(); Image img = null; try { java.awt.image.ImageProducer I_P; I_P = (java.awt.image.ImageProducer)imageURL.getContent(); img = tk.createImage(I_P);
Or equivalently, and possibly simpler, this:
String imageFileName = "foo.jpg"; InputStream jpgStream = getClass().getResourceAsStream(imageFileName); Toolkit tk = Toolkit.getDefaultToolkit(); Image img = null; try { byte imageBytes[]=new byte[jpgStream.available()]; jpgStream.read(imageBytes); img = tk.createImage(imageBytes);
(Like anything involving Jar files, this is from JDK 1.1 on).
getResource(String) does not work in applets in Netscape due to Netscape
security issues. You should use getResourceAsStream(String) there instead.
See
http://developer.netscape.com/software/jdk/relnotes.htm
Note that getResourceAsStream() is also good for reading a text (or other kind of) file from a JAR file.
public void init() { InputStream myStream = getClass().getResourceAsStream("myFile"); // ... }
Once you have it as an InputStream you can read it how you like.
4.1.10 I want to know about {applets,applications} but the lousy book I got just talks about {applications,applets}. What can I do?
If you fail to do this, when running as an application, the window won't close. See question 15.7 for a sample of the right handler.
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?
4.1.12 How can I position my dialogs centered(not top left)?
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.1.13 How can I get two applets on the same page to communicate with each other?
Applet anotherApplet = getAppletContext.getApplet("someName");
Cast anotherApplet to the correct applet subclass, and you can call any methods in the applet subclass. Don't forget to use appropriate synchronization when two threads tweak variables.
You can walk through all the applets on an HTML page using code like that below. However this appears to be broken in Communicator 4.04 on Win95.
Applet otherApplet; AppletContext ac =getAppletContext; for (Enumeration applets=ac.getApplets(); applets.hasMoreElements(); ) { otherApplet=(Applet)applets.nextElement(); if (otherApplet!=this) break; // do something with otherApplet, e.g. // if (otherApplet instanceof FooApplet) ... }
Some people suggest using the static members of a common class to communicate information between the applets. This is not recommended as it relies on class-loading behavior that may change in future.
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. One alternative is to make them into one applet with two GUIs. 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?
One programmer suggests using percentages for the height/width parameters in an applet tag, like this:
<APPLET CODE = "lewinsky.class" WIDTH="100%" HEIGHT="100%" >
You can't resize the applet directly, but it does get resized when you resize the browser window (tested with Netscape 3.04 and 4.04, but does not work with appletviewer). If you have nothing else on your HTML page and use 100% for your width and height, the browser window looks almost like a real application.
For the extremely tricky: have the browser reload the page with the applet when the browser resizes using new values for width and height (probably not what you want most of the time). You would need javascript to generate a page dynamically using document.write("...") when the browser resizes. Not recommended. Another possibility is to use the new SplitPane class in JFC.
4.1.15 How do I read a text file stored in a JAR?
Sun's HotJava browser fully supports the JDK 1.1 features.
People who are obliged to use a browser without standard Java support should use Java Plug-In. Java Plug-In substitutes a standard Java virtual machine for that shipped with the browser. It allows you to use RMI, JavaBeans components, and Java Foundation Classes in Internet Explorer 3.02, 4.0, and 4.01. Java Plug-In also works flawlessly with Netscape browsers. You can download Java Plug-In from http://java.sun.com/products/.
4.2.2Is 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.
4.2.3 I am developing an applet and testing it in Netscape Navigator.I find that after I recompile, I press reload, clear the caches, retype the URL of the HTML wrapper, and I still have the old version. Why is this?
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.
4.2.4 So,why can't Netscape reload the applet when you press the Reload button?
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.
4.2.5 Should I use Microsoft CAB files or Java JAR files?
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:
IE3 does not support JAR
IE4 supports compressed and uncompressed JAR, but not signed JAR
The Swing toolkit allows the creation of GUI's that are every bit as sophisticated as native code toolkits like MFC -- with the Java advantage that they run on every platform. The pluggable look and feel means that they can have the exact same appearance on every platform too, if the user chooses it.
With Swing, native window behavior is confined to external window frames (and their borders) and a few other things such as fonts and the buffers used to hold window contents. The composition, layout, and drawing of controls is now all handled by Java code. So identical code is executed to create and manage your user interface on every platform. Swing provides a much greater consistency of behavior across different platforms.
Swing works with JDK 1.1 if you download the swing.jar file and add it to your path. Swing is built-in to JDK 1.2, and Javasoft has just changed its 1.2 swing package naming strategy. It is leaving it as com.sun.java.swing to be compatible with JDK 1.1.
4.3.2 Why is my menu showing up behind other components when I use Swing?
For those who want the quick fix, and will read the article later, adding the line:
com.sun.java.swing.JPopupMenu.setDefaultLightWeightPopupEnabled(false);
before you create any menus will probably fix it (even if you're using menus other than JPopupMenu).
The summary answer is that a Lightweight component will not appear over a heavyweight component by default.
4.3.3 Why does my JFrame go away after I chose system close on the window?
The reason is that JFrame's have default handling of the system close operation, separate from the windowClosing event. You have to override that by calling:
setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
on your JFrame.
4.3.4 Should I use Swing or AWT to build my GUIs?
4.3.5 Where can I find a Swing tutorial?
Please let the FAQ maintainer know about other good Swing tutorials.
4.3.5 How can I run Swing code in a browser?
Another approach is to use the Java plug-in, which automatically gives a Swing compatible Java in the browser.
5.2 How do I print from a Java program?
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.
The JDK 1.1 printing API is more a screen hardcopy facility than a full blown publishing and illustration hardcopy API. JDK 1.2 offers a more full-featured printing API.
If you simply want to print text, then write it to a file and print the file. Or open a filename that corresponds to the printer. On Windows, that is "LPT1" and the code looks like:
try { FileOutputStream fos = new FileOutputStream("LPT1"); PrintStream ps = new PrintStream(fos); ps.print("Your string goes here"); ps.print("\f"); ps.close(); } catch (Exception e) { System.out.println("Exception occurred: " + e); }The final formfeed is needed by windows to start the printjob.
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".
5.4 Is there any package in Java to handle HTML?
5.5Why don't Dialogs work the way I want them to?
5.6 Where can I find information about the sun.* classes in the JDK?
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
5.7 How do you read environment variables from with a Java program?
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:
or
This sets the "foo" property to the value of the environment variable foo, and makes it available in the System properties. Make sure you do not leave any spaces after the -D or around the = sign. Inside the program you get the value with:
String env = System.getProperty("foo");
More simply, just put the environment variable on the commandline
and read it as arg[0]
Finally, you could execute a Runtime process to get the environment variables if you are on a platform that has them. This is a poor approach as it builds platform-specific knowledge into the program. See Q10.5 for more details. On Unix, the command that prints environment variables is "/usr/bin/env". On Windows95, it is "set"
5.8 How do you use the Date class to display the current time in my timezone?
DateFormat df = DateFormat.getDateInstance(); df.setTimeZone(TimeZone.getDefault());
If there is no preset timezone, it used to default (prior to JDK 1.1.2 or so) to PST - Pacific Standard Time as used in California. Since 1.1.2 the code now defaults to GMT when no TZ is in the properties file.
The default TZ that Java starts with may well be wrong for your purposes. You are frequently better off if you explicitly set the default TZ (not much of a default, is it?) with, e.g.
TimeZone tsz = TimeZone("ECT"); // use ECT timezone or whatever. TimeZone.setDefault(tsz);It is also possible to set a timezone not with a string, but according to a number of hours and minutes offset from GMT. Actually, the default timezone
If you want to see the properly formated version of your Date, you shouldn't use myDate.getTime().toString(). A Date object now only represents an instant in time, resolved to the millisecond. All other uses (such as extracting individual fields or formatting) have been deprecated. To display the current date 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); mon++; // in class Calendar & GregCal, months run 0-11 ;-( 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. Here is an example:
import java.util.*; import java.text.*; Locale.setDefault( Locale.ENGLISH ); System.out.println( DateFormat.getDateInstance(DateFormat.SHORT).format(new Date()) );
This will print (on April 7, 1998):
4/7/98
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")); System.out.println( formatter.format(new Date()) );
The last line results in output of: "7 Apr 1998 21:52:06 GMT"
You can even use:
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.9How are dates represented in Java?
The scheme is sufficient to represent dates from 292,269,053 B.C. to 292,272,993 A.D. (64 bits covers -9223372036854775808 to +9223372036854775807 millesecs so divide by 1000 to get secs, divide that by 3600*24*365.25 to get years, and you get -2.9227E8 to 2.9227E8 centered on the Epoch i.e. about 292,269,053 BC to 292,272,993 AD).
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.
You could consider using the BigDate class written by Roedy, and available at http://oberon.ark.com/~roedy
5.10 That may be, but how do I extract day, month, year from a Date?
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 (perhaps in vain) all this junk will be fixed once and for all in a future release.
5.11 How do I create my own Time Zone to apply to dates?
bst_tz = new SimpleTimeZone( 6 * 60 * 60 * 1000, // +6 hour offset from GMT "BST"); TimeZone.setDefault(bst_tz);
You can then apply that TimeZone to create a Calendar object like so:
GregorianCalendar BritishSummerTime = new GregorianCalendar(bst_tz);
5.12 How do I create the BST timezone specifically?
In most or all other timezones, daylight saving time is handled automatically and internally. But GMT is the reference for all other timezones, and so does not have the summertime update applied automatically. So here is the code to create a British Summer Time timezone that is offset 1 hour from GMT between two dates:
import java.util.*; import java.text.*; // BST runs from last Sun in March to 4th (not last) Sun in Oct // create a BST timezone (code courtesy of Tony Dahlman). SimpleTimeZone bst_tz = new SimpleTimeZone( 0, // no offset from GMT "BST", // individualized tz id Calendar.MARCH, -1, Calendar.SUNDAY,2*60*60*1000, // first Sun Apr 2AM Calendar.OCTOBER, 4, Calendar.SUNDAY,2*60*60*1000 // 4th Sun Oct 2AM ); // set the BST timezone as the default SimpleTimeZone.setDefault(bst_tz); // apply that TimeZone to create a Calendar object like so: GregorianCalendar BritishSummerTime = new GregorianCalendar(bst_tz,Locale.UK);
and here is how you would print out values using BST:
// create a template for printing the date DateFormat df = DateFormat.getTimeInstance( DateFormat.LONG,Locale.UK); // tell the template to use BST tz. df.setTimeZone(TimeZone.getDefault()); System.out.println("Using British Summer Time " +"the time is: " + df.format( BritishSummerTime.getTime() ) ); // Now get and compare with current time in GMT df.setTimeZone(TimeZone.getTimeZone("GMT") ); System.out.println("\nCurrent time in GMT is: " + df.format(BritishSummerTime.getTime() ) );
In the winter, this BST zone is aligned with GMT; in the summer it is one hour later (4am GMT is 5am BST).
You can look at a list of timezone names and offsets in the file $JAVAHOME/src/java/util/TimeZone.java
5.13 What kind of different date formats are allowed for the Date constructor with the string parameter?
Instead, you should convert a date/time String into a Date like this:
// don't forget to set the default TZ if needed. DateFormat HHmm = new SimpleDateFormat( "HH:mm" ); HHmm.setTimeZone( TimeZone.getDefault() ); Date lunch = HHmm.parse( "12:30" ); System.out.println( lunch );The above code would result in (when in the MST timezone),
Thu Jan 01 12:30:00 MST 1970To parse other date and time fields, refer to the SimpleDateFormat documentation.
5.14 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.
5.15I can't seem to change the current working directory.
5.16How do I create a Vector of ints?
int i =7; Vector holdsInts = new Vector(5,1); holdsInts.addElement(new Integer(i)); int j = ((Integer)holdsInts.elementAt(0)).intValue();
5.17 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?
5.18How do I get random numbers?
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:
import java.util.Random; 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 gracelessly 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 (inclusive):
java.util.Random r = new java.util.Random(); int j = (r.nextInt() & Integer.MAX_VALUE) % (high-low+1) + low;
The sentence above 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, but we "and" the nextInt() to convert it to zero. Sure, it's unlikely to occur, but you don't want the reactor going critical just because you missed this case while testing.
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 a (mod 2^n) operation.
5.19 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().
5.20 Where/why should I use the Enumeration interface?
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() ); }
And here's how you might look at all the tokens in a String:
StringTokenizer tokens = new StringTokenizer (SomeArbitraryString, "\n", false); Enumeration enum = tokens.elements(); while enum.hasMoreElements() System.out.println(enum.nextElement());
You should look for opportunities in your own data structures to implement Enumeration, anywhere where the structure has repeated elements.
5.21 Which version of WinZip is compatible with java.util.zip?
5.22 What is the Model/View/Controller paradigm?
There's a reasonable white paper on MVC in Swing at http://java.sun.com:81/products/jfc/swingdoc-static/swing_arch.html.
5.23 How can Java access other fonts on my system?
For fuller details, check the website http://www.alumni.caltech.edu/~dank/javafont.htm and the JavaSoft site at http://java.sun.com/products/jdk/1.1/docs/guide/intl/fontprop.html They have lots of information on this.
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.2Why 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().
6.3How do I write to the serial port on my PC using Java?
For systems prior to JDK 1.2, read on. 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/ It's free under the GPL, and works on Linux, Irix, Solaris, Win95, NT.
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/
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. Here is some sample code.
//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); } } }
public FileWriter(String fileName, boolean append) throws IOException public FileOutputStream(String name, boolean append) throws IOException
Another 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.5Is 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.
6.6How do I make the keyboard beep in Java?
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() ?
6.8 How do you do file I/O from an applet?
The simplest approach for server-side I/O is to use the Linlyn class available from http://www.afu.com. This is free software under the GNU license, and uses FTP to move files between an applet and the server. It is suitable for low-volume non-critical use like keeping a high-score file. The Linlyn class has a very simple application programmer interface.
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); // JDK 1.0.2: DataInputStream in = new DataInputStream(url.openStream()); BufferedReader in = new BufferedReader( // JDK 1.1 and later new InputStreamReader( url.openStream() ) ); String s = in.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:
In particular:
2. WebNFS. This is an evolution of the NFS (Network File System) to make file resources visible in browsers. More information at http://www.sun.com/webnfs
3. Open a socket back to the server and read/write the data. Have a process on the server that listens for socket connections from applets and does the requisite I/O. This does I/O on the server.
4. 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).
6.9 I used a C program to write a binary file. When I instantiate a DataInputStream on the file in Java, and try to readInt, I do not get the correct numbers. Why is this?
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 )And this code will assemble a double that has been written in reverse byte order:
byte[] gnol = byte[8]; stream.read(gnol); long l = ( (gnol[7]&0xff)<<56) | ((gnol[6]&0xff)<<48) | ((gnol[5]&0xff)<<36) | ... // and the rest double d = Double.longBitsToDouble(l).doubleValue();
6.10How do I make I/O faster? My file copy program is slow.
6.11 How do I do formatted I/O of floating point numbers?
Or use http://www.newbie.net/sharky/lava/ Or do a web search for hbprintf. Or use http://www.apl.jhu.edu/~hall/java/CoreJava-Format.html for the html with the javadoc info. The actual file is called http://www.apl.jhu.edu/~hall/java/CoreJava-Format.java However, you must rename the file to Format.java for it to compile. Also, one version of this had a bug: when you try to format a true 0 you go into an infinite loop (need to test d in exp_format).
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.
6.12How do I read numbers in exponential format in Java?
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; } // end switch } // end while } catch (IOException e) { System.out.println("IOException: " + e); } } // end main }
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.14How do I delete a directory in Java?
Make sure you don't have any open streams in the directory you're trying to remove. Do a close() on all streams, even if the underlying file is gone.
6.15 How do I tell how much disk space is free in Java?
Alternatively, check out JConfig:
http://www.tolstoy.com/samizdat/jconfig.html
JConfig is a cross-platform library that fills in many of the gaps in the
core Java API, and makes it possible to work with files, processes, file
types, video monitors, etc. in a much more Windows and Mac friendly manner.
6.16 How do I get a directory listing of the root directory C:\ on a PC?
File.list("C:\\."); or File.list("C:/.");
6.17 What is the difference between the various ZIP formats: ZIP, GZIP, and PKZIP?
The PNG format is specified in RFCs 1950, 1951, and 1952, and is unencumbered by licenses or patents.
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
Jar files are in ZIP format, but are not as complete as a full filesystem
archive format since file permissions are not saved. Some versions of WinZip
are known to be inadequate for processing the full PKZIP format. Use InfoZIP
instead.
6.18 How can I use characters other than ASCII in Java?
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].
6.19 I did a read from a Buffered stream, and I got fewer bytes than I specified.
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. 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/.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()); } } }
6.20 How do I redirect the System.err stream to a file?
FileOutputStream err = new FileOutputStream("stderr.log"); PrintStream errPrintStream = new PrintStream(err); System.setErr(errPrintStream);
This was introduced with JDK 1.1. There is also a corresponding setIn() for redirecting standard in, and a setOut() for standard out.
Note that you will get a compiler warning about a deprecated construct when you do this. PrintStreams are deprecated in favor of PrintWriters which handle Unicode properly. The PrintStream is marked as deprecated by marking all its constructors as deprecated. There is no way to create the PrintStream needed to redirect System.err or System.out without triggering the deprecated warning.
If you need to connect to C++ (or other language) systems or you need CORBA-specific services, then CORBA is your choice.
has a good intro to CORBA in the Java world.
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.
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?
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)
One gotcha under Win95 is that if the last entry in the hosts file
is not concluded with a carriage-return/line-feed then the hosts
file will not be read at all.
So if my system is called goober.best.com change the hosts file from
to
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
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
triggers the exception. Why?
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.UnsatisfiedLinkErrorno
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.
7.5I
want to pass a class file to willing recipients who are using my applet.
Any ideas how?
7.6
How do you succeed with new URL(someURL) from behind a proxy server?
note proxyPort is optional and it defaults to 80.
Without this, you will see an exception like:
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
127.0.0.1 goober.best.com localhost
Showing more of the file:
# Hosts file
127.0.0.1 localhost
129.146.77.177 goober
Socket sock = new Socket("155.152.5.1", 23);
InetAddress in = InetAddress.getByName("155.152.5.1");
in order to get jdb to run.
A. Tell the run time system what you are trying
to do, like this:
java.net.UnknownHostException
7.7What is "swizzle", as in "Swizzle this object?"
7.8I have been using the Serializing capabilities in 1.1 to save some objects to disk. I added a new field to one of my objects that get serialized and now deserializing my old data no longer works. I get this exception:
java.io.InvalidClassException: MacroData; Local class not compatible
A. 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
in the class. This is how versioning is achieved.
7.9My socket code looks good, but is broken!
[comments from net gurus welcome]
7.10 How do I map between IP address and hostname?
String host = InetAddress.getByName("211.10.2.119").getHostName();
7.11How 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.12RMI 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:
Visit the archive!
7.13 After a number of RMI client to server connections (55 on my system), subsequent RMI clients trying to connect fail. Why?
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).
7.14 How do I POST to a CGI script from an applet?
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");
7.15 How do I get a URLConnection to work through proxy firewalls?
// set up to use proxy System.getProperties().put("proxySet", "true"); System.getProperties().put("proxyHost", "proxy.server.name"); System.getProperties().put("proxyPort", "80");
Q. But how do I know the name of the proxy server?
A. This code just tells you how you can get a URL connection to the outside.
Since it is your proxy server, you are expected to know the name of it. There
isn't any code that you can write that will allow arbitrary URL connections
to be initiated from outside the firewall. Think about it! If there were,
the firewall would not be doing its job.
7.16 How can I write CGI programs in Java?
Unfortunately, the interface between the web server and the CGI program uses environment variables extensively. Use of environment variables has always been deprecated in Java, because of portability issues (not all systems have environment variables). The way to get around this is to write a "wrapper" for the Java program in a language that supports environment variables, and can then invoke the Java program with the appropriate environment data passed in as Java properties.
Because the Java runtime environment is not a lightweight process, it might take a moment for the CGI program to get started before anything happens. This is particularly true on operating systems, like NT, that have a large overhead to spawning new processes.
In preference to using Java for CGI on the server, you might consider using the Java servlet API in Netscape's Enterprise Server. This allows you to develop server-side programs in Java without suffering the same performance restrictions and other limitations of the CGI API. See http://search.netscape.com/comprod/server_central/query/eval_guide/enterprise/advantage.html for more details.
7.17 How can I write the "ping" program in Java?
Ping requires ICMP packets. These packets can only be created via a socket of the SOCK_RAW type. Currently, Java only allows SOCK_STREAM (TCP) and SOCK_DGRAM (UDP) sockets. It seems unlikely that this will be added very soon, since many Unix versions only allow SOCK_RAW sockets to be created by root, and winsock does not address ICMP packets (win32 includes an unsupported and undocumented ICMP.DLL).
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.
8.2 Does Java support Animated GIFs?
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.1How 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.
If that does not solve it then check that:
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.4How do I play video in Java?
The spec can be found at
Intel has released a SDK for the Java Media Framework Player API. The SDK is for Windows 95 and Windows NT For more information, see
SGI has released an implementation of JMF for IRIX:
8.5How can I play *.au files from an application?
public final static AudioClip newAudioClip(URL url) {
The method turns a URL (pointing to an audio file) into an AudioClip. Since the method is static it can be used without any objects of class Applet needing to exist, e.g. in an application. Once you have an AudioClip, you can play it with
MyAudioClip.play();
The Java Media Framework provides a richer API for playing sounds in an application.
For code prior to JDK 1.2, you can use the AudioClip or AudioPlayer class in sun.audio http://www.javaworld.com/javaworld/javatips/jw-javatip24.html If you do this your code is no longer 100% pure Java, as it relies on a vendor library.
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.6How 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?
Javasoft recommends against explicit calling (and, presumably overriding also) of addNotify() by applications programmers - this is especially important in these days of Lightweight components that do not have peers. If you have any code that requires peer resources, move it into a thread that is started from a conditional branch of the paint() or update() method.
A common reason for seeming to require peer resources in a constructor, or alternatively in the getPreferredSize() method, (which is also usually before the peer is created) is to measure the area required for your window, in terms of font and image sizes. Font sizes may be obtained by applying Toolkit.getDefaultToolkit().getFontMetrics() to the required font. This does not require a peer. Image sizes may be obtained by waiting for the relevant Image to load from the ImageProducer by using an ImageObserver, or a MediaTracker (see 8.15), also without requiring a peer. See 15.4 for more discussion of this problem.
If you override addNotify(), don't forget to call super.addNotify() in your overriding version.
8.8 How can Iforce a reload a fresh version of an image into my applet? My image file is changed periodically, and I want the applet to go and retrieve it, not cache it.
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 Isave an Image file to disk in jpg or gif format?
Jef Poskanzer has written an abstract ImageEncoder class and implemented
it for GIFs and PPMs. Those are at
http://www.acme.com/java/software/
A non-java solution is to use the standard IJG 'cjpeg' utility. It supports
GIF, PPM, BMP, PNG and Targa input files.
Hong Shi wrote a PPM to JPEG convertor.
http://www.ctr.columbia.edu/~hshi/report6880.htm
Sean Breslin has written a program that compresses a Java Image into a JPEG
file. http://www.afu.com/jpeg.txt
Florian Raemy has written a program that encodes a JPEG then decodes it again.
http://lcavwww.epfl.ch/demos/jpeg.html This is a proof of concept, not
industrial strength code that meets the JFIF (JPEG File Interchange Format)
standard.
8.10 What causes this problem?
$ 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.
8.11How can I convert between GIF and JPEG formats?
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/
8.12If you have an InputStream (rather than a file) that contains an Image, how can you display it?
Create a thread that pretends to be an http server. Make it listen to some port (8765 for example) for incoming requests. When the thread gets a request, it should simply whisk up the appropriate http headers and follow it by the InputStream. Thus the component that has the input stream and wants to do the getImage(url) can now invoke:
Toolkit.getImage("localhost:8765/")
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.
8.13 How can I record sounds in Java?
JMF 1.0.1 is bundled with JDK 1.2, and available as a separate download for
JDK 1.1 and Netscape Communicator 4 with Java 1.1. In the meantime, there
is a package for Win95/NT available at
http://www.scrawl.com/store/
It supports 8, 16-bit, stereo, mono, 11025, 22050, 44100 Hz record/play,
load/save .WAV files. You could also interface to native code for your platform.
8.14 Does Java have any built-in support for displaying HTML?
8.15 I loaded an Image file from a JPEG/GIF file using the Toolkit/Applet.createImage(URL/String) method, and (the height and width are -1 / it will not draw to the screen). What is wrong?
class MyComponent extends Component { ... public void paint(Graphics g) { ImageFilter cropper=new CropImageFilter(0,0,16,16); Image cropped_image=createImage(new FilteredImageSource(image.getSource(),cropper)); g.drawImage(image,10,400,this); // this line works g.drawImage(cropped_image,400,15,this); // this line doesn't - } }
since the cropped_image will not be created in time to be painted, and when it is finally created, another call will be scheduled to paint, which will try to draw another one, etc.
(Note also that creating objects like this in paint() methods is generally a very poor idea in Java, since they are called very frequently, and you will strongly offend the garbage collector. See 15.4 for examples of how to reuse objects.)
In order to get round this problem, you may i) add all such Images to a MediaTracker, and call the waitForAll() method. ii) implement your own ImageObserver interface, and wait for the imageUpdate() method to be called with the ALLBITS/FRAMEBITS value. i) is easier, but ii) is recommended, since there are reports of MediaTracker not working in some environments. See also 8.12.
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.
9.2 What is the story with Java and viruses? What is the blackwidow virus?
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).
In spring 1998 there were press reports of a "Java applet" called White Ghost. It turns out that it relies on security flaws in ActiveX, and the only susceptible systems are Microsoft's Active Desktop. If anyone has a URL for a copy of this code, and an analysis of it, please contact the FAQ author.
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 author.
9.3 Why do I get the warning string at the bottom of popup windows"Unsigned Java Applet Window" in my applets?
9.4Where can I find crypto libraries for Java?
A comprehensive and free crypto library (called Cryptix) is at
Another crypto library for Java is at
Blowfish, CRC16, CRC32, DES, DES3, IDEA, RC4, ROT13 (can they really call that "crypto"?), and more.
One commercial Java encryption source (from Ireland) is
A complete crypto API for Java (with HTML documentation) at:
The library provides comprehensive and complete range of crypto library and functions covering DES, 3DES, IDEA, Blowfish ...and RSA, DH, DSA and PGP access to Java programmers. The crypto functions are based on the C cryptlib, by Peter Gutmann. It would be illegal to export this under current US government rules, but the author of the code is outside the US, and not subject to US export regulations. Download it today before it becomes illegal.
Also, early access to Sun's Java Cryptography Extension (JCE) is available for JDK 1.1 at:
(This may not be exported outside the USA and Canada).
An actual port of PGP v2.6.3i to Java is at http://tassun.math.nsc.ru
9.5How do I find out what these terms mean?
9.6 Where is Javasofts Security FAQ?
String mystring = numString.trim(); int i = Integer.parseInt(myString); long l = Long.parseLong(myString)
or
String mystring = numString.trim(); i = Integer.parseInt(myString,myIntRadix);
Note 1: there is a gotcha with parseInt: it will throw a NumberFormatException for String values in the range "80000000" to "ffffffff". You might expect it to interpret them as negative, but it does not. The values have to be "-80000000" .. "-ffffffff" to be properly recognized as negative values. This is true for all radixes. According to Bug Parade bug report 4068580, the proper way to generate negative-valued hex Strings for eventual use by parseInt() is with Integer.toString( i, 16 ) ." Once that high "sign bit" is on, without the accompanying - character, parseInt() says "too big".
Note 2: there are similar methods for Byte, Short, and Long. Use myString.trim() to get rid of unwanted spaces before the conversion. Some of the parse methods can cope with spaces, others can't. They were written by two different people.
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(); double d = Double.valueOf(my_str).doubleValue();
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.3 How 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.5How do I execute a command from Java?
10.6 How do I do I/O redirection in Java using exec() ?
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.
10.8 OK,how do I read the output of a command?
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 Icompile code which has a cyclic dependency, i.e class pkg1.X contains a reference to class pkg2.Y ?
10.10 How can I store the errors from the javac compiler in a DOS file? javac foo.java > errorfile doesn't work.
On Win95, this doesn't work (as command.com is very poor software), so you have to use the javac error redirection mechanism:
10.11How can I pretty-print Java source?
indent (fails with "//" comments though)
cb (very few style choices though)
alias printjava 'vgrind -lC++ -t -w \!* | lp'
works pretty well too.
Perhaps the best tools are the GNU utilities. Use enscript to generate postscript files with Java-specific formatting. Then use GhostScript/GhostView to preview and print the files to a non-PostScript printer, if necessary. The scripts can be found at:
10.12 What is the point of creating the temporary reference to this.layoutMgr? This code is from the 1.0 AWT, and the programmer was probably pretty skilled.
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.13What 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.
10.14If I create a thread, and then null out the reference to it, what happens to the thread? Does it get interrupted or what?
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 Howdo 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().
10.17 How can I set a system property?
System.setProperty( "property", "new value" );Until then, you can get all the properties, and set just the one you want with code like this:
System.getProperties().put("property", "new value" );10.18 How can I clone using serialization?
import java.io.ByteArrayOutputStream; import java.io.ByteArrayInputStream; import java.io.ObjectOutputStream; import java.io.ObjectInputStream; public class Cloner { private Cloner() {} public static Object cloneObject(Object o) throws Exception { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ObjectOutputStream out = new ObjectOutputStream(bOut); out.writeObject(o); ByteArrayInputStream bIn = new ByteArrayInputStream(bOut.toByteArray()); ObjectInputStream in = new ObjectInputStream(bIn); return(in.readObject()); } public static void main(String args[]) throws Exception { java.util.Vector v = new java.util.Vector(); v.addElement(new StringBuffer("Hello")); java.util.Vector vClone = (java.util.Vector)Cloner.cloneObject(v); // Changing the StringBuffer int the cloned vector has no effect // on the original StringBuffer object -- demonstrating that we have // indeed done a deep copy ((StringBuffer)vClone.elementAt(0)).append(" world"); StringBuffer sb = (StringBuffer)v.elementAt(0); System.out.println(sb.toString()); sb = (StringBuffer)vClone.elementAt(0); System.out.println(sb.toString()); int array[] = { 1, 2, 3, 4, 5 }; int arrayClone[] = (int [])Cloner.cloneObject(array); // Again, changes to an element in the cloned array do not have any // effect on the original arrayClone[0]++; System.out.println(array[0]); System.out.println(arrayClone[0]); } }The main() routine is just a driver. All the cleverness is in the very brief cloneObject(). It does a "deep" clone, which is what you usually want (though Java gives you a "shallow" clone by default).
Going the other way there are currently three freely-available tools to translate Java into C. It seems that these have been done for hacking value, rather than practical purposes.
None of them support the AWT yet, and both j2c and JCC have additional restrictions.
There's a product to convert Visual Basic to Java. Details at
This program dumps info about the class file:
Chuck McManis was one of Sun's original Java implementors.
11.2 How are finalizers different from C++ destructors?
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.
11.3What's the Java equivalent of sizeof()?
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. Some people have suggested that you can find out the size of an object by having the object serialize itself to a ByteArrayOutputStream, and looking at the bytearray.length.
That won't work because a lot of additional data is written when an object is serialized. The additional data includes a description of the class, any objects referenced by the serialized object, null references (written as a single byte), etc. If you write another instance of the same class, the amount of data written can differ dramatically. And if you serialize the same object again, it isn't written at all -- even if its data fields have changed! Instead, a one byte token and a four byte "sequence number" that refer to the first writing are output. Using Object Serialization to determine the size of an object does not (except by coincidence) give the right answer.
11.4Does Java have the equivalent of "const" arguments in C and C++?
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 ints
11.5Are 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.6How 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.
If a language lawyer wants to weigh in on this theory, please go ahead.
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.7How 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 mydf = new DecimalFormat( "###0.000" ); mydf.setMinimumIntegerDigits(3); // for example System.out.println( mydf.format(fi) );
gives:
There are lots of different characters you can feed to the DecimalFormat constructor, not just "0". See $JAVAHOME/src/java/text/DecimalFormat.java source for details.
11.8 What is the Java equivalent of C++ friend"?
The four different Java protection levels are: private, package, protected, and public.
11.9Does 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: now disappeared from original site, if anyone knows whereabouts,
please send details.
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, JFC, AFC, WFC, 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. Many IPSs don't provide direct access to these groups (or those of other companies) but you can access them by setting the NNTPSERVER environment variable to point to the newserver.
12.3Are there any commercial/shareware/free Java libraries?
The documentation for JDK 1.2 explains that the Collection Framework defines three kinds of thing:
The standard interfaces are Collection, Set, List and Map, plus the more specialised SortedSet and SortedMap. Lists have duplicate elements whereas Sets do not. Finer distinctions such as immutability are defined in the implementor classes, enforced by throwing runtime exceptions. See the JDK1.2 documentation for a full discussion. Also see http://byrden.com/java/Tree/index.shtml for a description of extending the collection framework, and a freeware class implementing trees.
For more about sorting prior to JDK 1.2, look at the class SortDemo in the demo directory of the JDK. Alternatively, use one of the several classic sorts available from Roedy Green. They are supplied free with heavily commented Java source code.
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.
Visual Numerics has its Java Numeric Library available for download at http://www.vni.com/products/wpd/jnl/jnl_1_0.html. They offer the JNL as a proposed standard library for numerical functions missing from Java.
12.4 Why doesn't somebody write a shell in Java? Then they could use it on all platforms!
12.5 Are there any URLs for other libraries?
12.6 Are there any URLs for regular expression handlers in Java?
And don't forget to check out Lava -- a set of Java classes designed to support programmers who develop console-mode applications and/or C programmers who are converting to Java. The first release of Lava has printf and other text formatting, encryption, parsing and miscellaneous I/O. Lava can be downloaded from http://www.newbie.net/sharky/lava/
Also consider the Java version of the Unix find command. It offers Regex filename matching, mindepth, maxdepth, symlink follow / no follow, file type matching all cross-platform. The package is at http://www.geocities.com/~shecter/java.html
12.7 Are there any installers for Java? Preferably platform-neutral ones.
Don't set your CLASSPATH at all when starting out. If you have it set from a previous installation of JDK 1.0.2, unset it. The system knows where to look for libraries and your Java class files. By default, it searches your current directory. If you are creating your own packages, you might want to set CLASSPATH so it looks in the right places to find them.
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);
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.
Also recall that the Math package works in radians, not degrees. 360 degrees
= 2 pi radians. So use a conversion factor as shown if you are working with
degrees.
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. But when calling from a static method, you must provide the information, and you haven't - hence the error message.
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?
import java.awt.*; import java.awt.event.*; public class MyFrame extends Frame { public MyFrame(String s) {super(s);} public class WL extends WindowAdapter { public void windowClosing(WindowEvent e) {System.exit(0);} } // do your other Frame stuff }
Somewhere in your initialization code, put:
f1.addWindowListener( f1. new WL() );
This last syntax is not commonly known to many people yet, it's another whacky artifact of inner classes.
Alternatively, combining the inner class and setting the handler in one go, you could do this:
MyFrame f1 = new f("wave"); f1.addWindowListener( new WindowAdapter() { public void windowClosing(WindowEvent e) { // and/or setVisible(false) and/or dispose() System.exit(0); } });
See also the answer to Q.4.0.19, 4.0.30, and 15.7.
13.10 Why is b+=100; OK, but b = b+100; fails to compile?
byte b = 0; Incompatible type for =. Explicit cast needed to convert int to byte. b = b + 100; // compiler error message ^ b += 100; // works OK
The reason is "promotion". Arithmetic expressions are promoted to the type of the longest, floatiest operand in them, or at least to int. The first statement involves the assignment of an expression. The expression is promoted to 32 bits, and must be cast back down to 8 bits, like this "b = (byte) (b+100);". The second is an operator assignment, and the cast back to byte takes place automatically. The Java Specification says:
The compile-time narrowing of constants means that code such as:
byte theAnswer = 42;
is allowed, with no cast necessary. [JLS 5.2]
13.11 How do I add two Float objects together?
Float One; Float Two; Float Hard = One + Two;
but the compiler does not allow it.
Java has two separate ways of representing a 32 bit floating point number, Float and float. Float is a class, that whose sole purpose is to "wrap" a floating point number so it can be treated as an object. The class does not support floating point arithmetic, because the performance would be too slow. float is a primitive type (like int) that is used for floating point arithmetic.
You choose one or the other depending on your predominant use. If all you need of your floating point numbers is arithmetic, declare them to be "float". If you need to use them as objects, for example to place them in a Vector, declare them as "Float".
If you need both, tough. You have to declare them one way and convert whenever you need the capabilities of the other. Your specific code can be written as:
Float One = new Float(1.0); Float Two = new Float(2.0); Float Hard = new Float(One.floatValue() + Two.floatValue());
See also 3.8, 5.1 and 10.1.
13.12 How can I put all my classes and resources into one file and have java run it?
jre -cp app.jar Main
assuming the jar is called app.jar and it has a class called Main that has the main() method for the application.
13.13 How can I see line numbers in a stack trace using JDK 1.1.6?
To see the line numbers where your program throws an exception, use the -nojit option to turn off the Just In Time compiling.
See also "The 10 Most Common Java Programming Mistakes": http://webreview.com/wr/pub/97/12/19/feature/sidebar.html
14.2 I'm using Win95, and my DOS window won't accept filenames longer than 8.3.
If the option is checked you get exactly the kind of behavior you're seeing. The option is unchecked by default, so it must have been selected at some time in the past. Change it back to unchecked.
14.3 I'm using notepad to edit my files, and how can I save them with the extension ".java"? Also, in notepad some source files have all the characters on one line. Why is that?
Second answer: notepad expects to see a "carriage return/line feed" pair at the end of each line, rather than just the "newline" (line-feed) commonly used on Unix. Use this program to expand all newlines,
/* * Usage: jre crlf file1.java file2.java ... fileN.java */ import java.io.*; class crlf { public static void main(String s[]){ byte b[]; byte p; FileInputStream is; BufferedOutputStream os; File f; for (int i=0; i < s.length;i++){ try{ f=new File(s[i]); b=new byte[(int)f.length()]; is = new FileInputStream(f); is.read(b); is.close(); os = new BufferedOutputStream( new FileOutputStream(s[i]),b.length); p='?'; for(int j=0; j < b.length; j++){ if((p!='\r')&&(b[j]=='\n')) os.write('\r'); p=b[j]; os.write(p); } os.flush(); os.close(); }catch(IOException e){ System.err.println(e.toString()); } } } }The source code is to show new users a way to make a simple program which can read a file and write it out buffered.
compile with "javac crlf.java" and run with
java crlf
or just use wordpad instead of notepad. Wordpad is under
Start->Programs->Accessories->WordPad
Microsoft has continued its attempt to fragment and undermine support for Java with J++6. First, it bumped the version number up, skipping over releases 1.2 , 3, 4, and 5. This aligned the number with other MS products, but falsely conveys the impression that J++6 is an equally stable and mature product. (A similar thing ocurred with NT, which was introduced at version 3.1, and with Microsoft's CIFS - Common Internet Filesystem, which is neither common nor an internet standard. It was actually renamed to CIFS as part of Microsoft's wishful thinking to make this NT remote file protocol be adopted all over the web). Then Microsoft introduced two new keywords ("delegate" and "multicast"), as well as the complexity of conditional compilation and conditional methods.
Microsoft's SDK has been moved further and further from standard Java with each successive release. J++ combined with the visual editor generates calls to the Windows-only WFC library. Anyone writing Java code that uses VJ++6 is needlessly restricting their programs to only ever run on Microsoft platforms. Microsoft has been cut off from future Java technology, so they do not have JNI, JFC, RMI, Java Beans, IIOP/CORBA hooks, Swing, PLAF & Accessibility, the Security API, Drag N Drop, among other features. If you like Java, you should encourage Microsoft to be compatible by not using their divergent tools.
The entire purpose of VJ++ is to get people producing near-Java code that only runs on Windows. The strategy is being challenged in the law courts, giving VJ++ an uncertain future. So please use one of the other free or inexpensive standard IDEs for Windows instead. See Q1.14 for a list of these IDEs.
You may see some programmers refer to J--. By this they mean Microsoft's incompatible J++ SDK.
14.5 How do I fix the message about "out of environment variable space"?
shell=command /e:4096
15.2 I changed a final value, and recompiled just the file that it was in, and the entire rest of the program used the old value!
class Flags { final static boolean debug = true; }
and you change it to, and recompile just this file:
class Flags { final static boolean debug = false; }
Then the rest of your Java .class files will still see it as "true".
When you declare a "static final int" (or any other primitive), the compiler turns that into a compile time constant whose value can be substituted wherever it is used in your program. If you update the value in the source file, you'll need to recompile every class that uses it.
See Java Language Specification, section 13.4.8 "final Fields and Constants": "We call a field that is static, final, and initialized with a compile-time constant expression a primitive constant. If a field is a primitive constant, then deleting the keyword final or changing its value will not break compatibility with pre-existing binaries by causing them not to run, but they will not see any new value for the constant unless they are recompiled."
15.3 What is the "substring trap"?
public String substring(int beginIndex, int endIndex)
The name "endIndex" suggests that is the index where the Substring ends.
But in fact, the substring extends only to the character at position (endIndex-1)! It seems to be done this way so that s.substring(0,s.length()) is equal to s. If so, the name of the second parameter should be something like endInxLessOne or Length. But not the confusing and misleading endIndex. Beware of the substring trap.
15.4 Why does getGraphics() return null on my offscreen image?
class MyFrame extends Frame { MyFrame() { Image offscreen = createImage(100,100); Graphics offg = offscreen.getGraphics(); } ... }
will usually not work, since the peer will not exist at this time. Without the peer for the Frame, you cannot succeed in creating offscreen Images. (There's no problem creating Produced Images without a peer. Trying to draw them, of course, is another matter).
One "standard" form of offscreen code looks like this: (note the reuse of the Graphics and Image objects for as long as possible)
class Gumble extends java.awt.Something { private Image offi; private Graphics offg; public void update(Graphics g) { if (g == null) return; // Paranoia Dimension size = size(); if ( offi == null || offi.getWidth()!=size.width || offi.getHeight()!=size.height ) { if (offg!=null) offg.dispose(); offi = createImage(size.width, size.height); offg = offi.getGraphics(); // Regenerate offi here... } // If you use getClipBounds() here, // check that for being null, too! // several implementations have been known to pass them.... g.drawImage(offi); } public void paint(Graphics g) { update(g); } }
See also 8.7;
15.5 The dynamic type of a method argument doesn't seem to be used to choose an overridden method at runtime.
It's not the same for object parameters: the compiler decides at compile time, depending on the types of the parameter expressions, which method signature to use, and this is "hardwired" into the bytecode. The compiler does not look at the object argument at runtime and say "ah, this is a derived type, so I will choose the method that takes the derived type as an argument."
This is best seen in a code example:
class Base { } class Derived extends Base { } public class foo { public static void method(Base b) { System.out.println("In the base method..."); } public static void method(Derived d) { System.out.println("In the derived method..."); } public static void test(Base b) { if (b instanceof Derived) System.out.print("Derived: "); else System.out.print("Base: "); method(b); // which method? method(base) or method(derived)? } public static void main(String args[]) { Base b = new Base(); Derived d = new Derived(); System.out.println("test calls."); test(b); test(d); } }
Running the program gives an output of
test calls. Base: In the base method... Derived: In the base method...
See JLS section 15.11.4.4 and 15.11.3:
"If class S contains a declaration for a method named m with the
same descriptor (same number of parameters, the same parameter types,
and the same return type) required by the method invocation
as determined at compile time then this is the method to be
invoked."
15.6 Why did I lose my updates when I changed data fields in a graph that I was serializing?
Within a stream, the first reference to any object results in the object being serialized or externalized and the assignment of a handle for that object. Subsequent references to that object are encoded as the handle.
In other words, changing an object and then writing it again does not really write it twice. Instead it just writes a reference back to the first occurrence, losing any fields that have changed in the meantime.
There are three ways around this: (1) (inefficient) Reset (or close and reopen)
the stream, and start again by writing the new value of the object. This
is drastic -- you are throwing away all the serialization that you have already
done.
(2) (kludgey) Create a new object and write that.
(3) (could be a lot of work) Write your own protocol for object serialization.
Have something like a data stream where the contents of an object are marked
by special identifiers. Each "end" of the stream can decide whether it will
use a new object each time or reuse an existing object.
15.7 When I click on a Java window frame, it doesn't close!
The window closing event handler is simple:
Frame mf = new Frame("binky"); mf.addWindowListener( new WindowAdapter() { public void windowClosing(WindowEvent we) { System.exit(0); // or setVisible(false); etc. } });
This really should be the default behavior of an AWT Frame. So you'll be delighted to hear that JavaSoft has "made it so" for the JFrame Swing component. That leads to a slightly different problem. See 4.3.3. See also 13.9.
15.8 What's the deal with "super"? How far back into parent classes can I go?
There is no way to "chain" several together, and reach back higher into the parent class hierarchy. You can reference your immediate parent class and that's it. Looking at the generated byte code, if you have
class Parent { } class Child extends Parent { }
then, in Child "super.someParentMethod();" means "invokespecial X.someParentMethod()" in the JVM, not "invokevirtual". Invokevirtual means "call the right method for whatever object this is". Invokespecial means "call the exact method I am telling you."
15.9 When I change some component (e.g. a new label on a button) I don't see the change on the screen immediately even if I repaint().
invalidate(); validate();
They cause the component hierarchy to be marked as needing to be laid out again, and the validate causes that to be done. It may be expensive, but is always the most reliable way of getting the peers to recalculate size and to do what is needed to bring the display up to date.
15.10 Why aren't popup menus working cross-platform for me?
Therefore you need to ask the question isPopupTrigger() in both the mousePressed() and mouseReleased() methods when implementing the MouseListener interface. Alternatively override Component's processMouseEvent as a central place for handling mouse input.
15.11 Why aren't newlines working cross-platform for me?
if (c == '\n') fin = true;
is not cross-platform. On Unix the line terminator is "\n", on Windows, it is frequently "\r\n", on the Mac it is "\r".
The call System.getProperty("line.separator") will return a string containing the platform-specific line separator character(s), and you then need to compare it according to how your data is formatted (e.g. compare 2 characters or one). There is also a property for the separator character in file pathnames, and other values too.
15.12 Why did my polygon come out the wrong shape?
int xPoints[] = {71, 78, 71, 78}; int yPoints[] = {147, 147, 130, 130}; g.fillPolygon(xPoints, ypoints, xPoints.length);
Developer Felix Pahl supplied the answer in limerick form:
You must put the points in the order you would encounter them in if you went round the polygon's border. The filling algorithm is doing the right thing! Try drawing the points on paper to see:
71,130 78,130 O--------O | | | | | | o--------o 71,147 78,147
Under JDK1.1, the two endpoints are connected automatically and you would order the array elements as:
int xPoints[] = { 71, 78, 78, 71}; int yPoints[] = {130, 130, 147, 147};
Under JDK1.0.2, you have to explicitly connect the two endpoints, and you would write the array elements as:
int xPoints[] = { 71, 78, 78, 71, 71}; int yPoints[] = {130, 130, 147, 147, 130};
15.13 Why can't I see all the components I added to a Frame?
Frame myframe = new Frame("Child Frame"); myframe.resize(512,384); myframe.add(new Label("Child")); myframe.show();
you may find that the Label does not show up in the Frame. Or it may show up in appletviewer, but not in a browser.
The default layout manager for Frame is BorderLayout. Components positioned with a BorderLayout must include a positioning constant to be correct. So, change the add to
myframe.add("Center", new Label("Child"));
and all will be well.
15.14 Why do I get the wrong results when 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 not two object but one? What you most probably meant is "do these two Strings have the same contents?" which you can express this way:
if ( s1.equals(s2) )
This is a very, very easy mistake to make and impossible to spot until you have had it explained to you.
People talk about "interning" a String. That means calling the intern() method on a String. This places the String in the runtime constant pool if it was not already there. The compiler is required to intern() all literal Strings. If you intern() all your Strings as well then all duplicates are shared and comparisons can be done by the (much faster) address comparison rather than content comparison. It's a performance optimization. See also Q3.22.
Note that this comparison error also occurs with other objects, not just Strings. The code:
if (getBackground() == Color.black)is a test for object identity, rather than content identity. It will work if you originally setBackground(Color.black). To avoid difficult debugging in future, you almost certainly want to say
if (getBackground().equals( Color.black ) )or even (in this visual case) compare the darkness of the RGB values of the pixels.
15.15 Why doesn't final prevent my object from changing?
final StringBuffer s = new StringBuffer("don't change me"); // ... s.append(", but I did"); System.out.println(s);
And the new value of s is "don't change me, but I did". The reason is that the "final" modifier makes the reference variable (here, s) final, not the object that s points to. It means that the reference variable cannot be changed to point to some other StringBuffer. The state of the StringBuffer can still be modified by calling methods on it or directly assigning to its public fields.
The right way to think about final is that it prevents you assigning to that particular variable. The only way to make the fields of an object constant (unchanging) is to make all its data fields private, and not provide any set methods for them, only get methods. Even that won't stop other objects of the same class adjusting it.
15.16 Why can't the compiler find my package?
DBTest.java:10: Class database.Table not found in type declaration.The file Table.java and DBTest.java are in the same directory. They both have "package database;" at the top of the file. The current directory is included in the classpath.
The reason is that when compiling packages, you have to be at the 'top' of the directory/package hierarchy. So to compile both Table.java and DBTest.java, you have to be in the directory that contains the database directory (i.e. where the package hierarchy starts), and just:
javac database/Table.java javac database/DBTest.javaand it should all compile fine.
15.17 I have a program with keyboard input and a button. When the user hits the space bar, the button gets pressed as it is in focus!
Another approach is to manually set the focus on some other component (say the Frame) when you show the window. To do so you have to jump through hoops to outsmart the VM that is trying to set it on the button. One approach is to listen for the windowActivated event and set a Swing Timer to do a requestFocus() on the frame about 0.1 seconds after the activated message. This seems convoluted, but it is the only thing found that consistently works cross platform.
Another reader suggests that if the frame normally gets the focus first, you can override its gotFocus() event and set the focus to the component you want. Don't forget to return true!
15.18 What's the hidden size limitation of String serialization?
A possible workaround that is to strip the string down to "byte[]" and pass it around in RMI that way. The code with this restriction is in DataOutputStream
public final void writeUTF(String str) ... [perform the size-after-conversion-to-UTF computation] ... if (utflen > 65535) throw new UTFDataFormatException(); ...RMI relies on serialization, so RMI has the same String size limitation. 15.19 What happens to post-increment when an exception is thrown?
array[i++] = foo();and foo() throws an exception, i will be incremented anyway. This can cause problems if sometimes foo() throws an exception and you don't want i incremented in cases when it does.
This is a consequence of JLS 15.25.1 and 15.6.1 "the left-hand operand of a binary operator appears to be fully evaluated before any part of the right-hand operand is evaluated." (assignment is taken as a binary operator). Note that this is not how C++ behaves.
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, Jonathan Revusky, Ken Kalish, Dave Sanders, Bill Hyden, James Cloughley, Philip "diodes" Gustafson, Paul Kinnucan, Juan Valdéz, Antranig Basman, Felix Pahl, David N. Still, Simon Arthur, Mark Hammond, Dan Kegel, Thomas Weidenfeller, Pavel Shvartsman, Christen Monberg, George Reese, Ian Macgregor, John Sublett, David Zimmerman, Tony Dahlman, Druid, Chris Kelly, Patricia Shanahan, Paul Hill, Lyne Lamoureux, Don Kennedy, Alec Muffett, Andrew Mickish, Pavel Shvartsman, Neil of Parkway Consultants, Chris Thiessen, David Michaels, Bob Sutherland, Michael Allen Latta
I am maintaining a FAQ list to address specifically programming issues
(not a general tutorial on Java). Please mail suggested FAQ entries including
answer to me at pvdl on the site best.com.
Question with answer gets you a credit in the FAQ.
Peter van der Linden, Sun Certified Java Programmer.
-- end --