580 likes | 745 Views
Java for C++ Programmers. Second Night. Overview. First Night Basics Classes and Objects Second Night Enumerations Exceptions Input/Output Templates vs. Generics STL vs. JavaSE API. Second Night Agenda.
E N D
Java for C++ Programmers Second Night
Overview • First Night • Basics • Classes and Objects • Second Night • Enumerations • Exceptions • Input/Output • Templates vs. Generics • STL vs. JavaSE API
Second Night Agenda • Enumerations, Exceptions, Input/Output – enumeration declaration & usage, exception hierarchy, checked vs. unchecked exceptions, throwing & catching exceptions, scanner class, console I/O, file I/O • Discussion • Lab exercises • Break • Templates vs. Generics, STL vs. JavaSE API – • Discussion • Lab exercises
Enumerated Values in C++ • One way to define a set of enumerated values/constants in C++ is as follows… • Example usage… constint CLUBS = 0; constint DIAMONDS = 1; constint HEARTS = 2; constint SPADES = 3; // good invocations DrawSuit(CLUBS); DrawSuit(HEARTS); voidDrawSuit(int s) { // draws the suit in a GUI }
Enumerated Values in Java • Here’s the Java port of that C++ code… • Everything looks good, right? publicclass Suit { publicstaticfinalintCLUBS = 0; publicstaticfinalintDIAMONDS = 1; publicstaticfinalintHEARTS = 2; publicstaticfinalintSPADES = 3; } // good invocations drawCard(Suit.CLUBS); drawCard(Suit.DIAMONDS); staticvoid drawCard(int s) { // draws the suit in a GUI }
Enumerated Values in Java • Well, sort of – as long as the user behaves themselves… • Using something unbounded like an int or a String can be problematic, need to restrict the available choices // bad invocations drawCard(Suit.HEARTS * 5); drawCard(-516); staticvoid drawCard(int s) { // draws the suit in a GUI }
Enumerations in Java • Thankfully, there’s a better way to enumerate a set of values, staring in Java 5 there is an enumerated type • Similar to enum construct in C/C++ • Enums are declared similarly to classes publicenum Suit { CLUBS, DIAMONDS, HEARTS, SPADES }
Enumerations in Java • Now, each constant is strongly typed • When something is expecting a suit, we specify a Suit enum type • Invalid usage is now caught at compile time // good invocations drawCard(Suit.CLUBS); drawCard(Suit.DIAMONDS); // compiler errors drawCard(Suit.HEARTS * 5); drawCard(-516); staticvoid drawCard(Suit s) { // draws the symbol for the suit in a GUI }
Enumerations in Java • Additionally, we can switch on enums… // draws the symbol for the suit in a GUI staticvoid drawCard(Suit s) { switch(s) { caseCLUBS: caseSPADES: // switch color to black, then draw break; default: // switch color to red, then draw break; } }
Enumerations in Java • We can also give enums in Java additional members and methods publicenum Planet { VENUS(4.8685e24,6051.8e3), EARTH(5.9736e24,6378.1e3), MARS(0.64185e24,3397e3); publicstaticfinaldoubleG = 6.67300E-11; finaldoublemass; finaldoubleradius; Planet(double mass, double radius) { this.mass = mass; this.radius = radius; } double surfaceGravity() { returnG * mass / (radius * radius); } double surfaceWeight(double otherMass) { return otherMass * surfaceGravity(); } }
Enumerations • Example usage, similar to a class… • But we get compiler errors, if we try to construct more… // acceptable usage drawPlanet(Planet.EARTH); System.out.println("Surface gravity on earth: "); System.out.println(Planet.EARTH.surfaceGravity()); // compiler errors Planet.EARTH = new Planet(1.0, 1.0); Planet p = new Planet(1.0, 1.0);
Exceptions in C++ • C++ allows us to throw anything as an exception • Here is a modified factorial function which throws the number back if it is less than 0 intfactorial(int n) { // check for exceptional case if(n < 0) { throw n; } // computation for normal case int result = 1; for(int i = n; i > 0; i--) { result *= i; } return result; }
Exceptions in C++ • Example catching of that exception in C++… intmain(int argc, char** argv) { int num = -4; try { cout << "factorial(" << num << "): " << factorial(num) << endl; } catch(int i) { cerr << i << " is not valid" << endl; } return 0; }
Exceptions in C++ • We can also throw more complex types, for example, here is a custom exception class which stores an error message… classException { private: stringm_message; public: Exception(string message) : m_message(message) { }; stringGetMessage() { returnthis->m_message; }; };
Exceptions in C++ • Factorial function modified to throw custom exception type… intfactorial(int n) { // check for exceptional case if(n < 0) { throw Exception("number must be positive"); } // computation for normal case int result = 1; for(int i = n; i > 0; i--) { result *= i; } return result; }
Exceptions • Example catching of that exception in C++… intmain(int argc, char** argv) { int num = -4; try { cout << "factorial(" << num << "): " << factorial(num) << endl; } catch(Exception e) { cerr << e.GetMessage() << endl; } return 0; }
Object Throwable Error Exception RuntimeException Error Error Error Error Error Error … … … Exceptions in Java • In Java, we cannot throw primitives or most objects • Anything that is thrown must be a Throwable (or a valid subclass) • Though, typically we throw Exceptions (or subclasses)
Exceptions in Java • Here’s a Java port of that second example • We’re using the built-in Exception class… staticint factorial(int n) { // check for exceptional case if(n < 0) { thrownew Exception("number must be positive"); } // computation for normal case int result = 1; for(int i = n; i > 0; i--) { result *= i; } return result; }
Exceptions in Java • Here is the invoking function in Java, with the try/catch block added… publicstaticvoid main(String[] args) { int num = -4; try { System.out.println("factorial(" + num + "): " + factorial(num)); } catch(Exception e) { System.err.println(e.getMessage()); } }
Exceptions in Java • But, if we try to compile this, we get the following error… • Why? $ javac.exe Factorial.java Factorial.java:19: unreported exception java.lang.Exception; must be caught or declared to be thrown throw new Exception("number must be positive"); ^ 1 error
Object Throwable Error Exception RuntimeException Error Error Error Error Error Error … … … Java Exception Hierarchy • Java breaks up Exceptions into 2 categories • Unchecked: you do not need to explicitly handle these exceptions • Checked: you must handle these in your code, failure to do so is a compiler error Unchecked Checked
Handling Checked Exceptions • We have one of 2 options… • Handle the exception locally (wrap code in a try/catch block) • Propagate the exception by adding a throws declaration to the method signature
Exceptions in Java • The modified factorial function modified to declare an thrown exception… staticint factorial(int n) throws Exception { // check for exceptional case if(n < 0) { thrownew Exception("number must be positive"); } // computation for normal case int result = 1; for(int i = n; i > 0; i--) { result *= i; } return result; }
Exceptions in Java • Other notes about exceptions in Java… • e.printStackTrace() will print out the full stack trace as to where an exception originated • e.getMessage() will give you a detailed message string as to why the exception occurred • Try/catch blocks may also have a finally section with code in it • Always executed even if a return or throw is encountered
Console I/O in C++ • Simple C++ class that reads/writes to the console #include<iostream> usingnamespace std; intmain() { int n; string s; cout << "What do you want to buy: "; cin >> s; cout << "How many: "; cin >> n; cout << "You want " << n << " " << s << endl; return 0; }
Console Input/Output in Java • Already looked at System.out for print() and println(), though there are many more such as • printf() – C style output (added in Java 5) • write() – byte based output • System.err provides the same methods as System.out does, goes to stderr • System.in interface is our standard input stream • System.in is an InputStream class and is pretty low level (read bytes) • Typically another class is used to read from System.in
Console Input in Java • Scanner class was added in JSE 5 to simplify input… • Has a constructor which takes an InputStream class • Scanner(System.in) • Methods are available to read common data types… • nextBoolean() • nextFloat(), nextDouble() • nextShort(), nextInt(), nextLong() • next() - reads next String • Corresponding methods to check and see if another value is in stream… • i.e. hasNextInt() • http://java.sun.com/j2se/1.5.0/docs/api/java/util/Scanner.html
Console I/O in Java • Java port of our C++ example… import java.util.Scanner; publicclass ConsoleIO { publicstaticvoid main(String[] args) { Scanner console = new Scanner(System.in); System.out.print("What do you want to buy: "); String s = console.next(); System.out.print("How many: "); int n = console.nextInt(); System.out.println("You want " + n + " " + s); } }
File Input in C++ • Example reading integers from a file… #include<fstream> #include<iostream> usingnamespace std; intmain() { int num; fstream in("file.txt", ios::in); while(in >> num) { cout << "read " << num << endl; } in.close(); return 0; }
File Input in Java • Java port of C++ example… import java.io.File; import java.util.Scanner; publicclass FileIO { publicstaticvoid main(String[] args) { try { Scanner in = new Scanner(new File("file.txt")); while(in.hasNextInt()) { System.out.println("read " + in.nextInt()); } in.close(); } catch (Exception e) { e.printStackTrace(); } } }
File Output in C++ • Output to a file in C++… #include<fstream> #include<iostream> usingnamespace std; intmain() { fstream out("file.txt", ios::out); for(int i = 0; i < 10; i++) { out << i << endl; } out.close(); return 0; }
File Output in Java • Java port of C++ example (PrintStream is same class as System.out, so same methods available)… import java.io.PrintStream; publicclass FileIO { publicstaticvoid main(String[] args) { try { PrintStream out = new PrintStream("file.txt"); for(int i = 0; i < 10; i++) { out.println(i); } out.close(); } catch (Exception e) { e.printStackTrace(); } } }
Exercises • Write an Direction enum for the 4 cardinal directions (North, South, East & West). Then write (in another class) a walk method which takes a Direction enum as an argument • Write a class which reads numbers from one file (the 1st command line arg) and writes out each number squared to a second file (the 2nd command line arg)
C++ Templates • C++ allows us to define generic (template) types which can hold whatever type we specify • Frequently people include the C file at the end of the header file • Gotchas… • Compilation • Mixing templated and non-templated code • Spaces with respect to nested templates
C++ Templates • Example node header file… #ifndef _NODE_H_ #define _NODE_H_ template <classT> classNode { private: Tm_data; public: Node(T data); TGetData() const; }; #include"node.C" #endif
C++ Templates • Corresponding implementation in C++ #ifndef _NODE_C_ #define _NODE_C_ #include"Node.H" template <classT> Node<T>::Node(T data) { this->m_data = data; } template <classT> TNode<T>::GetData() const { returnthis->m_data; } #endif
C++ Templates • Example usage… #include<iostream> #include<string> #include"node.H" usingnamespace std; intmain() { Node<string> n("hamburger"); cout << n.GetData() << endl; return 0; }
Java Generics • Java introduced Generics in Java 5 which are similar to C++’s templates • Syntax is a bit less burdensome • Parts of the Java SE API are capable of using generics • Prior to Java 5, all of these things stored Object’s and were thus capable of storing any object what-so-ever (as it had to be a subclass of Object)
Java Generics • Port of templated Node class to Java… publicclass Node<T> { private T data; Node(T data) { this.data = data; } T getData() { returnthis.data; } }
Java Generics • Example driver… publicclass NodeTest { publicstaticvoid main(String[] args) { Node<String> n = new Node<String>("hamburger"); System.out.println(n.getData()); } }
Generics Gotchas • Cannot use primitive types as the generic type… • In C++ this is completely valid… • In Java, this is not… • We can still store an int, char, float or boolean, but we need to do something slightly different Node<int> n(516); Node<int> n = new Node<int>(516);
Wrapper Classes • For each of the primitive types, Java provides a “wrapper class” • Wrapper class is an object which stores the given primitive type… • Integer – stores an int primitive • Boolean – stores a boolean primitive • Float – stores a float primitive • Etc… • We can declare our generic type to be of the wrapper class type
Wrapper Classes & Generics • Example using the Integer wrapper class to store ints • In Java 5, primitives are automatically converted to and from the corresponding wrapper type as needed • This is known as auto boxing/un-boxing publicclass NodeTest { publicstaticvoid main(String[] args) { Node<Integer> n = new Node<Integer>(516); System.out.println(n.getData()); } }
Generics Gotchas • In C++, you can create an array of a templates type… • Java does not permit this, you end up with a compiler error… template <classT> void Node<T>::SomeTemplatedFunction() { T array[10]; } void SomeTemplatedFunction() { T array[10]; }
Generics Bounding • Allow a method to take anything that subclasses T • Allow only classes that implement the Comparable interface… void foo(Collection<? extends T> items) { /* ... */ } void foo(Collection<? extends Comparable> items) { /* ... */ }
C++ STL • The C++ STL provides numerous built-in data types that are used by programmers • Some of the more commonly used ones are… • vector • iterators • deque • list • map
Java SE API • One thing you will notice about Java is that the Java SE API is huge • Java SE 6 has Nearly 3800 classes, interfaces & enums in the built-in API • Bookmark the javadocs, they are your friend… • http://java.sun.com/javase/6/docs/api/
Java Collections Framework • Java has a robust collections (containers) framework • With Java 5, these have been generified to support arbitrary types with strong typing • There are interfaces provided for many ADTs • List, Set, Map, etc… • There are also multiple concrete implementations of many of the data structures, each providing their own advantages… • ArrayList, LinkedList, Stack, Vector, etc… • Typically you instantiate a concrete implementation, but maintain a handle on it based on its interface • Interface<type> = ImplementationOfInterface<type>();
C++ Vector • Sample C++ Vector usage… #include<vector> #include<iostream> usingnamespace std; intmain() { vector<int> v; v.push_back(1); v.push_back(20); v.push_back(2009); for(int i = 0, n = v.size(); i < n; i++) { cout << v[i] << endl; } for(vector<int>::iterator itr = v.begin(); itr != v.end(); itr++) { cout << *itr << endl; } return 0; }