Final Exam Review
1) Define
checked vs. unchecked exceptions. How can you tell which is which?
The compiler checks to make sure you’ve handled checked
exceptions, but handling of unchecked ones is optional.
The unchecked ones are descendants of RuntimeException, and all
the other kinds are checked.
2) Why
doesn't the compiler require you to handle ALL exceptions?
It would be very inefficient to handle all the runtime exceptions.
To handle all possible NullPointerExceptions, for example, you’d have to catch
or throw from any piece of code that used a reference variable, which would be
almost every method. And besides, a working program won’t have any null pointer
errors anyway. So the compiler only requires you to handle non-runtime ones,
which are less common and generally not within the programmer’s control, such
as I/O problems.
Code for
questions 3-4
<some code>
try {
<some
code>
} catch (<exception type A>) {
<some code>
} catch (<exception type B>) { <
some code>
} finally { <some code>
}
<some code>
3) What
makes the catch clause for type B run?
An exception is thrown inside the try block, and the exception
type matches B and not A.
4) Under
what conditions does the finally clause NOT run, barring natural disasters?
Only if the code does not enter the try block. If the try block
starts, the finally clause always runs.
5) How can
you make an exception be thrown in conditions that Java doesn't consider error
conditions? Why would you?
You can say: throw new Exception(“some helpful
message”);
You might do this to help with debugging, when you consider the
condition to be an error for your program. You could also do it to toss control
back to the calling method, although you could probably get the same effects
using if statements.
6) Suppose main
calls methodA, which calls methodB, which does some I/O that might cause an
IOException. What are your options for handling it?
1)
You can put a try block around the I/O
code with a catch clause for IOException.
2)
You can put “throws IOException” in the methodB
header and put the try block in methodA around the call to methodB.
3)
You can throw from both methodA and
methodB and catch in main.
7) Make sure
this method always returns a valid input, or quits if something’s very wrong:
public int getInteger(BufferedReader buf,
String message) {
while
(true) {
try
{
System.out.print(message);
int
x = Integer.parseInt(buf.readLine());
return
x;
}
catch (NumberFormatException e) {
System.out.print(“Integers
only. ”);
}
catch (IOException e) {
System.out.println(“Cannot read;
quitting.”);
System.exit(0);
}
}
}
8) What is a
stream?
A connection between a program and an IO device along which a
sequence of data can flow.
9) What are
the console IO classes we've used, and what do they do?
PrintStream - prints strings and anything else (System.out is one)
InputStream - reads bytes (System.in is one)
InputStreamReader - translates bytes from InputStream into chars
BufferedReader - translates chars from InputStreamReader into
strings (buffers the input for high efficiency)
10) What are
the file IO classes we've used, and what do they do?
File - represents a file on the hard drive
FileReader - translates bytes from File into chars
FileWriter - writes chars into a File
BufferedReader - translates chars from FileReader into strings
(buffers the input for high efficiency)
PrintWriter - prints strings and anything else
11) What's
the difference between these print statements?
System.out.println("Hi");
System.out.println(5);
System.out.println(new Alien());
The first two use two overloaded methods called “println” in the
PrintStream class; one takes an integer parameter, and the other takes a String
parameter. The third calls the toString() method of the Alien class; if one has
not been explicitly defined, it goes to the inherited one from Object, which
prints out a code that has something to do with the location of the object in
memory.
12) Make
this method input names from a file, where the file contains 50 names over
several lines that look like
"Name:Name:Name" and so forth. Put the names in an array and
return the array.
public String[] getNames(File file) throws
IOException {
String[]
names = new String[50];
BufferedReader
buf = new BufferedReader(new FileReader(file));
String
line = buf.readLine();
int
index = 0;
while
(line!=null) {
StringTokenizer
st = new StringTokenizer(line, “:”);
while
(st.hasMoreTokens()) {
names[index]
= st.nextToken();
index++;
}
line
= buf.readLine();
}
buf.close();
return
array;
}
13) Make
this method print each name on its own line in the file.
public void printNames(String[] names,
File file) throws IOException {
PrintWriter
pw = new PrintWriter(new FileWriter(file));
for
(int i=0; i<names.length; i++) {
pw.println(names[i]);
}
pw.close();
}
14) What is
a 2D array in Java really?
An array filled with references to other arrays.
15) What are
the first and last indices of an array with length L? 0 and L-1
16) What is
the value of bullets[0] after this code?
Bullet[] bullets = new Bullet[6];
null
17) What are
fixed-size and variable-size array declaration?
Fixed-size is when you use an integer literal for the size when
you create the array. Variable-size is when you use an integer variable
instead. In Java you can use variables, because you aren’t required to specify
the exact size of the array until runtime. (In other languages, this is not
allowed.)
18) What is
the danger of leaving holes in an array of objects? How can you get rid of
them?
You probably have code that loops through the array and does
something to each of the indices, and if you don’t check for holes each time
that will probably cause a null pointer exception. You can get ride of a hole
by shifting everything after it back by one, or by taking the one on the end
and putting it in the hole.
19) What are
2 ways to make a 2D array that holds these integers?
0
0 1
0 1 2
int[][] a = { {0}, {0, 1}, {0, 1, 2} };
int[][] a = new int[3][];
for (int i=0; i<a.length; i++) {
a[i] = new
int[i+1];
for (int j=0; j<a[i].length;
j++)
a[i][j]
= j;
}
20) Draw a
memory diagram for the above array.
21) What is
the scope of a "protected" superclass data member?
A protected superclass data member is accessible from any method
in the superclass, and any method in any descendant class.
22) What are
"unrelated" and "sibling" classes?
Unrelated classes have no inheritance hierarchy in common (except,
of course, that Object is the base class for both). Sibling classes have the
same parent class.
23) What
happens if you don't write a constructor in a class?
You get a default constructor that takes no parameters and has
only the call “super()” in the body. (If you happen to have a superclass that
doesn’t have a zero-parameter constructor, this will be a compiler error. If
you don’t have a superclass, it calls the Object version, which compiles just
fine.)
24) If class
A extends the abstract superclass B, is A instantiable?
Only if A implements any and all abstract methods in B.
25) What is
a signature, and what is a prototype?
A signature is the name and parameter list of a method. A
prototype is the signature, return type, and visibility.
26) How and
why would you overload this method? public
int max(int a, int b) {…}
You could overload it with a method with the same name and
different parameters, like max(double d, double e). The Math class does exactly
this, so you can call the max method with more than one type of parameter.
27) How and
why would you override this method? protected
void computeGrade() {…}
You could override it in a subclass with a method with the same
signature and return type and equal or greater visibility (protected or
public). The reason would be to create a specialized method for the subclass.
28) Suppose
the Grad and UnderGrad
classes both override the computeGrade()
method in the Student class. Write a loop that computes the
grades of the objects in the array Student[] class.
for (int i=0; i<class.length; i++) {
class[i].computeGrade();
}
Polymorphism allows us to call one method and get different
versions to run based on which subclass each array element actually is.
29) Now
suppose the array is declared as Object[] class. How
does the loop body have to change, and why?
It has to become:
((Student)class[i]).computeGrade();
This is because the Object class has no computeGrade() method. The
compiler requires you to cast the array element into a type that does have the
method before you call it.
30) What if
the array is declared as a Student array again, but we remove the computeGrades() method from the Student class?
if (class[i] instanceof Grad) {
((Grad)class[i]).computeGrade();
}
else if (class[i] instanceof UnderGrad) {
((UnderGrad)class[i]).computeGrade();
}
This time we have to cast each array element to the correct
subclass, because only the subclasses have the computeGrades() method.
31) In the
GUI version of the pig latin translator example, the PigGui class had the
following things:
PigGui
------
data members - GUI components
constructor - sets up the GUI
main - makes a PigGui object
toPigLatin - converts a string to pig
latin
findWordEnd - finds a space character
findVowel - finds a vowel character
actionPerformed - calls toPigLatin when a
button is clicked
If we were
to re-write this example in accordance with the Single-Task Object Principle,
how would we do it?
The following way separates the GUI functionality from the string
processing. Each object has one job, instead of one object doing both.
PigGui
------
data members - GUI components
constructor - sets up the GUI
main - makes a PigGui object and a
PigLatinTranslator object
actionPerformed - calls toPigLatin on the
PigLatinTranslator object on button click
PigLatinTranslator
------------------
data members - maybe constants for the tail
sequences "-" and "ay"
toPigLatin - converts a string to pig
latin
findWordEnd - finds a space character
findVowel - finds a vowel character
32) The
following method is passed a string containing an important political figure's
speech. Unfortunately this political figure is a little too enthusiastic, and
tends to inadvertently include improper words in such speeches. So the method
is also passed a couple of naughty words that
must be
replaced, wherever they're found in the speech, by publicly acceptable
alternatives. Return the sanitized string.
Helpful StringBuffer method: public
void replace(int start, int end, String replacement)
public String sanitize(String speech,
String bad, String veryBad) {
int endBad =
bad.length();
int endVeryBad =
veryBad.length();
StringBuffer sb
= new StringBuffer(speech);
for (int i=0;
i<sb.length(); i++) {
if
(i+endBad <= sb.length() &&
sb.substring(i,
i+endBad).equalsIgnoreCase(bad)) {
sb.replace(i,
i+endBad, "darn");
}
else if (i+endVeryBad
<= sb.length() &&
sb.substring(i,
i+endVeryBad).equalsIgnoreCase(veryBad)) {
sb.replace(i,
i+endVeryBad, "phooey");
}
}
return sb.toString();
}