Loading presentation...

Present Remotely

Send the link below via email or IM


Present to your audience

Start remote presentation

  • Invited audience members will follow you as you navigate and present
  • People invited to a presentation do not need a Prezi account
  • This link expires 10 minutes after you close the presentation
  • A maximum of 30 users can follow your presentation
  • Learn more about this feature in our knowledge base article

Do you really want to delete this prezi?

Neither you, nor the coeditors you shared it with will be able to recover it again.


Make your likes visible on Facebook?

Connect your Facebook account to Prezi and let your likes appear on your timeline.
You can change this under Settings & Account at any time.

No, thanks

Generics of Java

No description

William Price

on 25 October 2012

Comments (0)

Please log in to add your comment.

Report abuse

Transcript of Generics of Java

Generics<Java> numList.add(new Double(3.14));
Integer first = intList.get(0); List<Integer> intList = new ArrayList<>();
List<Number> numList; error: inconvertible types
required List<Number>, found List<Integer> Integer Number

Integer[] Number[]

List Collection

List<Integer> Collection<Integer>

List<Integer> Collection<Number>

List<Integer> List<Number> IFruit banana = new Banana();

List redFruits = new ArrayList();
redFruits.add(new Apple());
redFruits.add(new Cherry());

Map fruitsByColor = new HashMap();

fruitsByColor.put(Color.RED, redFruits);
fruitsByColor.put(Color.YELLOW, banana); static type safety? IFruit List Java 2 SE ≤ 1.4.x Map.put(Object key, Object value)
no warnings, no problems
until . . . much later: Color[] colors = ...;
for (int i=0; i<colors.length; i++) {
List fruits =
(List) fruitsByColor.get(colors[i]);
} ClassCastException William R. Price Software Architect
PROS, Inc. good luck finding the culprit. same method

same class

same package

small project

with moderate complexity (depends on the scope of the object) so what did we do? Map fruitsByColor = // Color->List
new HashMap();

List sameColor =
(List /*of Fruit*/)
fruitsByColor.get(Color.RED); We added clutter. banana was an IFruit; IFruit List Easy. Not too bad. Scope is growing. Tougher. Errrgh. our earlier example IFruit banana = ...;
List<IFruit> redFruits = ...;

Map<Color, List<IFruit>> fruitsByColor =
new HashMap<Color, List<IFruit>>();

fruitsByColor.put(Color.RED, redFruits);
fruitsByColor.put(Color.YELLOW, banana);

List<IFruits> sameColorFruits =
fruitsByColor.get(Color.GREEN); no cast
required Sun gave us "Java 5" circa 2004 J2SE 1.5 and added a little
"syntactic sugar" List


Comparator List<E>


Comparator<T> List<E> List of "E" public interface List <E> {
} class Foo {
private List<String> barNames;
} type parameter type argument (specifies a particular type) (placeholder; typically a single, uppercase letter) think back to Java2 SE ≤ 1.4.x compiler error { still valid "designed to be object oriented from the ground up." - Gosling & McGilton Sun Microsystems. (1996). The Java Language Environment [White Paper].
Retrieved from http://www.oracle.com/technetwork/java/index-136113.html "Java" and the Java logo(s) are registered trademarks of Oracle Corporation. single-rooted hierarchy everything* inherits from Object *except primitives and does OOP encourage
reusable design? strict compiler, static type checks
guarded casts at runtime Supporting broad problem domains requires a solution to make fewer assumptions. you can safely assume: 1. external data is: Object (or primitives) the end. Additional restrictions (Serializable,
Comparable, your own custom class, etc.) would forbid one or more potential use cases. Yes, that's often impractical. ... but sometimes necessary import java.util.*; Collection
Iterator One of the most
frequently used
libraries operates
almost exclusively
on Object. Documentation, but not a real safeguard. recognized by
the compiler Map<K,V> public interface Map <K,V> {
V get(Object key);
V put(K key, V value);
} NOT limited to one
type parameter return types also: field & local variable types use as... method parameters Nesting parameterized types class MultiValueMap <K,V> {
private Map<K, Set<V>> map;
} Design tip: keep it simple! Map<ZipCode,
Set<House>>>> favor domain-specific
data structures List<Map<String,String>> foo =
new ArrayList<Map<String,String>>(); "the diamond" Java 5 & 6 List<Map<String,String>> foo =
new ArrayList<>(); Java 7+ Smarter compiler. Less clutter. Did you think generics are only for classes & interfaces? <T> Set<T> extractUnique(
Collection<T> anyGroup) {

return new HashSet<T>(anyGroup);

} Generic method! class SortOrder {
boolean isAscending;

<T> SortOrder(T first,
T next,
Comparator<T> relation) {

int direction =
relation.compare(first, next);
if (direction == 0) {
throw new IllegalStateException(...);
isAscending = (direction < 0);
} Generic
constructor! Type parameters declared at method/constructor
scope are independent of type parameters at the
class level (if any). what's in it for me? Okay, there's new syntax. So, generics are really only for collections? a common perception, but the Collections library is
a perfect use case! define APIs using the
least-specific types possible generics make the API transparent relinquish control of the
specific implementation types reusable components: How? Object is insufficient;
my use case requires
something more specific if <T> == any class or interface,
only Object methods are common Bound <T>
with Constraints <T>

<T extends Number>

<T super Number> Object Number Integer T = interface
NumericList <N extends Number>
extends List<N> {

N min();
N max();
double sum();
double mean();
double median();
double standardDeviation();

} use bounds to specialize legal only in type
parameter definitions type parameters are not covariant is a Integer[] intObjArr = new Integer[2];
Number[] numObjArr = intObjArr; // same obj
intObjArr[0] = new Integer(42);
numObjArr[1] = new Double(3.14); // compiles ArrayStoreException prevents possible
here numList = intList; error: incompatible types
required List<Number>, found List<Integer> numList = (List<Number>) intList; because, unlike Arrays,
there is no runtime
check there Why not? Type Erasure something called a little by 2004 there was a METRIC TONNE of 3rd-party Java code [citation needed] Sun had options reification type erasure runtime type info
distinct, new APIs
force immediate choice compile-time only
reuse existing APIs
supports migration when you code: interface Map<K,V> {
V put (K key,
V val);
V get (Object key);

Map<String,String> m =
new HashMap<>();
m.put("foo", "bar");
String bar =

interface NumericPair
<N extends Number> {

void set(N n1,
N n2);
} interface Map {
Object put (Object key,
Object val);
Object get (Object key);

Map m =
new HashMap();
m.put("foo", "bar");
String bar =
(String) m.get("foo");

interface NumericPair {

void set(Number n1,
Number n2);
} the compiler emits: exactly what
you expect
in Java 1.4 bridge methods to
support polymorphism
(not shown) + consequences of
type erasure Every class or interface is
represented in bytecode
exactly ONCE C++ templates emit variants C# generics are reified, with access
to runtime type via reflection static fields & methods in Java
are still shared by all instances
regardless of parameterization Parameterized types are always reference types List<int> not allowed List<Integer> intList;
intList.add(42); // box int->Integer
int foo = intList.get(0); // unboxed remember: autoboxing creates heap objects,
beware NPE (e.g. list contains null) The type variable (<T>) is
no more than a placeholder class GenericFactory <T> {

T newInstance() {
return new T();

} static <E> E[] toArray(E e1,
E e2) {
E[] arr = new E[2];
arr[0] = e1; arr[1] = e2;
return arr;
} return T.class.newInstance(); can't reflect on T
can't instanceof T can't create
generic arrays Parameterized type is
not retained in arrays List[]


List<?>[] wildcard "some type" Type parameters always
represent ONE type List<?>
List<? extends Number>
List<? super Integer> Use '?' when you don't know
or truly don't care, ever.

The '?' wildcard should be rare and often an exceptional case. Generics do not preserve
type safety in serialized form! byte[] stream = serialize(List<T>);
List<?> raw = (List<?>) deserialize(stream);
List<T> typed = (List<T>) raw; Unchecked Cast Silence with -Xlint or @SuppressWarnings, but the compiler is correct: NOT safe!
Full transcript