1 哈喽
讲个笑里藏刀的故事,认真听哦
哈哈哈哈哈刀哈哈哈哈哈哈
还记得齐码吗,我回来了
目录
- 泛型(这个无趣)
- 通配符(这个无趣)
- 为什么使用泛型(这个还行)
- 它和渣男有啥区别(这个有趣趣)
- 总结(这个有趣趣趣)
如有错误或者不足请指出,联系方式QQ2714730493。
2 泛型
2.1 泛型的作用
泛型简单易用
类型安全 泛型的主要目标是实现java的类型安全。 泛型可以使编译器知道一个对象的限定类型是什么,这样编译器就可以在一个高的程度上验证这个类型
消除了强制类型转换 使得代码可读性好,减少了很多出错的机会
Java语言引入泛型的好处是安全简单。泛型的好处是在编译的时候检查类型安全,并且所有的强制转换都是自动和隐式的,提高代码的重用率。
2.2 泛型的原理
泛型的实现是靠类型擦除技术,类型擦除是在编译期完成的,也就是在编译期 ,编译器会将泛型的类型参数都擦除成它的限定类型,如果没有则擦除为object类型之后在获取的时候再强制类型转换为对应的类型。 在运行期间并没有泛型的任何信息,因此也没有优化。
2.3 泛型的使用
2.3.1 泛型类
泛型类:具有一个或多个类型变量的类,称之为泛型类
class A<T> {
}
class B<k,v>{
}
2.3.1 泛型方法
泛型方法:具有一个或多个类型变量的方法,称之为泛型方法
public <T> T fun(T t) {
}
//但是请注意: public void fun(T t1){} ,不是泛型方法。
2.4 泛型的规则
2.4.1 泛型可以使用在返回类型和参数类型上面
class A<T> {
public T fun(T t) {
return t;
}
}
2.4.2 泛型可以使用在成员变量上面和类型上面
class A<T> {
private T bean;
}
2.4.3 泛型可以使用在局部变量上面
class A<T> {
public void fun2(T t) {
T b =t;
}
}
2.4.4 泛型不可以new
class A<T> {
A a=new A();//报错
}
2.4.5 在创建泛型类实例时,需要为其类型变量赋值
class A<T> {
A<String>a = new A<String>();
}
2.4.6 泛型方法与泛型类没什么关系,泛型方法不一定非要在泛型类中
2.5 泛型的缺陷
2.5.1 局限性一
集合等号两边所传递的值必须相同否则会报错,原因就是Java中的泛型有一个擦除的机制,就是所编译器期间编译器认识泛型,但是在运行期间Java虚拟机就不认识泛型了。
List<String> list = new ArrayList<String>();
List<Object>list2 = new ArrayList<String>();//异常
2.5.2局限性二
泛型擦除和第一点一样
public void fun(List<Object> list){
System.out.println("泛型方法");
}
public void test(){
List<String>list = new ArrayList<String>();
fun(list);//报错
}
3 通配符
3.1 通配符“?”
public void fun(List<? extends Object> list){
System.out.println("泛型方法");
}
public void test(){
List<String>list = new ArrayList<String>();
//也可以这样写
//List<?> list = new ArrayList<String>();
fun(list);//报错
}
3.2 通配符不能使用在new的后面
因为如果写在new的后面不就相当于直接确定类型变量了吗,那么这就不是通配符了
3.3 通配符的局限性
3.3.1 参数类型为和返回值为通配符的方法是不能使用的
public void print(List<?> list) {
list.add("hello");//编译异常
list.get(0);
}
3.3.2 通配符可以继承
? extends Number,这个时候通配符就被限制为了Number和Number的子类型
参数类型为通配符的泛型不能用,但是返回值类型为泛型的可以用
public void print(List<? extends Number > list) {
list.add(1);//报错
Number num = list.get(0);
}
因为参数类型为泛型的时候,参数可以为long的,也可能是Integer的还可能是其他类型,而返回值为泛型的,就可以用Number来接收了。
3.3.3 通配符可以有上界
? super Integer,这个时候通配符就被限制为了Integer和” Integer的父类型
返回值类型为泛型的不能用,但是参数类型为通配符的泛型的可以用
public void print(List<? super Number > list) {
list.add(1);
Number num = list.get(0);//报错
}
因为返回值为泛型的时候,返回值可以为Number的,也可能是Object的还可能是其他类型就是Integer的父类型,会发生泛型擦除,而参数为泛型的,就可以放入Integer或者Integer的父类就可以了。
4 为什么使用泛型
先看看请求后台接口回传的数据
正确返回:
{
“status”:1,
“msg"登录成功”,
“data”:{“app_user_id”:“xxxxx”,
“app_user_type”:“xxxxx”,
“mobile”:“122222”}
}
账户密码错误后的错误返回信息:
{
“status”:0,
“msg”:“请求成功”,
“data”:{“app_user_id”:“xxxxx”,
“app_user_type”:“xxxxx”}
}
最外面是不是一样的,但是date这个属性,一下子是两个数据的对象,一下子是多个数据的对象,我该如何处理解析呢。
如果你用原生的一层一层解析,前面的当我没说。
4.1 创建请求Model
public class RequestModel<T> {
private int status;
private String msg;
private T data;
public void setStatus(int status) {
this.status = status;
}
public int getStatus() {
return status;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getMsg() {
return msg;
}
public void setData(T data) {
this.data = data;
}
public T getData() {
return data;
}
}
4.2 举例,请求获取Json数据Gson解析如何泛型data对象
//第一个对象解析
RequestModel<dataOneModel> requestModel = gson.fromJson(json,new TypeToken<RequestModel<dataOneModel>>(){}.getType());
//第二个对象解析
RequestModel<dataTwoModel> requestModel = gson.fromJson(json,new TypeToken<RequestModel<dataTwoModel>>(){}.getType());
5 它和渣男有啥区别
哈哈,这个我真不会。
既然看了我博客,我教你一点点
使用泛型(请自律),提升自己的代码效率(价值),就能远离编码无趣(渣男)。
6 emmm
我知道我有时候很傻很天真,被人记住了也不在乎,我真诚的想和你们好好的。我是Android程序员,请谅解我的直,我的傻。
点赞,加薪,脱单,瘦十斤。