Java 泛型方法/接口、泛型限定 |
您所在的位置:网站首页 › java接口中定义方法 › Java 泛型方法/接口、泛型限定 |
文章目录
一、为什么要定义泛型方法
1、从泛型类到泛型方法的演变过程
2、定义泛型方法的好处
二、创建一个泛型方法格式
常用的形式
三、泛型接口
1、格式
2、例子
四、类型通配符(泛型的高级应用)
1、什么是通配符 (?)
2、类型通配符上限定(? extends T =>可以接收T类型或者T的子类型)
3、类型通配符下限定 (? super T => 可以接收T类型或者T父类型)
一、为什么要定义泛型方法 1、从泛型类到泛型方法的演变过程 我们先来看个例子 //定义一个泛型类,并定义如下两个方法 class Test { public void show(T t){ System.out.println(t); } public void print(T t){ System.out.println(t); } /* 以前是这样定义,现在一个方法搞定 public void show(String t){ } public void show(Integer t){ } 或者 public void show(Object obj){ } */ } //在manin方法代码如下 public static void main(String[] args) { Test d = new Test(); d.show("java"); d.print("Object-C"); Test e = new Test(); e.show(2); e.print(new Integer(5)); }上面是一个简单的代码demo,运行没问题,正常输出。但是你会发现,其实代码有点冗余。我们定义了一个泛型类,并定义了 show(T t)和print(T t)方法。发现: 泛型类定义的泛型,在整个类中有效。如果被方法使用,那么泛型类的对象明确要操作的具体类型后,所要操作的类型已经固定了。就像上面main方法中。对象d,只能操作String类型,如果你要操作其他类型,只能额外去创建其他泛型对象e。 设想下,如果我能把泛型定义在方法上,这样不就可以优雅解决问题。于是变化代码如下 //定义一个类,并定义如下两个泛型方法 class Test { public void show(T t){ System.out.println(t); } public void print(T t){ System.out.println(t); } public void sum(U u,T t){ System.out.println(u+" version is "+t); } } // main方法如下 public static void main(String[] args) { Test d = new Test(); d.show("java"); d.print(5); d.sum("java", new Double(8)); }Test不再是泛型类,泛型方法show(T t)、print(T t)、sum(U u,T t) 更具有扩展性。 2、定义泛型方法的好处 泛型方法可以让不同方法操作不同类型,且类型还不确定。 与泛型类不同,泛型方法的类型参数只能在它锁修饰的泛型方法中使用。二、创建一个泛型方法格式 1、常用的形式 访问修饰符 [static][final] 返回值类型 方法名([形式参数列表])备注:[] 代可有可无的意思,泛型方法可以是实例方法或静态方法,类型参数可以在静态方法中,这是与泛型类最大的区别。 三、泛型接口 1、格式 interface 接口名2、例子 定义一个泛型接口 interface showInterface { public void show(T t); }(1) 实现类确定了类型 class ShowClass implements showInterface{ public void show(String t){ System.out.println("show:"+t); } }(2) 实现类类型不确定 class ShowClass implements showInterface{ public void show(T t){ System.out.println("show:"+t); } }main方法 public static void main(String[] args) { ShowClass obj = new ShowClass(); obj.show(6); /* ShowClass obj = new ShowClass(); obj.show("java"); */ }四、类型通配符(泛型的高级应用) 1、什么是通配符 (?) 看个例子就明白了。定义两个集合,分别输出两个集合的元素。 public static void main(String[] args) { ArrayList a1 = new ArrayList(); a1.add("a"); a1.add("b"); a1.add("c"); ArrayList a2 = new ArrayList(); a2.add(1); a2.add(2); a2.add(3); }在我们没学习泛型之前,我们会封装静态方法如下: public static void printList(ArrayList list){ for (Iterator iterator = list.iterator(); iterator.hasNext();) { Object object = (Object) iterator.next(); System.out.println(object); } }代码买啥毛病,运行也正确。会有一个疑问。为什么参数没定义泛型,但是却可以接受泛型呢?泛型是jdk1.5出来的,老版本肯定要兼容新版本。 在我们学习泛型方法后,我们进一步将代码修改如下: public static void vistor(ArrayList a){ Iterator iterator = a.iterator(); while(iterator.hasNext()){ T t = iterator.next(); System.out.println(t); } }定义一个泛型方法。如果是泛型类,是不允许泛型定义在static上面的。 如果不想定义泛型方法,又能够解决问题呢?这就要用到一个通配符的玩意 //占位符,也称为通配符。表示元素类型可以匹配任意类型 public static void sop(ArrayList a){ for(Iterator it = a.iterator();it.hasNext();){ System.out.println(it.next()); } }泛型方法T如果是具体类型的话,可以接收T t = iterator.next();。?是占位符,不明确具体类型,无法接收。 这种带通配符ArrayList a的List 仅仅表示他是各种泛型的父类,并不能把元素添加到其中。 我做了奇怪的例子 ArrayList list = new ArrayList(); list.add(null);上面说,带通配符ArrayList a的List 仅仅表示他是各种泛型的父类,并不能把元素添加到其中。是不是想违背了?仔细想想,null是任意引用类型的实例。这比较特殊。 2、类型通配符上限定(? extends T) 同样看一个例子. 定义一个集合,遍历元素的方法并输出。 //定义一个Person类 class Person { private String name; public Person(String name){ this.name = name; } public String getNmae(){ return this.name; } } // 定义一个Student 并继承 Person class Student extends Person { Student(String name){ super(name); } } main方法如下 public static void main(String[] args) { ArrayList a1 = new ArrayList(); a1.add(new Person("abc1")); a1.add(new Person("abc2")); a1.add(new Person("abc3")); printMethod(a1); // 下面是错误的。a2存的是Person,存在继承的话,也能放worker。但是等号右边只能存Student,存不进worker.类型安全问题。左右两边要一致 ArrayList a2 = new ArrayList(); a2.add(new Student("abc--1")); a2.add(new Student("abc--2")); a2.add(new Student("abc--3")); printMethod(a2); // ArrayList a2 = new ArrayList(); //如果我想调用也printMethod(a2);没毛病。怎么做?。 第一想法直接给占位符。但是带来一问题,不能调用具体方法。 } // 与main方法同级的静态工具类方法 public static void printMethod(ArrayList< Person> a1){ Iterator it = a1.iterator(); while(it.hasNext()){ System.out.println(it.next().getNmae()); } }如果我想调用也printMethod(a2);没毛病。怎么做?。 第一想法直接给占位符。但是带来一问题,不能调用具体方法。泛型也是一样的。如果我们想两者兼得,既能打印Stuednt,也能打印 Person,我们将printMethod修改如下 public static void printMethod(ArrayList |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |