Information Technology hand pointing right Graduate Program hand pointing right Java for Programmers hand pointing right Lecture 1

What is Java?

Java is a general-purpose language

Java is a general purpose programming language for computers, designed "from the ground up" to be object-oriented and to work within a network context. Properly constructed Java programs act and look the same no matter what platform they might be run on and no matter what tasks they may be asked to perform. Java has built into its package structure (more on that in a bit) enough power and flexibility to do almost anything. Java even provides a means to make platform-specific tasks happen correctly. Properly constructed Java programs need not crash. Java solves a lot of the problems involved in using earlier languages, it provides a secure environment, and it handles error conditions in a sane and safe manner.

Where can Java run?

Java programs can run independently or within a web-browser

A Java program generally falls into one of two broad categories, based on the context within which the program will be run. Java applications are run "from the command-line", may or may not include a GUI, and have all the rights which any other command-line program might have (to read and write local files, open sockets to other networked machines, and so on). Java applets run only in the context of a "Web-browser", always include at least a minimal GUI, and have restricted rights (cannot read or write local files, cannot open sockets to machines other than the machine from which they were served, and so on).

People who don't know much about Java can sometimes make a big fuss about applets and applications, as though somehow applets are different. They are not. An applet is just a container for visible components, but it is specialized so that it can also run within a web-browser. Let's take a quick look at a simple program which can run either as an applet (within a web-browser) or as an application (launched from the commandline):
testHarness.java

What are Java's advantages?

Java is portable

With the opening up of the internetwork to the general public, it quickly became obvious that computer applications themselves could be moved onto the net if there were languages which supported this approach. One of the requirements for web-based software distribution is clearly that the software be cross-platform. Platform-specific languages are inadequate for an environment where applications are distributed on-demand. Java is cross-platform.

Java achieves cross-platform capabilities by borrowing some ideas from the past, most notably the UCSD p-system. Java is based on a virtual machine. When Java source code is compiled, the target is a virtual machine: a theoretical machine which is hardware-independent. This intermediate code or byte-code is then interpreted at run-time by the actual machine which actually runs the program. Java is both compiled and interpreted.

The Java runtime system or Virtual Machine (VM) performs like an actual processor: executing stack-based instructions, managing a heap, creating and manipulating data types, and so on. There are no Java features which are implementation-specific, and there are no Java features left undefined. As a result, Java is highly portable.

Java is dynamic and easily extensible

Java manages the loading of classes at run-time. For example, a Java program need not know at compilation what database management system will be used by a program. As long as the program adheres to the Java DataBase Connectivity (JDBC) application programming interface (or API), it can figure out what classes it needs to load at run-time (for example, what database drivers to load for this run of the program). Java will even allow the loading of classes on-demand after the program is already running.

Java understands distributed resources

Java was written from the ground up assuming that it would be used on machines connected to networks. Java classes (compiled units of byte-code) are simply application components which hold executable code and data and which can be stored on a local system or on a network server. As classes are needed by an application they are located and loaded dynamically

Java is safe

Java was designed to allow dynamically portable software. Java assesses the safety of code before it is run and isolates untrusted classes. Java pays attention to the context within which bytecodes run, and assigns security as is appropriate. For example, classes loaded off the network are not to be trusted as much as classes loaded off your local machine so Java allows them to do different things.

Java addresses common design and programming problems. For example, there is no direct way to make your code perform pointer operations, so the things people used to call stupid pointer tricks which were so common in the C/C++ world just plain cannot happen in Java. As another example, Java fully supports exception handling. This means that you can plan and construct your program such that it deals in a sane way with anything which may go wrong. This insures that you can write programs which do not crash.

central idea
Packages,
Interfaces,
and
Implementations

Grouping classes

Java allows you to group classes into packages. Packages allow the programmer to control the visibility of classes and variables. Controlling access by other classes is a key approach to insuring the safety and stability of your program modules. We will talk often about the virtues of information hiding in building well-formed and well-behaved programs and modules. Go back and take another look at testHarness.java, which shows the use of packages.

Contracting for communications

Java allows you to build interfaces. An interface is a boundary across which two systems or sub-systems can communicate. An interface might be a hardware connector used to link to other devices, or it might be a convention used to allow communication between two software systems. Often there is some intermediate component between the two systems which connects their interfaces together. For example, two EIA-232 interfaces connected via a serial cable. In this context we are referring to software systems/sub-systems. A Java interface is code which describes the method signatures, but which doesn't specify the implementations of those methods. By programming to interfaces one can insure that a new implementation may be plugged in without rewriting the code which uses an instance of an interface. For example, Java defines a public interface called DataInput which is implemented by streams that can read primitive Java data types from a stream in a machine-independent manner. If your code is written to use something which implements the DataInput interface, then replacing the implementation with a new one does not require rewriting or even recompiling the existing code. In addition, this allows incremental development of a large programming project by teams of programmers: the interfaces are agreed upon and distributed, and everyone writes their implementation code to the interfaces involved.

Information hiding

Implementations make interfaces real. Implementaions and interfaces also allow one to control access, but this time on the level of access to specific methods as well. What is a program? A program is just a collection of data structures and algorithms to deal with those data structures. Java allows you to specify whether the data structures within a particular class are accessable outside the class, and it allows you to specify whether the methods of a class (the algorithms) are accessable as well. This means the programmer can make sure that it is very hard for other classes to have unintended effects upon the data structures and algorithms contained in a class. Information hiding is a key weapon in the programmer's armory of weapons against other people's bad code.

Single Inheritance
of Classes
and Multiple Inheritance
of Interfaces

The inheritance model

One of the things which can make programs written in other computer languages do very strange things or produce weird errors is when they allow inheritance from multiple parent-classes. Java allows a class to inherit from only one super-class, but it allows a class to implement multiple interfaces. Again, the emphasis for the programmer is on programming to interfaces rather than to implementations.

Composition

The use of composition to program is a powerful approach. Composition involves creating new objects out of collections of existing objects, and (preferably) delegating responsibilities to the internal objects. This approach encourages the hiding of data structures and algorithms, increases the safety and re-usability of new objects, and makes new implementations of existing interfaces work with old code without rewriting or recompiling the old code. This is A Good Thing, and helps push programmers to spend more time thinking and less time coding.

Type
Safety

Strong typing, overloading, and overriding

Java is a strongly-typed language. When you declare an instance of a variable you must declare what type it will have, and when you use it the context must allow that type. Casting of objects is possible, but only within strict sanity limitations.

A method of an object may be overloaded. This means there may be several different methods with the same method-name, and the compiler figures out which one is to be used at compile-time. For example, the class java.io.BufferedInputStream extends FilterInputStream which in turn extends InputStream. the class BufferedInputStream has two different methods called read:
read() which reads the next byte of data from the buffered input stream, and
read(byte[], int, int) which reads bytes into a portion of an array
The method java.io.BufferedInputStream.read is said to be overloaded.

A method of an object may also override a method in its superclass. This means the new method has the same method signature (name, arguments, and return type) as the corresponding method in the superclass, and it is left up to the interpreter to figure out which method to use at runtime. In other words, you can create an instance of a subclass which the old code has "never seen before" and the proper method will be located and loaded dynamically at runtime. There is no need to recompile anything else.

Static methods

You can also guarantee that there is only "one copy" of a method by declaring it to be static. Static methods do not belong to any particular instance of an object, and they are accessed directly through a class name rather than being deynamically selected at runtime like instance methods. For example, the class java.lang.String has a method public static String valueOf(char data[]) which returns the string representation of the char array argument.

  char [] someData = { 'L', 'e', 'm', 'm', 'i', 'n', 'g' };
  String someNewString = String.valueOf( someData );
Note that access to the method is through the class-name ["String"], and not through the instance-name..
Dynamic memory management

Memory Allocation and Deallocation

One of the biggest pains in other languages is the management of memory. Allocation and deallocation can be tricky, and it is easy for a programmer to write code which keeps allocating memory without properly recycling it when no longer needed. Java provides dynamic memory management at runtime. "Garbage collection" is scheduled to happen when all references to an object go away, so the programmer need not concern themselves with the details of getting that memory back onto the heap for later reallocation. There are limits and caveats associated with this, but basically garbage collection usually becomes a non-issue when programming in Java.

Threads

Multiple Independently-Executing Modules

In most programming languages, independent threads of execution are a pain to implement. Programmers often end up having to purchase "addon" packages which are platform-specific and sometimes quite tricky to install. Java just comes with threads, period. There is nothing to add on, there are no platform-specific implementation issues to watch out for, there is "no full and no muss". You will find yourself using threads often when you program in Java, and many times you will not even be aware that you are doing so. Threads are powerful, and in Java they are easy.

Networking

Communicating with Other Machines

Java was designed "from the ground up" assuming a network connection. If the machine (hardware) and native O/S under which the program is running support networking, then any Java program running there can support networking. Images, text, database tables, all these networked information and data sources are instantly accessable to any Java program with no extra "sweat".

Valid HTML 4.01! Last updated: 12 Sept 2003
jeffs@it.rit.edu