Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
CMPE212 – Section 001 - Reminders • Assignment 3 on Encapsulation due Friday. • You know everything you need to know for Assignment 4, as well. • Quiz 2 this week in the lab. Winter 2017 CMPE212 - Prof. McLeod 1 Today • Generic wildcards. • Generic Factory Demo. • Next topic (we won’t have time today): Lambda Functions. Winter 2017 CMPE212 - Prof. McLeod 2 Generic Methods and Java 7 • Constructors can also be generic. Even in a nongeneric class. • And you can use type inference as demonstrated in TestUtility.java: midStrings = Utility.getMidpoint(strings); • Same as: midStrings = Utility.<String>getMidpoint(strings); Winter 2017 CMPE212 - Prof. McLeod 3 Generics & Backwards Compatibility • Generic code can make for very versatile programs that can be applied to a range of objects – saving you a great deal of boring coding work. • But, generic code will not work easily with preJava 5.0 code. • And, of course, the Java 7 type inference stunts will not work with pre-Java 7.0 code. • Generics are a bit like Templates in C++ and C#, but are implemented in a different way. Winter 2017 CMPE212 - Prof. McLeod 4 Generics in Modern Java • This discussion assumes newer versions of Java (>= 1.7) • Generics allow you to write powerful, compact code that can work with many object types. Particularly useful with hierarchies. • Type inference, bounding, wildcards and the use of the Class<T> object adds power and convenience. • Let’s experiment! Winter 2017 CMPE212 - Prof. McLeod 5 First Demo • TestWildcards.java • Uses the Person hierarchy from last week. • Plays with wildcards, bounded generic methods, and how to create an array of generic classes. Winter 2017 CMPE212 - Prof. McLeod 6 Summary: Wildcards • If Child is a subclass of Parent then this works: Parent obj = new Child(); • But this will not work: ArrayList<Parent> alObj = ArrayList<Child>(); • This will work: ArrayList<?> alObj = ArrayList<Child>(); • A “wildcard” is the ? within the < >. • A wildcard can provide a super type generic class for other generic classes. Winter 2017 CMPE212 - Prof. McLeod 7 Summary: Wildcards, Cont. • You can bind a wildcard to classes that extend other classes using the extends keyword. For example: ArrayList<? extends Person> db • db can be assigned to an object of type ArrayList<Person>, ArrayList<Student> or ArrayList<Professor>. Winter 2017 CMPE212 - Prof. McLeod 8 Summary: Wildcards, Cont. • However, a generic typed with a wildcard is not mutable. • You can get around this using generic methods without the wildcard. But: – This is more restrictive and potentially “brittle”. – Avoid casting using the generic type. This may lead to “Unchecked Casts” which reduces the type safety of the generic method. (Hint: use @SuppressWarnings("unchecked")) – Use of Class<T> may be a way around this problem. Winter 2017 CMPE212 - Prof. McLeod 9 Summary: Wildcards, Cont. • ArrayList<?>[] is the only possible type that allows the creation of an array of generic classes. • But, why would you want to? • Easier to create an ArrayList of ArrayLists, for example. Winter 2017 CMPE212 - Prof. McLeod 10 Aside – Lower Bound for Wildcard • In ? extends T the extends keyword represents an upper bound for the type – T or any sub-type of T. • You can also use super as in ? super T which provides a lower bound for the type – T or any super-type of T. Winter 2017 CMPE212 - Prof. McLeod 11 Second Demo • GenericFactoryDemo.java • Can a generic method instantiate an array of type T? • Can a generic method instantiate a generic class typed to T? • Can a generic method instantiate objects of type T? If so, how? Winter 2017 CMPE212 - Prof. McLeod 12 Summary: Generic Factories • Factory methods generate objects, or more specifically, collections of objects. How can you make these methods non- type-specific? • You cannot create an array of type T in a generic method unless you can tolerate an unchecked cast to T[]. • You cannot instantiate objects of type T in a generic method directly. Winter 2017 CMPE212 - Prof. McLeod 13 The Class<T> Object • You can pass a type into a method using a Class<T> object. • The Object class contains a method .getClass() that returns a Class<T> object. Or you can just use the .class literal on a type. For example: String aString = "Hello!"; System.out.println(aString.getClass()); System.out.println(String.class); • Shows: class java.lang.String class java.lang.String Winter 2017 CMPE212 - Prof. McLeod 14 The Class<T> Object, Cont. • See the API for lots of methods belonging to this Object. Useful for determining all kinds of information about a type or an instance. • Also has a method called .newInstance() that returns an instance of type T. • This method can only invoke the default constructor of the type T. So, you must use mutators to set attributes. But now you have an instance to work with! Winter 2017 CMPE212 - Prof. McLeod 15 From Before: Anonymous Class Example public class AnonymousClassDemo { public static void main(String[] args) { MessageSender ms = new MessageSender() { public void sendGreeting (String name) { System.out.println("Hello " + name + "!"); } // end sendGreeting }; // end ms, NOTE ";"! ms.sendGreeting(“Steve"); } // end main } // end AnonymousClassDemo Winter 2017 CMPE212 - Prof. McLeod 16 Anonymous Class Example - Cont. • MessageSender is an interface, not an Object: public interface MessageSender { void sendGreeting (String name); } // end MessageSender interface • Java 8 now has a very tidy solution to using messy anonymous classes – Lambda Functions: Winter 2017 CMPE212 - Prof. McLeod 17 The Lambda Version public class LambdaDemo { public static void main(String[] args) { MessageSender ms = name -> System.out.println("Hello " + name); ms.sendGreeting("Steve"); } // end main } // end LambdaDemo Winter 2017 CMPE212 - Prof. McLeod 18 A Lambda Function • Kind of like an “anonymous method”. • Syntax: – Parameters for the method first. No parameters, use { }, one parameter by itself – no brackets required, more than one use (a, b, etc.). No types required. – Then the fancy -> “arrow”. – Then the method body. Put more than one statement inside { }. • Can even define an inner interface: Winter 2017 CMPE212 - Prof. McLeod 19 The Lambda Version, Cont. public class LambdaDemoAgain { interface MessageSender { void sendGreeting(String aName); } // end MessageSender interface public static void main(String[] args) { MessageSender ms = name -> System.out.println("Hello " + name); ms.sendGreeting("Steve"); } // end main } // end LambdaDemoAgain Winter 2017 CMPE212 - Prof. McLeod 20 Lambda Functions, Cont. • Note how the abstract method in the interface determines the structure of the lambda function – the parameter and parameter type, the method name and the lack of a return statement. • These functions could be useful! (Especially when attaching events to GUI components.) • Only certain interface structures can be used. Winter 2017 CMPE212 - Prof. McLeod 21