Command-line Arguments

advertisement
Options for User Input
• Options for getting information from the user
– Write event-driven code
• Con: requires a significant amount of new code to set-up
• Pro: the most versatile.
– Use System.in
• Con: less versatile then event-driven
• Pro: requires less new code
– Use the command line (String[ ] args)
• Con: very limited in its use
• Pro: the simplest to set up
Using the command line
• Remember what causes the “big bang” in
our programs?
Using the command line
• Remember what causes the “big bang” in
our programs?
public static void main (String [] args) {
Using the command line
• Remember what causes the “big bang” in
our programs?
public static void main (String [] args) {
• main expects an array of strings as a
parameter.
• The fact of the matter is that this array has
been a null array in each of our programs so
far.
Using the command line
• However, we can give this array values by
providing command line arguments when
we start a program running.
Using the command line
• However, we can give this array values by
providing command line arguments when
we start a program running.
java MyProgram String1 String2 String3
Using the command line
• However, we can give this array values by
providing command line arguments when
we start a program running.
$ java MyProgram String1 String2 String3
args[0] args[1] args[2]
Using the command line
• We can use this to get information from the
user when the program is started:
public class Echo {
public static void main(String [] args) {
System.out.println(“args[0] is “ + args[0]);
System.out.println(“args[1] is “ + args[1]);
} // end main
} // end Echo class
$ javac Echo.java
$ java Echo Mark Fienup
args[0] is Mark
args[1] is Fienup
What are some of the problems
with this solution
• This works great if we “behave” and enter two
arguments. But what if we don’t?
$ java Echo Mark Alan Fienup
args[0] is Mark
args[1] is Alan
(no problem, but Fienup gets ignored)
$ java Echo Mark
args[0] is Mark
Exception in thread “main”
java.lang.ArrayIndexOutOfBoundsException:
(Big problem!)
Fixing this problem
• There are several ways to work around this problem
– Use Java’s exception handling mechanism (not ready to talk about this yet)
– Write your own simple check and handle it yourself
public class MyEcho2 {
public static void main( String[] args ) {
if (args.length == 2) {
System.out.println("args[0] is ” + args[0]);
System.out.println("args[1] is " + args[1]);
} else {
System.out.println( "Usage: java MyEcho2 "
+ "string1 string2");
} // end if
} // end main
} // end MyEcho2
Fixing this problem
public class MyEcho2 {
public static void main( String[] args ) {
if (args.length == 2) {
System.out.println("args[0] is ” + args[0]);
System.out.println("args[1] is " + args[1]);
} else {
System.out.println( "Usage: java MyEcho2 "
+ "string1 string2");
} // end if
} // end main
} // end MyEcho2
$ java MyEcho2 Mark
Usage: java MyEcho2 string1 string2
$ java MyEcho2 Mark Alan Fienup
Usage: java MyEcho2 string1 string2
I learned something new!
• Will this code work if the user types NO arguments:
“java MyEcho2”?
public class MyEcho2 {
public static void main( String[] args ) {
if (args.length == 2) {
System.out.println("args[0] is ” + args[0]);
System.out.println("args[1] is " + args[1]);
} else {
System.out.println( "Usage: java MyEcho2 "
+ "string1 string2");
} // end if
} // end main
} // end MyEcho2
Yes!
• The args array reference could be “null”,
so doing args.length would cause an error!
• But it is not, since args is an array
reference to an actual array with zero
elements.
What about?
public class TestArray {
public static void main( String[] args )
System.out.println("args.length = " +
String[] temp0 = {};
System.out.println( "temp0.length = "
String[] tempNull;
System.out.println("tempNull.length="
} // end main
} // end TestArray class
{
args.length );
+ temp0.length );
+ tempNull.length);
$ javac TestArray.java
TestArray.java:7: variable tempNull might not have been
initialized
System.out.println( "tempNull.length = " +
tempNull.length );
^
1 error
What about?
public class TestArray {
public static void main( String[] args )
System.out.println("args.length = " +
String[] temp0 = {};
System.out.println( "temp0.length = "
String[] tempNull = null;
System.out.println("tempNull.length="
} // end main
} // end TestArray class
{
args.length );
+ temp0.length );
+ tempNull.length);
$ java TestArray
args.length = 0
temp0.length = 0
Exception in thread "main" java.lang.NullPointerException
at TestArray.main(TestArray.java:7)
Your turn to write a simple program
using the command line
• Write a program to echo all command-line
arguments to the System.out
$ java EchoAll This is a long line
args[0] is This
args[1] is is
args[2] is a
args[3] is long
args[4] is line
Simple Calculations at
Command Line
$ java Calculate 6 + 4
10
$ java Calculate 8 - 5
3
First Attempt - What’s wrong?
public class Calculate {
public static void main( String[] args ) {
int
operand1 = args[0];
String operator = args[1];
int
operand2 = args[2];
if ( operator.equals("+") ) {
System.out.println( operand1 + operand2 );
} else if ( operator.equals("-") ) {
System.out.println( operand1 - operand2 );
} else {
System.out.println("Invalid operator: " + operator);
} // end if
} // end main
} // end Calculate
$ javac Calculate.java
Calculate.java:3: incompatible types
found
: java.lang.String
required: int
int
operand1 = args[0];
^
Correct Calculate
public class Calculate {
public static void main( String[] args ) {
int
operand1 = Integer.parseInt( args[0] );
String operator = args[1];
int
operand2 = Integer.parseInt( args[2] );
if ( operator.equals("+") ) {
System.out.println( operand1
} else if ( operator.equals("-")
System.out.println( operand1
} else {
System.out.println( "Invalid
} // end if
} // end main
} // end Calculate
+ operand2 );
) {
- operand2 );
operator: "
+ operator );
The wrapper classes
• Primitive data types (int, double, boolean, etc.)
are not actually objects. Because of this, you
can’t use them easily in certain OO situations
• Because of that, java has “wrapper classes” such
as Integer, Double, and Boolean.
• These are true classes in the OO sense of the
word in that they contain data which store
information (often the value in it’s corresponding
primitive data type) and methods that can act on
this data.
But wait a minute!
• How is it that we can use the parseInt()
method without actually creating an
instance of the Integer class.
Lifetime Modifiers
What does static mean?
Lifetime Modifiers
What does static mean?
• The item being declared is a feature of the
class – what we usually call “class
methods” or “class variables.”
• The item being declared exists at load
time, before any instance is created.
Lifetime Modifiers
• A “class method” is one that can be
invoked without sending a message to an
instance of the class.
the main method of MemoPadApp
int operand1 = Integer.parseInt(args[0]);
double myRandom = Math.random();
Lifetime Modifiers
• A “class variable” is one that every instance has
access to and shares.
In chapter 5, Budd creates windows in which bouncing
balls live. Every instance of his BallWorld class
shares the same height and width dimensions,
implemented as static class variables:
public static int frameWidth=200;
public static int frameHeight=250;
Lifetime Modifiers
• We will use these rarely in the code we
write.
– The more you use static stuff, the less flexible
and modifiable your code tends to be.
• The Java class library uses these more
frequently. Budd will use them
occasionally.
– Thus, you will still get to see plenty of
examples before we are done!
Homework #2 - Implementing Constructors
• Goals for this assignment:
 practice implementing constructors
 practice factoring common behavior into helper
methods
 experience working with command-line arguments
• You will continue to work with the
MemoPad program for this assignment,
including the database class that you
implemented for Homework 1
Homework #2 - Task 1
1. Add a new constructor to your MemoDatabase class that
takes one argument: the maximum number of memos
that can be stored.
The constructor should use this argument when initializing the size of
the array in the constructor. The existing constructor should still use
a default value for the array size. Notice that the constant now
becomes the default maximum, not the actual maximum!
Test your new constructor by using it to create the database in the
MemoPad class and then running the program. Verify that the
database enforces the maximum size!
Make sure that the class's default constructor still works, too, and that it
still enforces its maximum number of entries.
Homework #2 - Task 2
2. Eliminate any code duplication in your MemoDatabase
class's constructors.
Your two constructors almost certainly have a lot of code common -they do almost exactly the same thing! Make the duplication go
away. One way to do that is to factor any common behavior into a
private method named initialize.
Re-test both constructors by using them to create the database in the
MemoPad class and then running the program.
Homework #2 - Task 3
3. Add a new constructor to the MemoPad class that takes
one argument: the MemoDatabase that it uses to store
the memos.
In this constructor, use the argument to initialize the database instance
variable.
Test your new constructor by using it to create the MemoPad in the
main() method and then running the program.
Homework #2 - Task 4
4. Change the original "default" constructor back to its
original form, from before Homework 1: initialize the
database variable to be a DefaultMemoDatabase.
Test the default constructor by using it to create the MemoPad in the
main() method and then running the program.
Homework #2 - Task 5
5. Eliminate any code duplication in the MemoPad
constructors.
The two constructors almost certainly have a lot of code common -they differ in only one line! Make the duplication go away. One way
to do that is to factor any common behavior into a private method
named initialize.
Re-test both constructors by using them to create the MemoPad in the
main() method and then running the program.
Homework #2 - Task 6
6. Modify the main() method in the MemoPadApp driver to
accept up to two optional arguments that control the kind
of MemoDatabase to be used.
One optional argument is the choice of database class.
-d indicates to use the default implementation.
-s indicates to use the student implementation.
Homework #2 - Sample Executions
If no argument is given, create a default
instance of MemoPad. For example:
$ java MemoPadApp
... MemoPadApp uses the default constructor
of MemoPad
Homework #2 - Sample Executions
• If the user specifies -d, create an instance
of DefaultMemoDatabase and use it to
initialize the MemoPad you create. For
example:
$ java MemoPadApp -d
... MemoPadApp creates a
DefaultMemoDatabase and passes it to
MemoPad's constructor
Homework #2 - Sample Executions
• If the user specifies -s, then the commandline may contain a second optional
argument, an integer to specify the
maximum number of entries in the
database.
• Use this integer to create an instance of
your database class. If no second argument
is given, create a default instance of your
array-based database class. In either case,
use this database object to initialize the
MemoPad you create.
Homework #2 - Sample Executions
$ java MemoPadApp -s
... MemoPadApp creates an instance of your
MemoDatabase (use default constructor) and passes it
to MemoPad's constructor
$
java MemoPadApp -s 100
... MemoPadApp creates an instance of your
MemoDatabase (use the int constructor) and passes
it to MemoPad's constructor
Homework #2 - Sample Executions
• If the user gives any other command-line
argument, print an error message and
return without creating any objects. For
example:
$ java MemoPadApp -oops
Usage: java MemoPadApp
java MemoPadApp -d
java MemoPadApp -s [size]
Download