The University of Sydney Page 1 INFO1113 / COMP9003 Object-Oriented Programming Lecture 11 Contents developed by Tyson Thomas The University of Sydney Page 2 Acknowledgement of Country I would like to acknowledge the Traditional Owners of Australia and recognise their continuing connection to land, water and culture. I am currently on the land of the Burramattagal people and pay my respects to their Elders, past, present and emerging. I further acknowledge the Traditional Owners of the country on which you are on and pay respects to their Elders, past, present and future. The University of Sydney Page 3 Reminder – Quiz this week (week 11) – Released on Thursday, 12 May at 23:59 – Due date Friday, 13 May at 23:59 – Quiz duration → 1.5 hours Only one attempt is allowed – Covers week 6 – 10 contents 10 MCQ questions 3 extended response questions – Identify errors – Write code from specification Abstract class, interface, Packaging Generics, Data Structure, Generic Array, Iterator Exception, Enum, JUnit Recursion, Javadoc Anonymous class, Lambda Expression The University of Sydney Page 4 Copyright Warning COMMONWEALTH OF AUSTRALIA Copyright Regulations 1969 WARNING This material has been reproduced and communicated to you by or on behalf of the University of Sydney pursuant to Part VB of the Copyright Act 1968 (the Act). The material in this communication may be subject to copyright under the Act. Any further copying or communication of this material by you may be the subject of copyright protection under the Act. Do not remove this notice. The University of Sydney Page 5 Topics: Part A ● Wildcards ● extends with Wildcard ● super with Wildcard The University of Sydney Page 6 Wildcards We are going back to using generics but we will be exploring the wildcards a little further. Unlike arrays, where we are able to assign types to a variable of an inherited type, Generic types cannot be assigned to a type that specifies a lower bound. The University of Sydney Page 7 Can we do the same with generics The University of Sydney Page 8 Wildcards The answer is No. However, we are able to read super types using wildcards and write to a list knowing its lower bound. The University of Sydney Page 9 class Person { String name; public Person(String name) { this.name = name; } public String toString() { return name; } } class Employee extends Person { int employeeID; public Employee(String name, int employeeID) { super(name); this.employeeID = employeeID; } public String toString() { return “[” + name + “,” + employeeID + “]”; } } public class GenericsWildcard { public static void readPeople(List people) { for(Person p : people) { System.out.println(p); } } public static void main(String[] args) { List employees = new ArrayList(); employees.add(new Employee(“Jeff”, 76559)); employees.add(new Employee(“Alice”, 27584)); employees.add(new Employee(“Kelly”, 4332)); readPeople(employees); } } Wildcards Creating an ArrayList that contains Employee objects. We can see that Employee is a type of Person. The University of Sydney Page 10 Wildcards class Person { String name; public Person(String name) { this.name = name; } public String toString() { return name; } } class Employee extends Person { int employeeID; public Employee(String name, int employeeID) { super(name); this.employeeID = employeeID; } public String toString() { return “[” + name + “,” + employeeID + “]”; } } public class GenericsWildcard { public static void readPeople(List people) { for(Person p : people) { System.out.println(p); } } public static void main(String[] args) { List employees = new ArrayList(); employees.add(new Employee(“Jeff“, 76559)); employees.add(new Employee(“Alice”, 27584)); employees.add(new Employee(“Kelly”, 4332)); readPeople(employees); } } Given the List requires person the compiler will refuse to accept a list that contains a subtype. The University of Sydney Page 11 Wildcards Given some class that utilises generics, we are able to specify a wildcard by using symbol. This will allow the many different types to be associated with the container. Syntax: Type variable; Type variable; Type variable; The University of Sydney Page 12 Wildcards Given some class that utilises generics, we are able to specify a wildcard by using symbol. This will allow the many different types to be associated with the container. Syntax: Type variable; Type variable; Type variable; Example: List list; List people; List employees; The University of Sydney Page 13 Wildcards Given some class that utilises generics, we are able to specify a wildcard by using symbol. This will allow the many different types to be associated with the container. Syntax: Type variable; Type variable; Type variable; Example: List list; List people; List employees; Given an upper bound, any type we retrieve from this collection can be treated as the upper bound. The University of Sydney Page 14 Wildcards Given some class that utilises generics, we are able to specify a wildcard by using symbol. This will allow the many different types to be associated with the container. Syntax: Type variable; Type variable; Type variable; Example: List list; List people; List employees; Given a collection which can contain its lower bound, we can only assume the types we read from this will be of Object but we can add Employee objects to it. The University of Sydney Page 15 Wildcards Given some class that utilises generics, we are able to specify a wildcard by using symbol. This will allow the many different types to be associated with the container. Syntax: Type variable; Type variable; Type variable; Example: List list; List people; List employees; We specified no lower or upper bound, this is a wild card which we can only read from and treat only as an object, The University of Sydney Page 16 So how do we read all the employees The University of Sydney Page 17 Wildcards Let’s fix this class Person { String name; public Person(String name) { this.name = name; } public String toString() { return name; } } class Employee extends Person { int employeeID; public Employee(String name, int employeeID) { super(name); this.employeeID = employeeID; } public String toString() { return “[” + name + “,” + employeeID + “]”; } } public class GenericsWildcard { public static void readPeople(List people) { for(Person p : people) { System.out.println(p); } } public static void main(String[] args) { List employees = new ArrayList(); employees.add(new Employee(“Jeff”, 76559)); employees.add(new Employee(“Alice”, 27584)); employees.add(new Employee(“Kelly”, 4332)); readPeople(employees); } } The University of Sydney Page 18 class Person { String name; public Person(String name) { this.name = name; } public String toString() { return name; } } class Employee extends Person { int employeeID; public Employee(String name, int employeeID) { super(name); this.employeeID = employeeID; } public String toString() { return “[” + name + “,” + employeeID + “]”; } } public class GenericsWildcard { public static void readPeople(List people) { for(Person p : people) { System.out.println(p); } } public static void main(String[] args) { List employees = new ArrayList(); employees.add(new Employee(“Jeff”, 76559)); employees.add(new Employee(“Alice”, 27584)); employees.add(new Employee(“Kelly”, 4332)); readPeople(employees); } } Wildcards Let’s fix this We have used a wildcard and provided an upper bound for the generic. The University of Sydney Page 19 class Person { String name; public Person(String name) { this.name = name; } public String toString() { return name; } } class Employee extends Person { int employeeID; public Employee(String name, int employeeID) { super(name); this.employeeID = employeeID; } public String toString() { return “[” + name + “,” + employeeID + “]”; } } public class GenericsWildcard { public static void readPeople(List people) { for(Person p : people) { System.out.println(p); } } public static void main(String[] args) { List employees = new ArrayList(); employees.add(new Employee(“Jeff”, 76559)); employees.add(new Employee(“Alice”, 27584)); employees.add(new Employee(“Kelly”, 4332)); readPeople(employees); } } Wildcards Let’s fix this Since the upper bound has been specified we are able to treat all object within this list as the upper bound The University of Sydney Page 20 class Person { String name; public Person(String name) { this.name = name; } public String toString() { return name; } } class Employee extends Person { int employeeID; public Employee(String name, int employeeID) { super(name); this.employeeID = employeeID; } public String toString() { return “[” + name + “,” + employeeID + “]”; } } public class GenericsWildcard { public static void readPeople(List people) { for(Person p : people) { System.out.println(p); } } public static void main(String[] args) { List employees = new ArrayList(); employees.add(new Employee(“Jeff”, 20, 76559)); employees.add(new Employee(“Alice”, 20, 27584)); employees.add(new Employee(“Kelly”, 32, 4332)); readPeople(employees); } } Wildcards Let’s fix this > java GenericsWildcard [Jeff,76559] [Alice,27584] [Kelly,4332] The University of Sydney Page 21 Wildcards But what if we have an inheritance hierarchy like so The following can be assigned to: List people = new ArrayList(); List people = new ArrayList(); List people = new ArrayList(); Person Employee Customer The University of Sydney Page 22 Wildcards However, we couldn’t add any objects to the list because we cannot assume what type the variable is bound to. Otherwise we could add Customer to a list that contains Employee or Person objects to Customer lists. The University of Sydney Page 23 Okay, so what about the super keyword The University of Sydney Page 24 Wildcards class Media { String title; public Media(String title) { this.title = title; } } class Book extends Media { int pageCount; public Book(String name, int pageCount) { super(name); this.pageCount = pageCount; } } class Video extends Media { double duration; public Video(String name, double duration) { super(name); this.duration = duration; } } public class GenericWrite { public static void addBook(List media, Book b) { media.add(b); } public static void main(String[] args) { List m = new ArrayList(); List b = new ArrayList(); addBook(m, new Book(“Pride and Prejudice”, 432)); addBook(b, new Book(“War and Peace”, 1225)); } } The University of Sydney Page 25 class Media { String title; public Media(String title) { this.title = title; } } class Book extends Media { int pageCount; public Book(String name, int pageCount) { super(name); this.pageCount = pageCount; } } class Video extends Media { double duration; public Video(String name, double duration) { super(name); this.duration = duration; } } public class GenericWrite { public static void addBook(List media, Book b) { media.add(b); } public static void main(String[] args) { List m = new ArrayList(); List b = new ArrayList(); addBook(m, new Book(“Pride and Prejudice”, 432)); addBook(b, new Book(“War and Peace”, 1225)); } } Wildcards Let’s consider the case where we have two collection types, one contains Media and the other contains Books. The University of Sydney Page 26 class Media { String title; public Media(String tit
le) { this.title = title; } } class Book extends Media { int pageCount; public Book(String name, int pageCount) { super(name); this.pageCount = pageCount; } } class Video extends Media { double duration; public Video(String name, double duration) { super(name); this.duration = duration; } } public class GenericWrite { public static void addBook(List media, Book b) { media.add(b); } public static void main(String[] args) { List m = new ArrayList(); List b = new ArrayList(); addBook(m, new Book(“Pride and Prejudice”, 432)); addBook(b, new Book(“War and Peace”, 1225)); } } Wildcards We want to add Book objects to both lists The University of Sydney Page 27 class Media { String title; public Media(String title) { this.title = title; } } class Book extends Media { int pageCount; public Book(String name, int pageCount) { super(name); this.pageCount = pageCount; } } class Video extends Media { double duration; public Video(String name, double duration) { super(name); this.duration = duration; } } public class GenericWrite { public static void addBook(List media, Book b) { media.add(b); } public static void main(String[] args) { List m = new ArrayList(); List b = new ArrayList(); addBook(m, new Book(“Pride and Prejudice”, 432)); addBook(b, new Book(“War and Peace”, 1225)); } } Wildcards However, the addBook method only accepts a list with the type argument of Media. The University of Sydney Page 28 class Media { String title; public Media(String title) { this.title = title; } } class Book extends Media { int pageCount; public Book(String name, int pageCount) { super(name); this.pageCount = pageCount; } } class Video extends Media { double duration; public Video(String name, double duration) { super(name); this.duration = duration; } } public class GenericWrite { public static void addBook(List media, Book b) { media.add(b); } public static void main(String[] args) { List m = new ArrayList(); List b = new ArrayList(); addBook(m, new Book(“Pride and Prejudice”, 432)); addBook(b, new Book(“War and Peace”, 1225)); } } Wildcards > Javac GenericWrite.java error: incompatible types: List cannot be converted to List addBook(b, new Book(“War and Peace”, 1225)); ^ Note: S me messages have been simplified; recompile with -Xdiags:verbose to get full output 1 error The University of Sydney Page 29 We can specify a lower bound on the list The University of Sydney Page 30 Wildcards class Media { String title; public Media(String title) { this.title = title; } } class Book extends Media { int pageCount; public Book(String name, int pageCount) { super(name); this.pageCount = pageCount; } } class Video extends Media { double duration; public Video(String name, double duration) { super(name); this.duration = duration; } } public class GenericWrite { public static void addBook(List media, Book b) { media.add(b); } public static void main(String[] args) { List m = new ArrayList(); List b = new ArrayList(); addBook(m, new Book(“Pride and Prejudice”, 432)); addBook(b, new Book(“War and Peace”, 1225)); } } The University of Sydney Page 31 class Media { String title; public Media(String title) { this.title = title; } } class Book extends Media { int pageCount; public Book(String name, int pageCount) { super(name); this.pageCount = pageCount; } } class Video extends Media { double duration; public Video(String name, double duration) { super(name); this.duration = duration; } } public class GenericWrite { public static void addBook(List media, Book b) { media.add(b); } public static void main(String[] args) { List m = new ArrayList(); List b = new ArrayList(); addBook(m, new Book(“Pride and Prejudice”, 432)); addBook(b, new Book(“War and Peace”, 1225)); } } Wildcards Given the list must be able to contain a Book we specify parameter to accept any list which can contain Book and its super types. The University of Sydney Page 32 class Media { String title; public Media(String title) { this.title = title; } } class Book extends Media { int pageCount; public Book(String name, int pageCount) { super(name); this.pageCount = pageCount; } } class Video extends Media { double duration; public Video(String name, double duration) { super(name); this.duration = duration; } } public class GenericWrite { public static void addBook(List media, Book b) { media.add(b); } public static void main(String[] args) { List m = new ArrayList(); List b = new ArrayList(); addBook(m, new Book(“Pride and Prejudice”, 432)); addBook(b, new Book(“War and Peace”, 1225)); } } Wildcards We can pass List and List to the addBook method without any compilation error. The University of Sydney Page 33 Wildcards Considering the inheritance heirarchy, we are able to specify the lower bound which can add the lower bound but nothing else. The following can be assigned to: List books = new ArrayList(); List media = new ArrayList(); Media Video Book The University of Sydney Page 34 Wildcards Considering the inheritance heirarchy, we are able to specify the lower bound which can add the lower bound but nothing else. The following can be assigned to: List books = new ArrayList(); List media = new ArrayList(); Media Video Book This can point to a Media list and therefore the list can contain Media types within it, however since it can also point to a Book list, we cannot add a type that isn’t the lower bound. The University of Sydney Page 35 Demo The University of Sydney Page 36 Topics: Part B Debugging at runtime The University of Sydney Page 37 JDB Logic errors are much harder to detect than syntax errors. Within Java, the compiler can display when we have incorrectly written a statement, but it cannot outline if there is an error in our logic, we just see incorrect output. The University of Sydney Page 38 So, how do we break down what is going on The University of Sydney Page 39 JDB The java debugger provides functionality to ● Inspect the current values of local variables ● Stop execution and step through the code ● Inspect object and class instances These simple tools allow you to inspect the state of your program of your choosing and understand where an error has occurred. The University of Sydney Page 40 JDB We can set up breakpoints that allows us to pause execution and inspect the current state of the program. When the program is paused, we can inspect local variables, dump object information, simply print an object value or set a variable to a specific value. Overriding values allows us to check scenarios which may not be easy to replicate. The University of Sydney Page 41 JDB We can set up breakpoints that allows us to pause execution and inspect the current state of the program. When the program is paused, we can inspect local variables, dump object information, simply print an object value or set a variable to a specific value. Overriding values allows us to check scenarios which may not be easy to replicate. We can specify a breakpoint using the commands stop at Example: stop at Program:53 Once it is paused, we can call locals and inspect all local variables to the method Similar to locals but for extracting information from an object. For methods that manipulate properties of an object we can inspect all properties. Similar to dump command but for specific variable, typically calling toString(). For any heavy control flow within the program, we can set the variable’s value. The University of Sydney Page 42 How can we debug our programs The University of Sydney Page 43 JDB So, we will need to ensure your program is compiled with debugging symbols. You can use jdb with a program compiled without debugging symbols but without this information we cannot easily inspect variables. > javac -g MyProgram.java The University of Sydney Page 44 JDB Once compiled, we can start a JDB session and inspect our program. This starts a session, waiting for the user to set up necessary checks and run the program. > jdb MyProgram The University of Sydney Page 45 JDB Once ready, we can set up breakpoints and then inset the program > jdb MyProgram Initializing jdb … > stop at MyProgram:32 Deferring breakpoint MyProgram:32. It will be set after the class is loaded. > run run MyProgram Set uncaught java.lang.Throwable Set deferred uncaught java.lang.Throwable > VM Started: Set deferred breakpoint MyProgram:32 Breakpoint hit: “thread=main”, MyProgram.main(), line=32 bci=6 32 op.execute(“My String!”); main[1] The University of Sydney Page 46 JDB Once ready, we can set up breakpoints and then inset the program > jdb MyProgram Initializing jdb … > stop at MyProgram:32 Deferring breakpoint MyProgram:32. It will be set after the class is loaded. > run run MyProgram Set uncaught java.lang.Throwable Set deferred uncaught java.lang.Throwable > VM Started: Set deferred breakpoint MyProgram:32 Breakpoint hit: “thread=main”, MyProgram.main(), line=32 bci=6 32 op.execute(“My String!”); main[1] Setting a breakpoint on this line The University of Sydney Page 47 JDB Once ready, we can set up breakpoints and then inset the program > jdb MyProgram Initializing jdb … > stop at MyProgram:32 Deferring breakpoint MyProgram:32. It will be set after the class is loaded. > run run MyProgram Set uncaught java.lang.Throwable Set deferred uncaught java.lang.Throwable > VM Started: Set deferred breakpoint MyProgram:32 Breakpoint hit: “thread=main”, MyProgram.main(), line=32 bci=6 32 op.execute(“My String!”); main[1] Setting a breakpoint on this line Running the program The University of Sydney Page 48 JDB Once ready, we can set up breakpoints and then inset the program > jdb MyProgram Initializing jdb … > stop at MyProgram:32 Deferring breakpoint MyProgram:32. It will be set after the class is loaded. > run run MyProgram Set uncaught java.lang.Throwable Set deferred uncaught java.lang.Throwable > VM Started: Set deferred breakpoint MyProgram:32 Breakpoint hit: “thread=main”, MyProgram.main(), line=32 bci=6 32 op.execute(“My String!”); main[1] Setting a breakpoint on this line Running the program Hit breakpoint, ready to inspect the program state. The University of Sydney Page 49 Let’s debug a program The University of Sydney Page 50 JDB Applications typically run for as long as they can (Webservers) so allow for functionality that allows us to inspect a currently running application gives this the opportunity to debug live programs. This kind of interactions is what allows the programmer to debug programs requiring user input. The University of Sydney Page 51 JDB When running your program, we can set the virtual machine to allow debug and open a port for JDB to connect to. Open up another window and use the following command. JDB will connect to the open session and interact with this. > java -Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n MyProgram > jdb –attach 8000 The University of Sydney Page 52 JDB When running your program, we can set the virtual machine to allow debug and open a port for JDB to connect to. Open up another window and use the following command. JDB will connect to the open session and interact with this. > java -Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n MyProgram We have specified the socket the jdwp server is listening on and the port jdb will connect to. > jdb –attach 8000 The University of Sydney Page 53 Quick demo! The University of Sydney Page 54 See you next time!