at some point you've likely heard about
Java generics generics were introduced
in the Java language in Java 5 in the
next few videos we're gonna take a deep
dive into what generics are how to use
them and ultimately how to create our
own Java generics the idea is this we
have a class we want to use for multiple
types we might have a listen source
numbers elicits or strings Alyssa's
source sprites or any other specific
class we want to write this list once
and use it for all object types let's
start with a hypothetical video game in
the game we'll have a list of sprites we
want to draw though our screen our code
updates the positions of the sprites in
each game loop we draw the sprites and
repeat so far if we wanted a list of
instances we needed to use an array we
define our sprite and add it to our
array by location this gets a bit tricky
because we need to know the number of
sprites in advance when we declare our
array or limit it to a set upper bound
number and keep track of the number in
the array there's no clear way to add or
remove sprites either for example if we
deleted a sprite from the middle of our
array we'd have to constantly shift the
array to delete sprites or we could add
a flag stating the sprite was active
this is all doable but it's not clean we
could create a linked list class to
manage our sprites and create methods
for adding and removing sprites this
would solve some of the problems but not
all what happens when we have another
list with similar requirements but it's
a list of something else like an
inventory list for our character
completely different objects in the list
but we still need an add and remove
methods so we could create another class
almost exactly the same code but this
time it uses inventory objects instead
of sprites that sucks when we repeat
code that's a sign that we're doing
something wrong another option might be
to make the class hold only instances of
objects then we can reuse a class for
anything the problem with that is we now
have to cast our objects back to the
class we want in order to use it
that's too much casting back and forth
and makes for ugly code what
if we accidentally add an inventory
object or a sprite list code goes boom
and we won't know it until we run the
program and we won't know where the
incorrect ad happens we'll add the
object successfully and then we'll crash
way later when we try to use the wrong
object the problem here is we don't have
type safety we can't guarantee the types
entering our list or coming back out we
are casting and praying and that's not
good
this was the solution before Java 5
luckily Java provides a large group of
collection classes that solve all of our
problems we won't go in those classes in
depth until another tutorial but right
now we'll stick with the ArrayList class
the ArrayList class is a collection
class that holds a dynamic array of some
objects what objects you ask well we
need to learn a little bit about the
generics before we can go into detail
about the collection classes so what is
a generic a generic is a class that acts
like a template for creating classes in
this case we define how the list works
without stating what the class is the
list holds we'll have add and remove
methods we won't say what class we're
adding and removing until we define the
instance once we instantiate our class
will tell us the type our list works
with no other type is allowed using a
generic class gives us type safety what
appears to happen behind the scenes is
Java we'll take our template and fill in
the classes we want and instantiate the
class using the type we pass to it
that's why you'll sometimes hear
generics referred to as templates I do
want to be clear however Java is not
using templates like C++ in reality Java
is just performing type checking for you
the code we saw before Java 5 looked
like this we had an ArrayList which we
could add any class instance we add
calling the add method and we get things
back out we add we get an instance typed
as object to use a class we'd cast it
back to the class we need in this object
list we can pull out items but we don't
know what kind of item cast objects
inside all this to the wrong type or put
the incorrect instance type and things
go boom at runtime
we need to tell Java what our ArrayList
holds so we can perform checks at
compile time we define our ArrayList
like this notice we're specifying the
type our ArrayList holds inside the
angle brackets this means when we go to
add sprites to the list using the add
method the add method will only accept
sprites the right-hand side of the
statement instantiates our ArrayList so
we need the parentheses like we would
for any class of saturation this is how
now an ArrayList that works with sprites
if we tried to add a string instance to
the list
it wouldn't go pile you might have
noticed we're telling Java this
ArrayList holds sprites in the type
declaration and then we're telling Java
again our ArrayList all sprites in the
class and Stan she ation that's annoying
and not necessary Java can figure it out
we can rewrite our instantiation like
this the angle brackets are referred to
as the diamond in Java figures out the
class type through type inference that's
just a fancy way of saying Java can
figure out the type from the left hand
side you're probably thinking hey do we
need this diamond at all Java can tell
from the left hand side we're using a
generic what happens when we do this
we'll get a warning saying the Java file
uses uncheck unsafe operations not a
helpful warning message what's happening
here is Java used to have a class called
ArrayList before they introduced
generics in Java 5 to make things
backward-compatible they introduced
something called raw types raw type is
the class as if the generics were never
introduced since the ArrayList predates
generics the raw type is the class free
Java 5 in the case of our ArrayList we
could do something like this
we can add a string to our sprite list
the class would behave as if we could
store any object in the ArrayList not
good we're back to where we were before
now if we add the type and the diamond
things work as you'd expect adding a
string makes things break this happens
at runtime and that's good we want type
checking when we compile because of this
you never want to use raw types there's
no reason to it's there for backwards
compatibility to all versions of Java
however we do want to make sure that we
use the diamond so the Java knows that
we're working with the parameterised
type not the raw type next you're likely
wondering what's the difference between
a raw type and the parameterised type
what I mean is what is the difference
between the raw type and passing object
as a class list like this well the raw
list doesn't have the generic compile
time checking while the object list
explicitly says we accept any object
that derives from the object class that
might seem like a slight difference but
let's look at it another way if we add
another list like this and then we have
a method in another class for drawing
our sprites that accepts a list called
draw if we define draw like this the
draw method will accept any of the list
we've created here it will treat any
list we pass as a raw type which is a
list of objects however if we define it
like this the draw method will only
compile with the object list and the raw
list it won't compile if we pass the
sprite list of the draw method and for
completeness if we create a draw method
expects only sprite list like this the
method will only work with the raw list
and the sprite list the lesson here is
an object list is a different type from
the sprite list even though sprites are
child classes form objects inheritance
is not supported in generic type
parameters
here's a weird bit if we print out the
class type for each list like this it
will print out this everything is an
ArrayList
we can even test the instances to see if
the class types are equal which I'll
print out is true that means you can do
weird things like this we can create a
sprite list cast it as raw list add a
string and things won't blow up until we
run it however if we try to cast the
sprite list to an ArrayList that holds
objects it won't even compile so what's
happening here I kind of looted to this
when I call generics templates but in
Java they're not really templates
there's two ways you can do generics
first way is the compiler creates a new
version of the class for every type we
wish to create this is code
specialization and a true template the
compiler would be creating a
specialization of every class we wish to
create our code would generate an
compiled code first write list or sprite
ArrayList and generate more code for our
object list and even more code for any
other ArrayList type that we want to
create it's gonna lead to really large
program sizes the other way is three
code sharing basically the compiler
creates one version of our ArrayList in
order to do this Java uses raw types and
then handles all the casting for us it's
much smaller code since there's only one
ArrayList class it's compiled but you
can make things interesting let's see
what that means let's start with the
code that we're using for sprites this
is what Java replaces it with behind the
scenes
that's why when we compared the class
types of the different instances they
all came out the same notice the
ArrayList is converted with raw type and
the cast is added when we get the sprite
out of the list the compiler is only
compiling one ArrayList class it's using
the one with objects that's also why we
can't use primitives we need something
that derives from objects for an
ArrayList we need a Java class at
compile time the casts are added where
they are requested but there are no new
ArrayList types created by the compiler
the same ArrayList code is shared for
all types passed to the ArrayList Java
is adding the cast for you behind the
scenes this cast can be added a compile
time because Java knows what's going in
and out of the list at compile time
runtimes a different story that's why
when we look at the class type of the
instances we get ArrayList for all the
instances the type contained by the
ArrayList is erased and requires
reflection tricks to get the type back
out we'll look into type it Reggie sure
more in the coming tutorials
so that's how generics work in Java we
looked at what generics were how to
instantiate them what are right types
and finally how Java treats generics
behind the scenes the important
takeaways are Java generics allow us to
reuse classes with different types
without sacrificing type safety and
behind the scenes there's still only one
class representing our generic class in
the next video we'll look at creating
our own generic types if you have any
questions Adam in the comments below and
if you got this far hopefully you liked
the video so make sure you like share
and subscribe and with that I'll see you
in the next tutorial