当前位置: 首页 > news >正文

java泛型学习篇(二)

java泛型学习篇(二)

1 自定义泛型类

1.1 基本语法

Class 类型 <T,R,M...>{
//成员,其中...代表<>括号里面的参数可以有多个ja
}

1.2 注意点

1.2.1 属性和方法都是可以使用泛型的

 T t;//属性使用泛型,合法public T getT() {return t;}
//方法使用泛型,合法
public void setT(T t) {this.t = t;
}

1.2.2 使用泛型的数组不能再类中初始化

//数组在new的时候不能确定T的类型,就无法创建内存空间
R[] rs=new R[8];//错误的写法 ❌

1.2.3 静态类和静态方法都是不可以使用泛型的

//如果静态方法和静态属性使用了泛型,JVM就无法完成初始化
//因为静态是和类相关的,在类加载中,对象还没有创建
static T t1;
public static R getOne() {//返回类型可以使用泛型return r;
}

1.2.4 泛型类的类型是再创建的时候确定的

ArrayList<Employee> arr = new ArrayList<Employee>();
//在编译期间,就确定了该泛型的类型为Employeev

1.2.5 如果创建对象,并没有指定泛型对应的数据类型,那么默认就是Object

ArrayList arr = new ArrayList();
//这种没有指定泛型,默认就是Object类型
//public class ArrayList<E> extends AbstractList<E>

2 自定义泛型接口

2.1 基本语法

interface 接口名<T,R,M...>
//其中...代表是<>里面所写的泛型的标识符类型可以是多个

2.2 注意点

2.2.1 接口中,静态成员有不能使用泛型

T t="123";
//这样是不行,因为接口中没有写参数的方法默认是被static修饰的方法
//static决定是类加载时就创建好了.那个时候压根就没有对象耶。

2.2.2 泛型接口的类型,由继承接口和实现接口确定

interface A extends B<String,Double>//当我们实现A接口时,指定了T为String类型,R为double类型   
//接口B中所有的方法的泛型约束都会改成<String,Double>

2.3 在默认方法中(jdk8及其以后)也是可以使用泛型的

//实现接口时,直接指定泛型接口的类型
//其是给该类中所重写的接口中原有的泛型替换成指定的类型
//如下面的D<Integer,Double>说明了B类中重写了D接口的方法的第一个泛型参数为Intger,第二个参数为Double类型
重写的时候替换的
class C implements D<Integer,Double>

2.4 没有指定类型时.默认是Object类型

Class A implements B 写法一等价于 class A implements B<Object,Object>  写法二
//B是接口,里面使用了泛型约束符(T、R、M、E之类的)
//其中A类重写的B接口的方法都会被<Object,Object>替换掉(不会展示泛型标识符)
//虽然这样写不会报错,但是建议写成写法二

3 自定义泛型方法

3.1 基本语法

修饰符 <T,R,E...> 返回类型 方法名(参数列表){//与之前方法的区别是返回类型前面多了个<T,R,E...>
}

3.2 注意点

3.2.1 泛型方法可以定义在普通类中,也可以定义在泛型类中

a 普通类中
class Teacher{//<E,t>就是泛型,是给say方法去使用的public <E,T> void say(E e,T t){//泛型方法}
}
b 泛型类中
class Student<T,R>{ //泛型类//一般泛型方法的泛型标识符和泛型标识符不一致public<U,M> void eat(U u,M m){//泛型方法}  
}

3.2.2 当泛型方法被调用时,类型会确定

Teacher t=new Teacher();
t.say("小红",123);
//当调用方法时,传入参数,编译器会自动确定类型
//你传的是什么类型,那边通过getClass得到的就是什么类型

3.3.3 修饰符后没有<T,R>,那么该方法不是泛型方法,而是使用了泛型

//tell方法不是泛型方法,而是使用了泛型的方法
public void tell(T t){
}

3.3.4 泛型方法可以使用类声明的泛型,也可以使用自己声明的泛型

class Student<T,R>{ //泛型类//t是使用了类声明的泛型,u是使用了自己声明的泛型public<U> void eat(T t,U u){//泛型方法}  
}

4 泛型方法练习

4.1 题目内容

/**题目内容1:Apple类方法有问题吗?,若有请指出问题在题目内容1 基础上去运行后面的代码,会输出什么样子的结果
*/
class Apple<T,R,M>{public<E> void floy(E e){//输出当前类名(不含包名)System.out.println(e.getClass().getSimpleName());}public Void eat(U u){}public void run(M m){}
}
//题目内容2
Apple<String,Integer,Double> apple=new Apple<>();
apple.fly(10); 
apple.fly(new Dog());

4.2 题目解答

class Apple<T,R,M>{public<E> void floy(E e){//输出当前类名(不含包名)System.out.println(e.getClass().getSimpleName());}public Void eat(U u){} //①这句话会报错,因为并没有类没有声明该泛型标识符,且该方法也不是泛型方法public void run(M m){}
}
//题目内容2
//②T--->String类型,R----->Integer,M----->Double类型
Apple<String,Integer,Double> apple=new Apple<>();
apple.fly(10); //打印的是Integer类型,因为fly方法形参使用的是泛型(泛型是不支持基本数据类型的),那么数据类型会自动装箱成Interger
apple.fly(new Dog());//打印的是Dog类型

5 泛型的继承和通配符

5.1 泛型是不具备继承性的

 ArrayList<Object> arr = new ArrayList<String>();//❌

5.2 <?>支持任意泛型类型

//List<?>表示任意泛型的List集合都会被接收
public static void m1(List<?> c) {for (Object object : c) {System.out.println(object);}
}

5.3 <? extends A> 支持A类以及A类的子类,规定了泛型的上限

//List<? extends AA>表示上限,AA和AA子类都可以接收
public static void m2(List<? extends AA> c) {for (Object object : c) {System.out.println(object);}
}

5.4 <? super A> 支持A类以及A类的父类,不限于直接父类,规定了泛型的下限

/List<? super AA>表示下限为AA,AAAA的所有父类都可以接受,不限于直接父类
public static void printCollection2(List<? super AA> c) {for (Object object : c) {System.out.println(object);}
}
http://www.lryc.cn/news/21414.html

相关文章:

  • Java基础
  • 骨骼控制(一)——动画动态节点(AnimDynamics)
  • Linux系统下搭建maven环境
  • English Learning - L2 语音作业打卡 Day3 2023.2.23 周四
  • RK3568平台开发系列讲解(驱动基础篇)GIC v3中断控制器
  • 决策树、随机森林、极端随机树(ERT)
  • 软件测试之因果图法
  • vue中子组件间接修改父组件传递过来的值
  • Java I/O
  • pytorch学习日记之图片的简单卷积、池化
  • 【java基础】抽象类和抽象方法
  • RDD的内核调度【博学谷学习记录】
  • 二叉树——二叉搜索树的最小绝对差
  • git的使用(终端输入指令)下
  • python使用influxdb-client管理InfluxDB的bucket
  • 【c++】模板2—类模板
  • 基于SpringCloud的可靠消息最终一致性03:项目骨架代码(下)
  • linux如何彻底的删除文件
  • 数据仓库Hive的安装和部署
  • Python调用CANoe常见问题
  • 一起Talk Android吧(第五百零七回:图片滤镜ImageFilterView)
  • Java 解释器和即时解释器(JIT)之间的区别
  • Acwing 蓝桥杯 第二章 二分与前缀和
  • CSDN原力增长规则解读 实测一个月
  • HDMI协议介绍(三)--InfoFrame
  • 【RocketMQ】源码详解:Broker端消息储存流程、消息格式
  • IoT项目系统架构案例2
  • Vue echarts封装
  • 蓝桥杯入门即劝退(二十二)反转字符(不走寻常路)
  • 数据仓库Hive