题外话
写博客两周了,从刚开始不知如何下手,到现在一篇博文阅读量过千,得到大佬的好评.一方面可以记录自己的学习,也可以把自己的知识分享给别人,我其实挺开心的,希望大家继续支持我这个九线码农.
泛型
概念:
泛型,即“参数化类型”。就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。
使用
先拿我之前使用的泛型抛砖引玉
package week.third.test;
import java.util.ArrayList;
public class Demo3 {
public static void main(String[] args) {
//创建集合不给出泛型
ArrayList list = new ArrayList();
list.add("h");
list.add("a");
//遍历集合
for (Object obj : list){
System.out.println(obj);
}
//进行遍历,打印出每个字符串长度
for (Object obj : list) {
String str = (String) obj;/*此处练习了向下转型*/
System.out.println(str.length());
}
//创建集合给出泛型
ArrayList<String> list2 = new ArrayList<>();
//添加元素
list2.add("h");
list2.add("o");
//list2.add(100);编译的时候就会报错,如果没有给出泛型,则不会报错
//使用增强for遍历集合
for (String str2 : list2
) {
System.out.println(str2);
}
}
}
泛型类
定义一个泛型类:
public class ClassName<T>{
private T data;
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
泛型接口:
public interface IntercaceName<T>{
T getData();
}
实现接口时,可以选择指定泛型类型,也可以选择不指定, 如下:
指定类型:
public class Interface1 implements IntercaceName<String> {
private String text;
@Override
public String getData() {
return text;
}
}
不指定类型:
public class Interface1<T> implements IntercaceName<T> {
private T data;
@Override
public T getData() {
return data;
}
}
泛型方法:
private static <T> T 方法名(T a, T b) {
}
泛型限制类型
在使用泛型时, 可以指定泛型的限定区域 ,
例如: 必须是某某类的子类或 某某接口的实现类,格式:<T extends 类或接口1 & 接口2>
泛型的作用
1、 提高代码复用率
2、 泛型中的类型在使用时指定,不需要强制类型转换(类型安全,编译器会检查类型)
注意事项:
在编译之后程序会采取去泛型化的措施。 也就是说Java中的泛型,只在编译阶段有效。在编译过程中,正确检验泛型结果后,会将泛型的相关信息擦出,并且在对象进入和离开方法的边界处添加类型检查和类型转换的方法。也就是说,泛型信息不会进入到运行时阶段。
说大事儿专用标题!
1.Java中的泛型是什么 ? 使用泛型的好处是什么?
泛型是一种参数化类型的机制。它可以使得代码适用于各种类型,从而编写更加通用的代码,例如集合框架。泛型是一种编译时类型确认机制。它提供了编译期的类型安全,确保在泛型类型(通常为泛型集合)上只能使用正确类型的对象,避免了在运行时出现ClassCastException。
2、Java的泛型是如何工作的 ? 什么是类型擦除 ?
泛型的正常工作是依赖编译器在编译源码的时候,先进行类型检查,然后进行类型擦除并且在类型参数出现的地方插入强制转换的相关指令实现的。编译器在编译时擦除了所有类型相关的信息,所以在运行时不存在任何类型相关的信息。例如List在运行时仅用一个List类型来表示。为什么要进行擦除呢?这是为了避免类型膨胀。
3.什么是泛型中的限定通配符和非限定通配符 ?
限定通配符对类型进行了限制。有两种限定通配符,一种是<? extends T>它通过确保类型必须是T的子类来设定类型的上界,另一种是<?superT>它通过确保类型必须是T的父类来设定类型的下界。泛型类型必须用限定内的类型来进行初始化,否则会导致编译错误。另一方面<?>表示了非限定通配符,因为<?>可以用任意类型来替代。
4.List<? extends T>和List <? super T>之间有什么区别 ?
这两个List的声明都是限定通配符的例子,List<?extends T>可以接受任何继承自T的类型的List,而List<? superT>可以接受任何T的父类构成的List。例如List<? extends Number>可以接受List或List。
5.如何编写一个泛型方法,让它能接受泛型参数并返回泛型类型?
编写泛型方法并不困难,你需要用泛型类型来替代原始类型,比如使用T, E or K,V等被广泛认可的类型占位符。
6.Java中如何使用泛型编写带有参数的类?
这是上一道面试题的延伸。面试官可能会要求你用泛型编写一个类型安全的类,而不是编写一个泛型方法。关键仍然是使用泛型类型来代替原始类型,而且要使用JDK中采用的标准占位符。
7.编写一段泛型程序来实现LRU缓存?
对于喜欢Java编程的人来说这相当于是一次练习。给你个提示,LinkedHashMap可以用来实现固定大小的LRU缓存,当LRU缓存已经满了的时候,它会把最老的键值对移出缓存。LinkedHashMap提供了一个称为removeEldestEntry()的方法,该方法会被put()和putAll()调用来删除最老的键值对。
8.你可以把List传递给一个接受List参数的方法吗?
对任何一个不太熟悉泛型的人来说,这个Java泛型题目看起来令人疑惑,因为乍看起来String是一种Object,所以List应当可以用在需要List的地方,但是事实并非如此。真这样做的话会导致编译错误。如果你再深一步考虑,你会发现Java这样做是有意义的,因为List可以存储任何类型的对象包括String,Integer等等,而List却只能用来存储Strings。
废话时间:
如果客官觉得食用合适可不可以给一个免费的赞!谢谢谢了!慢走客官!建议打包收藏,下次再来。店小二QQ:309021573,欢迎骚扰!