Generics In Java - Full Simple Tutorial
Summary
TLDRこのビデオでは、Javaのジェネリクスについて徹底解説します。ジェネリクスが初めての人にとっては、Tや?、<、>などの記号が混乱を招くかもしれませんが、ビデオの終わりには、ジェネリクスが何であるか、なぜ存在するのか、どのように役立つのか、そしてどのように自分のプログラムで使用できるのかを正確に理解できるようになります。ジェネリクスがJava開発者が以前直面していた問題をどのように解決するのか、そして型安全性を保ちながら様々な型に対応できるクラスを作成する方法を、簡潔かつ理解しやすい方法で共有します。
Takeaways
- 👥 Before generics existed in Java, developers had to duplicate code across multiple classes to support different data types
- 🌟 Generics provide the ability to declare type parameters (like T) so you can make a class or method work with many data types
- ⚙️ To use a generic class, you specify the type parameter in angle brackets (<>): Printer<Integer>
- 🔎 The T type parameter in a generic class represents the data type that class will work with
- 💡 Generics promote type safety because at compile time you'll know the types that will be used
- 📦 Java's collections framework (like ArrayList) uses generics extensively to define types for lists
- 🧩 You can constrain generics with extends to narrow which types can be passed in
- ☕️ In addition to generic classes, you can have generic methods by putting type parameters on the method signature
- 🎯 Wildcards (?) allow you to define methods or fields that can work with unknown generic types
- 🎓 By the end of the video you should understand the motivation, syntax and many applications for generics in Java
Q & A
ジェネリクスとは何ですか?
-ジェネリクスは、複数のデータ型で機能できるクラスやメソッドを作成するための機能です。1つの汎用的なコードを書くことができます。
ジェネリクスを使う主な利点は何ですか?
-コードの重複を減らし、タイプセーフティを高めることができます。
ジェネリクスの代表的な使用例を教えてください。
-コレクションフレームワーク(ArrayListなど)が良い例です。リストの内容のデータ型を指定できます。
Outlines
📚ジェネリクス入門
このセクションでは、Javaのジェネリクスについての基本的な導入を提供します。ジェネリクスが最初は複雑に見えるかもしれないが、Tや?、<、>などの記号の意味を理解することで、その有用性が明らかになると説明しています。ジェネリクスがどのようにJava開発者が型安全性を向上させ、コードの重複を減らすのに役立つか、実際の例(IntegerPrinterなど)を通じて説明します。ジェネリクスを使用することで、異なる型のオブジェクトを処理するために複数のクラスを作成する代わりに、一つの汎用クラスを作成することが可能になります。
🔄ジェネリクスの応用
ジェネリクスを使用して、さまざまなデータ型(ダブル、文字列など)で機能する単一のプリンタークラスを作成する方法を説明します。このセクションでは、ジェネリクスの実践的な応用に焦点を当て、JavaのArrayListの例を引き合いに出して、ジェネリクスがどのように型安全性を提供し、コードの柔軟性を向上させるかを示します。また、ジェネリクスがなければ、異なる型のオブジェクトを含むリストを作成する際に直面する型安全性の問題についても触れています。
🔍ジェネリクスの高度な使用法
ジェネリクスを使用して特定の基底クラスやインターフェースを継承する型のみを受け入れるクラスを作成する方法を紹介します。これにより、ジェネリクスの「境界」(bounds)という概念が導入され、型パラメータに制約を加えることで、より精密な型安全性を実現します。例えば、「Animal」クラスを継承する型のみを許可するプリンタークラスの作成が挙げられます。また、ジェネリックメソッドや複数のジェネリック型を持つメソッドの作成についても説明しており、ジェネリクスの柔軟性と強力な機能を示しています。
🎓ジェネリクスのワイルドカードと型安全性
ジェネリクスのワイルドカード(?)の使用法と、それが型安全性にどのように貢献するかを解説します。具体的には、任意の型のオブジェクトを含むリストを受け入れるメソッドの作成方法を示し、この機能がJavaの型システムの柔軟性をどのように高めるかを説明します。また、ワイルドカードを使用して「Animal」クラスを拡張する型のリストのみを受け入れるように制限する例を通じて、ジェネリクスの「境界付きワイルドカード」の概念を紹介します。このセクションは、ジェネリクスがJavaプログラミングにおける型安全性とコードの再利用性をどのように向上させるかを強調して終わります。
Mindmap
Keywords
Please replace the link and try again.
Highlights
Generics offer the ability to create classes flexible for many types, with structure and type safety
Java's collections framework uses generics, like ArrayLists specifying the type to hold
Bounded generics limit the type passed in, like only animals for a Printer class
Generic methods can take in any type of parameter using a generic type parameter
Wildcards allow methods to take Lists of unknown generic typed objects
Transcripts
in this video we're going to talk all
about generics in java generics can be
super confusing the first time you see
them with all the t's and question marks
and angle brackets and k's and v's but i
promise by the end of this video you'll
know exactly what generics are why they
exist and why they're useful and how you
can use them in your own programs my
name is john i'm a lead java software
engineer and i love sharing what i've
learned with you in a clear and
understandable way i also have a full
job of course available and a link down
in the description if you're interested
first to have a good understanding of
what generics do and why they exist it
helps to know the kinds of problems that
java developers were running into before
generics existed let's say i wanted to
create a class where all it would do is
hold an integer value that i give it and
then print out that integer whenever i
wanted to so we might call something
like that integer printer you can go
ahead and click finish and create that
so this class would be pretty simple we
would have an integer field for the
thing that we want to print so we can
call it thing to print and we can have a
constructor for this class that takes in
this thing to print so that would be
public integer printer then it takes in
an integer for the thing to print and
that would just set this dot thing to
print equal to the thing to print that
was passed in and we can have one method
to actually print this out whenever we
want to so that would be public void
print and all that does is just print
out the thing to print to the console so
system.out.printline thing to print so
if we wanted to use this integer printer
class we would just create an integer
printer printer equals new integer
printer
and pass in the integer that we want to
print here in the constructor so let's
say we want to print out the number 23
now of course we can call printer.print
and when we run our program of course it
prints out 23. but what if we wanted to
do exactly the same thing for a double
instead of an integer well we couldn't
use this class right because it only
holds an integer it doesn't hold a
double so what can we do well basically
what we have to do is make a copy of
this entire class and we can call it
double printer and then inside that
double printer we would basically have
all of the exact same code except
instead of integer we would have double
so this new class will work great for
holding and printing doubles but what if
we now want a class that'll do exactly
the same thing but work for strings well
of course you have to do the exact same
thing again you have to copy that class
make a new class called string printer
and change all these doubles to strings
if you want your class to be able to
print strings so now we have three
completely separate versions of
essentially the same kind of class and
you can start to see the problem we
would need a whole other class if we
wanted to do this with floats or dogs or
cats or cars or trucks or whatever type
of object that we wanted to print so
we'd end up with a ton of code
duplication and this is with a really
simple class if you had a more
complicated class the code duplication
would be even worse well that is where
generics come in generics offer you the
ability to have one class like this that
is flexible for many many different
types so let's go back to our original
integer printer and make it generic so
first instead of calling it integer
printer let's just call it printer
because it should be able to print
anything now when you want to use
generics in a class like this in java
right here after the class name in the
declaration but before the curly braces
you have to define what is called a type
parameter and you'll put your type
parameter in angle brackets like this by
convention in java typically you'll see
this type parameter just called t but
technically you can call this type
parameter whatever you want but i'm
going to just be using t so you can kind
of get used to seeing it because that's
the convention that you'll see elsewhere
you can think of it as standing for type
in this class what this t represents is
the type of thing that this printer is
going to be able to hold and print so
instead of just having an integer field
here it's going to be of type t
right now as we're coding this class we
don't know what types of things this
printer is going to be asked to print
but this gives the ability to create
printers for any types that you want so
of course we also have to change the
name of our constructor to just printer
to match the class name and that
constructor also instead of taking in an
integer is going to take in something of
type t so now this class is a generic
printer for whatever type we want but
now how do we actually use this class if
we want to for example create an integer
printer like we had before well back
here in our main method instead of an
integer printer now of course we're
going to just create a printer but now
you can see that we have a warning here
that printer is a raw type and
references to generic type printer
should be parameterized it wants to know
the type of thing that we want to be
able to print and in this example we
want to be able to print integers so how
we specify that is in angle brackets
here after printer we type in integer
that tells java i want a printer for
integers and we have a similar warning
here to get rid of that you just need to
put in angle brackets after the class
name printer in older versions of java
you used to have to put the type in
there again but you don't have to do
that anymore this integer here that
we're passing in in the angle brackets
is what's going to be used as this
t-type in this printer object that we
are creating now we can run our program
as we did before and it still prints out
23. but now what's cool is we can go in
and get rid of those two extra classes
that we made the double printer and the
string printer we can just delete those
because now we can use our generic
printer class to be able to create
printers for doubles and strings also so
now all we have to do if we want to
create a printer for doubles we just say
printer and pass in double or t the type
that we want this printer to be able to
print we can call it double printer
equals new printer and give it a value
like 33.5 and we can call
doubleprinter.print and of course it
prints out 33.5 so now we've created one
printer class that can print any type
that we get it doubles ants longs floats
pigs monkeys cars trucks whatever one
thing to note though is that generics
don't work with primitive types like
lowercase int and lowercase long but all
you have to do is just use the wrapper
classes like integer and everything
should just work the same way one place
that you've probably already used
generics all the time is with java's
collections framework for example if you
wanted to create an arraylist you've
probably done this where you've
specified in angle brackets the type of
thing that you want to have in your list
so if you want to create an arraylist of
cats you say arraylist cat we'll call it
cats equals new array list this gives
you an arraylist that you can only add
cats to so you can say cats.add
new cat and that works fine but if you
try to do cats.add
and pass in a new dog instead you get an
error because we specified that cat was
the type of thing that this list was
going to hold and if we try to give it a
dog we get an error in the same way up
here where we created a printer for
doubles if we try to pass in a string
hey there
we get a similar error because we told
java that this was going to be a printer
for doubles and here we're trying to
give it a string but you might be
thinking well hey john if we want to be
able to create a list of anything we
want why do we have to deal with all
these generics why can't we just create
like an array of just objects and then
we can put whatever we want in it well
it is true that you can do that and your
code will work but it won't be type safe
at all let me show you what i mean let's
say that our arraylist instead of
holding cats just holds objects this is
the kind of thing you'd have to do if
generics didn't exist you just have to
create an arraylist that can hold
whatever so in this imaginary world
without generics we still want to create
a list of cats so we've added our new
cat to our list but let's say sometime
later on in the code we want to be able
to get stuff off our list and use it so
if we want to get this first cat off the
list and put it in a variable we would
want to create a cat call it my cat
equals cats.get
the first element of the list at index
0. but here we get an error that we have
a tight mismatch you can't convert from
object to cat java doesn't know that
this is supposed to be a list of cats it
just knows it's a list of objects so we
have to tell java yes i know this is a
cat so you can go ahead and cast it to a
cat so i can store it in this variable
but what if instead of adding a cat to
the list somebody adds a dog well the
code all looks the same there's no
compilation errors or anything but of
course if you try to run it you're going
to get a classcast exception
right here on this line because you're
trying to cast this element in the list
as a cat but it's actually a dog so just
having an arraylist that can hold
whatever type of object causes all types
of these type safety issues and generics
solves that problem for us so now we can
say yes i want to create a list of cats
so then in the code if somebody tries to
add a dog to that list they get an error
and it won't even compile and also since
java knows that this is a list that can
only contain cats whenever you get a
thing off of that list it is 100
guaranteed to be a cat and you don't
have to do any special casting that's
how generics help us they offer the
ability to create classes that can
accommodate tons of different types but
also the structure and the type safety
of knowing exactly which type you're
using that class with at the moment but
there are even more cool advanced things
that you can do with generics let's go
back to our generic printer class so
right now we can create a printer of
whatever class that we want to right but
what if instead of being a printer for
any type we want this to be a more
specialized printer for animals for
example i have this cat class here that
extends the animal class and i also have
a dog class here that extends the animal
class so if we want this to just be a
printer for any type of animal instead
of just saying t we can say t
extends
animal now back here in our main method
we now get an error when we try to
create a printer for integers or doubles
because now this printer only works for
animals so we can create a cat printer
and in the constructor we can pass in a
new cat or we can create a printer for a
dog and pass in a new dog but what's
cool about that is now in our printer
class since we know that whatever is
passed in as this type extends animal
any method that is defined in the animal
class is available to us in our thing to
print variable because we know that this
thing to print this t is going to be
some type of an animal so now because we
know this thing to print is an animal
down here in our print method we can
call thing to print dot
eat because this eat method is available
in the animal class so if we didn't have
this extends animal if we just took in
any type at all we can't call the eat
method because this tea type isn't
guaranteed to be an animal at all so
there's no way to know whether it will
have an eat method available on it or
not when you do this type of thing it's
called a bounded generic because you're
giving a certain bound a limit on the
type that's able to be passed in you can
also use bounds with interfaces let's
say you wanted to guarantee that this
type implemented the serializable
interface you just put in extends
serializable you might think that
because this is an interface you should
put implements here instead of extends
but no it's just not the proper syntax
it still has to be extends even though
it's a little bit weird another cool
thing you can do is have multiple bounds
let's say you wanted to make sure that
it was a subclass of animal and also
implemented the serializable interface
to do that you can just say extends
animal
and serializable here with an ampersand
and you can list as many things as you
want here all separated by ampersands
there's just a couple restrictions you
can only have one class which makes
sense because java doesn't support
multiple inheritance and you always have
to list the class name first with any
interfaces after that if you try to
switch it around and put the interface
first you'll get an error in addition to
having generic classes you can also have
generic methods let's say we wanted to
make a method that can take in any type
of object and print it out with
exclamation points private static void
let's call it shout since it'll print
things out with exclamation points it'll
take in some kind of type that we're
going to call t we'll call it thing to
shout and inside that method all we're
going to do is print out that thing to
shout with a bunch of exclamation points
after it so right now we're getting an
error here because java is saying hey t
isn't the type what do you want me to do
with this to tell java that this t is
supposed to be a generic type right here
in the method signature right before the
return type you put that generic type in
angle brackets again you can call this
whatever as long as it matches here and
in the parameters but by convention
you're still just going to see t most of
the time so now here in our main method
we can call our shout method with
whatever we want you can send in a
string like john you can send in an int
57 or you can even send in a cat so this
can take in any type of parameter that
we want to send and when we run it it'll
print them out with exclamation points
java also supports the ability to have
multiple different generic types here so
in addition to taking in this t thing to
shout we can also take in say
the
other thing to shout all we have to do
is add this v to our angle brackets here
and separate them with a comma and now
this method will take in two of any sort
of type so we can pass in john and 74
and also go ahead and print out
other thing to shout and that works and
is now flexible with any two types at
all if you want you can also have
multiple generic types like this in your
generic classes so over here in our
printer class if we wanted to have
another field here let's call it v
other thing and all we have to do is
specify that up here in our angle
brackets as well separated by a comma if
you happen to want to return one of
these generic values that are being
passed into your generic methods all you
have to do is specify that return type
as the return type here so instead of
void if you want to return something of
type t you just put t here as the return
type and then in here of course you just
have to return something of type t which
can just be this
thing to shout the other advanced
generics topic i want to talk about is
wild cards let's talk about a situation
where you might want to use a wild card
and then we'll show how you can do it
let's say we wanted to be able to create
a method that can take in a list that
holds any type of objects and we want to
be able to print out that list so we
might call that print list so how do we
specify in the parameters here that we
want to be able to take in a list that
contains any type of thing you might
think that we can just say okay i want
to take in a list of objects we can call
it my list and all we'll do is just
print out that list to the console so
now up here we can create a list of
integers
call it in list
equals new array list we can take our
int list
and add the number three and then we can
try and call our print list method with
our int list as the parameter but if we
try and do that we get an error here
that says we can't pass in this list of
integers as this parameter that's
supposed to be a list of objects but it
might feel like you should be able to do
that right of course an integer is a
subclass of object so shouldn't we be
able to pass in just a list of integers
well even though integer is a subclass
of object a list of integers is not a
subclass of a list of objects so this
doesn't work this is where a wild card
will work to solve your problem so
instead of saying that this is a list of
objects we say that this is going to be
a list of unknown by passing in a
question mark this question mark is the
wild card you use a wild card a question
mark as the type parameter when you're
using a generic when you don't know
what exactly that generic type is going
to be so it's saying hey java i've got
this method here and i want it to be
able to take in a list of anything but i
don't know what it's going to be a list
of so now you can call this method with
a list of whatever you want in this case
we're doing it with a list of integers
but you can also do it with a list of
anything else let's say we had a list of
cats add a new
cat to that list change this to catlist
here and pass the catlist into our print
list method and it now works with lists
of both types with no errors you can
also have bounded wild cards similarly
to how we did in our generic class so
instead of being a list of anything at
all we can say this has to be a list of
something that extends the animal class
but now you can see up here that we're
getting an error when we're trying to
call this method with a list of integers
and that's because integer doesn't
extend animal we don't get that same
error here when we're calling it with a
list of cats because cat does extend
animal if you enjoyed this video or
learned something please let me know by
leaving a like and be sure to subscribe
so you don't miss each new java tutorial
and of course don't stop now keep
learning by watching one of the other
videos below thank you so much for
watching i really appreciate you being
here with me i'll see you next time
5.0 / 5 (0 votes)