From: pvdl@best.com (Peter van der Linden) Newsgroups: comp.lang.java.programmer, comp.lang.java.help, comp.lang.java.gui Subject: Java Programmers FAQ Date: 21 May 1999 13:50:56 -0700 Message-ID: <7i4gvg$1aq$1@shell15.ba.best.com> Summary: This posting answers frequently-asked questions by Java programmers Archive-name: computer-lang/java/programmers/faq Posting-Frequency: weekly Last-modified: 1999/05/19 URL: http://www.afu.com/javafaq.html Frequently Asked Questions (with answers) for Java programmers _____________________________________________________ ________| |________ \ | Java Programmers FAQ http://www.afu.com | / \ | Last modified May 19, 1999 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 faqidea at the address afu.com. ------------------------------------------------------------------------ The sections of the Java FAQ are: * 1. Java Book Information * 2. Getting Started * 2.5 Portability * 3. General Information * 4. Compilers and Tools * 5. Compiler Messages * 6. Java Language issues * 7. I/O * 8. Core library issues * 9. Computer Dating * 10. AWT * 11. Swing * 12. Browsers * 13. Applets * 14. Multi-Media * 15. Networking * 16. Security * 17. For C, C++ Afficionados * 18. Java Idioms * 19. Java Gotcha's * 20. Further Resources * 21. Acknowledgements ------------------------------- 1. Java Book Information 1. (sect. 1) How do I choose a Java book? [*] There is no one right answer to "which is the right Java book for me?" A lot depends on what you already know, and how you like to learn. If you already know how to program in another language, and Just want to learn Java, consider Just Java 1.2 from the FAQ author. Everything in one handy volume (language basics, Swing, networking, I/O, database access, etc) and it comes with a CD with tons of Java applets, games, applications, compiler tools, complete with source. Includes a Java compiler for Windows, the Mac, Linux, and Solaris (sparc and x86). look at http://www.amazon.com for details If you or your manager instead want a briefing on Java technology, thin clients, XML, CORBA, TCP/IP, Java beans, etc., take a look at Not Just Java from the FAQ author. [Image] This book doesn't teach you how to program in Java; it tells you why you might want to, and what kind of systems are most suited to Java. It describes E-Commerce and XML. look at http://www.amazon.com for details Here are the points to check when evaluating a programming book. o Above all, make sure that it is a Java book. If it comes with a CD, check that it has a Java compiler on it, not a J++ compiler. VJ++ does not implement Java 2. VJ++ is also a different language in some important ways, and is missing the latest Java libraries (Swing, Collections, JFC, RMI). If your interest is Java, leave the downrev VJ++ book back on the shelf. o Does the book cover the current level of Java, which is Java 1.2 (aka Java 2)? Look up "JApplet" in the index. If it's not there the book doesn't cover JDK 1.2, and you probably need a more up-to-date book. o Check that the book has a reasonable number of figures, diagrams, and illustrations. It is not possible to explain how to program a window system without pictures and diagrams. Other topics benefit from pictures, too. o Check what the book says about itself. Is it a reference work, intended for Java-experts to look things up in? This is the role of "Java in a Nutshell", and "The Java Almanac". Do you need that, or are you looking for a book that teaches by examples and explanations? o Read Peter Norvig's excellent advice on learning programming languages and being a programmer. o Appraise your own level of programming knowledge: are you proficient in some other language, or are you learning programming as well? Does the book cater to your level? o Read a section of the book. Does the style keep you interested, as it educates you? Will you get bored if you read many pages? Is the book too long for your initial purpose? Browse Amazon online and see what other readers say about the text. o If the book comes with a CD, how much other software is on the CD? You want at least a Java compiler plus all the examples from the book. Does the Java compiler work on your platform (Mac, Linux, etc)? Additional software on the CD is a big plus, as we learn the most from reading other people's code. Most people buy one book to begin with, then four or five more as they wish to learn more, and about more specialized topics. The FAQ author has purchased and read probably 60 Java books in the last three years. 2. (sect. 1) Where can I find a some lists of Java books and book reviews? [*] Here are some good ones: http://www.hszk.bme.hu/~werner/Java2BookReviewBETA.html and http://www.geocities.com/RainForest/Canopy/4774/Java/education.html also http://www.flathill.com/languages/java/ also http://www.fastgraph.com/books/java.html also http://teamjava.com/links/tj-srv.cgi?MUF=0,tj-booklist.muf also http://www.javaworld.com/javaworld/books/jw-books-index.html (an exhaustive list -- takes a long time to load). ------------------------------- 2. Getting Started 1. (Sect. 2) What is the easiest way to get started with Java? [*] Follow these steps. 1. Look at the books section of the FAQ to see what kind of book will suit you. There is no one perfect Java book. The right book depends on the style, pace, and detail that you are comfortable with. Amazon has good info and reviews on Java books. 2. Download a free Java compiler from http://java.sun.com Service packs for Solaris (if any are needed) can be found at: http://www.sun.com/solaris/jdk/download.1.2.1_02/en/sparc/1.2.1_02_sparc_jdk_patches.tar 3. Read the free Java tutorial, at http://java.sun.com/docs/books/tutorial/index.html (bookmark it, so you will easily find it again). 4. Avoid Microsoft's J++ product, which is in the words of Microsoft's own employees "polluted Java". It is designed to undermine standard Java, and has many deliberate platform-specific incompatibilities, including new keywords in the language. 5. To get some tips on getting started with a programming homework assignment, look at http://www.concentric.net/~pats/beginner.html. 6. Search this FAQ when something in Java confuses you. Many people have trodden this path before you, and the FAQ contains the accumulated knowledge and pointers to other references. 2. (Sect. 2) Why doesn't my "Hello World!" program compile? [*] There are three basic possibilities: 1. Are you successfully running the javac compiler? Try javac -garbage to see if it prints out a message about correct usage. If not, invoke javac using the full pathname, or set your PATH variable to include the directory that contains javac. 2. Is the CLASSPATH environment variable used correctly? In JDK 1.0.2, beginners had to set CLASSPATH, and it had to include both system libraries and your programs. In JDK 1.2, CLASSPATH is no longer needed for system libraries. You do want CLASSPATH to point to the directories containing any "user classes" you're using. Getting started, you will probably want at a minimum "." (the current directory) in your CLASSPATH. When CLASSPATH is wrong, javac will tell you it can't find definitions for classes you reference in the source file. For information on setting up the CLASSPATH, see Question 1.3 3. Is the source correct? Here javac will emit error and warning messages. See the questions on compiler messages in the next section. 3. (Sect. 2) Why doesn't my "Hello World!" program run? [*] There are five common mistakes that cause your VM (java or browser) to be unable to execute your classes 1. First, did you write an applet or an application? If an applet, you must make sure that you did extend the java.applet.Applet class. Your starting code should be in the init routine. If you wrote an application, your starting code should be in a routine called main(). Don't mix applets with applications until you have a bit more experience. 2. You must declare your main class as "public". If you don't, unfortunately some systems will still run the code, while others won't. The main class is either the one with the main() method in, or in the case of an Applet, the class that extends Applet. 3. Your class name and the file name must match exactly, even letter case. If your class is HelloWorld, your source file must be HelloWorld.java and your class file will be "HelloWorld.class". 4. If an Applet, and you used ftp to transfer the classes to the server, you must ftp all the classes, and you must use BINARY transfer not ASCII. 5. Errors in setting the CLASSPATH (and/or codebase in an applet). Even seasoned programmers do this, pointing inside a package or mistyping a path delimiter. For information on setting up the CLASSPATH and codebase, see Question 1.3 If you are running an applet, you should check the following further points: 1. If your class isn't loading, recheck the HTML applet tag. 2. If you are writing to System.out, the results are displayed in the browser's java console. You'll have to create a window if you want one. 3. Make sure your browser is compatible with the Java language features you are using. Internet Explorer and older versions of Netscape's browsers have omitted some support for JDK 1.1. Try your applet in the JDK's appletviewer first. 4. How do I set the CLASSPATH? [*] The CLASSPATH environment variable tells the VM's class loader where to find classes that are directly or indirectly invoked, including system classes. The CLASSPATH variable should o point to the directory containing the class file, for classes not in a package. o point to the package root, for classes in a package. The root is the parent directory of the highest directory of the package name. o point directly to the zip or jar file, if the classes are in an archive file. You may have to list the contents of the archive to get the correct package/path name for the class. Separate multiple paths and archives with a platform-specific separator, ";" for Windows; ":" for Solaris Also remember that o Browsers set the CLASSPATH to the directory of the HTML file, plus the codebase parameter. o in JDK 1.1 and after, java adds the system classes (lib/classes.zip), so you don't have to. o JDK 1.2 versions of java add "." (current directory), so you don't have to. (But jre doesn't - see below.) o JDK 1.1 jre tool does not use the CLASSPATH variable or assume the current directory. (On Solaris, CLASSPATH does work.) From JDK 1.1.2 on, it is generally an error if the user sets the CLASSPATH to include classes.zip. But CLASSPATH will need to be set to o point to the roots of the programmer's own packages, and third party packages o use rmic o use unbundled packages like Swing in JDK 1.1 o point to native code libraries. For the sake of consistency, the minimal classpath setting should be: " set CLASSPATH=. " Below you'll find examples for Windows (basic application class), Solaris (package class), javac (multiple packages), and browsers (applet codebase). ----------------------------- Here's some Windows examples, assuming the application class is D:\src\tries\HelloWorld.class ## JDK 1.1, no CLASSPATH set > cd D:\src\tries\ > D:\jdk11\bin\java HelloWorld # OK: 1.1 implicitly adds classes.zip and current dir > D:\jdk11\bin\jre HelloWorld # FAILS: jre does not automatically add . to CLASSPATH > cd D:\ > D:\jdk11\bin\jre -cp D:\src\tries HelloWorld # OK: jre adds classes.zip, -cp adds class directory ## JDK 1.1, CLASSPATH set > set CLASSPATH=D:\src\tries > D:\jdk11\bin\java HelloWorld # OK: java using CLASSPATH > D:\jdk11\bin\jre HelloWorld # FAILS: jre does not use CLASSPATH (on Windows) ## JDK 1.0.2, CLASSPATH set > set CLASSPATH=D:\jdk102\lib\classes.zip;D:\src\tries > D:\jdk102\bin\java HelloWorld # OK: > set CLASSPATH=D:\jdk102\lib\classes.zip;D:\src\tries > D:\jdk11\bin\java HelloWorld # FAILS: exception in thread NULL - wrong system classes ----------------------------- Here's some Solaris examples, assuming the application class is /usr/src/com/devjoes/killer/App.class and it is in package com.devjoes.killer: # JDK 1.1, no CLASSPATH set $ /usr/bin/jdk11/bin/jre -cp /usr/src com.devjoes.killer.App # OK: $ cd /usr/src/com/devjoes/killer/ $ /usr/bin/jdk11/bin/java App # fails: class name and path are wrong $ CLASSPATH=/usr/src/ $ /usr/bin/jdk11/bin/java App # fails: class name is com.devjoes.killer.App $ /usr/bin/jdk11/bin/java com.devjoes.killer.App # OK: ----------------------------- Here's some javac examples, for both Solaris and Windows, based on the following: Source files package Makes the call /usr/src/pack/Minimal.java package pack pack.sub.Try.run() /usr/src/pack/sub/Try.java package pack.sub (nothing) $ CLASSPATH="" $ /usr/bin/jdk11/bin/javac /usr/src/pack/sub/Try.java # OK: works fine $ /usr/bin/jdk11/bin/javac /usr/src/pack/Minimal.java # FAILS: can't find pack.sub.Try $ cd /usr/src $ /usr/bin/jdk10/bin/javac pack/Minimal.java # OK: finds pack.sub.Try based on . as package root $ cd /usr/src/pack $ CLASSPATH=/usr/src $ /usr/bin/jdk11/bin/javac Minimal.java # OK: finds pack.sub.Try based on CLASSPATH Now assume the killer application class /usr/src/com/devjoes/killer/FastApp.java (in package com.devjoes.killer) uses a third-party package in a jar file /usr/jars/JShapes.jar but makes no other reference to other classes. The following works fine: $ CLASSPATH=/usr/jars/JShapes.jar $ cd /usr/src/com/devjoes $ /usr/bin/jdk11/bin/javac killer/FastApp.java Finally, some applet examples. Many applets only use one class, in the same directory as the html file: <applet code=ArcTest.class height=400 width=400> To use classes in subdirectory, use the codebase parameter: <applet codebase="mysubdir/" code=ArcTest.class .. To use classes in an archive, use the archive parameter: <applet archive="applets.jar" code=ArcTest.class .. See also: JDK 1.1 ReadMe Solaris JDK 1.1 tool documentation Win32 JDK 1.1 tool documentation 5. (Sect. 2) How do I do keyboard (interactive) I/O in Java? [*] Interactive I/O in Java is very poorly supported. Programmers must piece together several library classes in non-obvious ways to get the required functionality. See the answer to Question 7.1. 6. (Sect. 2) How do I do file I/O in an applet? [*] By default, an applet can read files on the server, but not write them, and has no access to the client. This is for reasons of security. It would be very unsafe to let any old applet that you downloaded from an unknown origin on the Internet read/write your files. It would be as unwise as allowing this kind of access to an ActiveX control (which is one reason ActiveX is dead on the Internet). There are several different ways to relax the default rules. See the answer to Question 7.8. 7. (Sect. 2) How do I do I/O to the serial port on my computer? [*] Java 1.0 and 1.1 do not have a serial port API. There are several commercially-available libraries that supply the needed functionality. JDK 1.2 introduces access to the serial and parallel ports as an extension (optional extra) library. See also the answer to Question 6.3. 8. (Sect. 2) How do I do formatted I/O like printf and scanf in C/C++? [*] The java.text package introduced with Java 1.1 supports formatted I/O. See also the answer to questions 7.11, 7.12, and 17.7. 9. (Sect. 2) I have spent more debugging time finding case (upper vs lower) typos than everything else put together and squared! [*] Do not forget that your remark must be phrased in the form of a question to win on FAQ Jeopardy. In any event, it is worth reminding those new to Java that letter case really matters in Java, and that the names of public classes should exactly match (including case) the names of the files they live in. See also the answer to Question 1.1.2 10. (Sect. 2) Why do I get this compiler error: "Can't make static reference to method..."? [*] Your code probably looks something like this: 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(); } 11. (Sect. 2) Why can't I do myArray.length() ? Arrays are just objects, right? [*] Yes, the Java specification says that arrays are object references [JLS 10.2] just like classes are. However, arrays cannot contain methods. Instead you have to use myArray.length, which is a data item (not a method) called "length", belonging to myArray. 12. (Sect. 2) How do I close a Java window by using the icon in the upper right hand corner of a window? [*] Create an event handler class to extend WindowAdapter. Then override WindowAdapter's windowClosing() to do the actions you want when a window's "close" action is clicked. Then add that to the listeners for that 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 wacky 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 questions 1.0.19, 1.0.30 and 15.7. 13. (Sect. 2) Why is b+=100; OK, but b = b+100; fails to compile? [*] You have code like this 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: "A compound assignment expression of the form E1 op= E2 is equivalent to E1 = (typecast)((E1) op (E2)), where "typecast" is the type of E1, except that E1 is evaluated only once" [JLS 15.25.2] The compile-time narrowing of constants means that code such as: byte theAnswer = 42; is allowed, with no cast necessary. [JLS 5.2] 14. (Sect. 2) How do I add two Float objects together? [*] You want to write code like this 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 questions 6.n , 5.1, and 10.1. 15. (Sect. 2) How can I put all my classes and resources into one file and have java run it? [*] Use a JAR file. Put all the files in a JAR, then run the app like this: java -jar [-options] jarfile Mainclass [args...] 16. (Sect. 2) How can I see line numbers in a stack trace using JDK 1.1.6? [*] From JDK 1.1.5 on (i.e. JDK 1.1.6, JDK 1.2) the stack trace of an uncaught exception no longer has source code line numbers. It only says "(Compiled Code)". To see the line numbers where your program throws an exception, use the command line argument in JDK 1.2: java -Djava.compiler=NONE myapp This info is well-concealed in the release note at: http://java.sun.com/products/jdk/1.2/changes.html#aaa24 ----------------------------- Specify standard Java on your new PC! Your new PC can come with the most up-to-date standard version of Java, but only if you ask for it! The JavaLobby is asking PC vendors to support Java, and to ship new machines with the Java Plug-In pre-installed. See http://www.javalobby.org/servlet/PetitionServlet/pjpc Please help the Java Lobby to promote this initiative. ----------------------------------------------------------------------- Please support Java Portability. The biggest value of Java is its portability. o Portability makes it easier for companies to change/upgrade operating systems and platforms, without losing their investment in applications software. o Portability makes it easier for Java programmers to transfer their skills to new employers. o Portability makes a wider variety of software available on all computers. Software portability is very much in the interest of most software developers and customers. Even if you only use Windows 95, portability matters to you. If your software was all written in Java, it would all just run when you moved from MS-DOS to Windows 3.1 to Windows 95 to Windows 98 to Windows NT, and even on Windows CE. Instead, you typically need to buy new applications software all over again when Windows changes. Portability is not in Microsoft's interest, as it removes a revenue stream and makes it easy for users to try other operating systems. The 1998 anti-monopoly case against Microsoft revealed a Microsoft internal memo. The memo revealed that Microsoft's "strategic objective" was to "kill cross-platform Java." by "grow[ing] the polluted Java market." This is Exhibit 101 (MS7 033448) in the case. In November 1998, a Federal judge ruled that Microsoft was probably breaking its written agreement with Sun by distributing incompatible Java, and that Microsoft had to stop doing that. If portability matters to you or your users, avoid Java products from Microsoft; it is deliberately trying to sabotage it. Microsoft's own internal documents make this goal unambiguous. See http://www.usdoj.gov/atr/cases/f1700/1762.htm. See also "The Microsoft Java Dilemma" paper at http://www.geocities.com/ResearchTriangle/Node/2005/msjava.htm ----------------------------- Windows-Specific 17. Is there a Java implementation for Windows 3.1? [*] Yes. See Question 1.6 It's not that great though because Windows 3.1 has inadequate features to support great software. 18. (Sect. 2) I'm using Win95, and my DOS window won't accept filenames longer than 8.3. "This program cannot be run in DOS mode" [*] Both these problems are resolved by the same process. Assuming you're running the Win95/98 command.com, then you've changed the MS-DOS Prompt options under the "Properties" menu item. In the Properties dialog, Program->Advanced gets you a dialog. Here, make sure the "Prevent MS-DOS-based programs from detecting Windows" checkbox is UNCHECKED. 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. 19. (Sect. 2) 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? [*] First answer: put the entire filename in quotes in the save dialog. Once you have created your first Java file, double click on it in Explorer, select "Notepad" from the "Open with" box, and Notepad will stop adding the spurious ".txt" to your .java files. 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 outfile.txt or just use Wordpad instead of Notepad. Wordpad is under Start->Programs->Accessories->WordPad 20. (Sect. 2) How do I fix the message about "out of environment space"? [*] This occurs under Windows when you have long CLASSPATH names. You need to increase the environment space. On Windows 95,8 put this in your c:\windows\system.ini [NonWindowsApp] CommandEnvSize=4096 On NT you can right-click on My Computer, select System Properties then go to the Environment tab and then increase COMSPEC to the value you want. The previous suggestion to put this in your config.sys: shell=command /e:4096 apparently causes you to create two copies of command.com which wastes memory. ------------------------------- 3. General Information 1. (Sect. 3) Is Java "Open" or "Proprietary"? [*] The Java specification is publicly available, and anyone is free to do clean-room implementations of the JVM and core Java API's. Sun includes a perpetual, irrevocable, free and royalty-free license in the front of the Addison-Wesley books containing the specification. Sun also provides free access to the Java source. See http://java.sun.com/communitysource/ Using the Java trademark does requires licensing from Sun. It is not clear if the Embedded or Personal Java specifications are open, as it is not clear if a clean-room implementation may be done without licensing from Sun. 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, whose owners do not allow competing implementations of the same API, and whose owners change the APIs as a strategic weapon against competitors. 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. 2. (Sect. 3) What is the best way to refer someone to the FAQ when they ask a question I know is answered there? [*] The Java Programmers FAQ (at http://www.afu.com) answers your question in section N.n. ... 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. If you want to look at the definition of Internet standards like FTP, telnet, visit the IETF site at http://www.ietf.org where all the RFC's (Request For Comments) can be found. 3. (Sect. 3) What if my question is not answered in this FAQ? [*] Go to http://www.dejanews.com/home_ps.shtml In May 1999, Dejanews changed their name to Deja.com, and their web design to a truly horrible garish interface, covered with ads and harder to search. Consider using these search sites instead: http://www.exit109.com/~jeremy/news/deja.html http://www.dogpile.com http://www.google.com http://www.hotbot.com http://www.mamma.com o Under "Newsgroups" enter "comp.lang.java.programmer" (or whatever) o Under "Subject" enter "Frotteur" (or other topic you find pressing) o Click "Create Filter" o It will go to a new document, and you should click the link labeled 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 a Java newsgroup search. http://www.javaworld.com/search.html can search the Javaworld newspaper. 4. (Sect. 3) What Java mailing lists are there? [*] There are quite a few Java mailing lists. http://java.miningco.com/msub7.htm has a comprehensive list. 5. (Sect. 3) Where can I look at the definitive Java Language Specification? [*] This is available online at: http://java.sun.com/docs/books/jls/html/index.html (Java 1.0) and the Java 1.1 inner classes document at: http://java.sun.com/products/jdk/1.1/docs/guide/innerclasses/ spec/innerclasses.doc.html and the other Java 1.1 update at: http://java.sun.com/docs/books/jls/html/1.1Update.html and the Java API is at: http://java.sun.com/products/jdk/1.1/docs/api 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/coll.127.1/@Ab2CollToc?subject=java 6. (Sect. 3) Where can I find information about future Java APIs? [*] JavaSoft has followed a policy of creating new APIs in consultation with leading industry participants, then posting the draft specification for public review and comments. Check the JavaSoft roadmap of new APIs and products at http://java.sun.com:80/products/api-overview/index.html Also, some APIs that are under consideration, possibly for JDK 1.2 are at: http://java.sun.com/products/jdk/preview/docs/ 7. (Sect. 3) I'm looking for a Java style guide on naming conventions. [*] Check out the section "Naming Conventions" in the language specification http://java.sun.com/docs/books/jls/html/6.doc.html#11186 Also take a look at Doug Lea's draft coding standard - http://gee.cs.oswego.edu/dl/html/javaCodingStd.html See also naming conventions for some basic rules of thumb. 8. (Sect. 3) How do I check on known bugs in the JDK? [*] Look at the Java Developer Connection at http://java.sun.com/jdc. All the Java bugs that Sun knows about are listed there, with the exception of security-related bugs. The legal department in Sun vetoed the open publication of security bugs. After you have checked that the bug is not already listed, you can submit a bug report through: http://java.sun.com:80/cgi-bin/bugreport.cgi You should check that the bug doesn't already exist for two reasons: first, you might find the bug with a workaround listed. Second, you don't want to waste everyone's time with a duplicate bug report. 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 http://developer.javasoft.com/developer/bugParade/#votes 9. (Sect. 3) What computers have Java ports? Is there a port to Win 3.1? [*] A partial list of JDK ports is available from http://java.sun.com/cgi-bin/java-ports.cgi An (impressive) list of the systems that the GPL Kaffee JVM runs on is at http://www.transvirtual.com/ports.html A list of the software updates you should install to run Java on Solaris is at http://java.sun.com/products/jdk/1.2/install-solaris-patches.html#2.6 There are several Java ports to Win 3.1. IBM's ADK1.02 is available at the following locations: o http://ncc.hursley.ibm.com/javainfo/latest/answers/faq0.html o http://www.alphaworks.ibm.com/formula IBM offers a port to Linux, as do others. The IBM Jikes port is at http://www.alphaworks.ibm.com/ There is a large amount of useful software there, including a profiling tool called jinsight. 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). Also take a look at JavaSoft's JavaPC kit that can switch a PC into a thin client Java system (and back to Win3.1/DOS when you want). It's meant for software OEMs and large corporations running lots of older PCs, but you can use it on the latest Pentium II too. Details are at http://java.sun.com/products/javapc/index.html. JavaPC is available now for $100, runs on 486's with 8Mb or more 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.0.2 API, the JavaPC software allows IS managers to deploy JDK 1.1-compatible Java applications on PCs running DOS and Windows 3.x. 10. (Sect. 3) Where can I find information on Java 3D? [*] The Java 3D FAQ at http://tintoy.ncsa.uiuc.edu/~srp/java3d/faq.html may have the answers you're looking for. It contains general information about Java 3D, as well as programming tips. 11. (Sect. 3) Where can I find information about Java Certification? [*] Sun is sponsoring an examination which programmers worldwide can take. Those passing can use the designation "Sun Certified Java Programmer". There is also a second-level test, involving writing a program to spec, and taking a further test. That results in the qualification "Sun Certified Java Developer". You can find out all about the exam at: http://www.sun.com/service/suned/ 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. There is a Java certification FAQ at: http://www.marcusgreen.co.uk 12. (Sect. 3) How can I find links to recent news about Java? [*] This site contains links to late-breaking online news stories about Java. http://www.intelligence.com/java/ Another good Java news source is http://www.nikos.com/javatoys. This site is a fine site for programmers who want to be well-informed about computer industry topics. It has a lot of coverage of Linux as well as more general news. http://slashdot.org Highly recommended. 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). 13. (Sect. 3) What are the folks at GNU doing with Java? [*] First note that the URLs in this section change quickly, and soon become outdated. If you have an update, send it in. There is a Gnu Java page at http://www.gnu.org/software/java/java.html Guava (a GPL'd Java compiler) can be found at ftp://ftp.yggdrasil.com/pub/dist/devel/compilers/guavac/ Alternatively, it may be available at http://http.cs.berkeley.edu/~engberg/guavac Work is progressing on the Cygnus Java frontend to gcc. See http://www.cygnus.com/product/javalang/ Kaffe (a JVM) can be found at http://www.transvirtual.com This is Tim Wilkenson's company devoted to commercializing the Kaffe JVM for the embedded systems market. He also releases a version of it under the GPL. It also comes with a the beginnings of a class library and the Pizza compiler. Classpath is a free implementation of Sun's Java libraries (v1.1), being developed for the GNU Project ( http://www.gnu.org). Information regarding classpath is at http://www.classpath.org They aim to develop a 100% free drop in replacement for Sun's class libraries, targeting first the Japhar JVM (below). They are always looking for help, so feel free to stop by and volunteer. See also http://www.japhar.org This is the Hungry Programmer's JVM. Currently it is development grade only. 14. (Sect. 3) What is "San Francisco"? [*] San Francisco is the code name for a very large Java project led by IBM, and involving other companies. The project is to provide a Java framework for data processing applications. A large number of classes are provided for general ledger, sales order, inventory management, etc., and these classes can be extended and customized for particular industries (vertical markets). It is a large and ambitious software project. 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 15. (Sect. 3) What large Office-style or other applications have been written in Java? [*] Well, the first one to consider is IBM's San Francisco project, mentioned above. There is also Lotus's e-suite - a suite of Java applets and beans including a spreadsheet and a word processor. See http://esuite.lotus.com. These became available in March 1998. Another office suite in Java is Applix Anyware at http://www.applix.com/anyware/index.htm. Applix became available in downloadable demo form in April 1998. 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 workstations sold in Germany. The Linux version is freely downloadable from http://www.stardivision.com. Another is Digital Harbor's Wav word processor. It supports component software, and it runs in 1MB, not the 114Mb of the latest MS Word. A free trial is avilable. See: http://www.digitalharbor.com Another Java application is Formula One for Java, an Excel-compatible spreadsheet written in 100% pure Java, and available for all systems that support Java. It runs as a Java Bean, so can easily be assembled as one component of a larger system. It also runs as an application, and as an applet! Formula One is a product of Visual Components, Inc. See http://www.f1j.com. Another one is Ncode Research Inc. who write Java viewers for office suites. They are file-format specialists. Their mission is to make all popular file formats available for the Java platform. They write 100% Pure Java viewers for Word, Excel and PowerPoint (including Office 95 and 97 formats). See http://www.ncode.com/ Another company operating in the same space is JSoft, at http://www.jsoftinc.com Intentia, the 8th largest ERP vendor (annual sales of $320 million), has moved their entire suite of applications (Movex - covering 8 markets) from RPG to Java - 20 million lines worth. See their press release. However, the industry is seeing few new office productivity applications written in any language. The niche for single-user office productivity applications is 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 vendors' products, but they are the mainstay of the industry. There are many companies working on Java Beans, like http://www.quadbase.com who have Java graphing software (see also GraphMaker mentioned later in this document). EspressChart is a Java Bean that gives you the ability to add 2D and 3D graphs in your applications/applets. This bean is easy to use, 100% Java, and runs anywhere. There are some excellent Java games applets at http://www.javaarcade.com Check out the pinball -- dig that crazy rhythm, man. There are more good Java games applets at http://www.frontiernet.net/~imaging/java_games.html and at http://www.gamesdomain.co.uk/GamesArena If you want to use Java to learn math & computer graphics, visit http://www.frontiernet.net/~imaging/math_is_a_game.html ObjectDesign Inc., has an ODBMS written in 100% java. The product is named PSE Pro for Java. See http://www.objectdesign.com Another database written in Java is available from http://www.cloudscape.com. Another database written in Java is available from http://www.instantdb.co.uk. InstantDB is available free to non-commercial organizations, and is very well documented and maintained. (Recommended!) 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.java javac has a script wrapper just to set the heap size as a command line argument, as you can do in your own programs. 16. (Sect 3.) What Java User Groups are there? [*] There are scores of Java User groups around the world, mostly in urban areas, and centers of software technology development. A partial list with contact information can be found at http://sunsite.unc.edu/javafaq/usergroups.html. If you can't find a user group in your area/school, it's easy and satisfying to start one. 17. (Sect 3.) What is a Java Bean? [*] A Java bean is a Java class that follows some simple conventions. Because it follows conventions, it can easily be processed by a software tool that connects Beans together at runtime. Java beans are reusable software components. Think of Java beans as being the software equivalent of Lego[tm] bricks. Instead of plugging together plastic bricks, you can easily plug together classes, and have them fit and work with each other. See http://www.jc100.org/ See the Java Bean FAQ at http://java.sun.com/beans/faq/faq.general.html 18. (Sect 3.) Where can I find examples of the use of the Java class libraries? [*] The two volumes of "Java Class Libraries" by Chan, Lee and Krama published by Addison Wesley, have extensive examples of how to use the standard libraries. One programmer comments "When I need to use an unfamiliar area of the class libraries one of the first things I do is read their examples." You can see them online at http://java.sun.com/docs/books/chanlee/second_edition/vol1/examples.html and http://java.sun.com/docs/books/chanlee/second_edition/examples.html 19. (Sect 3.) How can I find out exactly what version of Java I have on my system? [*] On a Solaris system, you can use the pkginfo command, like this: pkginfo -l SUNWjvrt It will give a reply like this: PKGINST: SUNWjvrt NAME: JavaVM run time environment CATEGORY: system ARCH: sparc VERSION: 1.1.6,REV=1998.07.30.16.21 BASEDIR: / VENDOR: Sun Microsystems, Inc. ...etc You may also try java -fullversion Although that's not an officially-supported command option, and has gone away in JDK 1.2. Try also java -version 20. (Sect 3.) What Java newsgroups are there? [*] comp.lang.java.beans comp.lang.java.corba comp.lang.java.databases comp.lang.java.gui comp.lang.java.help (it renamed comp.lang.java.setup) comp.lang.java.machine (it renamed comp.lang.java.tech) comp.lang.java.programmer (it renamed c.l.j.api and c.l.j.misc) comp.lang.java.advocacy (argue all day with anonymous shills) comp.lang.java.softwaretools alt.comp.lang.java-games New Java newsgroups are added every so often. Try not to crosspost. ------------------------------- 4. Compilers and Tools 1. (Sect. 4) Is there a lex and yacc or preferably a flex and bison equivalent for Java? [*] There is a lex equivalent called JavaLex and a yacc equivalent called CUP. LALR(1) parser JavaLex and JavaCup: http://www.cs.princeton.edu/~appel/modern/java/ LL(k) parser JavaCC: http://www.suntest.com/JavaCC/ LALR(1) parser SableCC from McGill U. http://www.sable.mcgill.ca/sablecc/index.html is generously made available under GNU license. 2. (Sect. 4) Where can I find a byte code obfuscator? [*] Java Obfuscators replace the original class, field and methods names in the bytecode with meaningless strings. Second generation obfuscators are now appearing that also obfuscate the control flow and encrypt String literals. People use obfuscators on their applets if they want to hide their code from others. Generally, you wouldn't do this with software that you put on your website for others to enjoy. It runs counter to the "open source" philosophy of learning from other's code and allowing them to learn from yours. Zelix KlassMaster is a commercially supported obfuscator. It has a free evaluation version at http://www.zelix.com/klassmaster Another commercially supported obfuscator, with a downloadable free trial is at http://www.4thpass.com/SourceGuard. There are also some free works from students and others. http://www.primenet.com/~ej/ http://www.math.gatech.edu/~mladue/HoseMocha.java Some people have reported problems using these with JDK 1.1. 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://www.geocities.com/SiliconValley/Bridge/8617/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://www.meurrens.org/ip-Links/Java/codeEngineering/. 3. (Sect. 4) Which program is used to create .zip files compatible with the java* programs? (e.g. classes.zip, moz3_0.zip) [*] Use the jar-tool from JDK1.1(.1): jar [ options ] [manifest] destination input-file [input-files] E.g.: jar cvf myJarFile.jar *.class creates a compressed archive. And watch out -- the order of the options ("cvf") determine the order of the arguments! jar cvfO myJarFile.zip *.class creates it fullsize (uncompressed) (note the 'O'-option used for JDK1.0.2) On Unix you can also use: zip -rn ".class" my_file.zip * 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): 1. zip your files uncompressed (can use WinZip 6.2 up); Unix command: zip -r0 classes.zip <directories> 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: <APPLET CODEBASE="." ARCHIVE=my_zip_file.zip,myOtherZip.zip,thirdfile.zip CODE="my_main_class.class" WIDTH=600 HEIGHT=250> </APPLET> From JDK 1.1 on, an example of the applet tag used with a jar file is <APPLET ARCHIVE=myfile.jar CODE=myapplet.class WIDTH=600 HEIGHT=250> </APPLET> 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. 4. (Sect. 4) Can I compile a Java program to a binary executable, .exe on a PC? [*] Compiling into native code destroys portability, which is one of the main benefits of Java. If you want to create a native executable because you wanted to make it easy to distribute and use programs, consider a Jar file instead. Some companies make products that do this. See the webpages for Symantec http://www.symantec.com, Supercede http://www.supercede.com, and Tower Technology http://www.twr.com. The first two are targeted to Windows. Tower Technology supports several flavors of Unix. Also, there is a native Java compiler from IBM, known as the HPJ (High Performance Java) compiler. One user has reported that it created a 2Mb executable from a 12K java file, and did not run any faster. See http://www.alphaworks.ibm.com/ See also Instantiations JOVE http://www.instantiations.com/jove.htm, the paper about the Toba project http://research.microsoft.com/research/lt/toddpro/papers/coots97.pdf, Network World, "Vendors Rush To Speed Java Performance", Feb 9 1998, at http://www.nwfusion.com/news/0209java.html 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. C++ does not have a standard ABI, so 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. 5. (Sect. 4) How can I performance profile my Java code? [*]java -prof MyClass 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 sort -r +82 <java.prof > java.sort 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. JDK 1.2 comes with some limited profiling capability built-in. Depending on your needs, it may be all that you need. Execute the following to get a short summary of what you can do: java -Xrunhprof:help For example, you can see which methods are taking the most time to execute, in the context of particular stack traces. 6. (Sect. 4) 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: /E|/Jwrkshop/JDK/bin/java.lang.Throwable.html [*] 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. 7. (Sect. 4) 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? [*] The first way is javac *.java Another way is javac -depend tip.java 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 the compiler 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. 8. (Sect. 4) Why do I get the java.lang.UnsatisfiedLinkError when I run my Java program containing Native Method invocations? [*] Your program is not able to find your shared library or DLL. 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. Note that jdb looks for libraries with "_g" appended to their names. Thus, if you intend to use jdb on a Java application that invokes native methods, you must ensure that the appropriately named libraries are in jdb's path. The "debug" nm libraries can simply be renamed copies of the nondebug libraries. For example, if your app invokes native methods in a library named mynm.dll (on Windows) or mynm.so (on Solaris), make a copy in the same directory and name it mynm_g.dll or mynm_g.so. 9. (Sect. 4) An anonymous class can't seem to access a private outer method. Why is that? [*] It's a known bug in the JDK 1.1.4. The code is: 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 put a workaround in the compiler to silently set the field to package access. 10. (Sect. 4) What are the major Java releases and their contents? [*] There have been three Java releases from Sun so far, plus a number of bugfix (dot-dot) releases. The releases are: o JDK 1.0.2 This was the release FCS in May 1996. It had some security fixes over JDK 1.0. o JDK 1.1 This release (Feb 1997) introduced a new event model in the window system. It also made JDBC support and beans support a standard feature. It changed and standardized the native code interface to JNI. It also introduced inner classes. o JDK 1.2 This release (Dec 1998) made the Swing library a standard feature. Swing is a set of rich platform-independent graphical components. It also introduced the Collections library, and Java 2D. 11. (Sect. 4) What is the difference between jre and java? [*] They are functionally equivalent, with minor differences in the handling of default classpath and options supported. To reduce confusion, the jre command was removed in JDK 1.2. Instead there is a "java" command in both bin and jre/bin. jre.exe is the java launcher that comes with the Java Runtime Environment. 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 java launcher that 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. 12. (Sect. 4) What IDEs (Integrated Development Environments) are there? [*] Some popular IDEs include: (... if you have info on the platforms that each of these support, send it in, and I'll add it to the FAQ). Apptivity (Progress) http://www.apptivity.com Blue J (free) http://www.sd.monash.edu.au/bluej Bluette (free) http://www.bluette.com Chicory (free) http://www.chicory.com CodeWarrior Professional http://www.metrowerks.com Freebuilder (free) http://www.freebuilder.org GRASP (free) http://www.eng.auburn.edu/grasp Grinder http://www.tpex.com Java WorkShop (Sun) http://www.sun.com/workshop/java Javelin, Visual Object Development for Java http://www.stepahead.com.au JBuilder (Inprise) http://www.inprise.com/jbuilder JDE for emacs http://sunsite.auc.dk/jde/ Jirvana (free) http://www.jirvana.com/Jirvana/Jirvana.html JPadPro http://www.modelworks.com Kawa (Webcetera) http://www.tek-tools.com/kawa Metamata http://www.metamata.com NetBeans (Swing-based) http://www.netbeans.com PARTS alpha (ObjectShare) http://www.objectshare.com PowerJ (Sybase) http://www.sybase.com/products/powerj SilverStream http://www.silverstream.com Simplicity for Java http://www.datarepresentations.com Super Mojo (Penumbra) http://www.penumbrasoftware.com SuperCede (Asymetrix) http://www.supercede.com teikade (PFU Ltd) http://www.pfu.co.jp/teikade Together/J (Object Intl Inc.) http://www.oi.com Visaj (Imperial SW Tech) http://www.imperial-software-tech.co.uk VisualAge (IBM) http://www.software.ibm.com/ad/vajava Visual Cafe (Symantec) http://cafe.symantec.com Visual J++ (Microsoft) http://msdn.microsoft.com/visualj/default.asp (not recommended) Xelfi 0.94 http://www.xelfi.com 13. (Sect. 4) Why is Visual J++ not recommended? Because Microsoft's strategic objective is "Kill cross-platform Java" [*] It is not in Microsoft's financial interest to allow users to easily move software to different platforms. Microsoft is the only company in the computer industry that is actively trying to undermine Java. This is not speculation -- the Department of Justice's lawsuit quoted a Microsoft memo describing the strategic objective to "kill cross-platform Java by grow[ing] the polluted Java market". See http://www.usdoj.gov/atr/cases/f1700/1762.htm VJ++ can be used in a compatible way, but the tool encourages use of Windows lock-ins. The J++ compiler introduced new keywords and other deliberate incompatibilities. Microsoft is being sued because of unauthorized changes it made in Java. A federal judge issued a preliminary injunction against Microsoft in March 1998, prohibiting them from labelling their incompatible J++ product as Java. Another injunction was issued against Microsoft in Nov 1998, requiring them to remove some deliberate incompatibilities with standard Java. (Recall that Microsoft did not create Java, but contracted with Sun to distribute it). Microsoft is in a real jam over Java; it contracted with Sun to distribute standard Java, and then made many changes to its product to make it deliberately non-portable. Sun sued Microsoft to enforce the contract, and the preliminary legal decisions have been in Sun's favor. Some analysts speculate that Microsoft will leave its customers in the lurch and cancel VJ++. See http://cnn.com/TECH/computing/9903/23/javajam.idg/index.html 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. As a Java programmer please join the Java Lobby, an independent organization dedicated to representing independent 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: o Use development environments from other vendors, or convert Microsoft Visual J++ to use Sun's JDK, following the instructions at http://www.orbiter.demon.co.uk/ o Use Netscape Communicator (not Internet Explorer) o If required to use Internet Explorer, use the Java Plug-In to get a standard Java system inside it. o Use a standard JVM from GNU, Kaffe, any of the IDE vendors, or Sun (but not Microsoft's J++ SDK) o Free standard Java compilers and the Java Plug-In can be downloaded from http://java.sun.com. o Free standard Java Virtual Machines can be downloaded from http://www.kaffe.org, http://www.oryxsoft.com/projects/gvm, and http://www.redhat.com/linux-info/jolt o 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. o 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, as Microsoft frequently insists. Microsoft is actually charged with o taking anti-competitive action to exclude competition in browsers, in order to protect its monopoly in desktop operating systems. o using its monopoly to impose restrictive agreements that require PC manufacturers to accept the Microsoft browser with Windows, and that hinder the promotion of competing browsers. Many people think that contracts between "A" and "B", restricting/discouraging "B" from distributing "C's" products are sleazy. ["A" is Microsoft, "B" is AOL, many ISPs, computer vendors, etc. "C" is Netscape"]. Such contracts are in restraint of competition and illegal when used by a monopoly. This is why Microsoft is facing mounting legal problems in the United States, Italy, Brazil, and the European Union. 14. (Sect. 4) What language is the Java compiler and JVM written in? [*] Sun's javac Java compiler is written in Java. Sun's java JVM interpreter is written in Java with some C, C++ for platform-specific and low level routines. Sun's Java Web Server is written in Java. Other companies have chosen other approaches. IBM's Jikes compiler (which is praised for its speed) is written in C++, but of course each version only runs on one platform. Jikes versions have been prepared for IBM AIX, Linux Intel (glibc), Win95/NT and Solaris Sparc at http://www.alphaworks.ibm.com/formula/jikes. 15. (Sect. 4) How do I turn off the JIT in the JDK? [*] The command that works in both JDK 1.1.6 on, and JDK 1.2/2 is java -Djava.compiler=NONE ... One reason for turning off the JIT is to get more information about any exception that is thrown in your code. But HotSpot is able to produce line numbers in stack traces even for JIT'd code. HotSpot rocks. 16. (Sect. 4) How can I store the errors from the javac compiler in a DOS file? javac foo.java > errorfile doesn't work. [*] javac writes errors to stderr, The problem is that DOS doesn't allow stderr to be redirected (as command.com is very poor software). So you have to use a special error redirection mechanism in the compiler: javac -J-Djavac.pipe.output=true myfile.java > errors.txt In JDK 1.2, you can use: javac -Xstdout You typically use this when a compilation produces a lot of error messages, and they scroll off the DOS window before you can read them. Alternatively, you can get a scollbar to appear on a DOS window by changing the properties with the "Layout" tab. Change the Screen Buffer Size Height: to some multiple > 1 of the Window Size Height. E.g. use a buffer height of 100 and screen height of 25 (the default). This will give you three buffers of scroll "history." The DOS limitation is improved in NT, where you can write javac myfile.java 2> errors.dat 17. (Sect. 4) How can I pretty-print Java source? [*] For tools that reformat code, try: o http://www.parallax.co.uk/~rolf/download/jpp.pl o http://www.bigfoot.com/~davidsont/jstyle o http://www.mmsindia.com/JPretty.html o http://www.almide.demon.co.uk/source_code/java/JavaCC/Pretty/Pretty.html o http://www.geocities.com/~starkville For tools that print code neatly, try: o http://www.eng.auburn.edu/department/cse/research/grasp/ Some Unix utilities work adequately: o cb (very few style choices though) o 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: o GNU Enscript - pretty printer and PostScript formatter o Ghostscript, Ghostview, and GSView for Unix o gsv25w32.zip - GSView for NT (requires the following Ghostscript files) o gs510ini.zip - Ghostscript configuration, initialization, and example files o gs510w32.zip - Ghostscript core binaries for Windows NT o gs510fn1.zip - Ghostscript standard fonts ------------------------------- 5. Compiler Messages Most of the "questions" in this section are diagnostic messages from the compiler. Each answer explains what the message means, and how to avoid it. 1. (Sect. 5) Why did I get an OutOfMemory error when porting working code from JDK 1.0.2 to 1.1? [*] The preset memory limit has changed. It went down to 16MB so as not to penalize low memory machines. You can adjust it with java -mx128m Frotz # jdk 1.1 java -Xmx128m Frotz # jdk 1.2 to get a 128MB extent. Also see the Runtime methods freeMemory() and totalMemory(). 2. (Sect. 5) Why do I get a "Statement not reached" error from javac for no apparent reason? [*] JDK 1.0 has a limit of 63 words of storage for local variables in any method. longs and doubles require two words of storage, and all other primitive types and all reference types require one word. If you assign values to more than 63 words of local variables, you will get a "Statement not reached" error on the statement after you assign to the variable that contains the 64th word. In JDK 1.1, the low limit was removed. 3. (Sect. 5) class MyOrdinaryClass must be declared abstract. It does not define void actionPerformed(java.awt.event.ActionEvent) [*] This is one of those error messages where the compiler tries to guess what you meant, and gives you a message based on a wrong guess! So the message is confusing. Your MyOrdinaryClass class implements ActionListener, which means you must include a definition of the methods from the ActionListener interface. But you did not. You either left a method out, or (more likely) you misspelled its name. Perhaps you wrote "ActionListener" instead of "actionListener". So the compiler did not find the method to fulfill the interface. Since there was a method promised but not supplied, the compiler thinks you were aiming at an abstract class, and it prints an error message accordingly. 4. (Sect. 5) Variable may not have been initialized. 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); [*] The compiler will warn you if you use a variable before it is certain to have been initialized (not just with the default value) since this means you probably forgot to set it. In the case of exceptions, you have to consider that the flow of control may terminate abruptly, with no operations completed. In the example above, if an exception is raised in the try clause, variable test will not be assigned a value, yet you are using it after the catch clause. One solution would be to declare test with an explicit initial value of null, but this works only because toString() works on a null reference. (toString() is invoked implicitly by operator + with String operand.) Always initialize to a value that will work notwithstanding exceptions being thrown. 5. (Sect. 5) No constructor {superclass}() I extended the class called Frotz, and the compiler is giving me an error message "No constructor Frotz()" in the child class. Why? [*] When you define a constructor for a class, the compiler inserts a call to the superclass' parameterless constructor unless you explicitly call the superclass' constructor at the start of your constructor. If the superclass doesn't *have* a parameterless constructor, the compiler emits a message to that effect. The solution is usually to call the superclass' constructor at the start of your constructor. 6. (Sect. 5) No constructor matching MyCheckbox(myApplet) MyApplet.java:11: No constructor matching MyCheckbox(myApplet) found in class MyCheckbox. bp1 = new MyCheckbox(this); ^ [*] If a compiler isn't finding a constructor you thought you created, check whether you gave a return value to the method (remember, constructors have no return value). E.g., public void MyCheckbox( Container parent ) If you did, the compiler will think it is an ordinary method, not a constructor. This is a common mistake and hard to spot. 7. (Sect. 5) Type expected {public method variable} public static void main(String[] args) { ^ Statement expected. public static final float Conversion_Factor = 39.37; ^ Type expected. [*] Argument and variable declarations inside methods are never public or static because they are local to a method. (Before JDK 1.1 they couldn't be final either, but there was no good reason for that restriction and it was dropped.) If you have public or static variables, move them outside the method. They are usually put at the beginning of the class. 8. (Sect. 5) Can't access protected method clone in class java.lang.Object T.java:96: Can't access protected method clone in class java.lang.Object. OtherT is not a subclass of the current class. [*] Object.clone() is protected because subclasses might want to restrict access to cloning, and if Object.clone() were declared public, subclasses could never make it more restrictive. The subclass can make access to the clone() operation less restrictive. 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 { // in case members need cloning X c = (X)super.clone(); return c; } catch (CloneNotSupportedException e) { // should not happen, because of Cloneable throw new InternalError(); } } } 9. (Sect. 5) Deprecated methods What does "deprecated" mean? I got this in a compiler error message. [*] "Deprecated" means you are using an older API, that Sun has replaced with a newer one (usually to follow more consistent naming conventions). Deprecated methods are not recommended for use. They are supported in the short term, but your code should be updated with the new. To update your code, compile your old code using javac's "-deprecation" option to list deprecated methods, then find the replacement methods in the current HTML API documentation for the old deprecated methods. As an example of a deprecated API, Component.size() was replaced by Component.getSize(). See also http://java.sun.com/products/jdk/1.1/docs/guide/ misc/deprecation/index.html, "1.1 Deprecated Methods" and http://java.sun.com/products/jdk/1.1/docs/guide/ awt/DeprecatedMethods.html, "Deprecated methods in the 1.1 AWT" 10. (Sect. 5) double y = sin(90); What's wrong? That code provokes compiler messages. [*] You need to write it this way: double cvtDegToRad = Math.PI/180; double x = 90*cvtDegToRad; double y = Math.sin(x); sin is a static method of the Math class that takes radians. You need to use the "Math" classname, e.g. Math.sin instead of plain sin, because you have to say what class or object these methods belong to. A very common mistake is to assume that importing a class means that you don't have to qualify the names of its members. When you call a method you have to state the name of the class or object it belongs to, regardless of any imports you have done. (Except inside the class itself, obviously). The trig functions are static methods of the Math class, so you give the name of the class in invoking them. Further, the Math class works in radians, not degrees. 360 degrees = 2 pi radians, so use a conversion factor as shown if you are working with degrees. 11. (Sect. 5) Can't make static reference to method... [*] Your code probably looks something like this: class myclass { public static void main(String args[]) { myMethod(); } public void myMethod() { //some code } } Static (class) methods can only call without qualification other static methods, so you either have to qualify the call in (static) main() to (nonstatic) myMethod() with an object of type myclass, or you have to make myMethod() static. People often forget that even though main is "in" myclass, there is no implicit object when you are in main() because it is static. This happens especially when writing code to run an applet as an application, where you want to call init() and start() from main. public static void main(String[] args) { Applet ma = new myApplet(); // have to create object ma.init(); // use to qualify access to non-static methods ma.start(); } 12. (Sect. 5) Incompatible type for =. Explicit cast needed... byte b = 0; Incompatible type for =. Explicit cast needed to convert int to byte. b = b + 100; // compiler error message b += 100; // works OK [*] 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 Language Specification says that a compound assignment expression of the form E1 op= E2 is equivalent to E1 = (typecast)((E1) op (E2)), where "typecast" is the type of E1, except that E1 is evaluated only once. (See JLS 15.25.2 Compound Assignment Operators) The compile-time narrowing of constants means that code such as: byte theAnswer = 42; is allowed, with no cast necessary. (See JLS 5.2 Assignment Conversion) Other sites: JLS 5.2 Assignment Conversion JLS 15.25.2 Compound Assignment Operators 13. (Sect. 5) Class {package}.{class} not found in type declaration. I am trying to compile file "{class2}.java" in a package, and I get this compiler error. {class2}.java refers to {package}.{class}, but the file {class}.java and {class2}.java are in the same {package} directory, which is the current directory and which is in the CLASSPATH variable. Both files have "package {package};" at the top of the file. What's the problem? [*] When the source refers to classes in packages, the CLASSPATH has to point to the root of the package/directory hierarchy for a reference to resolve correctly. This is true even for source files in the same package (and directory). I.e., assuming {class} and {class2} are both in {package}, {class} can't make a reference to {class2} unless the CLASSPATH is set so javac can find {package}/{class2}.java. It should make no difference what directory you are in when you invoke javac, unless you are relying on "." in the CLASSPATH to point to the package root or are specifying the source file with a relative path (e.g., {package}/{class}.java). Some examples, assuming o - Foo.java and Bar.java are in /java/source/pack/ o - Both have "package pack;" as the first statement o - Foo.java includes "Bar b = new Bar();" # solaris ksh $ alias jc=/java/jdk11/bin/javac $ CLASSPATH=/java/source/ $ jc /java/source/pack/*.java # works fine $ cd /java/source/pack $ CLASSPATH=. $ jc *.java # fails - Foo.java can't find class Bar $ cd .. # now . is package root, /java/source/ $ jc pack/*.java # works 14. (Sect. 5) public class "Foo" must be defined in "Foo.java" I get this message even though it is in Foo.java. What gives? [*] Javac verifies that a public class is defined in a file of the same name (e.g., that public class Foo is defined in Foo.java). Two things you can check: First, make sure the case matches exactly. public class Foo cannot be in foo.java; it has to be in Foo.java. Second, are you using MKS on win32? Javac on win32 assumes you are using the DOS path separator (\) even though MKS accepts the Unix path separator (/). When javac tries to parse a your Unix-style path, it won't produce the correct filename, the match will fail, and it will emit an error. You have to use the DOS path separator (\), which must be escaped in MKS - e.g., "javac H:\\source\\package\\Foo.java". Alternatively, you can traverse to each source directory and avoid pathnames altogether. ------------------------------- 6. Java Language Issues How-to 1. (Sect 6.) How do I compare two Strings? if (s1 == s2) is giving me funny results. [*] The comparison using "==" on objects, such as Strings, is asking, "Do these two objects have the same reference?" 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*?" Compare String contents with any of the following: if (s1.equals(s2) ) if (s1.equalsIgnoreCase(s2) ) if (s1.startsWith(s2) ) if (s1.endsWith(s2) ) if (s1.regionMatches(s1_offset, s2, s2_offset, length) ) if (s1.compareTo(s2) < 0) (There are other ways, too.) 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. 2. (Sect. 6) How do you get the code value of a char? I would like to transform a char into the corresponding int value, that represents the code value of the char. How? [*] Like this. char c = 'A'; int i = c; 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. The same is true for Pascal, Ada, and other languages. 3. (Sect. 6) Why does b >>>= 1 give me the same result as b >>= 1? [*] ">>" is a "signed" or "arithmetic" shift, namely, it replicates the sign bit on the left as it shifts. The ">>>" operator is an "unsigned" or "logical" shift; it does a shift right and zero fill. However, ">>>" looks like it does a signed shift with negative bytes and shorts, where int promotion alters the sign. This 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 had 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 instead: // 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) ); 4. (Sect. 6) Why does the <unexpected> happen in floating point? [*] There are several unexpected things that seem to bite programmers with floating point. This is almost always a result of the programmer not being fully conversant with floating point arithmetic in general, rather than a problem relating to Java. The question of floating point accuracy comes up with Java more than with C++ (for example) because of Java's decision in the println() method to print enough digits to distinguish the number from the next-closest number, rather than rounding it to 6 significant digits by default as the C/C++ libraries do. [ISO C, Sect 7.9.6.1, line 21 of "the double argument"] If you seem to be having problems with floating point, the 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 or 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. You are actually getting more accuracy than on systems (like C,C++) that suppress the less significant digits. For more information and detailed specifications on how Java deals with floating point, see the URLs listed below. Other sites: What Every Computer Scientist Should Know About Floating Point. http://java.sun.com/products/jdk/1.1/compatibility.html#incompatibilities JLS 4.2.3 Floating-Point Types and Values JLS 4.2.4 Floating-Point Operations JLS 3.10.2 Floating-Point Literals JLS 5.2.3 Narrowing Primitive Conversions http://gams.nist.gov/javanumerics/jgfnwg-01.html See also "the guff from Hough" at http://www.validgh.com/java If you want the rounded floating point output that most languages have, use the new java.text package of Java 1.1 to limit the number of digits that are output. If you need more precision than about 16 digits, use the BigInteger and BigDecimal classes of Java 1.1. Understanding the Java Language 5. (Sect. 6) How can I program linked lists if Java doesn't have pointers? [*] Of all the misconceptions about Java, this is the most egregious. Far from not having pointers, in Java, object-oriented programming is conducted exclusively with pointers. In other words, objects are only ever accessed through pointers, never directly. The pointers are termed "references" and they are automatically dereferenced for you. 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 memory management 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? 6. (Sect. 6) Are parameters in Java passed by value or by reference? [*] All parameters (values of primitive types and values that are references to objects) are passed by value. However this does not tell the whole story, since objects are always manipulated through reference variables in Java. Thus one can equally say that objects are passed by reference (and the reference variable is passed by value). This is a consequence of the fact that variables do not take on the values of "objects" but values of "references to objects" as described in the previous question on linked lists. Bottom line: The caller's copy of primitive type arguments (int, char, etc.) _do not_ change when the corresponding parameter is changed. However, the fields of the caller's object _do_ change when the called method changes the corresponding fields of the object (reference) passed as a parameter. Also in this FAQ: How can I program linked lists if Java doesn't have pointers? Other sites: JLS 8.4.1 Formal Parameters 7. (Sect. 6) What are "class literals"? [*] A feature introduced in JDK 1.1. They are literals of type "Class" that hold a value representing any class. There are even values to represent "void" and an array, like this: 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"); Note that 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. 8. (Sect. 6) What are the naming conventions in Java? [*] The naming conventions are straightforward: 1. Package names are guaranteed uniqueness by using the Internet domain name in reverse order: com.javasoft.jag - the "com" or "edu" (etc.) part used to be in upper case, but now lower case is the recommendation. 2. Class and interface names are descriptive nouns, with the first letter of each word capitalized: PolarCoords. Interfaces are often (not always) called "something-able", e.g. "Runnable", "Sortable". Caution: java.util.Observable is not an interface, though java.util.Observer is. These two are poorly designed. 3. Object and data (field) names are nouns/noun phrases, with the first letter lowercase, and the first letter of subsequent words capitalized: currentLimit 4. Method names are verbs/verb phrases, with the first letter lowercase, and the first letter of subsequent words capitalized: calculateCurrentLimit 5. Constant (final) names are in caps: UPPER_LIMIT 6. Also in the FAQ: Where can I find a Java style guide on naming conventions? Other sites: JLS 6.8 Naming Conventions 9. (Sect. 6) Should I prefer importing {package}.{class} over {package}.*? 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; [*] No, it makes no difference to the class files or runtime speed. 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 runtime 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. At compile time, 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. However, there are style advantages. Some 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 Modem in both those packages. If you use the * form of import, you import both of the Modem classes and then must fully qualify the class each time you use it, to say which of the two you mean. In Java 1.2, the class java.util.List was introduced. That had the same unqualified name as java.awt.List. If your code had "import java.awt.*; import java.util.*;" it would no longer compile. You'd get a message about ambiguous classname. If you import all of a package indiscriminately you might get bitten when the package API changes. 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; to use the imported class, you have to use the full package name. 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.*;" 10. (Sect. 6) How can I use Math.cos() etc. without the prefix "Math."? 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? [*] No. There is no good alternative. There are several bad alternatives: 1. Using "import" doesn't work. The import stament only imports packages, subpackages, and classes, not class members. This doesn't work: import java.lang.Math.*; 2. Minimizing class name usage is unclear and bad style. - You could wrap the functions in your own class. double sin(double x) { return Math.sin(x); } // etc. for each function But you'd have to use your class name everywhere but inside your class, so it doesn't help. - You can make a null reference to the Math class and use it to refer to the static methods. Declare java.lang.Math M = null; angle = M.cos(i); Besides not being clear, this invites abuse and errors. - You could inherit the names 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, it is poor OOP style to use inheritance to obtain a name abbreviation rather than to express a type hierarchy. 11. (Sect. 6) Why is there a standard JNI? [*] JNI is the Java Native Interface. It defines the way that a Java program can call C programs. The industry has agreed on, and Sun has codified, JNI as the standard. Microsoft shuns the standard and uses a protocol of its own called Raw Native Interface, RNI. You might think that once a Java program uses JNI, portability is lost, and hence it doesn't matter if vendors diverge from the JNI standard. Not so. Code that accesses a native library using JNI can run on any VM that supports JNI, so it's portable across VMs on the same platform. Further, you can port a native library to all platforms Java supports (indeed, this is how Sun implements the Java Platform), so JNI _enables_ cross-platform development where it's necessary to use platform-specific idioms for certain functionality. Conversely, code that uses RNI can only run on Microsoft's VMs on the win32 platform. Microsoft's RNI has the effect of limiting RNI programs to the Microsoft VM. Further, Microsoft's failure to support JNI locks out JNI-based functionality on Windows. 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 JVMs except Microsoft's. The standard JNI thus has two purposes: 1. Source code compatibility between different platforms. 2. Binary code compatibility between different JVMs on the same platform. Microsoft's use of RNI locks in programmers who use it, and Microsoft's failure to support JNI locks out programmers who don't use RNI. Users can't run standard JNI applications on Microsoft VMs, or RNI applications on non-Microsoft VM's. As a result, since most users will support only one VM, they'll be locked in to complementary software - in the case of Microsoft, a proprietary standard. A standard JNI means that you can use any standard JVM to run your code on this platform. 12. (Sect. 6) How do I find out more about JNI? How do I find out more about Java Anything? [*] Taking the questions one at a time. Use of JNI detracts from program portability. So you would only do it when you need some critical single-platform effect. The documentation on JNI is at: http://java.sun.com/docs/books/tutorial/native1.1/index.html If your interest extends to reading a book on JNI, a good one is "Essential JNI Java Native Interface" by Rob Gordon; ISBN 0-13-679895-0. See http://www.amazon.com/exec/obidos/ASIN/0136798950/afuinc In general, if you want to find out about topic "X" in Java, your first stop should be to search the http://java.sun.com website for "X". For example if you want to know about Internationalization in Java, a search at the site quickly takes you to http://java.sun.com/products/jdk/1.1/docs/guide/intl/intlTOC.doc.html. 13. (Sect. 6) How do I get unsigned ints in Java? [*] Java doesn't have unsigned ints. The reason is that this is a poorly designed area of C. The rules for what type you end up with when you mix signed and unsigned in expressions are complicated, and they changed between K&R and ANSI C (you might have heard this under the name "unsigned preserving vs. value preserving"). Worse, they depended on the underlying hardware, so they varied from platform to platform, causing bugs in all kinds of unexpected places. The book "Expert C Programming" goes into this in more depth (page 25). So, to avoid bringing over the hidden complexities, Java does not bring over unsigned types from C. Use type char if you are OK with 16-bit unsigned quantities. Otherwise, go to the next larger type and use masking. If you don't have to worry about division by numbers with the high bit set, then when you use >>> for right shift and remember to AND each byte with 0xFF where they are being expanded into a larger type, then there is no difference in the bit patterns generated. Specifically, to convert an int to its unsigned representation, use: ((long)i) & 0x00000000FFFFFFFFL This promotes the signed (and possibly negative) int to long (with sign extension) then chops off the sign-extension, leaving it as the same 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. 14. (Sect. 6) What happened to "private protected"? [*] It first appeared in JDK 1.0 FCS (it had not been in the betas). Then it was removed in JDK 1.0.1. It was an ugly hack syntax-wise, and it didn't fit consistently with the other access modifiers. It never worked properly: in the versions of the JDK before it was removed, calls to private protected methods were not dynamically bound, as they should have been. It added very little capability to the language. It's always a bad idea to reuse existing keywords with a different meaning. Using two of them together only compounds the sin. 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. Inheritance 15. What are the differences between an interface and an abstract class? [*] Some use a semantic distinction: an abstract superclass models the "is" relationship, while an interface models the "has" relationship. The rule would be, if it's a subtype, inherit; otherwise, implement. But, in the absence of real-world characteristics to distinguish the objects from their properties and parents, that becomes a circular argument. In this case, you have to look at the practical differences in Java (compared with C++). Most differences between interfaces and abstract classes stem from three characteristics: 1. Both define method signatures that a derived class will have. 2. An abstract class can also define a partial implementation. 3. A class can implement many interfaces, but inherit from only one class. In greater detail, these topics are: 1. Method signatures Both interfaces and abstract classes permit one to treat the derived-type class as the derived-from-type class. Both define a set of available methods in a way that can be enforced by the type-checking mechanism. This is typically used to permit different (derived) types to behave in the same way (as what they are derived from - i.e., they all support particular methods). For example, all java.* types can be printed as Strings because Object, the superclass of all java.* types, has a toString() method. Similarly, all types that implement the Observable interface can be passed an Observer to signal when an event has occurred. This permits an algorithm or service to operate on different (derived) types as if they were the same (derived-from) type. This mechanism supports not only polymorphism (one object treated as another), but differentiation. In either case, the (derived) types can implement the method in the way appropriate to that type. However, you're not likely to override inherited functionality, but you must implement interface methods, so if you expect significant differentiation, then an interface might be warranted. Finally, this mechanism supports a weak variant of access control. Only inherited methods are available to callers who only have a reference to the superclass or interface type. It's weak because they can attempt a narrowing cast if they know their target type. Nonetheless, it reduces some complexity. 2. Inheriting implementation Inheriting an implementation is useful where the code should be shared. This happens where derived types vary the functionality only a little bit, or where a complex set of method interfaces can through mutual reference be implemented with relatively few methods that can be implemented by derived types. You can also reuse code by having your class use or keep an object of another type that implements that code, but that doesn't permit your callers to treat you in a particular way. To both "get" functionality and to be treated "as" the superclass are the essentials of the type/subtype relationship. 3. Java's rule of single inheritance Java differs from C++ in permitting only single inheritance. This makes for some difficult choices, if you would like to share combinations of inherited functionality and polymorphism from more than one source. However, it does reinforce the notion of inheritance as a subtyping (is) relationship, and implicitly that type relationships form a tree rather than a network. Other differences to consider: 1. Abstract class implementations may include fields 2. Interfaces may include final data members 3. It is slightly slower to call an implemented method via an interface reference. There is an even smaller penalty for calling a superclass method via a subclass reference (i.e., where the subclass does not override the method). There is almost no penalty for calling a subclass method via a superclass reference. (All are compared to a direct method call, i.e., calling the derived class method via a derived class reference). 16. (Sect. 6) How do static methods interact with inheritance? [*] Static (per-class, rather than per-object) methods do not participate in overriding (choosing the right method at runtime based on the class of the object). Probably the best and simplest way to think about this (and to write your code) is to write every invocation of a static method using the fully qualified class name: 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(). A.method2() will be called regardless of whether you use the fully-qualified class name or not, but using "A." makes it obvious to all. 17. (Sect. 6) Why is the String class final? I often want to override it. [*] Being final guarantees that instances of String are read-only. (The String class implements read-only objects, but if it were not final it would be possible to write a subclass of String which permitted instances to be changed.) Strings need to be read-only for security and efficiency. As for efficiency, Strings are very commonly used, even behind the scenes by the Java compiler. Efficiency gains in the String class 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. It's easier to optimize accesses to an object that is known to be unc