啥都不说先上例子:定义一个Show方法,实现一个“弱智”的功能,输出传入的参数值。 先来考虑传入的是一个 有一天这个”弱智”系统升级了需要调用 灾难来了。。。 甲方爸爸想要一个万能的输入,可以输入 float 类型,String类型,自定义的类 class 对象(来算算会写多少个 show方法?emm~ 我们一起来数星星…) 怎么办?================ 思考:方法中的形式参数(形参) 关键点:形参中的数据类型是否也能像变量一样定义方法的时候先不确定,当真正使用的时候再确定 是什么数据类型。 解决:我们也可以定义一个类型变量,用任意个字母从形式上来代替一个数据类型,如下用字母T表示某种数据类型。行话叫做**“将数据类型参数化”**,代码如下: 问题又来了~ java 编译器 不认识 我随意定义的字母***T*** ,怎么办– 告诉它 不就完啦。因此我们有了 问题又又来了~ 放哪里 ? 肯定要放在 使用***T***的前面。括号中的形参会使用 , 不要忘记方法返回值类型 也是要指定数据类型的(这个例子中是 很顺利,我们已经完成了一个完整的泛型方法代码的编写。总结下: 继续思考,Java的核心思想是什么? 万物皆对象!显然,很多时候希望这个类型变量:T ,能在整个类范围中使用,而不是仅仅局限于方法。因此有了泛型类 – 很简单 同理,为了**统一标准往往需要使用 问题叒来了,接口中定义的 在理解**“擦拭法”前,先回顾下前面泛型的使用。尽管我们定义了泛型 类型推导,只介绍Java 8版本的泛型的类型推导,【2018年Java 10版本的局部类型推导请自行百度】。 重点是理解为什么 Integer 和 Double一起返回的类型是Number。 泛型类中的类型推导。 显然我们也可以指定类型. 来思考下,如果指定的不是 现在有需求定义一个泛型方法对输入的2个变量比较大小。我们很容易写出下面代码 问题:怎么比较传入的两个变量的大小? 分析:T的类型是什么?目前在没用使用该方法时候(定义方法),T的类型默认为Object ,那么eA 和 eB要比较大小就必须采用 Object中比较大小的方法,可惜Object中没有比较大小的方法。怎么办? Java中提供了一个接口 同理,有上界也存在下界 T super xxx 。 注:超纲了,感兴趣的可以自行百度 😃… 同时用这个案例来说明JAVA中接口的作用:提供统一标准. 定义一个接口,提供统一标准:需要实现 Min 和 Max两个方法 2.定义泛型类,约束类型变量上界,实现接口
一、上栗子
int
类型参数,秒写下面代码:public static void Show(int param){//为了能在main方法中调用,定义为static,知识点:静态方法调用 System.out.println(param); } //main方法如下 public static void main(String[] args) { Show(123); //调用static方法,输入123; }
Show
方法输入浮点数。So easy~ 立马想到学过的多态–方法重载**(overload)**,添加一个相同名字的方法:public static void Show(int param){ //为什么这个方法要定义为 static? System.out.println(param); } public static void Show(double param){//知识点:方法重载【同一个类中】 System.out.println(param); } //测试方法--main方法 public static void main(String[] args) { Show(126); //调用static方法,输入123; Show(25.88); }
param
是一个变量可以指代同种类型的任意值。 两个show方法中唯一的不同就是param
的数据类型不同。public static void Show(T param){// T 就是任意的字母来代表某个数据类型,目前不知道具体是什么类型 System.out.println(param); }
<T>
尖括号告诉编译器这个字母 ***T***是有特殊含义的,它指代某个具体的数据类型。void
表示没有返回值),因此 <T>
显然要放到返回值(这里是 void) 前面 所以完整代码如下:public static <T> void Show(T param){// <T> 告诉编译器 T这个字母已经赋予了神圣的使命 System.out.println(param); } //测试方法--main方法 public static void main(String[] args) { Show(126); Show(25.88); Show("输出字符串也没问题"); Show(new Date());//输出Date 对象也ok }
啰嗦的说:]任给一个字母表示数据类型,然后用一对尖括号<>告诉编译器。编程习惯常用大写字母T、E、K、V 等来表示。同时 <> 的位置一定是放在所有类型变量使用之前。二、泛型类与泛型接口
<T>
这个类型变量的声明放**类名
**后面就好了。如下public class MyGenerics<T>{// <T>声明一个类型变量T;告诉编译器T在整个class范围内都代表某个数据类型 public static void Show(T param){ //不需要在方法中声明 <T> System.out.println(param); } } //测试类(主类)中的 main方法写测试代码 public static void main(String[] args) { MyGenerics myGen=new MyGenerics(); myGen.Show(126); myGen.Show(25.88); myGen.Show("输出字符串也没问题"); myGen.Show(new Date());//输出Date 对象也ok }
接口
,将类型变量<T>
放入接口定义则有了泛型接口;public interface InterfaceGen<T> { public void Show(T param); } public class MyGenerics implements InterfaceGen{//重新类MyGenerics实现接口InterfaceGen @Override //问:这是啥? public void Show(Object obj){ //思考:A这个方法哪里来的? B参数为什么是Object? System.out.println(obj); } }
param
类型是 T 为什么在实现中 变为了 Object
.三、Java泛型实现-擦拭法
public static <T> void Show(T param)
但是我们在调用该方法的时候Show(126);
并没有像变量赋值一样给*类型变量T*指定具体的数据类型。同样在使用泛型类的时候也没有指定具体类型。这是为什么?很简单,在编译阶段编译器根据实际输入值进行了类型推导。然后用推导出的类型来替换类型变量T,最后生成字节码。这一过程就叫做“擦拭”
public static <T> T add(T a1,T a2){ return a1; } //对该方法的调用 Integer x=add(12,22) //两个参数都是整形,这里的类型是Integer类型。所以返回值也为 Integer。 Number x=add(12,22.58)//取Integer和Double的最小公倍数,可以理解为他们共同的父类返回为Number。
MyGenerics myGen=new MyGenerics();
用泛型类MyGenerics
实例化对象的时候没有指明具体数据类型,编译器也没办法通过对象实例化来确定***T*** 的数据类型。怎么办?很简单所有类类型的最小公倍数不就是根类Object,因此默认情况下,所有的泛型类类型都会使用Object类型替换。这就回答了上一节为什么param
类型是 T 在实现中 变为了 Object
。MyGenerics<Number> myGen=new MyGenerics<Number>()
这样实际对象myGen
中类型变量T将都替换为Number类型。实际使用中myGen.Show(x)
x变量的类型可以为Number
以及Number
的***子类***Number
这样的抽象类,而是接口会怎么样?例如 MyGenerics<Comparable> myGen=new MyGenerics<Comparable>()
答案:myGen.Show(x)
x对象变量的类型一定是实现了接口Comparable的类。四、泛型类型上界
public static <T> void Cmp(T eA ,T eB){ //遇到问题了 怎么比较 eA和eB 的大小 }
Comparable
代码改下如下public static <T extends Comparable> int Cmp(T eA ,T eB){ //可以试试 eA和eB 具有比较大小的方法 compareTo. return eA.compareTo(eB); }
T extends Comparable
是什么? 就是规定了泛型类型的上界,也就说当使用该方法时,传入的类类型必须是实现了Comparable接口的类,相当于做了限制约束。五、以一个案例作为结束
public interface MinMax<T extends Comparable<T>>{ public T Min(); public T Max(); }
class MyClass<T extends Comparable<T>> implements MinMax<T> { T[] vals; MyClass(T[] ob) { vals = ob; } @Override public T Min(T a) { T val = vals[0]; for (int i = 1; i < vals.length; ++i) { if (vals[i].compareTo(val) < 0) { val = vals[i]; } } return val; } @Override public T Max(T a) { T val = vals[0]; for (int i = 1; i < vals.length; ++i) { if (vals[i].compareTo(val) > 0) { val = vals[i]; } } return val; } } //测试类中的主方法 public static void main(String args[]) { Integer inums[] = {56, 47, 23, 45, 85, 12, 55}; Character chs[] = {'x', 'w', 'z', 'y', 'b', 'o', 'p'}; MyClass<Integer> iob = new MyClass<Integer>(inums); MyClass<Character> cob = new MyClass<Character>(chs); System.out.println( 'Max value in inums: '+iob.max()); System.out.println('Min value in inums: '+iob.min()); System.out.println('Max value in chs: '+cob.max()); System.out.println('Min value in chs: '+cob.min()); }
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算