|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
November 6, 1997 Java takes on C and C++ George Ellis, Kollmorgen Corp Java is hot, and C++ programmers are turning to it in droves. Is Java for you? Compare it to C++ and see. Java is a hot item. Proponents say it will loosen the Microsoft/Intel grip on the computer industry. They say it will change the architecture of personal computing as users connect to applications via scaled-down, Web-connected hardware. By one estimate, 60% of all C++ programmers are learning to program in Java. (Reference 1). All this for a language that, until recently, provided little besides animation for Web pages. Java has detractors, though. To judge it for yourself, look at why Java has been so broadly welcomed and why not everyone is so sure about it. Then look at Java's features--some so novel that they expand the very concept of a computer language. Consider new developments that are increasing Java's capabilities: Java Beans, just-in-time (JIT) compilers, Java applets, and a pared-down version of Java for embedded applications (see box "A Java glossary"). Finally, compare Java to the reigning development languages, C and C++, and convert a C program to its Java counterpart. Some straightforward examples show you how. Whether you think Java is the next step in computer evolution or you're just curious, you're in for good news: Information about Java is accessible to anyone with a link to the Internet. Reviews, specifications, tutorials, and even basic developer's tools are available without charge on the Web. Even tools that aren't free are thoroughly detailed at their producers' Web sites. Also, you probably already have a "Java virtual machine" on your computer inside your Web browser. What is Java? Java is a computer language created by Sun Microsystems. It's similar to C++ in syntax, variable typing, flow control, and in most other ways of describing computer languages. But Java adds functionality well outside the span of C or any other conventional language. For example, it defines security features, database connectivity, multithreaded operation, and even an automatic documentation feature. Java also goes deeper than conventional computer languages by defining the byte code to which source code compiles (see box "Java byte code"). In that sense, Java is the first mainstream language to define its own machine. The three main advantages of Java are that it runs on many platforms, it's ideal for networks, and it's "safer" than C and C++. These advantages also come with some countering disadvantages or problems, however, at least for now. The key to Java's multiple-platform operation is the Java virtual machine (JVM). The JVM executes byte code, which is similar to a stack-oriented assembler language. In a sense, today's JVM is a simulated computer, interpreting object code for a machine that doesn't yet exist in hardware. There is simply no equivalent to the JVM in conventional languages. The JVM can be a stand-alone application under Sun Solaris, or it can be part of a Windows-based Web browser. As long as the JVM is a correct implementation, Java byte code runs identically on every machine and under every operating system. Java is ideal for networks. It provides a mechanism for compiling source code into an "applet," a code segment that downloads from a Web site to your Web browser and then runs on your browser's JVM. It's easy to paste Java applets into Web sites for more active and more interactive Web pages, and Web-browser JVMs enhance security by limiting applets' access. Web applications--applets combined with conventional Web pages--run from a remote site and can connect to a low-cost machine dubbed the "network computer," or NC. Future NCs will use Java accelerator chips to boost performance while keeping costs low. Java's safety, relative to other languages, comes from added features--for example, automatic array-bounds checking. Java also requires programmers to deal with exceptions (errors) generated by some library functions. In addition, Java eliminates memory leaks by tightly controlling allocation and deallocation of memory space. It also excludes troublesome parts of C, such as pointers, which prevent automatic memory deallocation and which lead to C's notorious pointer bugs. Java also severely limits declaration of global variables and functions, and it eliminates C's dizzying ability to include files that include files that include more files. Not everyone is convinced that Java is the language of the future, however. Many people are waiting for substance--more applications, more tools, more deployment. And some companies that bought into Java early have had serious problems (Reference 2). Also, Java office suites can feel like a step backward, and testing shows that many applications don't run identically on different platforms, or even in different Web browsers on the same platform (Reference 3). Finally, reported bugs in automatic memory deallocation have been so severe that they crash the JVM (Reference 4). Java proponents consider these problems normal for new technology, but others see long-term deficiencies. Sun's mantra, "Write once, run anywhere," is, for now, just a promise. In a test of Java-based office applications on seven platforms using as many as six browsers on each, the testers concluded that "Java performance varied widely, depending on which operating systems and browsers we used. More frustrating, Java programs that ran fine on one configuration were unreliable on the next" (Reference 3). But things could be getting better. According to Sun, the new version of Java (JDK 1.1) has 5000 compliance tests that a JVM should meet. Another concern with Java is speed. The dark side of the JVM is that an interpretive layer comes between the application and the processor. In other words, Java compiles into byte code, and the byte code requires interpretation. A Java program can execute a mere 5 to 10% as fast as its C++ counterpart (Reference 5). But the future does look brighter. First, JDK 1.1 claims to be two to three times faster than JDK 1.02. In addition, JIT-compiler technology can greatly alleviate the speed problem. Speed improvements JIT compilers speed Java execution by automatically converting generic Java byte code to platform-specific code at runtime. The end effect is that, after allowing time for compilation, Java can execute at speeds comparable to C++ (Reference 5). Netscape has licensed Symantec's JIT to include in its new Web browser (Navigator 4.0), so applets can benefit from JIT, too. To learn more about JIT, connect to cafe.symantec.com or see Reference 6. If you're not concerned about portability, you can use development tools that compile directly to machine code, skipping the JVM altogether; some examples include Asymetrix SuperCede and Visi Vibe (see Reference 5). Finally, Java accelerator chips can also help by providing hardware that can execute Java byte code. For many Java applets, download time is the issue, not execution speed. Java has moved to improve this problem as well. It now includes the Java archive format (JAR), a Java-specific means of compressing applets that download two to five times faster than uncompressed applets. Applets, applications The difference between an applet and an application is simple, involving the use of system resources. An application is a stand-alone program that manages its own resources. An application gets its own main window frame, performs its own memory management, and handles its own display functions. Applications run on stand-alone JVMs. Sun provides stand-alone JVMs at www.javasoft.com/products/ jdk/1.1/jre. (Note: Web sites change frequently, so if you can't connect here, try navigating the main site: www.javasoft.com.) Stand-alone JVMs are also part of Java development tools, such as Symantec Visual Café, Microsoft Visual J++, and Sun Java Workshop. Applets use the resources of another program, typically a Web browser. For example, a Java applet can run in the window frame provided by the main application. An applet can also run on a JVM that's part of a browser. Browsers that have JVMs include Microsoft Internet Explorer, Netscape Navigator, Sun HotJava, and the browser in Lotus Notes 4.5. Applets are subject to strict limitations imposed to stop an errant (or purposely destructive) applet from damaging its temporary host. For example, to prevent damage to files and the spread of viruses, applets can't read from or write to the file system on a browser's computer (Reference 7). Similarly, applets can't run programs or program parts, such as dynamic-link libraries, on a browser's computer. Consequently, an applet can't call destructive programs that aren't subject to applet limitations. Also, applets can't connect a browser's computer to any other server. Contrast Java with C/C++ Compared with C, Java limits the use of global variables, constants, and functions. All globals in a file must reside in one class, and that class must have the same name as the file. For example, Java defines sin( ) in a class named Math.Class, which is in a file named Math.java. Other classes may call sin( ), but only as Math.sin( ). Thus, every global is clearly identified and easy to find. To access variables and functions in other Java files, you use the import command. This command resembles C's #include, but it's different. Whereas #include copies source code into your program, import only provides directions to global methods and data. C doesn't force you to identify the location of globals; if the variable shows up during linking, C is happy. With Java, you must define which modules hold which global functions and data. You even have to import standard Java code such as Java.Math. Like C, Java starts execution in main( ), but Java allows each file to have its own main( ). In other words, every file--even a utility file--can operate as a stand-alone application. This useful ability allows programmers to include tests that exercise utilities from the command line. For example, if you write a class with string formatting routines, a main( ) for testing could format a few examples. Of course, only one main( ) at a time is selectable, and with the possibility of having many main( ) methods, how does Java specify which main( ) to run? The answer is intuitive: main( ) comes from the application or applet that is running. So, if you run hello.class, which imports errors.class, the main( ) from hello gets selected. If you launch that same errors.class, the main( ) from errors gets selected. Java stops memory leaks by taking memory control out of the programmer's hands; a "garbage collector" handles memory deallocation automatically. With a C program, defining a flexible memory space with global access is simple: Grab memory with a pointer and a call to alloc( ), and keep that pointer around as long as you need it. The problem is that you must explicitly free the memory; if you forget, memory gets taken but is never returned--a memory leak. It's a common bug that's tough to find. And if memory leaks are bad in C and C++, they are terrible in the unsecured world of the Web. Java eliminates memory leaks. Programmers don't explicitly free memory; instead, they rely on the garbage collector, an algorithm that runs quietly in the background, sweeping up after spent routines. Comparing in detail A comparison of Java with C and C++ reveals both similarities and differences. Some parts of Java parallel C so closely you'll recognize them immediately. But Java also eliminates some features of C and C++--some that you might not miss, but others that you probably will. Java also adds major features that extend well beyond C and C++. Converting a C program to Java illustrates some of the similarities and differences. Java keeps the appearance of C; you'll recognize the operators, syntax, comments, and data types (byte, short, char, int, long, float, double, but no unsigned int). Program flow will be familiar, including case, do, while, and for. Like C, Java is case-sensitive: String is quite different from string. The object orientation (see box "Java and OOP") is similar to C++; you'll recognize the new operator and constructors. Functions overload in a similar manner. Although Java is similar to C and C++, it excludes many C and C++ features and functions. As noted earlier, Java eliminates pointers, replacing them with references that have a small subset of pointer functions. Java doesn't include operator overloading or multiple inheritance from C++, nor does it have function prototypes. Java compilers are smart enough to search the source-code file, as well as all imported files to find the required prototypes. You won't need to deal with "undefined forward references" anymore. Better still, you won't need header files. Java removes some features that C programmers will miss. Presumably the reasoning for the omissions is sound, but you'll miss the features nevertheless. The elimination of variable-list arguments, for example, creates awkward code, because the printf( ) family is gone. You can print formatted text, but it takes more work. As you'll see in a later example program, this omission can cause some problems. Java also removes stand-alone functions. For example, an awkward sequence of characters--Math--must precede every call to tan, sin, cos, log, exp, and so on. True, this approach eliminates confusion about just which sin you get linked to, but it's awkward all the same. Along these same lines, Java has no stand-alone constants. You can't use PI; you will need Math.PI. Java removes the preprocessor. There's no Java equivalent to C's #define. There are no macros. Conditional compilation is gone. There's no equivalent to:
Finally, enum is gone. Most of the missing features are conveniences, and Java does generally provide work arounds. But, if you're a C programmer converting to Java, be prepared to be disappointed from time to time. A host of new Java features redefine what a language is. For example, Java directly supports multitasking through threads. Multitasking is usually a function of an OS, not a language. In Java, you can define a code segment as a "thread" and launch it in a multitasking environment with just a few lines of code. Java also improves exception handling, which has come a long way since C first appeared in the early 1980s. In those days, C offered little more than return codes from library functions. Now, Java provides the try/catch/finally block. As the name indicates, you try a sequence in the try block, which might generate an exception. This sequence might be file I/O or serial communications. In the catch block, you list one or more exceptions, such as "file not found" or "divide by zero," with the code that should execute when each exception occurs. In the finally block, you list code that should run whether or not an exception occurred--for example, to close the file that generated the exception. The following pseudo-code provides an example:
In fact, Java not only supports this error handling, but also forces programmers to deal with exceptions that circumstance might "throw" at their code. Another new feature of Java is interface. Interfaces define a set of data and methods that different classes implement. For example, suppose you're putting together a graphics package in which you create a class for a point, another class for a rectangle, another for an ellipse, and so on. Each shape needs different implementations of the same methods--for example, draw( ), move( ), and erase( ). You could use inheritance for this purpose by inheriting all shapes from a Java super class, Graphics. This approach can be onerous, however, especially if you're trying to use classes that come from multiple sources. The interface can be simpler than relying on inheritance. As an example, you could define a Graphical interface:
Then, you can include the Graphical interface in each of the classes that need to implement it:
Because interface allows you to join otherwise unrelated classes, some people think of it as Java's replacement for multiple inheritance (one subclass inheriting from two or more super classes). However, although interface can stand in for multiple inheritance in some cases, it's not a general replacement. Java also adds features that make programming a little easier. For example, all data types automatically convert to a string. The following code fills xstring with "x = 1.2345'':
Java introduces the logical (or unsigned) shift-right operator (>>>) to augment the arithmetic (or signed) shift right (>>). For example,
produces AfterShift = 0x00FFFFFF. Alternatively, using the >> operator would result in AfterShift = 0xFFFFFFFF, because the sign bit would shift into the leftmost position for each shift. The >>> operator is necessary in part because Java does not support unsigned integers. (C assumes an unsigned shift when the type is unsigned and a signed shift otherwise.) Java also includes some useful canned functions. They include a hash table, a tokenizer, and a stack. Java's Abstract Windowing Toolkit (AWT) provides (almost) uniform user interfaces across multiple operating systems. AWT is a collection of tools for a windowing environment: list box, scroll bars, pushbuttons, slide bars, and so on. It's a good example of how Java defines things that are outside most languages--things that are usually left for manufacturers to define. Pascal doesn't define buttons (Borland Delphi does), Basic doesn't define mouse events (Microsoft Visual Basic does), and C doesn't define list boxes (Microsoft Visual C++ does). Java casts a wide net, enforcing uniformity beyond today's languages. Document while you code--really Everyone involved in documentation would like to see the process made easier. To this end, Java includes JavaDoc, a stand-alone utility that automatically generates HTML-based documentation from source code. To mark lines for JavaDoc, you use a special comment:
The Java compiler recognizes the /* . . . */ as comments and ignores these lines. JavaDoc recognizes the /** prefix as indicating a comment for its own consumption. The programmer can add general comments or assign predefined tags for the author, the version, cross references, parameters, and variables. JavaDoc simplifies documentation by letting you put information directly in the source code and by providing some basic organization. Updates are easier, because you can modify the documentation alongside the source. Of course, JavaDoc won't cure the documentation problem: You still have to enter the information. But it can make the process a little simpler. You can learn more about JavaDoc at www.javasoft.com/Series/Tutorial/book.html (this address is case-sensitive). Packages are a convenience with Java. Java has a strict requirement that a file can contain no more than one public class. Thus, if you want to provide a large set of classes--say, for many graphics shapes--you would need one file for each class, and the end user would have to import these classes individually. Packages let you group multiple classes together, however, and users can import a package with a single line. In fact, many standard Java classes are in packages. For example, when you use the Abstract Windowing Toolkit, you normally include the following import statement:
to import all the members of the AWT package. Now, look at a simple C program and see what it takes to convert it to Java. The C program calculates the phase and gain of a lowpass filter with a break frequency of 100 Hz:
where K = 628.3, which is 100 Hz expressed in radians. When evaluating at a fixed frequency, s (the Laplace operator) simplifes to j omega, lc, where j=square root(1) and omega, lc=2 pi f. Therefore,
The gain or magnitude of T(omega, lc) is
The unit of gain is usually decibels, or dB, where
The phase is
Both the C and the Java programs below calculate gain and phase at 21 frequencies between 10 and 1000 Hz. The C program appears in Listing 1. Its output is:
and so on. In converting Listing 1's C program to Java, designing LowPass.Java as an applet can simplify some overhead issues. However, designing it as an applet means you'll need to write output to a component from the AWT rather than directly to the screen. In this example, the AWT component will be ResultsLB, an AWT list box. (List boxes--rectangular areas in a window that displays text--are common in Windows applications--for example, to display a group of files that a user can select from.) Also, because Java has no printf( ), you'll need to write a routine (formatFixed) that converts floating point to strings for display in tabular form. Unfortunately, formatFixed requires more lines of code than LowPass itself. To begin the conversion, first remove the #includes and replace them with nearly equivalent imports:
Now create lowPass, a class based on Applet. public class lowPass extends Applet { Now, add log10 and dB, two functions that make converting to decibels more convenient. Note the "Math." prefix with log and PI.
You need to initialize the applet with the init( ) method. This program calls the super class init( ), which is the standard Applet init( ). Next, call setLayout( ) to set the layout manager.
Now, resize the window, create
a new list box called resize(432,264); You can reshape the resultsLB list box and set the font to a nonproportional font so columns will line up easily. resultsLB.reshape(0,0,432,230); Call go( ), the routine that calculates the phase and gain for the lowpass filter.
Declare resultsLB as a List from Java.awt: java.awt.List resultsLB; Convert go( ), the routine that outputs the data. Start by defining the routine go( ) and numerous constants just as you would in C:
Print to the list box, resultsLB, with the addItem( ) method: resultsLB.addItem(' Frequency Gain Phase'); Now, add the math, which is identical to math in C. The only differences are the sightings of "Math.":
Finally, add lines to the list box, resultsLB, with the addItem( ) method:
Now, the bad news. Java eliminated printf( ), and the standard Java string-conversion routines don't provide enough control over formatting. A routine to convert floating-point numbers is necessary to get around this shortcoming. The solution is method formatFixed( ), defined with three arguments: the value, the number of digits before the decimal, and the number after. The logic is almost indiscernible from C. That's it. The finished product, written in Java, appears in Listing 2. By the way, notice that the conversion is not just that of a C program to Java, but also of a DOS program to a windowing program. Whereas Java added five or 10 lines to this end, some modern C and C++ development environments for Windows could require many times that number to go from DOS to Windows. As you can see, Java has a lot in common with C and C++, but there are many differences. If you'd like more details, you can obtain a complete Java specification at javasoft.com/docs/books/jls/html/index.html. Also, Sun posts a complete copy of The Java Tutorial (Reference 8) at java.sun.com/nav/read/Tutorial. If you want to go further, consider downloading the JDK from Sun or buying a commercial Java development packages (Reference 5) and writing some Java code of your own.
To obtain the software listings, download 23ms323.zip. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| EDN Access | Feedback | Table of Contents | |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Copyright © 1997 EDN Magazine, EDN Access. EDN is a registered trademark of Reed Properties Inc, used under license. EDN is published by Cahners Publishing Company, a unit of Reed Elsevier Inc. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||