Presentation is loading. Please wait.

Presentation is loading. Please wait.

Generics, Lambdas, Reflections

Similar presentations


Presentation on theme: "Generics, Lambdas, Reflections"— Presentation transcript:

1 Generics, Lambdas, Reflections
Lecture 6 Advanced Java Generics, Lambdas, Reflections

2 Type Safety in Java Type safety:
Java is a statically typed language. Every variable must have a type at compile time Type safety: Making sure the object referenced by a variable is of a type compatible with the type of the variable Object type can be one of three options: The type of the object is equal to the type of its variable Person person = new Person(); The type of the object extends the type of its variable Person person = new Man(); //where Person is a Class The type of the object implements the type of its variable Person person = new Man(); //where Person is an Interface In Java, the compiler verifies type safety for us, and throws errors during compilation as needed

3 Type safety But sometimes the language constructs weakens the type information, to enable more generic code. Example:

4 Type safety Example: The get() and add()methods of List work with Object (a super class of every class). The type of objects in the List is not known at compile time to enable the reusability of List. We cannot know if all the types in the List are equal.

5 Generics Similar to C++’s templates, but simpler.
Like in C++ Java's generics can be defined on methods, classes and interfaces. Code example: public class Pair<X, Y> { private X x, private Y y; public Pair(X x, Y y){ this.x = x; this.y = y; } public X getX(){ return x;} }

6

7 Generics and Primitives
Generics in Java do not allow the use of primitives! ArrayList<int> intArrayList; //compilation error! ArrayList<Integer> integerArrayList; //works fine! Solution: autoboxing and unboxing A convenient way to auto transform primitive data type to it’s corresponding java wrapper classes and vice versa Helpful in reducing code size – no need to convert primitive type to object type explicitly!

8 Java Wrapper Classes Each primitive type in Java has a corresponding wrapper class type Wrapper classes are objects that wrap the primitive type Wrapper Classes vs Primitive Types: Primitive types cannot be null while wrapper classes can be null Wrapper classes can be used in generics, primitive types cannot

9 Autoboxing and Unboxing
Autoboxing is done on primitive value in these cases: Passed as a parameter to a method that expects an object of the corresponding wrapper class Example: a method with Integer argument can be called by passing int, Java compiler will do the conversion of int to Integer. Assigned to a variable of the corresponding wrapper class Example, assigning a long variable to a Long object Unboxing is done on wrapper classes in these cases: Passed as a parameter to a method that expects a value of the corresponding primitive type Example: a method with int argument can be called by passing Integer, Java compiler will do the conversion of Integer to int. Assigned to a variable of the corresponding primitive type Example, assigning a Long object to a long primitive

10 Autoboxing and Unboxing - Examples
In this autoboxing example, the added values are of primitive type int, while the list contains objects of type Integer: In this unboxing example, the values retrieved from the container are of an Integer object, while the summed up result of a primitive type of int: 1 2 3 List<Integer> li = new ArrayList<>(); for (int i = 1; i < 50; i += 2) li.add(i); public static int sumEven(List<Integer> li) { int sum = 0; for (Integer i: li) if (i % 2 == 0) sum += i; return sum; } How is this done? While compiling the compiler converts: Autoboxing example: line 3 to li.add(Integer.valueOf(i)); Unboxing example: line 5 to sum += i.intValue();

11 Generic Interfaces – Java 5
Generic interface are exactly the same as generic classes Syntax Example: public interface Person<T, E> { public Person(T age, E weight); public T getAge(); public E getWeight(); }

12 Generic Method

13 Some comments A generic type argument can have a lower bound type defined using the extend word. Comparable is an interface which defines a single method int compareTo(T arg) All java's wrapper types implements this interface. 

14 Generic Methods – Java 8+
public class Person { private int age; private int weight; public Person(int age, int weight) { this.age = age; this.weight = weight; } public int getAge() { return age; public int getWeight() { return weight; Given an array of Person objects what is the maximal object? Is it the heaviest Person? Maybe the oldest Person? It depends on how you want to compare the Person!

15 Generic Methods Implementation
public static <T> T max(T[] array, Comparator<T> comparator) { if (array.length == 0) throw new IllegalArgumentException("empty array"); int maxIndex=0; for (int i=1; i<array.length; i++) if (comparator.compare(array[maxIndex], array[i]) < 0) maxIndex = i; return array[maxIndex]; } Note the <T> in front of the method signature which parametrize the method.

16 Using Generic Methods public static class PersonComparatorByAge implements Comparator<Person> { public int compare(Person o1, Person o2) { return o1.getAge() - o2.getAge(); } public static class PersonComparatorByWeight implements Comparator<Person> { return o1.getWeight() - o2.getWeight(); public static void main(String[] args) { Person[] Persons = {new Person(7,50), new Person(9,200), new Person(3,100)}; System.out.println(max(Persons, new PersonComparatorByWeight ()).getWeight()); // 200 System.out.println(max(Persons, new PersonComparatorByAge()).getAge()); // 9

17 Generic Limitations Not being able to work on primitive types.
Generics are "erased" at runtime: At complie time the compiler knows that List<Integer> is not a List<String>. At run time, both of them looks like List<Object>. This limitation can be seen in the following code: This won’t compile  as the compiler knows that at runtime the defined methods has the same signature.

18 Generic Limitations More on “type erasure”:
You can do: List<String> list; ((List)list).add(new Object()); An error will be thrown only when you get the value of a String. Arrays of generic types cannot be instantiated directly i.e., the following will not compile: But can be worked around this way:  pairs is an array of Pair without any additional generic type information.

19 Wildcards Pair<Object,Object> is not a super-class of Pair<Integer,Integer>. Pair<?,?> is a super-class of Pair<Integer,Integer>. Bad example: This method accepts only Collection<Object>

20 Wildcards (more at: https://docs. oracle
Good example: This method accepts any Collection However The compiler does not allow to add() because the inner type is unknown at compile time.

21 Default methods in interface
A default method is a method which implemented directly in an interface. It provides default implementation for classes implementing that interface. Example: isEmpty() method in Stack.

22 Default methods in interface: motivation

23 Default Methods – Java 8+
Allows us to implement methods directly in the interface! We add default keyword before the access modifier of the method we wish to implement. This implementation will be the default implementation for all classes implementing this interface, and did not override it. Default methods tutorial:

24 Default Method - Example
interface Stack<E> { void push(E something); E pop(); int size(); boolean isEmpty(); } interface Stack<E> { void push(E something); E pop(); int size(); default boolean isEmpty(){ return (size())==0); } Implementation of isEmpty()wil act as the default implementation for all implementing classes, as long as the class does not overwrite the implementation.

25 Abstract classes vs. interfaces
Another solution: declare an abstract AbstractStack class which implements the Stack interface and the method isEmpty(). BUT: you can only derive from one parent class in Java. This will enforce classes to derive from this class, which can be very constraining. Since in Java a class can implement a number of interfaces - the default method does not enforce such constraints.

26 Anonymous classes Anonymous classes enable you to make the code shorter. They enable you to declare and instantiate a class at the same time. They are like local classes except that they do not have a name. Use them if you need to use a local class only once.

27 Anonymous classes (motivation)
We had this example before: What if a class is not Comparable or has more than one way to compare objects?

28 Anonymous classes (motivation)

29 Anonymous classes (motivation)

30 Anonymous classes (now code..)

31 Anonymous classes – motivation for Lambdas
If the implementation of your anonymous class is very simple. The code becomes cumbersome (a lot of “wrapping” for a little bit of code), and sometimes unclear. A common example is as an interface that contains only one method. In this case we’re trying to pass functionality as an argument. Just as in our Comparator example. Lambda expressions enable you to do this compactly.

32 Examples The general syntax is (args...) -> { body }
If you just want to return something you can write: (args...) -> ... (int a, int b) -> {  return a + b; } () -> System.out.println("Hello World"); (String s) -> { System.out.println(s); } () -> 42 () -> { return }; Guide:

33 Anonymous classes – motivation for Lambdas
Lambdas example:

34 Persons Example – Using Lambda
public static void main(String[] args) { Person[] Persons = {new Person(7,50), new Person(9,200), new Person(3,100)}; System.out.println(max(Persons, (Person o1, Person o2) -> { return o1.getAge() - o2.getAge(); }).getAge()); return o1.getWeight() - o2.getWeight(); }).getWeight()); } Anonymous Classes: public static void main(String[] args) { Person[] Persons = {new Person(7,50), new Person(9,200), new Person(3,100)}; System.out.println(max(Persons, new Comparator<Person>(){ public int compare(Person o1, Person o2) { return o1.getAge() - o2.getAge(); } }).getAge()); // prints 9 return o1.getWeight() - o2.getWeight(); }).getWeight()); // prints 200 }

35 Reflection – class object
There is a special class called Class. Instances of Class represent classes and interfaces in a running Java application. Class has no public constructor. Instead, Class objects are constructed automatically by the JVM.

36 Reflection – class object
The static class property: for a class A, A.class returns an object of the type Class. The method getClass(): for an object a of type A, a.getClass() returns an object of the type Class. getName() - corresponding class name isAssignableFrom(Class) -  the calling Class represents a superclass or superinterface of the class represented by the given Class object (see example)

37

38 Another example

39

40 Output:


Download ppt "Generics, Lambdas, Reflections"

Similar presentations


Ads by Google