java泛型的使用

java泛型的使用

泛型的产生机制就是放什么类型的数据进去,取出来的就是什么类型,而不用进行类型转换

泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。

泛型是在编译阶段有效

Java 泛型只在编译阶段有效,即在编译过程中,程序会正确的检验泛型结果。而编译成功后,class 文件是不包含任何泛型信息的

使用泛型可以指代任意对象类型;

泛型类

public class CC<T>{
 
    private T ob;
 
     
    public CC(T ob) {
        super();
        this.ob = ob;
    }
 
    public T getOb() {
        return ob;
    }
 
    public void setOb(T ob) {
        this.ob = ob;
    }
     
    /**
     * 打印T的类型
     */
    public void print(){
        System.out.println("T的实际类型是:"+ob.getClass().getName());
    }
     
}


        // begin test CC
        CC<Integer> cc=new CC<Integer>(1);
        cc.print();
        int icc=cc.getOb();
        System.out.println("i3="+icc);
         
        CC<String> cc2=new CC<String>("我是泛型,好简单啊");
        cc2.print();
        String icc2=cc2.getOb();
        System.out.println("s2="+icc2);
        // end test CC

泛型方法

public class Box<T> {
    private T box;
    public T getBox(T t){
        this.box = t;
        return t;
    }
    public void getType(){
        System.out.println("T的实际类型为:"+box.getClass().getName());
    }
     
    public static void main(String[] args) {
        Box box = new Box();
        System.out.println(box.getBox(1));
        box.getType();
         
        System.out.println(box.getBox("Tom"));
        box.getType();
    }
 
}
T的实际类型为:java.lang.Integer<br>
Tom
T的实际类型为:java.lang.String
	public static <T> void f(T t){
		System.out.println("T的类型是:"+t.getClass().getName());
	}
	
	public static void main(String[] args) {
		f("");
		f(1);
		f(1.0f);
		f(new Object());
	}

泛型通配符

  在泛型中,我们可以用 ? 来代替任意类型

public List wildCard(List<?> list){
     
    return list;
}
 
public static void main(String[] args) {
    GenericTest gt = new GenericTest();
    //构造一个 Interger 类型的集合
    List<Integer> integer = new ArrayList<Integer>();
    integer.add(1);
    System.out.println(gt.wildCard(integer));
    //构造一个 String 类型的集合
    List<String> str = new ArrayList<String>();
    gt.wildCard(str);
    //构造一个 Object 类型的集合
    List<Object> obj = new ArrayList<Object>();
    obj.add(1);
    obj.add("a");
    System.out.println(gt.wildCard(obj));
    //构造一个 任意类型的 集合,这和 List<Object> 存放数据没啥区别
    List list = new ArrayList();
    gt.wildCard(list);
     
}
	private static void take(Demo<?> a){
		a.print();
	}
	
	public static void main(String[] args) {
		Demo<Dog> demo=new Demo<Dog>(new Dog());
		take(demo);
		
		Demo<Cat> demo2=new Demo<Cat>(new Cat());
		take(demo2);
	}

泛型的上限和下限

  ①、上限: 语法(? extends className),即只能为 className 或 className 的子类

//通配符的下限,只能是 Number 或 Number的子类
    public List wildCard(List<? extends Number> list){
         
        return list;
    }
 
    public static void main(String[] args) {
        GenericTest gt = new GenericTest();
        //构造一个 Interger 类型的集合
        List<Integer> integer = new ArrayList<Integer>();
        integer.add(1);
        System.out.println(gt.wildCard(integer));
        //构造一个 String 类型的集合
        List<String> str = new ArrayList<String>();
        //gt.wildCard(str);   //编译报错
        //构造一个 Object 类型的集合
        List<Object> obj = new ArrayList<Object>();
        obj.add(1);
        obj.add("a");
        //System.out.println(gt.wildCard(obj)); //编译报错
         
    }

下限: 语法(? super className),即只能为 className 或 className 的父类

//通配符的上限,只能是 Number 或 Number的父类
    public List wildCard(List<? super Number> list){
         
        return list;
    }
 
    public static void main(String[] args) {
        GenericTest gt = new GenericTest();
        //构造一个 Interger 类型的集合
        List<Integer> integer = new ArrayList<Integer>();
        integer.add(1);
        //System.out.println(gt.wildCard(integer));  //编译报错
        //构造一个 String 类型的集合
        List<String> str = new ArrayList<String>();
        //gt.wildCard(str);   //编译报错
        //构造一个 Object 类型的集合
        List<Object> obj = new ArrayList<Object>();
        obj.add(1);
        obj.add("a");
        System.out.println(gt.wildCard(obj));
    }
 
public class Animal {
 
    public void print(){
        System.out.println("动物");
    }
}

public class Dog extends Animal{
 
    public void print(){
        System.out.println("Dog");
    }
}

public class Cat extends Animal{
 
    public void print(){
        System.out.println("Cat");
    }
}

public class Demo <T extends Animal>{
 
    private T ob;
 
    public T getOb() {
        return ob;
    }
 
    public void setOb(T ob) {
        this.ob = ob;
    }
 
    public Demo(T ob) {
        super();
        this.ob = ob;
    }
     
    public void print(){
        System.out.println("T的类型是:"+ob.getClass().getName());
    }
}

public class Test {
 
    public static void main(String[] args) {
        Demo<Dog> demo=new Demo<Dog>(new Dog());
        Dog dog=demo.getOb();
        dog.print();
         
         
        Demo<Cat> demo2=new Demo<Cat>(new Cat());
        Cat cat=demo2.getOb();
        cat.print();
         
        Demo<Animal> demo3=new Demo<Animal>(new Animal());
    }
}

不能用基本类型来定义泛型,如 int、float

如果使用 ? 接收泛型对象时,则不能设置被泛型指定的内容

List<?> list = new ArrayList<>();
        list.add("aa");  //错误,无法设置

泛型方法的定义与其所在的类是否是泛型类是没有任何关系的,所在的类可以是泛型类,也可以不是泛型类

泛型类没有继承关系,即String 为 Object 类型的子类,则 List<String> 是 List<Object> 的子类这句话是错误的

 public static <T> List<T> asList(T... a) {
        return new ArrayList<>(a);
    }
1 String[] str = {"a","b","c"};
2 List listStr = Arrays.asList(str);
3 System.out.println(listStr.size());//3
4 
5 int[] i = {1,2,3};
6 List listI = Arrays.asList(i);
7 System.out.println(listI.size());//1

上面的结果第一个listStr.size()==3,而第二个 listI.size()==1。这是为什么呢?

  我们看源码,在 Arrays.asList 中,方法声明为  <T> List<T> asList(T... a)。该方法接收一个可变参数,并且这个可变参数类型是作为泛型的参数。我们知道基本数据类型是不能作为泛型的参数的,但是数组是引用类型,所以数组是可以泛型化的,于是 int[] 作为了整个参数类型,而不是 int 作为参数类型。

  所以将上面的方法泛型化补全应该是:

 1 String[] str = {"a","b","c"};
 2 List<String> listStr = Arrays.asList(str);
 3 System.out.println(listStr.size());//3
 4 
 5 int[] i = {1,2,3};
 6 List<int[]> listI = Arrays.asList(i);//注意这里List参数为 int[] ,而不是 int
 7 System.out.println(listI.size());//1
 8 
 9 Integer[] in = {1,2,3};
10 List<Integer> listIn = Arrays.asList(in);//这里参数为int的包装类Integer,所以集合长度为3
11 System.out.println(listIn.size());//3

猜你喜欢

转载自blog.csdn.net/qq_35029061/article/details/84026292