Download Note - first

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
CSPP51036
Java Programming
Instructor: Andrew Siegel
Syllabus, discussion group, etc.
 Everything is posted on course website
http://masters.cs.uchicago.edu/~asiegel/courses/cspp51036
 Please pay particular attention to grading
policy/homework submission
 First homework already posted.
 Please be sure to sign up for discussion group
asap!
Grading
 Bi-weekly homework assignment
– 5 total
– 3 day automatic extension for 10%
– Serious emergency = not graded
– Submit electronically, receive confirmation. 24 hours to
deal with any problems.
– Typically, functionality only will be graded. Wrong
answer = no credit.
– Design will be graded only when problems specify
design requirements.
 Final
– In-class, conceptual, purposeful.
Who is this class for?
 There is no assumption that you know any
Java or other OO programming language. If
you do, you may find the first few weeks
boring.
 You must have programming experience.
We will not spend very much time on
syntax, procedural constructs, operators,
etc. It is assumed that you can pick this up.
Getting Help – TA’s
 The class will be split into a number of subgroups,
each of which is assigned to one of the TA’s.
 The TA’s will organize office hours/review
sessions according to the needs of their group.
 Quickest way to answer small questions is with
email to course list. Everyone is encouraged to
answer – will be factored into grade. Very good
way to learn.
 Try not to spend too much class time discussing
homeworks – ta’s will handle this.
Course Format
 All lecture
 Will follow book closely!
 Feel free to ask questions any time
 Probably won’t call on you unsolicited
 Probably will make fun of you
 Attendance is optional but recommended
 Might use overhead projector, might not.
 Will post notes each week in any case
Software/hardware requirements
 Command-line tools best when first learning.
 Sun’s Java Software Development Kit (SDK)
– Already installed on Linux cluster
– May choose to install on your own machine – free and
easy, download manageable (book CD has copy). See
beginning of chapter 2 for installation instructions.
 Some IDE (Forte, Visual Age, Visual Café, etc.)
not recommended. May use but are responsible for
exporting in a manner understandable by jdk.
 Your favorite text editor – emacs is recommended.
Textpad is pretty good for Java.
History of Java
 First version released in 1995
 Four major versions released since then
– 1.02 (1996) JDBC, Distributed Objects
– 1.1 (1997) New Event Model
– 1.2 (1998) Swing
– 1.3 (2000) Cleanup
– 1.4 (2002)
Programming with Java
What is/isn’t Java?
 Read chapter 1 of Core Java
– Discussion is very balanced
 Basically, compared to C Java is a relatively high-
level language with many built-in features for
portably doing useful things such as:
–
–
–
–
–
–
–
Multithreading
Writing distributed programs
Writing GUI clients
Error handling
Extending Web servers
Embedding programs in Web browsers
Connecting to commercial databases
Compiling/running first java
program
 Create source code file (call it for example
MyFirstProgram.java).
 To compile:
prompt >> javac MyFirstProgram.java
 This produces byte code file named
MyFirstProgram.class
 To run:
prompt >> java MyFirstProgram
Observations
 .class file is not machine code. It is intermediate
form called Java Byte code. Can run on any
platform as long as platform has a Java Virtual
Machine (JVM).
 The second step on previous slide invokes the
JVM to interpret the byte code on the given
platform.
 In theory, byte code can be moved to another
platform and be run there without recompiling –
this is the magic of applets.
 Leave off the .class part when invoking the JVM.
Observations
 This is an old-fashioned command-line
program. Java also supports GUI
applications and web-browser hosted
programs called applets.
 After the first couple of weeks we will use
graphical rather than scripting front-ends.
Writing first program
 To keep things simple our first few
programs will all be written as just a single
main program.
 In java, the file in which your program
resides must contain a .java extension (e.g.
MyFirstProgram.java).
Writing first program
 Then, the program must be wrapped in a
class definition which is the same as the file
basename (MyFirstProgram). Careful, Java
is case-sensitive.
class MyFirstProgram { … }
 Finally, main is defined similar to C, but
with a few more modifiers:
public static void main(String[] args){ … }
These are all required. No shortcuts.
Writing first program
 Just as in C, main(..) is the principle entry point
into the program. When you say
java Program
Java looks in Program for a procedure named
main. This is where the program starts.
 To print to stdout in java use:
System.out.println(“ …”);
 MyFirstProgram.
Basic Programming
Constructs
What you should learn on your own
Breakdown of a java program
 Strategy to start is write evertything in a
single main program and very quickly
review the basics of java syntax (very little
time here).
 Then we break into procedures.
 Then class/packages.
Single-threaded program
 For a single thread of execution, each line
of code is executed sequentially (as in C).
 Each statement is terminated with a
semicolon.
 Unlike C, declarations can occur anywhere
within a program.
 Basic operators, control statements almost
exactly like C. A few minor differences.
 Best to just look at some examples.
Java Data Types
 Sizes fully specified by Java standard.
 Java is a very strongly typed language
 Integer types
– int (4 bytes signed)
– short (2 bytes signed)
– long (8 bytes signed) use suffix L (eg 1000000000L)
– byte (1 byte signed)
 Floating-point types
– float (4 bytes) use suffix F (eg 1.28F)
– double( 8 bytes)
Additional Data Types
 char
– Two-byte unicode
– Assignment with ‘ ‘
• e.g. char c = ‘h’;
 boolean
– true or false
e.g. boolean x = true;
if (x){…};
Operators/Control Flow
 Almost exactly like regular ANSI C.
 +, *, -, /, %, ++, --, +=, etc.
 ==, !=, >, < , etc.
 if statements, for loops, while loops, do loops,
switch statements, etc.
 continue, break, return, System.exit(0).
 Read pp 54– in Core Java.
 No need to spend class time going over these.
Scoping
 Braces are used as in C to denote begin/end of
blocks
 Be careful of the following:
int j = 0;
if ( j <1 ){
int k = 2;
…
}
k = 3; //Error! k inaccessible here
 Declarations do not propogate upwards.
Adding datatypes -- classes
 Java has handful of built-in datatypes just
discussed (int, float, etc.)
 Just like in C, user typically creates own
homemade datatypes to work with particular
application (ie structs and enums).
 In Java these are called classes.
 Many class definitions come as a standard part of
the Java distribution. Most common Example is
String class.
Strings
 Java provides a class definition for a type called
String
 Since the String class is part of the java.lang
package, no special imports are required to use it
(like a header file in C).
 Just like regular datatypes (and like C), variables
of type String are declared as:
String s1;
String s2, s3; //etc.
 Note that String is uppercase. This is the Java
convention for classnames.
Strings
 Initializing a String is painless
s1 = “This is some java String”;
 Note that double quotes are required.
 Memory is allocated dynamically.
 Think of above method as shortcut for more
standard way (assuming s1 has been declared):
s1 = new String(“This is some java String”);
 new operator required to create memory for new
String object.
String methods
 Given a String object we can then access any
public String method or instance variable (field).
 Best to think of analogy with C. Given a variable
of some struct type, we can access any of the
struct’s members. If one of these members is a
pointer to a function, we can essentially call a
function using the struct. (x.doit(x,…))
 In Java, this idea is taken quite a bit further, but
the above analogy is a good start.
String Examples
 Best to see by way of example:
String s = new String(“Hello”);
Char c = s.charAt(3);
System.out.println(c);
 Method charAt called on String object s
taking single integer parameter.
 How might this look in a procedural
language with structures? (homework)
String class documentation
 Incredibly important!
– Each standard java class definition is fully documented
online
– You must become facile at reading/interpreting these
documents. This is how everything is done in Java.
– A little hard at first but then very simple. Makes
learning new functionality much easier (if it’s well
written).
– Make a link to
http://java.sun.com/j2se/1.4/docs/api/index.html
 Much of homework will come from interpreting
this page.
1d Arrays
 Arrays in Java are dynamic; they are
allocated with the new operator.
 Creating a (1d) array is a two-step process:
int[] x; //declare x to be an array of ints
//x has the value of null right now
x = new int[100]; //allocate 100 ints worth
 At this point the values of x are all zeroes.
 Assignment is then just like C.
1d Arrays
 Note that in Java, unlike C, the compiler will not
let you overrun the bounds of an array. Give it a
try.
 Note that you must use the new operator to size
the array. It cannot be done statically as in C.
Until this is done, the array reference has a value
of null.
 The array comes with a field called length which
stores the number of elements in the array. Try
printing x.length in the previous example. This is a
simple but nice convenience.
Misc tricks to get work done
Parsings Strings
 Recall that the args array is an array of Strings.
Thus, to accept key input as integers, float, etc. we
must convert.
 To convert to int, use the Integer.parseInt(String)
function.
Ex. String s1 = “32”;
int j = Integer.parseInt(s1); // j now holds 32
 Converting to double is analogous:
Ex. String s1 = “32”;
double j = Double.parseDouble(s1); // j now holds 32
Parsing Strings
 Note that the conversion methods are just regular
procedural funtions. That is, no object was created
in order to call the method. The entity before the
‘.’ is _not_ an object. More on this later.
 What if the String is unparseable? (e.g. “andrew”
rather than “32”).
 Study the Integer and Double classes and look for
a description of the errors that are thrown by the
various methods. Does anything stand out? See
example Looper.java. More on this later.
Reading Keyboard input at
runtime
 How do we prompt for keyboard input at
runtime?
 Requires knowing a little weird i/o stuff.
For now, let’s use a simple class that I wrote
with a few simple methods.
 Class is called ParserUtils.java. Please
retrieve from Java Library directory on
course site.
ParserUtils.java
 Class definition contains two methods:
– String getKeyInput()
– String[] getTokens(String)
 First method blocks program until user enters
some data (followed by enter). What user types in
then stored in String return.
 Second method takes String and breaks into
tokens based on white space, stores in String array
return.
 To call these methods, use class name followed by
‘.’ before method name. See Parser.java
Reading text file
 This also requires some ugly i/o operations we’ll
cover later.
 For now, we’ll use a simple class
TextManipTools.java (see course site).
 This has single method
String[] readFileByLines(String)
 This method reads the filename specified by
String into an array of Strings, each element of
which holds one line of text.
 See DumpFile.java
Intro to Java Classes
Java Classes
 Placeholder for beginning notes on making
simple java classes
Interfaces, Inhteritance,
Polymorphism
What is an Java interface?
 Like a class but only contains abstract
methods and final variables
example:
interface FooInterface{
void foo1();
int foo2(double x);
}
abstract interface FooInterface{
public abstract void foo1();
public abstract int foo2(double x);
}
Both are correct!
the abstract and public
keywords are implied,
so the shorthand is
recommended.
Interfaces, cont.
 Unlike a class, an interface cannot be instantiated!
 Rather, an interface is implemented by some other
class:
class FooClass implements FooInterface{
....
}
 This means one thing only: FooClass must contain
versions of both foo1 and foo2 that actually do
something useful. We say that FooClass must
provide implementations for all of the methods in
FooInterface.
Interfaces, cont.
 When a class implements an interface, think of the
class as entering a contract to provide meat for all
methods in the interface.
 The compiler will check that this contract is
adhered to.
 Otherwise, the class implementing the interface
can contain anything else that a regular class
contains.
 Again: do not try to instantiate an interface – this
is meaningless!
More interface rules
 A class may implement any number of interfaces
as:
class FooClass implements A, B, C{
...
}
 An interface may also contain public static final
variables. Usually, these qualifiers are left off. We
just say:
interface MyConstants{
double PI = 3.141592;
double E = 1.7182818;
}
can be acessed as either
MyConstants.PI or just
PI by any class that
implements the interface
Certification-type questions
 What happens when multiple interface
implementation results in name conflicts?
– if the methods have different signatures, they are
considered overloaded and there is no problem
– if the methods have the same signature and the same
return type, they are considered to be the same method.
– if they have the same signature and different return
types, a compilation error will result.
– If they have same signature/return type but throw
different exceptions, they are considered to be same,
and resulting throws list is union of original two
Marker Interfaces
 Some interfaces contain no methods or
constants at all (ie they are empty).
 These are called “marker interfaces”.
 Examples are Cloneable and Serializable in
java library.
 We will understand these better once we
understand subtype-supertype relationships.
Subtyping with Interfaces
 Understanding mechanics of interfaces is
only about 1/3 of the story.
 Next, we have to understand how interfaces
allow for polymorphism.
 Finally, we study probably the hardest part –
how to best use polymorphism to really
write superior code.
Rules of subtyping
 If class C implements interface I, then C is a
subtype of I.
 What does this imply? We can do things like:
C aC;
aC = new C();
I aC;
aC = new C();
This is the regular stuff
Can do this also!
 In the latter case, we often say that the runtime type of aC
is C, but the static or declared type is I.
 In the former case, both types are C
Substitutability of Types
 Rule: A value of a subtype can appear wherever a
value of its supertype is expected. In other words,
a value of a sybtype can always substitute for a
value of a supertype.
 To rephrase for objects: An instance of a subclass
can appear wherever an instance of a superclass is
expected.
Note: superclass here refers to interface at this point.
We will make more general soon.
Generic examples of subtyping
class Circle implements Drawable, Scalable{ ...
Circle aCircle;
Drawable aDrawable;
Scalable aScalable;
aCircle = new Circle(); //ok
aCircle = new Drawable(); //BAD!
aDrawable = new Circle();//ok
aScalable = new Circle(); //ok
1,3,4 are ok because a Circle object is created and it is assigned
to a declared type of either Circle or one of its supertypes.
More examples
Drawable aDrawable;
Circle aCircle;
aCircle = new Circle();//fine
aDrawable = aCircle;//fine – aDrawable is type superclass
aDrawable = new Circle();
aCircle = aDrawable; //NO; cannot assign more general to
//more specific without an explicit
//cast
aCircle = (Circle) aDrawable; //this is ok – explicit cast!
Widening and Narrowing
 The conversion of a subtype to one of its
supertypes is called widening. The conversioning
of a supertype to one of its subtypes is called
narrowing.
 Widening happens automatically during an
assignment. Nothing special is required. This is
also typically called upcasting.
 Narrowing requires a proper explicit cast,
otherwise the compiler will complain. This is an
example of Java’s very strong typing. It is your
best friend. Narrowing is also known as
“downcasting”.
ClassCasts and instanceof


The java compiler will allow any cast. If the cast
is illegal, a runtime exception will be thrown
(ClassCastException).
There are two ways to safeguard against this.
1. with a try-catch block (later)
2. Using the instanceof operator as:
if (aDrawable instanceof Circle){
aCircle = (Circle) aDrawable
}
instanceof tells the actual type of an object rather than its
declared type.
Why on earth do this?
 How could this ever be used to your advantage?
Why not simlply type all Circles as Circle, etc. In
other words, why ever do:
Drawable aCircle = new Circle();
vs.
Circle aCircle = new Circle();
 Much easier to understand if we use upcasting in
method calls.
Using Upcasting in method calls
Imagine there is a class Renderer that has a method Render
that can operate on any object that knows how to morph
any two objects that can draw themselves. e.g.;
class Renderer{
...
public void morph(Drawable o1, Drawable o2){
// calls made to o1.draw(), o2.draw() here\
}
You can call morph as e.g.:
Renderer rn = new Renderer();
Circle c = new Circle(); Rectangle r = new Rectangle();
rn.morph(c,r); //c,r are automatically upcast to Drawables
Comparable interface
 Another good example is Java’s
Comparable interface, which contains the
compareTo method.
 One of the Arrays.sort methods operates on
any array of Objects that implement the
Comparable interface.
 Thus, specific objects to be sorted are
implicitly upcast when passed to the sort
method.
When is downcasting needed?
 Once an object is upcast, you cannot call methods
that do not exist in the supertype.
 For example, if Rectangle objects have a method
called rotate(), that method cannot be called from
within morph unless an explicit downcast is
performed.
 This is an example of Java’s strong typing. The
compiler cannot be sure that the actual object
passed in has a rotate method, so it forces you to
say so explicitly.
Extending interfaces
 An interface may also extend another interface.
 In that case, the extender is known as the
superinterface and the extendee is the
subinterface.
 Example:
interface FooInterface{
int foo1();
}
interface FooInterface2 extends FooInterface{
int foo2();
}
FooInerface2 contains both methods foo1 and foo2, and anything that implements
FooInterface2 must implement both of these.
Part III: How interfaces are used
 This is difficult because there is no single, simple
answer to the question.
 Like any semantic feature in a programming
language, there are no hard and fast rules about in
what situations it should best be exploited.
 However, there are many guidelines and general
strategies (or else the feature would have never
bee included).
 We’ll cover a few ways in which interfaces are
typically used.
Some interface uses
1.
2.
3.
4.
5.
To simply clarify the the functionality associated
with a particular abstraction.
To abstract functionality in a method to make it
more general, such as pointers to functions are
used in C. sort is a good example.
To implement callbacks, such as in GUI
programming
To write more general, implementation
depending code that is easy to extend and
maintain.
To simulate global constants.
Clarifying functionality
 Often you just want to write a code to do
something. It will never do anything else.
You are not concerned about extensibility.
 Even in such a case, it can be nice to
organize your program using interfaces. It
makes the code easy to read and the intent
of the author very clear.
Callbacks
 Callbacks are a general programming
technique where a method call another
method which then calls the calling method
(typically to inform the caller when some
action has taken place).
 Timer and Swing ActionListeners are good
examples.
To write more general
implementation
 A method that operates on a variable of type
interface automatically works for any subtype of that interface.
 This is much more general than writing
your program to operate only on a particular
subtype.
 See Shape example.
Abstracting functionality
 A method can often be made more general by
customizing its work based on the implementation
of some other function that it calls.
 sort(...) is a good example. A sort() function can
sort any list of items as long as you tell it how to
compare any two items.
 Numerical methods for solvering differential
equations often depend on taking discrete
derivatives: you can make such a routine general
by specifying the derivate technique
independently.
Ineritance
Basic inheritance
 Interfaces can be thought of as a special case of a
more general class relationship called inheritance.
 When a class C2 inherits from or extends another
class C1, C1 is called the superclass of C2, and
C2 the subclass of C1.
 This means that all of the public and protected
members of the superclass are available to the
subclass. This includes implementation and
instance variables!
 Any class that is not explicitly declared as final
can be extended.
Inheritance syntax
For one class to be a subclass of another, we use
the extends keyword:
class GradStudent extends Student{ ...}
class Manager extends Employee{...}
etc.
The superclass requires no special syntax.
Subtyping
 Everything we learned about typing and
subtyping holds a fortiori for super and
subclasses.
 Specifically, classes which extend other
classes are of both type superclass and type
subclass.
 A class can only extend a single class (no
multiple implementation inheritance).
Method overriding
 Overriding refers to the introduction of an
instance method in a subclass that has the
same name, signature, and return type of a
method in the superclass.
 Implementation of this method in the
subclass replaced the implementation of the
method in the superclass.
Overriding example
class A{
public void m1(){...}
}
class B extends A{
public void m1(){...}
}
For objects of class B, its own unique version of m1 will be
called. We say that the method m1 in B overrides the
method m1 in its superclass.
What is the point?
 Great advantage of implementation inheritance is
code re-use.
 By factoring functionality common among many
classes to a single superclass, each subclass is
much simpler.
 Furthermore, code changes need to occur in only
one place.
 However, when distributing a library, this can also
be anathema to clients when used non-judiciously
– breaks encapsulation!
When to use inheritance
 As with every semantic construct, there are
no firm rules. Even general guidelines are
not uniformly agreed upon.
 A non-controversial statement is probably:
Be very careful not to overuse. Deep
inheritance hierarchies are very hard to keep
track of and maintain.
 We will be exploring these issues constantly
throughout the rest of the class.
The rules: Certification fodder
 The easier (but still sometimes subtle)
question is what the exact rules are.
 Divide rules up into several sections
–
–
–
–
instance variables
constrcutors
methods
issues with static iv’s and methods
Rules for instance variables
 First must understand concept of a package in
Java.
 A package is a collection of related class
definition. For example, java.lang, java.util,
java.util.regex, etc.
 Classes that are not placed within a package are
automatically in the “default package”.
 It’s generally a good idea to explicitily place all of
your programs within a package.
Using classes from a package
 Two ways to access classes from a package:
– use full package name:
• java.util.ArrayList x = new java.util.ArrayList();
– use import statement:
• import java.util.ArrayList
• then can use just class name everywhere after import
 What if names conflict?
– compiler warning
– must use full name to distinguish
 Can also use wildcard for all classes in package
– import javva.util.*;
Creating packages
 To create a package, place the package identifier
at the top of your source code.
e.g. package myjava.lib;
 This places the current class/classes in a package
called myjava.lib (notice the lowercase convention
for package names).
 Important: this class must be placed in a
corresponding directory structure
$ROOT/myjava/lib.
 Your CLASSPATH must contain $ROOT
Class visibility
 Classes themselves can be public or default (I’m
avoiding discussion of inner classes here)
public class Foo{ ...}
class Foo{ ... }
 classes that are public are visible outside of their
package
 classes that are default are visible only within their
package
 Every source code file can have at most one public
class but infinitely many package-scope classes.
Rules for instance variables
 public: accessible from any class
 default: accessible from any class within
same package
 protected: default + any subclass
 private: accessible only in class where
defined.
– note: this includes any object created from that
class
More on private iv’s
 If class B extends class A and A has private iv’s,
those iv’s are part of class B.
 However, those iv’s cannot directly be accessed by
class B.
 This is an important distinction – they are part of
class B, but cannot be accessed directly by class
B!?
 class B would have to call non-private
accessor/mutator methods to access A’s iv’s.
Private vs. Protected iv’s
 To give direct access to superclass iv’s, make them
protected.
 This is sometimes a very good idea, and
sometimes a very bad idea. Ideas?
 Horstmann points out that it breaks encapsultion.
This is true, but the whole idea of inheritance
breaks encapsulation.
 General rule: when constructing a library, be very
careful when making anything non-private,
espcially iv’s. When programming within a
package, requirements less stringent.
Rules for constructors
 Unlike other methods and iv’s, constructors
are not inherited
 When instantiating a class B that is a
subclass of some class A:
– To call A’s constructor the first line of B’s
constructor must be
super(...); // assume this is a valid constructor
– super(...) may be ommitted if you wish to call
the superclass default constructor.
Rules for methods
 Visibility rules are the same for variables.
 Public methods are often preferred way to
access iv’s.
 A method in a superclass may be redefined
in a subclass. This is called overriding (see
next slide).
 Regular rules of overloading apply.
Method overriding
 Overriding refers to the introduction of an
instance method in a subclass that has the
same name, signature, and return type of a
method in the superclass.
 Implementation of this method in the
subclass replaced the implementation of the
method in the superclass.
Simple examples
Best to start abstract. Let’s do data-only classes:
class A{
private int iv1;
public int iv2;
protected int iv3;
int iv4;
}
class B extends A{
Overriding example
class A{
public void m1(){...}
}
class B extends A{
public void m1(){...}
}
For objects of class B, its own unique version of m1 will be
called. We say that the method m1 in B overrides the
method m1 in its superclass.
Rules for static methods and
fields
 Static methods and fields cannot be
overriden.
 I don’t ever do this. Please consult book if
you are interested. It is not typical.
Abstract classes
 We’ve covered two extremes of inheritance:
– interfaces: all methods are abstract in
superclass and superclass (ie interface) serves
to define common type
– non-abstract superclasses: all methods are nonabstract in superclass and subclass actually
inheritents implementation.
• good for code re-use
• also good for defining common type
Abstract classes, cont.
 Using abstract methods, we can actually program
in between these two models.
 This is done by creating superclasses that are
mixtures of abstract and non-abstract methods plus
iv’s.
 The non-abstract methods and iv’s are inherited
just like with regular classes.
 The abstract methods are treated just like interface
methods – they must be implemented.
Rules for abstract classes
 Any method in a class may be given the
abstract keyword.
public abstract void foo(...)
 If one or more methods in a class are
abstract, the class itself must be declared
abstract
abstract class Foo{ ...}
 Abstract classes may be subclassed, but not
instantiated.
More on abstract classes
 Abstract methods must have no meat.
 It is not required that a subclass implement every
(or any) abstract method in an abstract superclass.
 However, if all abstract methods are not
implemented in the subclass, the subclass must be
declared abstract.
 classes with all abstract methods are almost
exactly like interfaces (what are the differences?)
Graphic view
pure impl
inheritance
regular class
Code
Reuse
mixed impl/
interface
inheritance
abstract class
pure interface
inheritance
interface
polymorphism
Example: InputStream class
 java.io.InputStream is a good case-study in
abstract classes
 InputStream is abstract because int read() is not
implemented.
 It is up to a subclass of InputStream to implement
this method.
 FileInputStream one such concrete subclass?
 Question: what is the advantage of this structure?
Overview of Swing
Widgets, layouts, events
What is Swing
 All of our “clients” to this point have been text-
based. These are also known as scripting clients.
 Most commercial software is “event driven”
– events are mouse clicks, mouse drags, etc.
– events take place on components, aka widgets
• buttons, text areas, comboboxes, etc.
 Swing is Java’s library for creating graphical
clients, typically knowns as GUI (Graphical User
Interfaces)
GUI vs. Scripting
 Advantages
– Easy for non-computer person to use
– Self-documenting
– Attractive
 Disadvantages
– More complex coding
– Memory hogs
– Slower to use for expert user
How to Create GUIs in Java
 Three steps for simple GUI
– Determine what components that you would
like your “form” to contain. Examples are
buttons, checkboxes, text areas, graphics
panels, etc.
– Determine how you would like these panels to
layout on your form. This is the domain of
layout managers.
– Attach event handlers to the desired
components in the GUI.
Creating a GUI application
 Must create a JFrame and call the show()
method. This is normally done by creating a
class that extends JFrame as:
class MyFrame extends JFrame{
MyFrame(){
setSize(300,300); //sets the pixel size
}
main(){
MyFrame frame = new MyFrame();
frame.show();
}
}
Swing Components
Swing components, cont.
 Each component is a Java class with a fairly
extensive inheritency hierarchy:
Object
Component
Container
JComponent
Window
JPanel
Frame
JFrame
Using Swing Components
 Very simple, just create object from
appropriate class – examples:
–
–
–
–
JButton but = new JButton();
JTextField text = new JTextField();
JTextArea text = new JTextArea();
JLabel lab = new JLabel();
 Many more classes. Don’t need to know
every one to get started.
 See ch. 9 Hortsmann
Adding components
 Once a component is created, it can be
added to a container by calling the
container’s add method:
Container cp = getContentPane();
cp.add(new JButton(“cancel”));
cp.add(new JButton(“go”));
How these are laid out is determined by the layout
manager.
Laying out components
 Not so difficult but takes a little practice
 Do not use absolute positioning – not very
portable, does not resize well, etc.
Laying out components
 Use layout managers – basically tells form how to
align components when they’re added.
 Each Container has a layout manager associated
with it.
 A JPanel is a Container – to have different layout
managers associated with different parts of a form,
tile with JPanels and set the desired layout
manager for each JPanel, then add components
directly to panels.
Layout Managers
 Java comes with 7 or 8. Most common and
easiest to use are
– FlowLayout
– BorderLayout
– GridLayout
 Using just these three it is possible to attain
fairly precise layout for most simple
applications.
Setting layout managers
 Very easy to associate a layout manager
with a component. Simply call the
setLayout method on the Container:
JPanel p1 = new JPanel();
p1.setLayout(new FlowLayout(FlowLayout.LEFT));
JPanel p2 = new JPanel();
p2.setLayout(new BorderLayout());
As Components are added to the container, the layout
manager determines their size and positioning.
Event handling
What are events?
 All components can listen for one or more events.
 Typical examples are:
– Mouse movements
– Mouse clicks
– Hitting any key
– Hitting return key
– etc.
 Telling the GUI what to do when a particular
event occurs is the role of the event handler.
ActionEvent
 In Java, most components have a special
event called an ActionEvent.
 This is loosely speaking the most common
or canonical event for that component.
 A good example is a click for a button.
 To have any component listen for
ActionEvents, you must register the
component with an ActionListener. e.g.
– button.addActionListener(new MyAL());
Delegation, cont.
 This is referred to as the Delegation Model.
 When you register an ActionListener with a
component, you must pass it the class which
will handle the event – that is, do the work
when the event is triggered.
 For an ActionEvent, this class must
implement the ActionListener interface.
 This is simple a way of guaranteeing that
the actionPerformed method is defined.
actionPerformed
 The actionPerformed method has the following
signature:
void actionPerformed(ActionEvent)
 The object of type ActionEvent passed to the event
handler is used to query information about the
event.
 Some common methods are:
– getSource()
• object reference to component generating event
– getActionCommand()
• some text associated with event (text on button, etc).
actionPerformed, cont.
 These methods are particularly useful when
using one eventhandler for multiple
components.
Simplest GUI
import javax.swing.JFrame;
class SimpleGUI extends JFrame{
SimpleGUI(){
setSize(400,400); //set frames size in pixels
setDefaultCloseOperation(EXIT_ON_CLOSE);
show();
}
public static void main(String[] args){
SimpleGUI gui = new SimpleGUI();
System.out.println(“main thread coninues”);
}
}
Another Simple GUI
import javax.swing.*;
class SimpleGUI extends JFrame{
SimpleGUI(){
setSize(400,400); //set frames size in pixels
setDefaultCloseOperation(EXIT_ON_CLOSE);
JButton but1 = new JButton(“Click me”);
Container cp = getContentPane();//must do this
cp.add(but1);
show();
}
public static void main(String[] args){
SimpleGUI gui = new SimpleGUI();
System.out.println(“main thread coninues”);
}}
Add Layout Manager
import javax.swing.*; import java.awt.*;
class SimpleGUI extends JFrame{
SimpleGUI(){
setSize(400,400); //set frames size in pixels
setDefaultCloseOperation(EXIT_ON_CLOSE);
JButton but1 = new JButton(“Click me”);
Container cp = getContentPane();//must do this
cp.setLayout(new FlowLayout(FlowLayout.CENTER
cp.add(but1);
show();
}
public static void main(String[] args){
SimpleGUI gui = new SimpleGUI();
System.out.println(“main thread coninues”);
Add call to event handler
import javax.swing.*; import java.awt.*;
class SimpleGUI extends JFrame{
SimpleGUI(){
setSize(400,400); //set frames size in pixels
setDefaultCloseOperation(EXIT_ON_CLOSE);
JButton but1 = new JButton(“Click me”);
Container cp = getContentPane();//must do this
cp.setLayout(new FlowLayout(FlowLayout.CENTER
but1.addActionListener(new MyActionListener());
cp.add(but1);
show();
}
public static void main(String[] args){
SimpleGUI gui = new SimpleGUI();
System.out.println(“main thread coninues”);
Event Handler Code
class MyActionListener implements ActionListener{
public void actionPerformed(ActionEvent ae){
JOptionPane.showMessageDialog(“I got clicked”, null);
}
}
Add second button/event
class SimpleGUI extends JFrame{
SimpleGUI(){
/* .... */
JButton but1 = new JButton(“Click me”);
JButton but2 = new JButton(“exit”);
MyActionListener al = new MyActionListener();
but1.addActionListener(al);
but2.addActionListener(al);
cp.add(but1);
cp.add(but2);
show();
}
}
How to distinguish events –Less
good way
class MyActionListener implents ActionListener{
public void actionPerformed(ActionEvent ae){
if (ae.getActionCommand().equals(“Exit”){
System.exit(1);
}
else if (ae.getActionCommand().equals(“Click me”){
JOptionPane.showMessageDialog(null, “I’m clicked”);
}
}
Good way
class MyActionListener implents ActionListener{
public void actionPerformed(ActionEvent ae){
if (ae.getSource() == but2){
System.exit(1);
}
else if (ae.getSource() == but1){
JOptionPane.showMessageDialog(null, “I’m clicked”)
}
}
Question: How are but1, but2 brought into scope to do this?
Question: Why is this better?
Putting it all together
 See LoginForm.java example in class notes
Java I/O classes
Flexible and somewhat slick, but a bit
of a mess
Java classes for doing i/o
 Includes file i/o, memory i/o, socket i/o, inter-
process (pipes), etc.
 All stored in package java.io
 Excellent example of OO design
– Very general and scaleable
 Unfortunately, also obfuscates simple tasks.
 How to proceed
– Understand basic design
– Create some libraries to do common tasks
InputStream/OutputStream
 Start by studying the java.io.InputStream and
java.io.OutputStream API
 These are base class for performing all binary i/o
 Note that these classes are abstract each with a
single abstract method
– abstract int read()
– abstract void write(int)
 Concrete subclasses must provide implementation
of read/write that can get/put a single byte to/from
the relevant source
Concrete subclasses of
InputStream/OutputStream
 Since InputStream/OutputStream are
abstract, they cannot be used to create
objects (of course, they can be used for
typing).
 A very common non-abstract subclass is
FileOutputStream/FileInputStream.
 These can be used in a simple way to do the
most basic byte-based file io
Example with FileInputStream
/* class example DataInput1.java */
/* assumes each char is one byte -- dangerous
import java.io.FileInputStream;
public class DataInput1{
public static void main(String[] args) throws Exception{
String file = args[0];
int input;
FileInputStream fin = new FileInputStream(file);
while ( (input = fin.read()) != -1){
System.out.print((char) input);
}
}
}
Example with FileOutputStream
/* class example DataOutput1.java */
/* assumes each char is a single byte */
import java.io.FileOutputStream;
public class DataOutput1{
public static void main(String[] args) throws Exception{
String file = args[0];
String output = "Hello World";
FileOutputStream fout = new FileOutputStream(file);
char[] outputAsChars = output.toCharArray();
for (int i = 0; i < outputAsChars.length; ++i)
fout.write(outputAsChars[i]);
}
}
Higher-level functionality
 FileInputStream and FileOuputStream allow you
to do pretty much any file i/o at a very low level.
 However, this is too low-level for Java.
 Java provides many more libraries to read/write
higher-level constructs:
–
–
–
–
–
characters
Strings
native datatypes
arrays
arbitrary objects (serialization)
Decorator Pattern
 These capabilities are added using a design
called the Decorator Pattern.
 InputStream/OutputStream instances are
passed to a wrapper or decorator class that
uses them and adds to their functionality.
 For example, floating point numbers can be
read from a file by chaining together a
FileInputStream and another class that
assembles bytes into portable floating point.
Purpose of Decorator

Best way to think of this is as follows:
–
There are two important issues when constructing an
i/o library
•
•
–
–
–
Where the i/o is going (file, etc).
How the data is represented (String, native type, etc.)
Rather than create a class for each combination,
Decorator classes allow you to mix and match,
augment functionality of base classes.
This is a bit confusing but is very flexible.
Decotators can also add other capabilities, such as
peek ahead, push back, write line number, etc.
Decorator Pattern
Java i/o Decorator Classes
 All Java i/o decorator classes inherit from
FilterInputStream and FilterOutputStream
 Look at the api for these classes and note a few
things:
– They wrap instances of InputStream/OutputStream
respectively.
– They inherit from InputStream/OutputStream
respectively
 This is an odd inheritence hierarchy but is
necessary to ensure that the FilterStreams support
the same interface as the underlying class.
More on Filter Streams
 Easiest way to think of the filter streams as
wrapping an underlying class which they
augment the functionality of.
Consider the respective constructors
– FilterInputStream(InputStream in);
– FilterOutputStream(OutputStream out);
 In each case, the FilterStreams use an
underlying presumably simpler inputstream
and augment its functionality.
Some FilterStream examples to
clarify this
 Perhaps most common FilterInputStream is
DataInputStream.
 Study the API and be sure you understand
the inheritance hierarchy
 DataInputStream stores an InputStream and
uses this to do higher-level i/o
– readInt, readDouble, etc.
 DataOutputStream is analogous
Example of DataInputStream
/* DataInputStream2 example in course examples */
import java.io.DataOutputStream;
import java.io.FileOutputStream;
public class DataOutput2{
public static void main(String[] args) throws Exception{
String file = args[0];
double[] data = {1.1,1.2,1.3,1.4,1.5};
DataOutputStream dout = new DataOutputStream
(new FileOutputStream(file));
for (int i = 0; i < data.length; ++i){
dout.writeDouble(data[i]);
}
dout.close();}}
Example of DataInputStream
/* DataOutput2 example in course examples */
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.EOFException;
public class DataInput2{
public static void main(String[] args) throws Exception{
String file = args[0];
DataInputStream din = new DataInputStream(new FileInputStream(file
double data;
try{
while (true){
data = din.readDouble();
System.out.println(data);
}
}
catch (EOFException eofe){}
din.close();}}
Other Decorators
 Another common set of decorator classes is
BufferedInputStream and BufferedOutputStream.
 These augment the functionality of the underlying
stream by providing system buffering for higherperformance i/o
 They also add support for the mark method.
 Examples on next slide (notice how these classes
can be multiply chained together in various ways.
BufferedInputStream Example
import java.io.*; /
public class DataInput3{
public static void main(String[] args) throws Exception{
String file = args[0];
DataInputStream din = new DataInputStream
(new BufferedInputStream
(new FileInputStream(file)));
double data;
/* need an exception to know when end of file is hit */
try{
while (true){
data = din.readDouble();
System.out.println(data);
}
}
catch (EOFException eofe){}
din.close();}}
BufferedOutputStream example
import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
public class DataOutput3{
public static void main(String[] args) throws Exception{
String file = args[0];
double[] data = {1.1,1.2,1.3,1.4,1.5};
DataOutputStream dout = new DataOutputStream
(new BufferedOutputStream
(new FileOutputStream(file)));
for (int i = 0; i < data.length; ++i){
dout.writeDouble(data[i]);
}
dout.close();}}
Other output streams
 FileOutputStream is probably the most common.
 However, note that we could replace
FileOutputStream with another Outputstream in
these examples.
 In that case, the same decorated or undecorated
data would be sent to some other device.
 Good example of this is thread communicatoin,
memory i/o, and socket i/o (using Socket class).
 I strongly encourage you to familiarize yourself
with these classes.
Character-based i/o
Reader and Writer classes
Reader/Writer
 Java maintains a second class hierarchy for
performing higher-level character-based i/o.
 The two base classes in this case are
– java.io.Reader
– java.io.Writer
 Study the API for these classes.
 Very similar to InputStream/OutputStream
 Here I’ll show how to do some common i/o
tasks as examples
FileWriter Example
/* example Writer1.java in course examples */
/* using a simple FileWriter for String-based i/o */
import java.io.FileWriter;
public class Writer1{
public static void main(String[] args) throws Exception{
String file = args[0];
String output = "Hello World!";
FileWriter fw = new FileWriter(file);
fw.write(output);
fw.close();
}
}
Reading lines from stdin
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class Reader1{
public static void main(String[] args) throws Exception{
/* convert System.in, which is an InputStream,
to a Reader by wrapping in InputStreamReader,
then wrap everything in BufferedReader
*/
String input;
BufferedReader bin = new BufferedReader
converts an
(new InputStreamReader
InputStream
(System.in));
to a Reader
while ( (input = bin.readLine()) != null){
System.out.println("you typed " + input);
}}}
Reading by line from file
import java.io.BufferedReader; /*Reader2.java */
import java.io.InputStreamReader;
import java.io.FileInputStream;
public class Reader2{
public static void main(String[] args) throws Exception{
/* convert a FileInputStream, which is an InputStream,
to a Reader by wrapping in InputStreamReader,
then wrap everything in BufferedReader and call
the readLine method to get a line at a time
*/
String input;
String file = args[0];
BufferedReader bin = new BufferedReader
(new InputStreamReader
(new FileInputStream(file)));
while ( (input = bin.readLine()) != null){
System.out.println(input);
} }}
Exercise
 Study the jdk API for GZIPOutputStream
and GZIPInputStream. Write a program that
reads and writes gzip files.
Serialization
 Objects can be written to streams also. This
process is known as serialization.
 This is a huge convenience compared with
having to marshal and unmarshal iv’s.
 But the issue is even deeper – how are
methods represented, objects that contain
objects as iv’s, etc.
 Java takes care of all of this with a very nice
serialization interface.
Serialization classes
 Relevant classes
– java.io.ObjectInputStream
– java.io.ObjectOutputStream
 Note that these required an underlying
Input/OutputStream to do their work.
 For a class to be serializable, it also must
implement the Serializable interface (no methods).
 Finally, a class-scope variable can be declared as
transient, meaning that it is ignored during
serialization.
Serialization Example
/* simple example of Serialization -- writing an object directly
to an OutputStream without having to marshal and unmarshal */
import java.io.*;
public class Serialization{
public static void main(String[] args) throws Exception{
String flag = args[0]; String file = args[1];
Currency c = new Currency("US Dollar", "USD“, 10, 5);
Currency d;
if (flag.equals("-w")){
ObjectOutputStream out
= new ObjectOutputStream(new FileOutputStream(new File(file)));
out.writeObject(c);
}
else if (flag.equals("-r")){
ObjectInputStream in =
new ObjectInputStream(new FileInputStream(new File(file)));
System.out.println("Reading serialized object");
d = (Currency) in.readObject();
}}}
Related Topics
 java.io.File class
– Very nice. Many methods for portably manipulating
files
 java.io.Socket class
– Provides Input/OutputStreams for communication
across ports of different computers
 PrintWriter class (e.g. println method)
 Writing zip files, jar files, etc.
 java rmi: Remote Method Invocation:
– DO’s on top of serialization
Suggested Readings
 Eckel’s detailed section on i/o
 Patterns in Java, A Catalog of Reusable
Design Patterns Illustratred with UML,
Mark Grand, Wiley Press.
 Design Patterns, Elements of Reusable
Object-Oriented Software, Gamma et al.
Java Exceptions
Intro to Exceptions
 What are exceptions?
– Events that occur during the execution of a
program that interrupt the normal flow of
control.
 One technique for handling Exceptions is to
use return statements in method calls.
 This is fine, but java provides a much more
general and flexible formalism that forces
programmers to consider exceptional cases.
Exception Class hierarchy
Object
• must handle
• may handle
• too serious to catch
Throwable
Error
Exception
many
RuntimeException
IndexOutOfBounds
NullPointerException
Exception Handling Basics
 Three parts to Exception handling
1. claiming exception
2. throwing exception
3. catching exception
 A method has the option of throwing one or more
exceptions when specified conditions occur. This
exception must be claimed by the method. Another
method calling this method must either catch or
rethrow the exception. (unless it is a
RuntimeException)
Claiming Exceptions
 Method declaration must specify every
exception that the method potentially
throws
MethodDeclaration throws Exception1, Exception2, ..., ExceptionN
 Exceptions themselves are concrete
subclasses of Throwable and must be
defined and locatable in regular way.
Throwing Exception
 To throw an Exception, use the throw keyword
followed by an instance of the Exception class
void foo() throws SomeException{
if (whatever) {...}
else{ throw new SomeException(...)}
 We’ll talk about passing data via the Exception
constructor soon.
 Note that if a method foo has a throw clause
within it, that the Exception that is thrown (or one
of its superclasses) must be claimed after the
signature.
Catching Exceptions
 The third piece of the picture is catching
exceptions.
 This is what you will do with most commonly,
since many of java’s library methods are defined
to throw one or more runtime exception.
 Catching exceptions:
– When a method is called that throws and Exception e.g
SomeException, it must be called in a try-catch block:
try{
foo();
}
catch(SomeException se){...}
Catching Exceptions, cont.
 Note that if a method throws an Exception
that is NOT a RuntimeException, you must
do one of two things:
– try-catch it (often called handling it)
– rethrow it
 In the latter case, responsibility then moves
up the calling chain to handle it, and so on
all the way up to main.
More on try-catch
The general form of the try-catch structure is:
try{
/* any number of lines of code
that call any number of methods
with any thrown Exceptions */
}
catch(Exception1 e1){
/* do anything you want here
e.g. change value and try again.
print error and quit
print stacktrace
*/
catch (Exception2 e2){
/* any number of exceptions can be handled ... */
}
Example1
import java.io.*;
public class Exception1{
public static void main(String[] args){
InputStream f;
try{
f = new FileInputStream("foo.txt");
}
catch(FileNotFoundException fnfe){
System.out.println(fnfe.getMessage());
}
}
}
Example2
import java.io.*;
public class Exception2{
public static void main(String[] args){
InputStream fin;
try{
fin = new FileInputStream("foo.txt");
int input = fin.read();
}
catch(FileNotFoundException fnfe){
System.out.println(fnfe.getMessage());
}
catch(IOException ioe){
System.out.println(ioe.getMessage());
} }}
import java.io.*;
public class Exception2{
public static void main(String[] args){
InputStream fin;
try{
fin = new FileInputStream("foo.txt");
int input = fin.read();
}
catch(FileNotFoundException fnfe){
System.out.println(fnfe.getMessage());
}
catch(IOException ioe){
System.out.println(ioe.getMessage());
}
}
}
Recommendations
 Do not use Exceptions to handle normal
conditions in the program that can be
checked with if statements. For example:
– to find the end of an array
– to check if an object is null
 See other commented examples in course
notes.
Creating your own Exceptions
 You can follow this procedure exactly when
creating your own Exception.
 Create a class that subclasses Exception (or
RuntimeException).
 You may also add functionality so that a
relevant message is stored when the error is
thrown, and any other customized
functionality you choose.
 See Exception5.java example
Swing Graphics
Programming
Using Graphics object
 Use JPanels
– They have a surface on which you can draw.
– They are containers and thus can hold other
components
 How to draw on a Jpanel
Class MyPanel extends JPanel{
public void paintComponent(Graphics g){
//use Graphics methods to draw
}
}
Drawing on a JPanel
 How does this work?
– Framework calls paintComponent
automatically whenever the application needs
to be redrawn.
– Can force this yourself, but do not call
paintComponent directly.
– Instead, call repaint(), which will cause
paintComponent to be called for all
components.
Graphics object method
 Framework hand over an object that
implements the abstract class Graphics.
 Contains functions for drawing shapes to
panel.
 Simplest Example:
Class HelloWorld extends Jpanel{
public void paintComponent(Graphics g){
g.drawString(“Hello World, 50,50”);
}
}
More Graphics Object Methods
 Many more methods. Consult API as
always.
 Typical examples:
–
–
–
–
–
drawOval
drawCircle
drawImage
drawPolyLine
fillArc
Graphics2D Object
 Much more sophisticated rendering
capabilites.
 To access, use same technique and then
downcast Graphics object to Graphics2D
object (latter is subclass of former).
 See Graphics2D API for additional methods
 See DrawTest.java and
Colors
 Use java.awt.Color class
– 13 standard colors stored as static variables
• Color.red, Color.blue, Color.yellow, etc.
– To specify rbg value, create Color object:
• new Color(int red, int green, int blue);
 Use setPaint(Color) method of Graphics object to
specify a Color.
 Also setBackground(Color) method
 Useful: brighter() and darker() methods for Color
objects
Filling shapes
 Can fill the interior of any closed shape.
 Use fill() method.
 See FillTest.java
Drawing images
 Very fun
 Supports standard GIF images.
Example
Toolkit tk = getDefaultToolkit();
Image img = tk.getImage(“foo.gif);
g.drawImage(img, 0, 0, null);
(assuming g is instance of Graphics class)
Drawing images
 Very fun
 Supports standard GIF images.
Example
Toolkit tk = getDefaultToolkit();
Image img = tk.getImage(“foo.gif);
drawImage(img, 0, 0, null);
Odds and Ends
Timing, system commands, toString
and .equals
Timing Java code
 Simplest is to use static method in System class
double currentTimeMillis();
Example:
public static void main (String args[]){
double begin = System.CurrentTimeMillis();
doWork();
double end = System.CurrentTimeMillis();
double time = (end – begin)/(1000.*60);
System.out.println(“Total time minutes: “ + time);
}
Spawning an OS process
 Very simple but a little different architecturally
 Every java program keeps a single copy of a class
Runtime which allows the user to interact with
the OS
 This is obtained with a static method call
(“Singleton pattern”) and returns a Process object:
Runtime rt = Runtime.getRuntime();
Process p = rt.exec(“ls *.java”);
InputStream in = p.getInputStream();
//exercise: wrap this PipeInputStream in Reader
Overriding equals method
 A method with signature boolean equals(Object)
exists in the object class.
 This method by default determines whether two
Objects point to the same memory location:
SomeObject o1, o2;
o1 = new SomeObject(); o2 = o1;
if (o1.equals(o2)) // yes, same loc in mem
 This is not very useful in general. Good idea to
override with more useful comparison metric
.equals, cont.
 Very good example is String class.
 .equals is overriden for String class to
actually do a character by character
comparison.
 Thus, two String which occupy different
memory but have the same contents are
considered equal.
 Note that using == always does a memory
comparison! Very import!!
.equals, cont.
 There are a few subtle rules that any
overriding of a .equals must follow.
 We’ll study these plus other object methods
(in particular clone) next class.
Very Basic Applets
Programs that run within web
browsers
What are applets?
 Applets are simply java programs that run in web
browsers.
 Created a big stir in mid-90’s when Netscape
agreed to embed jvm in Navigator web browswer.
 Great promise – applications automatically
distributed to anyone on any platform!
 Reality – non-uniform browswer support,
limitations imposed by security, easier ways to
accomplish same thing!
What are applets, cont.
 Still useful in just the right situation
– fancy, full-fledged client
– can make some assumptions/have some control over
client technology
 Also, very good for understanding issues in web
client-server programming
 Otherwise, server-heavy programming with html
or client-side scripting wins out.
 Also, Java WebStart new alternative
– can launch full applications remotely without need for
host browser
Applet inheritance tree
Object
Component
Container
Window
Panel
Frame
Applet
JFrame
JApplet
Use to access
Swing Components
Some Hello World Applets
 To see how applets work, we start with a
couple of versions of a HelloWorld program
– One uses the fact that an Applet is a Panel with
a graphics object
– The other uses a button label
 Soon, we will add full event-handling
capabilities and nice graphics. This is just a
start.
HelloWorldApplet1
import java.awt.*;
import javax.swing.*;
public class HelloWorldApplet1 extends JApplet{
public void init(){
getContentPane().add(new JLabel(
“Hello World”,
SwingConstants.CENTER));
}
}
• Note that all Applets are class that extend either
Applet or JApplet
• init() is called when the Applet is loaded
HelloWorldApplet2
import java.awt.*;
import javax.swing.*;
public class HelloWorldApplet1 extends JApplet{
public void painComponent(Graphics g){
g.drawString(“Hello World”, 50, 50);
}
}
• Since Applets are Panels, we can override PaintComponent
and get a Graphics Object
• This will become particularly handy when doing animations
Running Applets
 To run applets, do the following:
– Compile class file in regular way
– Create an html file that includes an applet tag pointing
to the applet
<applet code = “Appletname.class” width = 200 height =
50></applet> (width and height are pixel coords)
– Invoke browser or appletviewer on html file
 Note that applet tag can include other parameters,
some of which of used by browser automatically
(e.g. width).
 Also, Java2 plug-in required for browsers to
support applets. Good to test with appletviewer
first.
Life Cycle of Applet
 To write more sophisticated applets, a
number of other methods may need to be
overwritten.
–
–
–
–
void init()
void start()
void stop()
void destroy()
 We discuss the role of each next.
init() method
 The browswer calls the init method when the
applet is loaded for the first time.
 init() behaves much like a constructor.
 Typical uses:
–
–
–
–
parsing param values from html files
opening streams and sockets
creating GUI components
opening database connections
 Important: note that the refresh button doesn’t
necessarily reload applet. This is browserdependent. To guarantee reloading, browser needs
to be killed and restarted.
start() method
 called every time page is located
– this can mean moving off and back onto page, hitting
reload, etc.
 always called after init() when page is first loaded.
 Typical uses:
– starting animations
– anything else that needs to start anew with every
location of applet
– for simpler things this method can be ignored
stop() method
 called whenever user moves off the page
where applet sits
 always called after start
 typical uses
– ending animations
– stopping other time-consuming system activity
 often ignore this for simpler applets
destroy() method
 called once when browser shuts down
normally
 always called after stop()
 typical uses:
– close database connections
– close streams
– clean up any other resources
 often ignored for simpler applets
More on applet life-cycle
 It’s very import to be aware that some other
software, ie the host browser, is calling these
methods at certain times.
 You the program do not call these methods.
 This is classic OO framework: “don’t call us, we’ll
call you”.
 You write the class and specialize certain methods,
some other code calls your custorm versions of
those methods at specified times.
Other applet issues
 Security
– Horstmann pg. 499
 Pop-up windows
– Horstmann pg. 500
 Applet tags and attributes
– Horstmann pg. 502
 Passing info to applets
– Horstmann pg. 506
 Applets making socket connections
Jar Files
Packaging java applications
What is a jar file?
 JAR: Java Archive
– typical way of distributing java applications/libraries
 JARs are ZIP files containing
– java class files
– possibly other resource files (images, audio, text, etc.)
– optional manifest file: describes certain attributes of
JAR file.
 Applets, beans, applications typically all
distributed as single of collection of JAR files.
Creating JAR Files
 Either use commandline tool like
– jar cvf whatever.jar *.class
or API
– see java.util.jar docs
 No name restrictions for jar file – whatever is
legal on a given platform
 Can jar directories as well as files. In that case,
contents are added recursively
 Syntax similar to tar. See
http://java.sun.com/docs/books/tutorial/jar
for more details
Self-running JAR files
 jars can get quite complex when using with J2EE.
– Manifest files can be used to specify security attributes,
versioning, extensions, services, etc.
 Also, for better performance multi-class applets
can be packaged as jar files.
 Course web page contains links to more detailed
info on creating sophisticated JARs
 Here were present executable JAR files as a
simple example.
Steps to making executable jar
 To make an executable jar, take the following
steps:
– create a .jar of all class files in your application using
jar cvf Whatever.jar *.class
(packages and nested directories work fine here).
– create a manifest file with any name (say manifest.mf).
manifest.mf must at least contain a line pointing to the
main class, e.g.:
Main-Class: com/mypackage/MainAppClass
– finally, add manifest using the update flag u
jar uvfm Whatever.jar manifest.mf
– run as “java –jar Whatever.jar”
Gotchas
 Manifest file must contain linefeed as last
character or else won’t be parsed properly.
 You should always use packages with jar
files.
– be careful to put full pathname to Main-Class.
Other issues
 Launching a jar from an icon
– System dependent. See Horstmann.
 Locating Resources
– See URL class
 Sealing JARs
– Sealed: true attribute in manifest file
 Signing JARs
– can give trusted permission to trusted parties.
– See web link above for more details
Overriding Object Methods
The Object Class
 Every java class has Object as its superclass and
thus inherits the Object methods.
 Object is a non-abstract class
 Many Object methods, however, have
implementations that aren’t particularly useful in
general
 In most cases it is a good idea to override these
methods with more useful versions.
 In other cases it is required if you want your
objects to correctly work with other class libraries.
Some Object class methods
 Object methods of interest:
– clone
– equals
– hashcode
– toString
– finalize
 Other object methods
– getClass
– wait, notify, notifyAll (relevant for threaded
programming)
Clone method
 Recall that the “=“ operator simply copies Object
references. e.g.,
>> Student s1 = new Student(“Smith”, Jim, 3.13);
>> Student s2 = s1;
>> s1.setGPA(3.2);
>> System.out.println(s2.getGPA());
3.2
 What if we want to actually make a copy of an
Object?
 Most elegant way is to use the clone() method
inherited from Object.
Student s2 = (Student) s1.clone();
Subtleties of clone() method
 First, note that the clone method is
protected in the Object class.
 This means that it is protected for
subclasses as well.
 Hence, it cannot be called from within an
Object of another class and package.
 To use the clone method, you must override
in your subclass and upgrade visibility to
public.
More subtleties of clone
 Also, any class that uses clone must
implement the Cloneable interface.
 This is a bit different from other interfaces
that we’ve seen.
 There are no methods; rather, it is used just
as a marker of your intent.
 The method that needs to be implemented is
inherited from Object.
More clone() issues
 Finally, clone throws a
CloneNotSupportedException.
 This is thrown if your class is not marked
Cloneable.
 This is all a little odd but you must handle
this in subclass.
Steps for cloning
 To reiterate, if you would like objects of
class C to support cloning, do the following:
– implement the Cloneable interface
– override the clone method with public access
privileges
– call super.clone()
– Handle CloneNotSupported Exception.
 This will get you default cloning, but more
subtleties still lurk.
Shallow Copies
 We haven’t yet said what the default clone()
method does.
 By default, clone makes a shallow copy of all iv’s
in a class.
 Shallow copy means that all native datatype iv’s
are copied in regular way, but iv’s that are objects
are not recursed upon – that is, references are
copied.
 This is not what you typically want.
 Must override clone explicitly clone object iv’s!
Immutable Objects
 A special class of Objects are called immutable
because their state cannot be changed once set.
 Common examples are String, Integer, etc.
 Immutable object simplify programming in certain
instances, such as when writing thread safe code.
 They also simplify cloning, since an object that
cannot be changed doesn’t really need to be deepcopied.
 See ShallowCopy2.java in course examples
Deep Copies
 For deep copies that recurse through the
object iv’s, you have to do some more work.
 super.clone() is first called to clone the first
level of iv’s.
 Returned cloned object’s object fields are
then accessed one by one and clone method
is called for each.
 See DeepClone.java example
Additional clone() properties
 Note that the following are typical, but not
strictly required:
–
–
–
x.clone() != x;
x.clone().getClass() == x.getClass();
x.clone().equals(x);
 Finally, though no one really cares,
Object does not support clone();
toString() method
 The Object method
String toString();
is intended to return a readable textual
representation of the object upon which it is
called. This is great for debugging!
 Best way to think of this is using a print statement.
If we execute:
System.out.println(someObject);
we would like to see some meaningful info about
someObject, such as values of iv’s, etc.
default toString()
 By default toString() prints total garbage that no
one is interested in
getClass().getName() + '@' + Integer.toHexString(hashCode())
 By convention, print simple formatted list of field
names and values (or some important
subset).
 The intent is not to overformat.
 Typically used for debugging.
 Always override toString()!
equals() method
 Recall that boolean == method compares when
applied to object compares references.
 That is, two object are the same if the point to the
same memory.
 Since java does not support operator overloading,
you cannot change this operator.
 However, the equals method of the Object class
gives you a chance to more meaningful compare
objects of a given class.
equals method, cont
 By default, equals(Object o) does exactly
what the == operator does – compare object
references.
 To override, simply override method with
version that does more meaningful test, ie
compares iv’s and returns true if equal, false
otherwise.
 See Equals.java example in course notes.
equals subtleties
 As with any method that you override, to do
so properly you must obey contracts that go
beyond interface matching.
 With equals, the extra conditions that must
be met are discussed on the next slide:
equals contract
 It is reflexive: for any reference value x, x.equals(x)
should return true.
 It is symmetric: for any reference values x and y,
x.equals(y) should return true if and only if
y.equals(x) returns true.
 It is transitive: for any reference values x, y, and z, if
x.equals(y) returns true and y.equals(z) returns true,
then x.equals(z) should return true.
 It is consistent: for any reference values x and y,
multiple invocations of x.equals(y) consistently return
true or consistently return false, provided no
information used in equals comparisons on the object
is modified.
 For any non-null reference value x, x.equals(null)
should return false.
hashcode() method
 Java provides all objects with the ability to
generate a hash code.
 By default, the hashing algorithm is
typically based on an integer representation
of the java address.
 This method is supported for use with
java.util.Hashtable
 Will discuss Hashtable in detail during
Collections discussion.
Rules for overriding hashcode
 Whenever invoked on the same object more than once, the
hashCode method must return the same integer, provided no
information used in equals comparisons on the object is modified.
 If two objects are equal according to the equals(Object) method,
then calling the hashCode method on each of the two objects
must produce the same integer result.
 It is not required that if two objects are unequal according to the
equals(java.lang.Object) method, then calling the hashCode
method on each of the two objects must produce distinct integer
results. However, the programmer should be aware that producing
distinct integer results for unequal objects may improve the
performance of hashtables.
finalize() method
 Called as final step when Object is no longer used,
just before garbage collection
 Object version does nothing
 Since java has automatic garbage collection,
finalize() does not need to be overridden reclaim
memory.
 Can be used to reclaim other resources – close
streams, database connections, threads.
 However, it is strongly recommended not to rely
on this for scarce resources.
 Be explicit and create own dispose method.
A little more Swing
MVC Pattern
More graphics
Graphics
 See course examples
– applets/BrownianMotionApplet.java
• shows how to do a simple animation with some basic drawing
in the start() method
– graphics/Mandelbrot.java
• shows how to create an image from raw data and draw to an
applet by overriding paintComponent.
– graphics/Shapes.java
• A great example of how to architect a simple GUI that seems
more complex when poorly designed.
– graphics/Painter.java
• Classic example of how to paint on a Panel
– graphics/Bounce.java
• Classic example of why one needs threads.
Miscellaneous
Some how-to snippets
 See the following codes in the course
examples
– GetProperties.java
• How to query various system properties
– ProcessTest.java
• An example spawning an OS executable
– NumberFormat.java
• An example formatting a double
– TimeTest.java
• An example using simple System timers.
What is the Collections
framework?
 Collections framework provides two things:
– implementations of common high-level data structures: e.g. Maps,
Sets, Lists, etc.
– An organized class hierarchy with rules/formality for adding new
implementations
 The latter point is the sense in which Collections are a
framework.
 Note the difference between providing a framework +
implementation and just implementation.
 Some other differences:
– code reuse
– clarity
– unit testing?
History
 Pre Java SDK1.2, Java provided a handful of data
structures:
– Hashtable
– Vector
– Bitset
 These were for the most part good and easy to use,
but they were not organized into a more general
framework.
 SDK1.2 added the larger skeleton which organizes
a much more general set of data structures.
 Legacy datastructures retrofitted to new model.
General comments about data
structures
 “Containers” for storing data.
 Different data structures provide different
abstractions for getting/setting elements of data.
–
–
–
–
linked lists
hastables
vectors
arrays
 Same data structures can even be implemented in
different ways for performance/memory:
– queue over linked list
– queue over arrays
More on data structures
 Everyone should take a basic class in building data
structures
 I recommend the book Mastering Algorthims with
C by Kyle Loudon
 In Java, one does not usually build data structures,
but rather uses the provided one
 Using Java’s data structures requires a little
understanding of the Collections framework
 Adding your own requires a deeper understanding.
Learning to use data structures
 Dual purposes for us to study Collections:
– Be able to choose, properly use built-in data
structures.
– Another study in OO class design
 Thus, we start by study the Collections class
design.
 Then, we provide many examples of how to
use the built-in types in real programming.
Collections-related Interface
hierarchy
Collection
List
Set
Map
Iterator
SortedMap
ListIterator
SortedSet
• The Collection inteface stores groups of Objects,
with duplicates allowed
• The Set interface extends Collection but forbids
duplicates
• The List interface extends Collection, allows duplicates,
and introduces positional indexing.
• Map is a separate hierarchy
Collection implementations
 Note that Java does not provide any direct
implementations of Collection.
 Rather, concrete implementations are based
on other interfaces which extend Collection,
such as Set, List, etc.
 Still, the most general code will be written
using Collection to type variables.
Collection Interface
boolean add(Object o);
boolean addAll(Collection c);
void clear();
boolean contains(Object o);
boolean containsAll(Collection c);
boolean equals(Object o);
int hashCode();
boolean isEmpty();
Iterator iterator();
boolean remove(Object o);
boolean removeAll(Collection c);
boolean retainAll(Collection c);
int size();
Object[] toArray();
Object[] toArray(Object[] a);
Optional operation, throw
UnsupportedOperationException
Comments on Collection
methods
 Note the iterator() method, which returns an
Object which implements the Iterator
interface.
 Iterator objects are used to traverse
elements of the collection in their natural
order.
 Iterator has the following methods:
– boolean hasNext(); // are there any more elements?
– Object next();
// return the next element
– void remove();
// remove the next element
AbstractCollection Class
java.util.AbstractCollection
•Abstract class which is partial implementation of
of Collection interface
•Implements all methods except iterator() and size()
• Makes it much less work to implement Collections
Interface
List interface
 An interface that extends the Collections interface.
 An ordered collection (also known as a sequence).
– The user of this interface has precise control over where
in the list each element is inserted.
– The user can access elements by their integer index
(position in the list), and search for elements in the list.
 Unlike Set, allows duplicate elements.
 Provides a special Iterator called ListIterator for
looping through elements of the List.
Additional methods in List
Interface
 List extends Collection with additional
methods for performing index-based
operations:
–
–
–
–
–
–
–
void add(int index, Object element)
boolean addAll(int index, Collection collection)
Object get(int index)
int indexOf(Object element)
int lastIndexOf(Object element)
Object remove(int index)
Object set(int index, Object element)
List/ListIterator Interface
 The List interface also provides for
working with a subset of the collection,
as well as iterating through the entire
list in a position friendly manner:
– ListIterator listIterator()
– ListIterator listIterator(int startIndex)
– List subList(int fromIndex, int toIndex)
 ListIterator extends Iterator and adds
methods for bi-directional traversal as
well as adding/removing elements from
the underlying collection.
Concrete List Implementations
 There are two concrete implementations of the
List interface
– LinkedList
– ArrayList
 Which is best to use depends on specific needs.
 Recall that linked lists are optimal for
inserting/removing elements.
 ArrayLists are good for traversing.
 Note that LinkedList and ArrayList both extend
abstract partial implementations of the List
interface.
LinkedList Class
 The LinkedList class offeres a few
additional methods for directly
manipulating the ends of the list:
–
–
–
–
–
–
void addFirst(Object)
void addLast(Object);
Object getFirst();
Object getLast();
Object removeFirst();
Object removeLast();
 These methods make it natural to implement other simpler
data structures, like Stacks and Queues.
LinkedList examples
 See heavily commented LinkedList Example in course
notes
 A few things to be aware of:
– it is really bad to use the positional indexing features copiously of
LinkedList if you care at all about performance. This is because the
LinkedList has no memory and must always traverse the chain
from the beginning.
– Elements can be changed both with the List and ListIterator
objects. That latter is often more convenient.
– You can create havoc by creating several iterators that you use to
mutate the List. There is some protection built-in, but best is to
have only one iterator that will actually mutate the list structure.
ArrayList Class
 Also supports the List interface, so top-level code
can pretty much invisibly use this class or
LinkedList (minus a few additional operations in
LinkedList).
 However, ArrayList is much better for using
positional index access methods.
 At the same time, ArrayList is much worse at
inserting elements.
 This behavior follows from how ArrayLists are
structured: they are just like Vectors.
More on ArrayList
 Additional methods for managing size of
underlying array
 size, isEmpty, get, set, iterator, and listIterator
methods all run in constant time.
 Adding n elements take O[n] time.
 Can explicitly grow capacity in anticipation of
adding many elements.
 Note: legacy Vector class almost identical. Main
differences are naming and synchronization.
 See short ArrayList example.
Set Interface
 Set also extends Collection, but it prohibits
duplicate items (this is what defines a Set).
 No new methods are introduced; specifically, none
for index-based operations (elements of Sets are
not ordered).
 Concrete Set implementations contain methods
that forbid adding two equal Objects.
 More formally, sets contain no pair of elements e1
and e2 such that e1.equals(e2), and at most one
null element
 Java has two implementations: HashSet, TreeSet
HashSets and hash tables
 Lists allow for ordered elements, but searching
them is very slow.
 Can speed up search tremendously if you don’t
care about ordering.
 Hash tables let you do this. Drawback is that you
have no control over how elements are ordered.
 hashCode() computes integer (quickly) which
corresponds to position in hash table.
 Independent of other objects in table.
HashSet Class
 Hash tables can be used to implement several
important data structures.
 Simplest of these is HashSet
– add elements with add(Object) method
– contains(Object) is redefined to first look for
duplicates.
– if duplicate exists, Object is not added
 What determines a duplicate?
– careful here, must redefine both hashCode() and
equals(Object)!
HashSet
 Look HashSetExample.java
 Play around with some additional methods.
 Try creating your own classes and override
hashCode method.
 Do Some timings.
 Be certain you understand this for final!
Tree Sets
 Another concrete set implementation in Java is
TreeSet.
 Similar to HashSet, but one advantage:
– While elements are added with no regard for order, they
are returned (via iterator) in sorted order.
– What is sorted order?
• this is defined either by having class implement Comparable
interface, or passing a Comparator object to the TreeSet
Constructor.
• Latter is more flexible: doesn’t lock in specific sorting rule, for
example. Collection could be sorted in one place by name,
another by age, etc.
Comparable interface
 Many java classes already implement this. Try
String, Character, Integer, etc.
 Your own classes will have to do this explicitly:
– Comparable defines the method
public int compareTo(Object other);
– Comparator defines the method
public int compare(Object a, Object b);
 As we discussed before, be aware of the general
contracts of these interfaces.
 See TreeSetExample.java
Maps
 Maps are similar to collections but are
actually represented by an entirely different
class hierarchy.
 Maps store objects by key/value pairs:
– map.add(“1234”, “Andrew”);
– ie Object Andrew is stored by Object key 1234
 Keys may not be duplicated
 Each key may map to only one value
Java Map interface
 Methods can be broken down into three
groups:
– querying
– altering
– obtaining different views
 Fairly similar to Collection methods, but
Java designers still thought best to make
separate hierarchy – no simple answers
here.
Map methods
 Here is a list of the Map methods:
–
–
–
–
–
–
–
–
–
–
–
–
void clear()
boolean containsKey(Object)
boolean containsValue(Object)
Set entrySet()
boolean get(Object)
boolean isEmpty()
Set keySet()
Object put(Object, Object)
void putall(Map)
Object remove(Object)
int size()
Collection values()
Map Implementations
 We won’t go into too much detail on Maps.
 Java provides several common class
implementations:
– HashMap
• a hashtable implementation of a map
• good for quick searching where order doesn’t matter
• must override hashCode and equals
– TreeMap
• A tree implementation of a map
• Good when natural ordering is required
• Must be able to define ordering for added elements.
JNI
Linking Java and C code
JNI
 Stands for “Java Native Interface”
 Set of tools/code that allows user to call “native”
methods from Java.
 Includes “bindings” for C/C++.
 Can be used to call C/C++ from Java (typical), or
Java from C (invocation API)
 Differs from spawning executable – data is passed
to/from C/C++ method
 Question: why is this difficult?
Reasons for using JNI
 Feature not available in java language
(rare).
 Code already written in another language,
don’t want to rewrite (typical).
 Java is slow (how slow?)
 Other language has no additional features
per se, but has much better syntax for
handling certain operations (Fortran for
math).
Problems with JNI
 Only provides C/C++ bindings. Going to
Fortran, COBOL, Ada, etc. requires extra
step.
 Not portable
 Mapping is not trivial
 Can be unsafe
 Cannot run from applet (security issues)
Machinery for using JNI
Steps to follow …
Basic steps to calling native code
1. Write java class with at least one method
declared with native keyword. Provide no
implementation
– public native void sayHello();
– Example above is most simple, but method may pass
any parameters or have any return type.
2. Add a call to System.loadLibrary(“libname”) in
the class that declares the native method:
–
static{
System.loadLibrary(“hello”);}//static means called only once.
Steps, cont.
3. Compile the class
–
javac Hello.java
4. Produce the C/C++ header files using the javah
utility:
– Javah Hello
– This produces the header file Hello.h
5. Write your implementation file by first copying
the function signature produced in the include
file. Also, #include the header file.
#include “Hello.h”
Steps, cont.
6. Write the implementation in C/C++. This will
require using JNI methods to access the data or
possibly casts to convert to basic C/C++ types
7. Best technique: Break into two steps. Think of
your C/C++ function as a wrapper which accesses
the Java data and maps it to C data using JNI
methods, then shoves the converted data into a
prewritten standalone C program.
Steps, cont.
8. Compile your native method(s) as a shared object
(or DLL on Windows).
– WARNING: Be sure to point your linker to the include
files in /jdk1.3/include and jdk1.3/include/linux (for
example).
– WARNING: Mixing languages is much easier using a
straight C wrapper rather than C++.
9. Set the environment variable
LD_LIBRARY_PATH to the shared object
directory
 Run main Java class.
C language bindings
What does Java pass to my method?
What does Java pass to my C
function?
 JNIEnv* : A pointer to the the JNI
environment. This pointer is a handle to the
current thread in the JVM, and contains
mapping functions and other housekeeping
information.
 jobject : A reference to the object that
called the native code. (like “this” pointer).
 Any arguments specified by the method.
Pause for some nice pictures
Legacy C calls Java
Java calls legacy
JNI is inter-language “glue”
Simple examples on union
 HelloWorld Example: No data passed
– Hello.java
– Hello.cc
 Max example : Only native dataypes
– Utils.java
– utils.cc
 Advanced Max example: Arrays
– Utils.java
– utils.cc
 Max Java-C-Fortran: max.f
General Strategy
 Keep interface as simple as
Native datatype mappings
Java Type
boolean
byte
char
short
int
long
float
double
void
Native Type
jboolean
jbyte
jchar
jshort
jint
jlong
jfloat
jdouble
void
Size in bits
8, unsigned
8
16, unsigned
16
32
64
32
64
N/a
Java object Mappings
• Object passed by reference
• All objects have type jobject as:
Object mappings, cont.
 For example, if a method getLine exists in a
class call Prompt, then:
private native String getLine(String Prompt);
is mapped into
JNIExport jstring JNICALL Java_Prompt_getLine(JNIEnv *, jobject,
jstring);
 But how to access data/methods from object
that is passed in?
JNI Advice
 Can seem like a bewildering number of functions.
 Do not try to learn it all.
 Keep interfaces very simple.
– Preferably, only native datatypes, Strings, and arrays.
 Be careful about
– Copies vs. rerences
– Freeing memory
 Best not to allocate memory from with native
code.
Accessing java strings
 Do NOT do the following:
JNIEXPORT jstring JNICALL
Java_Prompt_getLine(JNIEnv *env, jobject obj, jstring
prompt){
printf(“%s”, prompt);
}
 Why is this bad?
Right way to access Strings
 Must use special methods in env structure
char *str = (*env)->GetStringUTFChars(env,prompt,0);
/* this maps into regular C char* */
printf(“%s”, str); /* now it is ok to print */
(*env)->ReleaseStringUTFChars(env, prompt, str);
/* must release String to avoid memory leaks */
Returning Strings
 Previous technique allows us to use a String
passed in from Java.
 What if we want to return a String?
 Can use NewStringUTF as:
char buf[128]; /* allocate memory for local char* in C */
scanf(“%s”, buf); /* read into char* from stdio */
return( (*env)->NewStringUTF(env, buf));
/* construct and return the Java String */
Other JNI String methods
 GetStringChars
– Takes the Java String and returns a pointer to an array
of Unicode characters that comprise it.
 ReleaseStringChars
– Releases the pointer to the array of Unicode characters
 NewString
– Constructs a new String object from an array of
Unicode Characters
 GetStringLength
– Returns the length of a string of Unicode characters
Java arrays
 Note that you can NOT do the following:
JNIExport jint JNICALL Java_IntArray_sumArray(JNIEnv
*env, jobject obj, jintArray arr){
int i, sum = 0;
for (i = 0; i<10; i++){
sum += arr[i]; /* NO! – why not?
}
...
 Must use java methods to access array data in C
Array methods
 The previous example should be written as:
jsize len = (*env)->GetArrayLength(env,arr);
jint *body = (*env)->GetIntArrayElements(env,arr,0);
for (i=0;i<len;++i){
sum += body[i];
}
(*env)->ReleastIntArrayElements(env,arr,body,0);
/* very important – copies back to java array if copy had to be
made */
Array methods, cont.
 Note that there are analagous functions for
float, byte, double, etc:
– Get<type>ArrayElements
– Release<type>ArrayElements
 Important: These Get functions may copy
the entire array. If this is undesirable, use
Get/Set<type>ArrayRegion functions
Function for accessing arrays
Function
GetBooleanArrayElements
GetByteArrayElements
GetShortArrayElements
GetIntArrayElements
GetLongArrayElements
GetFloatArrayElements
GetDoubleArrayElements
GetObjectArrayElements
Array Type
boolean
byte
short
int
long
float
double
object
Functions for releasing arrays
Function
Array Type
ReleaseBooleanArrayElements
ReleaseByteArrayElements
ReleaseShortArrayElements
RelaseIntArrayElements
ReleaseLongArrayElements
ReleaseFloatArrayElements
ReleaseDoubleArrayElements
ReleaseObjectArrayElements
boolean
byte
short
int
long
float
double
object
Calling java methods
 What if you pass a java object to a C routine
and wish to “call back” a method on the
Java object.
 Good to avoid this when you can but
sometimes it is very important.
 Need to use the jobject reference that is
passed in by java.
Steps to follow
 Native method calls JNI function GetObjectClass
– returns the jclass object that is type of that obj
 Native method calls JNI function GetMethodID
– returns jmethodID of method in class (0 for no such
method)
 Finally, native method calls JNI function
CallVoidMethod.
– invokes an instance of method with void return type.
You pass object, methodID, and actual arguments.
A simple alternative – spawning a
system executable
 Advantages
– Infinitely simpler
– Portable
– Can use any native language
 Disadvantages
– Can only pass data to and from vi stdout
– Must reload executable for each invocation
Legacy Collections
 java.util.Vector
– Still useable, but typically ArrayList is
preffered.
– Only major difference is if you are using
muliple threads
 java.util.HashTable
– Still useable, but typically HashMap is
preferred.
– Again, different if using multiple threads.
Multithreaded programming
with Java
What are threads?
 Like several concurrent subprograms running
within the same address space.
 Within a program, individual threads are explicitly
“spawned” and give the appearance of
simultaneously running sequences of commands.
 On a single proc machine, the simultaneous
running is an illusion – cpu is time splicing.
 Differ from separate processes in that each
process runs in its own address space – shared
memory model
Why use threads?
 Single-user programs/clients
– continuously responsive user interfaces
• accept input when event handler is bus
– Can actually speed up certain tasks
 Servers
– Allows multiple client connections
simultaneously
General examples
 User clicks GUI button to download web page
(occurs in separate thread so GUI isn’t “frozen”)
 Massive numerical problems split among
processors
– assumes each thread runs on separate processor; not
necessarily the case
 Server spawns thread for each client connection
and main thread goes back to accept()
 User clicks button which begins time-consuming
database lookup. Client can accept more input
while lookup is taking place.
Concrete example
 Consider two versions of a program which
animates a ball bouncing around in a window.
 In one version, the animation takes place in the
event handler thread. Thus, the gui is frozen for
the whole animation
 In a second version, the animation takes place in a
new thread spawned in the event handler. This
gives the event thread a chance to operate.
 Run Bounce.java and BounceThread.java
Second concrete example
 Imagine a GUI program that performs a
time-consuming task in the event handler
(such as the AuctionSimulator).
 How can the GUI remain responsive?
 If we do task in a separate thread and sleep
it periodically, user interface thread will
appear “live”.
 See FrameThread.java and
FrameNoThread.java
Machinery – How to setup
threads in Java
How to create separate threads
in Java -- technique I
 Extend Thread. Specifically ...
– Create a class that extends Thread and place the
work that the Thread will carry out in the run()
method (ie override the run method).
– Create an object from your class that extends
the Thread class.
– Call the start() method on the Thread object.
– The new Thread then unters the runnable state
(it may or may not run depending on
resources/priority).
How to create threads
Technique 2
 Implement Runnable. Specifically ...
– Create a class that implements the Runnable
interface. Place all of the work that the Thread
will perform in the run() method.
– Create an object from the Runnable class.
– Create a Thread object and pass the Runnable
object to the constructor.
– Call the start() method on Thread object.
 See simple examples under basic directory.
Simple Example Thread
Class ThreadExample{
public static void main(String[] args){
System.out.println(“Main thread started”);
MyFirstThread t = new MyFirstThread()
t.start();
}
}
Class MyFirstThread extends Thread{
void run(){
System.out.println(“in new thread …”);
}
}
Example using second technique
class ThreadTest{
public static void main(String[] args){
System.out.println(“main thread started …”);
MyRunnableObj r = new MyRunnableObj();
Thread t = new Thread(r);
t.start();
}
}
Class MyRunnableObj implements Runnable{
public void run(){
System.out.println(“new thread started …”);
}
}
What happens to new threads?
 Main thread continues
 New threads execute the run method and die
when they are finished
 If any thread calls System.exit(0), it will kill
all threads.
 Think of each run() as its own main
 Program does not exit until all non-daemon
threads die.
Thread States
 Four states a Thread can be in:
– New
• When you create with new operator but haven’t run yet.
– Runnable
• When you invoke start() method. Note that Thread is not
necessarily running, could be waiting.
– Blocked
•
•
•
•
When sleep() is called
Blocking operation such as input/output
wait() is called by the Thread object
Thread tries to obtain a lock on a locked object
Thread states, cont.
– Dead
• Dies a natural death because the run method exits
normally
• Dies abruptly after an uncaught exception terminates
the run method
– Use isAlive() method to determine if Thread is
currently alive (either runnable or blocked).
Thread Priority
 The execution of multiple threads on a
single CPU is called scheduling.
 The Java runtime supports a very simple,
deterministic scheduling algorithm known
as fixed priority scheduling.
Thread Priority
 Each Java thread is given a numeric priority
between MIN_PRIORITY and MAX_PRIORITY.
 When multiple threads are ready to be executed,
the thread with the highest priority is chosen for
execution.
 Only when that thread stops, or is suspended for
some reason, will a lower priority thread start
executing.
 Scheduling of the CPU is fully preemptive. If a
thread with a higher priority than the currently
executing thread needs to execute, the higher
priority thread is immediately scheduled.
Thread Priority
 The Java runtime will not preempt the currently
running thread for another thread of the same
priority. In other words, the Java runtime does not
time-slice. However, the system implementation
of threads underlying the Java Thread class may
support time-slicing. Do not write code that relies
on time-slicing.
 In addition, a given thread may, at any time, give
up its right to execute by calling the yield method.
Threads can only yield the CPU to other threads of
the same priority--attempts to yield to a lower
priority thread are ignored.
Thread Priority
 When all the runnable threads in the system
have the same priority, the scheduler
chooses the next thread to run in a simple,
non-preemptive, round-robin scheduling
order.
A common scenario: polling vs
callbacks
 How do we implement the following?
– Thread1 spawns Thread2
– Thread1 does work
– Thread2 does work that results in new value of
variable (or new data in file, etc).
– Thread1 finishes work and needs update value
(or file) from Thread2’s work.
– How can we synchronize activities?
What’s so difficult?
Atomic processes, sharing resources,
synchronization, deadlock
Bottom Line
 Any time a writeable variable is visible to
more than one thread, potential problems
exist.
 Simple example: two clients try to purchase
item at same time.
– Order or execution unpredictable
– If (itemsLeft > itemsRequested) not reliable!
 Must create “thread-safe” programs
 More on this later …
Managing Threads
 Everything in either Object or Thread class
 Two classes of methods:
– Those defined in Object
• wait(), notify(), notifyAll()
– Those defined in Thread class
• join(), sleep(), interrupt(), isAlive(), yield(), etc.
 All involve situations where threads
communicate with each other in some way.
 Will discuss later …
Producer/Consumer example
 One thread is called the Producer. Producer
shoves consecutive integers into a
Cubbyhole object as fast as it can.
 Other thread is called Consumer. Consumer
grabs from the Cubbyhole object as fast as
it can.
 Consumer would like to grab once for each
put by the Producer, but what if one goes
faster than the other?
Producer Class
public class Producer extends Thread {
private CubbyHole cubbyhole;
private int number;
public Producer(CubbyHole c, int number) {
cubbyhole = c;
this.number = number;
}
public void run() {
for (int i = 0; i < 10; i++) {
cubbyhole.put(i);
System.out.println("Producer #" + this.number
+ " put: " + i);
try {
sleep((int)(Math.random() * 100));
} catch (InterruptedException e) { }
}}}
Consumer class
public class Consumer extends Thread {
private CubbyHole cubbyhole;
private int number;
public Consumer(CubbyHole c, int number) {
cubbyhole = c;
this.number = number;
}
public void run() {
int value = 0;
for (int i = 0; i < 10; i++) {
value = cubbyhole.get();
System.out.println("Consumer #" + this.number
+ " got: " + value);
}}}
Comments
 Note that these classes of themselves do not
forbid a race condition.
 This is done by shychronizing access to the
Cubbyhole object.
 We want to guarantee that the Consumer
thread can’t get until the Producer has
produced.
 Need to study wait() and notify() methods.
How to synchronize code
 This topic confuses many beginning Java
programmers
 Two forms:
– synchronized(objReference){ …}//synchronize a block
– synchronized void methodName(){…}//synch a method
 Former is more general, but causes confusion.
Best to use simple form whenever possible.
 Second form is equivalent to:
– synchronized(this) for entire method body
Synchronizing a method
 Fairly straightforward rules:
– When a given thread is executing a synchronized
method in an object, no other thread can execute an
other synchronized method on the SAME OBJECT!
– We say that the first thread obtains a lock on the object
and doesn’t release it until it finishes the synched
method
– Beware that only code which tries to obtain a lock on
the object will have to wait. For example, if a thread
wishes to call a non-synched method in the object, it
will not be blocked.
Synchronizing a block
 Remember the following rules:
– When a thread encounters a synchronized block
of code, it attempts to obtain a lock on the
object that is being synchronized upon.
– Consider the first thread in a program that
encounters the lock. Since it is the first thread,
it will successfully obtain the lock.
– Now consider a second thread that encounters
any synchronized block of code that
synchronzies on the same object.
Synchronizing a block, cont.
– This second thread will attempt to obtain the
lock on objReference.
– It will fail to obtain the lock unless the first
thread has released it. This means that the first
thread must have finished its synchronized
block of code.
– If the second thread cannot obtain the lock, it
must wait until the first thread releases it.
wait() and notify()/notifyAll()
 A common scenario is as follows:
A thread enters a synchronized block of code (and
thus obtains the object lock).
The code cannot continue the sychronized block
until some other thread has done some work on
the same object and left it in a new state
Thus, the first thread wants to temporarily
relinquish the lock to another thread.
wait() and notify()/notifyAll()
 Called when a thread needs to wait for some
other thread(s) to complete a task before
continuing.
 The current thread simply calls wait(), and
the thread freezes until another object calls
notify() upon the waiting object (or
notifyAll()).
 notifyAll() is much safer since notify()
chooses randomly!
wait() and notify()/notifyAll()
 Beware, wait() can only be called from a
synchronized method or block of code.
 When wait is called on an object, its lock is
released until it is notified.
Moving out of blocked state
 Must use the opposite route that put the
Thread into the blocked state
– If put to sleep, specified time interval must
elapse.
– If waiting for i/o operation, operation must
have finished.
– If the thread called wait(), then another thread
must call notify/notifyAll.
– If waiting for a lock, then owning thread must
have relinquished the lock.
Synchronized Cubbyhole
public class CubbyHole {
private int contents;
private boolean available = false;
public synchronized int get() {
while (available == false) {
try {
wait();
} catch (InterruptedException e) { }
}
available = false;
notifyAll();
return contents;
}
Cubbyhole, cont.
public synchronized void put(int value) {
while (available == true) {
try {
wait();
} catch (InterruptedException e) { }
}
contents = value;
available = true;
notifyAll();
}
}
Interrupting Threads
 Thread terminates when run method ends.
 So, run method should check once in a
while whether there is more work to do in
regular way.
 However, what if thread is sleeping or
otherwise blocked?
 This is where interrupt() method comes
into play.
Interrupting, cont.
 When interrupt method is called on thread
that is blocking, the blocking call is
terminated by an InterruptException.
public void run(){
try{
while (more work to do){ do work }
catch(InterrupetedException e){
//thread was interrupted during sleep or wait
//do whatever you wish here
}
Interrupting, cont.
 Problem with previous code is that
interrupts only succeed if thread is blocked
in call to sleep() or wait().
 Can get around this by calling interrupted()
periodically to see if thread has recently
been interrupted:
while (!interrupted() && more work to do){
// do work
}
Deadlock – Dining Philosophers
example
 http://java.sun.com/docs/books/tutorial/esse
ntial/threads/deadlock.html
Atomic operations -- Bank
Account example
 See BankTest.java and SynchBankTest.java
Tips on writing thread-safe code
 Obvious way is to use synchronization (see next
slide)
– Performance problems
– Can lead to deadlock
– General rule: don’t overuse if possible
 Local variables
– Each thread gets its own copy
 “Immutable sequences”
– Objects which can’t be changed (String, Integer, etc.)
Re-entrant threads
 Java’s model supports a concept called re-
entrant threads.
 If a thread t obtains a lock on object o by
calling a synchronized method in o (say
m1), and then from within m1 calls a
second sychronized method in o m2,
deadlock is guaranteed not to occur.
Other useful methods
 join() tells the calling thread to halt
execution until the second thread (whose
yield method is called), has completed.
Thread t = new Thread(runnableObj);
t.join();
Additional Topics
 Priorities
 Thread Groups
 Creating Thread pools
 Threads and Swing
 Higher-level methods – Timer class
Distributed Objects
 Higher level alternative to sockets
 RMI or CORBA
Nested Classes
Nested Classes
 An nested class is a class that is defined
inside another class.
 To this point we have only studied top-level
classes.
– at most one public per file
– arbitrarily man package-scope per file
– either package or public ONLY
 Nested classes introduced in jdk1.1
Why use nested classes?
 Simplifies many coding tasks
– can define small classes on the fly near the
objects created from them + concise syntax
– can access outer classes iv’s automatically – no
need to pass a this pointer to the constructor of
separate outer class
– can be hidden from other classes in the same
package
 However, price to pay in terms of
complexity, number of gotchas, etc.
Pre jdk1.1
 In jdk1.0, the clean and simple class rules were
ballyhooed as a major improvement over C++
 Addition of inner classes complicates things
significantly
 However, they do make certain code much less
awkard to write, particularly when writing GUIs
 Still, you do not have to use them, but they can be
quite cool and I do recommend it in moderation!
Types of nested classes
 Inner classes
– local
• anonymous or named
– non-local
• named only
 Static nested classes
– non-local named only
Non-local inner classes
 Simply a nested class that does not have the static
attribute and is not defined within a class method.
 Can be private, public, package, protected,
abstract, etc. just like any class member.
 Think of outer class as owning inner class – inner
class can only be instantiated via outer class
reference (including this)
 Inner class has access to all outer class iv’s,
private or otherwise!
Simple non-local inner class
example
class Outer{
private int x1;
Outer(int x1){
this.x1 = x1;
}
public void foo(){ System.out.println(“fooing”);}
public class Inner{
private int x1 = 0;
void foo(){
System.out.println(“Outer value of x1: “ + Outer.this.x1);
System.out.println(“Inner value of x1: “ + this.x1);
}
}
Simple example, cont -- driver
• Rules for instantiation a little funny
public class TestDrive{
public static void main(String[] args){
Outer outer = new Outer(); // can create in regular way
Inner inner = outer.new Inner(); //must call new through
//outer object handle
inner.foo();
// note that this can only be done if inner is visible
// according to the regular scoping rules
}
}
When to use non-local inner
classes
 Most typically used when inner class is
instatiated from outer class.
 If classes naturally “belong together”, it is
cumbersome to pass a this pointer to a
separate outer class just so second class can
access first class’s properties/methods.
 Note that inner class can access outer class’s
private data, making them even more
powerful than mechanism implied above!
Local inner classes
 Inner classes may also be defined within class
methods.
 These are called local inner classes.
 Principle advantage is scoping: such classes are
completely inaccessible anywhere but the method
itself where they are defined.
 Thus, they have no visibility attribute (public, etc.)
 Also, can NOT access local variables other than
those declared with final attribute.
Local anonymous inner classes
 Local inner classes can be taken a step
further – it is not required to give them an
explicit name.
 This is very convenient when you want to
use a class only once and the code that it
contains is succinct.
 Great example is defining Swing callback
functions.
Anonymous class example
but.addActionListener(
new ActionListener(){
public void actionPerformed(actionEvent ae){
//do work here
}
}
);
Final Exam Review
Questions
Question0
class A {
static void display ( ){ System.out.println ( "Class A" ) ; }
}
class B extends A {
static void display ( ) { System.out.println ( "Class B" ); }
}
When we create an object and call the display ( ) method as:.
A aa = new B() ;
aa.display ( )
What is displayed ??
What if display is non-static??
Question1

1.
2.
3.
4.
5.
Given a class A with a protected iv ivp, which of
the following are possible ways of accessing
ivp?
using the this pointer within a subclass of A
within the same package
using the this pointer within a subclass of B
outside of the package
using an instance of A from within any class in
the same package
using an instance of A from within any class
using an instance of A from within any class in
the CLASSPATH
Question2

1.
2.
3.
4.
5.
Given a class A with a private iv ivp, which of
the following are possible ways of accessing
ivp?
using the this pointer within a subclass of A
within the same package
using the this pointer within a subclass of B
outside of the package
using an instance of A from within any class in
the same package
using an instance of A from within any class
using an instance of A from within any class in
the CLASSPATH
Question3
 List the visibility keywords in order of
1.
2.
3.
4.
most to least restrictive.
private default protected public
public protected default private
private protected default public
public default private protected
Question4
 If an iv has private scope in some
superclass, then no subclass can access the
iv using the this pointer.
Question5
 Immutable classes may contain accessor
methods
Question6
 Immutable classes are Threadsafe.
Question7
class X{
public boolean equals(Object o){
X anX = (X) o;
if (anX.iv1 == this.iv1) return true;
return false;
}
? int iv1;
 What can be inferred about iv1?
private, protected, default, public, all, some??
Question8-10
 Assuming the class X is exactly as it
appears on the previous slide (with public in
place of ?), is the following valid?
X x2 = (X) anX.clone();
 If so, is this clone and adequate clone? If
not, how would you modify the class X to
make it cloneable?
 Is X serializable as-is?
Question11
 Is it appropriate to store anX in HashMap,
again assuming that X is defined verbatim
as you see?
 Is it legal to store anX in a HashMap?
Question12
 Is it possible for a subclass to override a
private superclass method?
Question13
 Can a static variable be used in a non-static
context?
Question14
 Can a static method access a non-static
variable?
Question15
 Can a class with all static methods be
instantiated?
Questions16-18
public class ClassA {
public void methodOne(int i) { }
public void methodTwo(int i) { }
public static void methodThree(int i) { }
public static void methodFour(int i) { } }
public class ClassB extends ClassA {
public static void methodOne(int i) { }
public void methodTwo(int i) { }
public void methodThree(int i) { }
public static void methodFour(int i) { } }
a. Which method overrides a method in the superclass?
b. Which method hides a method in the superclass?
c. What do the other methods do?
Question19-24 Exception
handling (T or F)
 All java Exceptions must either be caught or
thrown.
 Classes can throw Exceptions.
 Static methods can throw Exceptions.
 main can be declared to throw Exception
 rethrowing Exceptions is bad programming style
 Every method that throws an Exception should be
placed in its own try-catch block
 It is bad programming style to have empty catch
blocks, at least in production code.
Question25
 Which best describes and Applet?
1. A thin client
2. A fat client
3. A lightweight web server
4. A full-blown application server
Question 26-31
 All applets extend either Applet or JApplet.
 Applets need a main method to run
 All applets must override at least the start, stop,
init, and destroy methods.
 start, stop, init, and destroy methods are declared
abstract in the Applet class
 Unsigned applets cannot make socket connections
to any server.
 Unsigned applets cannot access files on the local
directory
Somewhat irritating
certification type questions
Question 1)
Which of the following lines will compile without
warning or error?
1) float f=1.3;
2) char c="a";
3) byte b=257;
4) boolean b=null;
5) int i=10;
What will happen if you try to compile and
run the following code
public class MyClass {
public static void main(String arguments[]) {
amethod(arguments);
}
public void amethod(String[] arguments) {
System.out.println(arguments);
System.out.println(arguments[1]);
}}
1) error Can't make static reference to void amethod.
2) error method main not correct
3) error array must include parameter
4) amethod must be declared with String
Which of the following will compile without error
1)
import java.awt.*;
package Mypackage;
class Myclass {}
2)
package MyPackage;
import java.awt.*;
class MyClass{}
3)
/*This is a comment */
package MyPackage;
import java.awt.*;
class MyClass{}
What will happen when you compile and run the following code
public class MyClass{
static int i;
public static void main(String argv[]){
System.out.println(i);
}}
1) Error Variable i may not have been initialized
2) null
3) 1
4) 0
What will be the result of attempting to compile and run the
following code?
abstract class MineBase {
abstract void amethod();
static int i;
}
public class Mine extends MineBase {
public static void main(String argv[]){
int[] ar=new int[5];
for(i=0;i < ar.length;i++)
System.out.println(ar[i]);
}}
1) a sequence of 5 0's will be printed
2) Error: ar is used before it is initialized
3) Error Mine must be declared abstract
4) IndexOutOfBoundes Error
What will be printed out if you attempt to compile and run the following cod
int i=1;
switch (i) {
case 0:
System.out.println("zero");
break;
case 1:
System.out.println("one");
case 2:
System.out.println("two");
default:
System.out.println("default");
}
1) one
2) one, default
3) one, two, default
Which of the following statements are true?
1) Methods cannot be overriden to be more private
2) Static methods cannot be overloaded
3) Private methods cannot be overloaded
4) An overloaded method cannot throw exceptions
not checked in the base class
What will happen if you attempt to compile and run the
following code?
class Base {}
class Sub extends Base {}
class Sub2 extends Base {}
public class CEx{
public static void main(String argv[]){
Base b=new Base();
Sub s=(Sub) b;
}}
1) Compile and run without error
2) Compile time Exception
3) Runtime Exception
What will happen when you attempt to compile and run the following code?.
class Background implements Runnable{
int i=0;
public int run(){
while(true){
i++;
System.out.println("i="+i);
} //End while
return 1;
}//End run
}//End class
1) It will compile and the run method will print out the increasing value of i.
2) It will compile and calling start will print out the increasing value of i.
3) The code will cause an error at compile time.
4) Compilation will cause an error because while cannot take
What will be the result when you try to compile and run the following code?
private class Base{
Base(){
int i = 100;
System.out.println(i);}}
public class Pri extends Base{
static int i = 200;
public static void main(String argv[]){
Pri p = new Pri();
System.out.println(i);}}
1) Error at compile time
2) 200
3) 100 followed by 200
4) 100
JNI
JNI (Java Native Interface)
JNI
 Stands for “Java Native Interface”
 Set of tools/code that allows user to call “native”
methods from Java.
 Includes “bindings” for C/C++.
 Can be used to call C/C++ from Java (typical), or
Java from C (invocation API)
 Differs from spawning executable – data is passed
to/from C/C++ method
 Question: why is this difficult?
Reasons for using JNI
 Feature not available in java language
(rare).
 Code already written in another language,
don’t want to rewrite (typical).
 Java is slow (how slow?)
 Other language has no additional features
per se, but has much better syntax for
handling certain operations (Fortran for
math).
Problems with JNI
 Only provides C/C++ bindings. Going to
Fortran, COBOL, Ada, etc. requires extra
step.
 Not portable
 Mapping is not trivial
 Can be unsafe
 Cannot run from applet (security issues)
Machinery for using JNI
Steps to follow …
Basic steps to calling native code
1. Write java class with at least one method
declared with native keyword. Provide no
implementation
– public native void sayHello();
– Example above is most simple, but method may pass
any parameters or have any return type.
2. Add a call to System.loadLibrary(“libname”) in
the class that declares the native method:
–
static{
System.loadLibrary(“hello”);}//static means called only once.
Steps, cont.
3. Compile the class
–
javac Hello.java
4. Produce the C/C++ header files using the javah
utility:
– Javah Hello
– This produces the header file Hello.h
5. Write your implementation file by first copying
the function signature produced in the include
file. Also, #include the header file.
#include “Hello.h”
Steps, cont.
6. Write the implementation in C/C++. This will
require using JNI methods to access the data or
possibly casts to convert to basic C/C++ types
7. Best technique: Break into two steps. Think of
your C/C++ function as a wrapper which accesses
the Java data and maps it to C data using JNI
methods, then shoves the converted data into a
prewritten standalone C program.
Steps, cont.
8. Compile your native method(s) as a shared object
(or DLL on Windows).
– WARNING: Be sure to point your linker to the include
files in /jdk1.3/include and jdk1.3/include/linux (for
example).
– WARNING: Mixing languages is much easier using a
straight C wrapper rather than C++.
9. Set the environment variable
LD_LIBRARY_PATH to the shared object
directory
 Run main Java class.
C language bindings
What does Java pass to my method?
What does Java pass to my C
function?
 JNIEnv* : A pointer to the the JNI
environment. This pointer is a handle to the
current thread in the JVM, and contains
mapping functions and other housekeeping
information.
 jobject : A reference to the object that
called the native code. (like “this” pointer).
 Any arguments specified by the method.
Pause for some nice pictures
Legacy C calls Java
Java calls legacy
JNI is inter-language “glue”
Simple examples on union
 HelloWorld Example: No data passed
– Hello.java
– Hello.cc
 Max example : Only native dataypes
– Utils.java
– utils.cc
 Advanced Max example: Arrays
– Utils.java
– utils.cc
 Max Java-C-Fortran: max.f
General Strategy
 Keep interface as simple as
Native datatype mappings
Java Type
boolean
byte
char
short
int
long
float
double
void
Native Type
jboolean
jbyte
jchar
jshort
jint
jlong
jfloat
jdouble
void
Size in bits
8, unsigned
8
16, unsigned
16
32
64
32
64
N/a
Java object Mappings
• Object passed by reference
• All objects have type jobject as:
Object mappings, cont.
 For example, if a method getLine exists in a
class call Prompt, then:
private native String getLine(String Prompt);
is mapped into
JNIExport jstring JNICALL Java_Prompt_getLine(JNIEnv *, jobject,
jstring);
 But how to access data/methods from object
that is passed in?
JNI Advice
 Can seem like a bewildering number of functions.
 Do not try to learn it all.
 Keep interfaces very simple.
– Preferably, only native datatypes, Strings, and arrays.
 Be careful about
– Copies vs. rerences
– Freeing memory
 Best not to allocate memory from with native
code.
Accessing java strings
 Do NOT do the following:
JNIEXPORT jstring JNICALL
Java_Prompt_getLine(JNIEnv *env, jobject obj, jstring
prompt){
printf(“%s”, prompt);
}
 Why is this bad?
Right way to access Strings
 Must use special methods in env structure
char *str = (*env)->GetStringUTFChars(env,prompt,0);
/* this maps into regular C char* */
printf(“%s”, str); /* now it is ok to print */
(*env)->ReleaseStringUTFChars(env, prompt, str);
/* must release String to avoid memory leaks */
Returning Strings
 Previous technique allows us to use a String
passed in from Java.
 What if we want to return a String?
 Can use NewStringUTF as:
char buf[128]; /* allocate memory for local char* in C */
scanf(“%s”, buf); /* read into char* from stdio */
return( (*env)->NewStringUTF(env, buf));
/* construct and return the Java String */
Other JNI String methods
 GetStringChars
– Takes the Java String and returns a pointer to an array
of Unicode characters that comprise it.
 ReleaseStringChars
– Releases the pointer to the array of Unicode characters
 NewString
– Constructs a new String object from an array of
Unicode Characters
 GetStringLength
– Returns the length of a string of Unicode characters
Java arrays
 Note that you can NOT do the following:
JNIExport jint JNICALL Java_IntArray_sumArray(JNIEnv
*env, jobject obj, jintArray arr){
int i, sum = 0;
for (i = 0; i<10; i++){
sum += arr[i]; /* NO! – why not?
}
...
 Must use java methods to access array data in C
Array methods
 The previous example should be written as:
jsize len = (*env)->GetArrayLength(env,arr);
jint *body = (*env)->GetIntArrayElements(env,arr,0);
for (i=0;i<len;++i){
sum += body[i];
}
(*env)->ReleastIntArrayElements(env,arr,body,0);
/* very important – copies back to java array if copy had to be
made */
Array methods, cont.
 Note that there are analagous functions for
float, byte, double, etc:
– Get<type>ArrayElements
– Release<type>ArrayElements
 Important: These Get functions may copy
the entire array. If this is undesirable, use
Get/Set<type>ArrayRegion functions
Function for accessing arrays
Function
GetBooleanArrayElements
GetByteArrayElements
GetShortArrayElements
GetIntArrayElements
GetLongArrayElements
GetFloatArrayElements
GetDoubleArrayElements
GetObjectArrayElements
Array Type
boolean
byte
short
int
long
float
double
object
Functions for releasing arrays
Function
ReleaseBooleanArrayElements
ReleaseByteArrayElements
ReleaseShortArrayElements
RelaseIntArrayElements
ReleaseLongArrayElements
ReleaseFloatArrayElements
ReleaseDoubleArrayElements
ReleaseObjectArrayElements
Array Type
boolean
byte
short
int
long
float
double
object
Calling java methods
 What if you pass a java object to a C routine
and wish to “call back” a method on the
Java object.
 Good to avoid this when you can but
sometimes it is very important.
 Need to use the jobject reference that is
passed in by java.
Steps to follow
 Native method calls JNI function GetObjectClass
– returns the jclass object that is type of that obj
 Native method calls JNI function GetMethodID
– returns jmethodID of method in class (0 for no such
method)
 Finally, native method calls JNI function
CallVoidMethod.
– invokes an instance of method with void return type.
You pass object, methodID, and actual arguments.
A simple alternative – spawning a
system executable
 Advantages
– Infinitely simpler
– Portable
– Can use any native language
 Disadvantages
– Can only pass data to and from vi stdout
– Must reload executable for each invocation
Spawning Executable -technique
 Process p = Runtime.exec(“some_exec”);
 Use p to manage process:
– p.getInputStream();
– p.getOutputStream();
– p.kill();
– p.halt();
Part 2
Extending Web Server Functionality
Servlets and JSP
Web Servers
 A server program that listens on a standard port
and handles http protocol.
 Http protocol consists mainly of requests for
documents
 Documents are typically html files
 Two most important http protocol elements:
– GET (request document, may upload data)
– POST (request document, upload data).
 This protocol is hidden from you by browser.
Early Web Servers
 Earliest web sites were static:
– Browser requests page
– Server hands over page
 CGI (Common Gateway Interface) scripts defined
a standard for extending functionality
– http GET/POST data could be passed to and processed
in separate function (C, Perl, Python, etc.)
– This often included call to back-end database and
response to user via modified html document
Shortcomings of CGI
 E-Commerce became more popular and
web sites became more heavily used. This
brought to the fore some shortcomings of
CGI:
– New process spawned for every hit – not
scalable
– No concept of sesssion or state
– Pretty low level
– Security risks (C in particular)
Servlets
 Java’s answer to CGI, very simple, high-
level
 Requirements: a servlet-enabled web server
 When specified by your web page, web
page passes http requests to java method
(assuming everything is setup properly)
 Servlet method then has access to all of
Java capabilities – jdbc very important here.
 Servlet then writes html back to user.
Servlets, cont.
 Important: a web server takes care of all
interactions with the servlet – servlet
extends functionality.
 On the client side, servlet pages are
typically requested in one of two ways:
– As a regular URL address
– As a link in a regular html document
 Details are server-dependent
Writing servlets
 All servlets extend the Servlet class.
 All http servlets (by far most typical) should
extend the HttpServlet class.
 In extending HttpServlet, you typically
override the following methods:
– init, doGet,doPost, destroy (very common)
– doPut, doDelete, doOptions, doTrace (rare)
Main HttpServlet Methods
 init()
– called once when servlet is loaded by server.
Contains any initializations that are common to
all requests.
 doGet(HttpServletRequest,
HttpServletResponse)
– Called each time the servlet receives an http
GET request posted by a client. Passes two
objects, one representing the information of the
request, the other used to configure a response.
Main HttpServlet Methods, cont.
 doPost(HttpServletRequest,
HttpServletResponse)
– Same as doGet but for an http POST request.
 destroy()
– Called before servlet is unloaded from memory.
Performs any final cleanup, freeing memory,
closing connections, etc.
Service Method
 Important: The method
service(HttpServletRequest,
HttpServletResponse)
is also called for each servlet invocation.
 Service() in turn calls doGet and doPost,
etc.
 It is best not to override service even if you
want to handle doGet and doPost
identically. Simply have one call the other.
HttpServletRequest Object
 Passed when browser calls doGet and doPost.
 Most import methods for beginning servlet
programming
– getParameter(String paramName)
– getParameterNames()
– getParameterValues()
 Makes getting data from web pages very simple.
 Many other methods for images, cookies, etc.
HttpServletResponse Object
 Passed when browser calls doGet or doPost
 Most import methods for beginning servlet
programming:
– getWriter();
• Get Writer for communicating back to client
– setContentType(String);
• Typically use “text/html”, indicating that html will
be sent back to the browser
Examples
 Use html form to connect to servlet, accept
form data, and then echo it back with the
output stream.
 Postdata.java
: Java servlet
 Form.html
: HTML front-end
 Basic steps very simple – just need to
know a little HTML and a few Java
methods
General Comments
 Recall that each request for a servlet gets its
own thread but access the same methods.
Thus, synchronization issues arise.