java 基础 泛型使用总结

来源:互联网 发布:js有没有sleep 编辑:程序博客网 时间:2024/06/05 04:17

没事,写一个关于泛型使用的总结,泛型相信大家都不陌生,学过javase的人都知道,泛型一般在框架中用的比较多,平时还是用的比较少的,今天就 总结下泛型怎么使用,

为什么jdk1.5要引入泛型?

先看段代码:

package com.generic;


import java.util.ArrayList;
import java.util.Iterator;


public class Demo1 {
public static void main(String[] args) {
ArrayList arrayList = new ArrayList();
arrayList.add("刘德华");
arrayList.add("王祖贤");
arrayList.add(100);


Iterator iterator = arrayList.iterator();
while(iterator.hasNext()){
String result = (String) iterator.next();//这里会报错
System.out.println(result);
}
}
}

比如上面的集合 我没有使用泛型,如果要遍历的话 我还要强转,而且我一不小心往集合中放了一个Integer类型进去,就容易报错,也许你会说 怎么可能自己会注意的,但是你做项目,而且忙起来那记得这么多,而且报错还是在运行期间报错,

更是致命,我们最好让错误发生在编译时间,这样程序员就可以修复这个错误,

所以总结起来引入泛型好处就是:减少了强转,增加了程序员的安全性,也方便了很多

那么泛型一般可以作用于:类,方法,接口上

泛型作用于类上就叫泛型类:先讲讲泛型类的使用

泛型类的使用

语法格式:public class 类名<泛型类型1,…>   注意:泛型类型必须是引用类型

写个demo玩下,

package com.generic;
public class Demo1 {
public static void main(String[] args) {
Person person = new Person("张三");
person.show();

Person person1 = new Person(1111);
person1.show();
}
}


class Person<T>{
private T mt;

public Person(T t) {
super();
this.mt = t;
}


public void show(){
System.out.println(mt);
}
}

只有在你创建对象时才知道泛型是什么类型的,这个特别适合在你抽取某一个功能时,需要父类引入泛型,子类具体传递那个泛型,android中adapter有几个方法 其实用到的也就是getView()方法,其他方法都用不上,而且每次都写在那里,那么这个时候你就写一个抽象的父类,把三个用不上的方法给写上 把getView()写成抽象的方法  因为每个子类实现不一样,这样你数据实体就可以使用泛型来定义,

泛型使用在类上有二个情况,一种是你知道传递什么类型,还有一个情况是你不知道传递什么类型,

知道传递什么类型的情况:

package com.generic;
public class Demo1 {
public static void main(String[] args) {
}
}


abstract class Person<T>{

}
class Man extends Person<String>{

}

在Man这个类中你知道要传递是String类型,如果你Man也不知道传递是什么泛型,可以这么写:

package com.generic;
public class Demo1 {
public static void main(String[] args) {
Man<String> man = new Man<String>();
man.show();
}
}


abstract class Person<T>{

}
class Man<T> extends Person<T>{
public void show(){
System.out.println("您好");
}
}

现在讲下泛型接口的时候:

语法格式:格式:public  interface 接口名<泛型类型1…>

package com.generic;
public class Demo1 {
public static void main(String[] args) {
}
}


interface InnerImpl<T>{
public void show();
}
class A implements InnerImpl<String>{
@Override
public void show() {

}
}

泛型类和接口是一样的,在这不多讲,

泛型方法

把泛型定义在方法上 

语法格式   : public <泛型类型> 返回类型 方法名(泛型类型 .)泛型接口

package com.generic;
public class Demo1 {
public static void main(String[] args) {
A a = new A();
a.show(0);
a.show("helloworld");
a.show(100);
}
}


class A{
public void show(String str){
System.out.println(str);
}
public void show(int i){
System.out.println(i);
}
public void show(double d){
System.out.println(d);
}
}

比如我在A类中 有这么多show的重载方法,如果我要让show方法接受的形参能根据它传递过来的就打印出来什么,我们就不用写那么多重载的方法了,这个就用泛型方法就可以解决!

package com.generic;
public class Demo1 {
public static void main(String[] args) {
A a = new A();
a.show(0);
a.show("helloworld");
a.show(100);
}
}


class A{
public <T >void show(T t){
System.out.println(t);
}
}

用泛型方法解决上面的 问题,我们知道方法有静态方法,那么静态方法有泛型会怎么办呢?

package com.generic;
public class Demo1 {
public static void main(String[] args) {
A a = new A();
a.show(0);
a.show("helloworld");
a.show(100);
}
}
class A{
public static <T >void show(T t){
System.out.println(t);
}
}

其实是一样的,但是有警告,它会让你直接用A的方式调用这个方法,而不是创建对象去调用方法,那么如果我方法有返回值呢?而且是泛型传递什么我就返回什么.

package com.generic;
public class Demo1 {
public static void main(String[] args) {
String str = A.show("helloword");
int i = A.show(100);
}
}
class A{
public static <T > T show(T t){
return t;
}
}

这样就ok,

泛型还有一个高级的地方就是泛型通配符

泛型通配符<?>
任意类型,如果没有明确,那么就是Object以及任意的Java类了
还是用例子来说明:

package com.generic;


import java.util.ArrayList;
import java.util.List;


public class Demo1 {
public static void main(String[] args) {
List<Object> obj = new ArrayList<Object>();

//下面三个报错是因为泛型如果明确写的时候,前后必须一致
// List<Object> obj1 = new ArrayList<Animal>();
// List<Object> obj2 = new ArrayList<Dog>();
// List<Object> obj3 = new ArrayList<Cat>();

//使用通配符
List<?> obj1 = new ArrayList<Animal>();
List<?> obj2 = new ArrayList<Dog>();
List<?> obj3 = new ArrayList<Cat>();
}
}

class Animal{

}
class Dog extends Animal{

}
class Cat extends Animal{

}
下面使用通配符就可以搞定了,

如果我现在有一个需求就是要求集合能存储的是Animal以及Animal的子类,这个时候就会用到? extends E 这个通配符了,它表示的是向下限定,E及其子类,如果不是E的子类放到集合中就会编译报错:

List<? extends Animal> obj1 = new ArrayList<Animal>();
List<? extends Animal> obj2 = new ArrayList<Dog>();
List<? extends Animal> obj3 = new ArrayList<Cat>();


现在需求又变了,我要求是传递Animal以及Animal的父类,就使用这个? super E  E代表Animal,这个就不写demo玩了,好了  可以睡觉了




0 0
原创粉丝点击