泛型是什么?
泛型是什么呢?从字面意思来理解就是广泛的类型(个人理解)。泛型是 jdk1.5 的产物,被业界大佬称之为 jdk 的里程碑事件。到底是什么原因使得这样的产物让广大 Java 程序员赞不绝口。听我细细侃来。
引出泛型:
每件事物的产生必然有一定的道理,泛型亦是如此。
我们来看一下下面这个集合:
public class Ttest01 {
public static void main(String[] args) {
MySet set = new MySet();
// 向集合中添加一个字符串
set.add("abc");
String info = (String) set.get(0);
System.out.println(info);
// 向集合中添加一个整数
set.add(2);
// 插入一个整数,取的时候除了我们自己没有人知道插入的类型是什么
// 究竟强转成什么,不同的用户有不同的选择
String info1 = (String) set.get(1);
System.out.println(info1);
}
}
// 集合类
class MySet{
Object[] mySet = new Object[10];
int idx = 0;
// 向集合中插入一个元素
public void add(Object value) {
mySet[idx ++] = value;
}
// 获取元素的值
public Object get(int idx) {
return mySet[idx];
}
}
通过上面的样例,代码在编写的过程中是不会报错的,但是在实际运行过程中呢?
显然代码报错了。
先不说代码有错的问题,假设给你一个这样的集合,咱不知道集合中每个元素的数据类型,咱是不是要一个一个进行强制转换呢?而且我们也不知道究竟应该转成哪种类型才不会报错。(我要是项目经理,估计就被气死了)
泛型应运而生:
既然一个集合中有String类型,有 Integer 类型,那么我们能不能一个集合中只存储 String ,一个集合只存 Integer 类型呢?显然是可以的。
看代码:
public class Ttest01 {
public static void main(String[] args) {
MySet1 set = new MySet1();
set.add("abc");
String info = (String) set.get(0);
System.out.println(info);
}
}
class MySet1{
String[] mySet = new String[10];
int idx = 0;
public void add(String value) {
mySet[idx ++] = value;
}
public String get(int idx) {
return mySet[idx];
}
}
当我们规定这个集合中只能存 String 类型时,那么我们想插入一个 Integer 类型的数据时会出现什么情况呢?
红线警告了,说明我们只能向集合中插入 String 类型。
当指定集合中的具体类型有什么好处呢?
1、给予每个使用该集合的用户 明确的信息。
2、如果插入不同的数据类型会进行错误提示。
3、不再需要进行不确定的强制类型转换。
可能有的小伙伴会想,我们原来的集合既可以存储String类型的,又可以存储 Integer 类型的,这样不好吗?
别慌,相信现在你已经明白一点,原来的方式取出时是不方便的,并且对于一个不知道你的集合中各个元素的数据类型的用户来说,使用起来是及其不方便的。
还有一点,在后面会提到。
泛型推导:
说了这么多废话,终于到Boss出场了。
当我们想让一个集合中都是 Integer 类型会怎么做呢?
class MySet2{
Integer[] mySet = new Integer[10];
int idx = 0;
public void add(Integer value) {
mySet[idx ++] = value;
}
public Integer get(int idx) {
return mySet[idx];
}
}
我们上面的 String 类型是什么样的呢?
class MySet1{
String[] mySet = new String[10];
int idx = 0;
public void add(String value) {
mySet[idx ++] = value;
}
public Object get(int idx) {
return mySet[idx];
}
}
仔细观察一下就会发现,这两个类型里面有很多重复的代码,如果说 之后还会有 Double,Person、Dog 类型的,我们是不是要写更多的代码呢?了解 Java 的都
多少知道一点,就是代码的复用。
class MySet1{
X[] mySet = new X[10];
int idx = 0;
public void add(X value) {
mySet[idx ++] = value;
}
public X get(int idx) {
return mySet[idx];
}
}
看这个代码,我们将两份代码中不同的部分用 X 替换掉,每次只调用这个是不是就 OK 了。
那么如何传递这个 X 呢?
class MySet1<X>{
X[] mySet = new X[10];
int idx = 0;
public void add(X value) {
mySet[idx ++] = value;
}
public X get(int idx) {
return mySet[idx];
}
}
上面的方式是不健全的,说白了就是有问题的,在泛型类中是不可以直接 new X[10] 的,具体就不再详细说了(原谅博主的尴尬,下面的例子效果是一样的,具体看下面的例子吧)。
所以不得不通过另一个例子来说明问题了,实际上只要知道 X 是怎么推出来的就行了。
通过下面的例子我们看一下如何调用:
import org.omg.CORBA.Object;
import java.util.Arrays;
public class Ttest01 {
public static void main(String[] args) {
MySet1<String> set = new MySet1<String>();
set.add("a");
System.out.println(set.get());
}
}
// 给予类一个放参数的位置
class MySet1<E>{
private E value;
public void add(E value) {
this.value = value;
}
public E get() {
return value;
}
}
像方法一样 加个参数就可以啦。
想让集合中都是 Integer 类型怎么办呢?
MySet1<Integer> set = new MySet1<Integer>();
所以根据需要修改不同的参数即可。
如果想集合中既有String又有Interger 呢?
MySet1 set = new MySet1();
看下完整代码:
import org.omg.CORBA.Object;
import java.util.Arrays;
public class Ttest01 {
public static void main(String[] args) {
MySet1 set = new MySet1();
set.add("a");
set.add("123");
System.out.println(set.get());
}
}
class MySet1<E>{
private E value;
public void add(E value) {
this.value = value;
}
public E get() {
return value;
}
}
是没问题的,运行结果也是没问题的,可以自己尝试一下。
所以说,泛型是原先集合的加强,在原来的基础上进去强化。
类是对象的模板,泛型是类的模板
这句话通过上面的例子可以好好琢磨一下,根据泛型我们可以创建的不同的类,
MySet1< Integer >
MySet1< String >
仔细看看确实蛮有道理的,嘻嘻。
泛型好在哪里?
下面是我从某个地方的论坛上看到的,感谢大佬,引用一下:
Java语言引入泛型的好处是安全简单。泛型的好处是在编译的时候检查类型安全,并且所有的强制转换都是自动和隐式的,提高代码的重用率。
1,类型安全。 泛型的主要目标是提高 Java
程序的类型安全。通过知道使用泛型定义的变量的类型限制,编译器可以在一个高得多的程度上验证类型假设。没有泛型,这些假设就只存在于程序员的头脑中(或者如果幸运的话,还存在于代码注释中)。2,消除强制类型转换。 泛型的一个附带好处是,消除源代码中的许多强制类型转换。这使得代码更加可读,并且减少了出错机会。
3,潜在的性能收益。
泛型为较大的优化带来可能。在泛型的初始实现中,编译器将强制类型转换(没有泛型的话,程序员会指定这些强制类型转换)插入生成的字节码中。但是更多类型信息可用于编译器这一事实,为未来版本的
JVM 的优化带来可能。由于泛型的实现方式,支持泛型(几乎)不需要 JVM
或类文件更改。所有工作都在编译器中完成,编译器生成类似于没有泛型(和强制类型转换)时所写的代码,只是更能确保类型安全而已。
后记:
基本就介绍完了,中间有点小尴尬,不过相信正在看的你一定可以理解的,如果有疑问的可以随时问我,相互学习,共同进步。
如果感觉对您有帮助,点个赞,点个关注哦,感谢感谢。
加油!少年!