java泛型的使用

java泛型的使用

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

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

泛型是在编译阶段有效

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

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

泛型类

public class CC{
 
    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 cc=new CC(1);
        cc.print();
        int icc=cc.getOb();
        System.out.println("i3="+icc);
         
        CC cc2=new CC("我是泛型,好简单啊");
        cc2.print();
        String icc2=cc2.getOb();
        System.out.println("s2="+icc2);
        // end test CC


 

java泛型的使用_第1张图片

泛型方法

public class Box {
    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
Tom T的实际类型为:java.lang.String

 

返回值为任意类型的泛型

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

java泛型的使用_第2张图片

泛型的上限和下限

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

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

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

//通配符的上限,只能是 Number 或 Number的父类
    public List wildCard(List list){
         
        return list;
    }
 
    public static void main(String[] args) {
        GenericTest gt = new GenericTest();
        //构造一个 Interger 类型的集合
        List integer = new ArrayList();
        integer.add(1);
        //System.out.println(gt.wildCard(integer));  //编译报错
        //构造一个 String 类型的集合
        List str = new ArrayList();
        //gt.wildCard(str);   //编译报错
        //构造一个 Object 类型的集合
        List obj = new ArrayList();
        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 {
 
    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 demo=new Demo(new Dog());
        Dog dog=demo.getOb();
        dog.print();
         
         
        Demo demo2=new Demo(new Cat());
        Cat cat=demo2.getOb();
        cat.print();
         
        Demo demo3=new Demo(new Animal());
    }
}

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

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

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

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

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

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

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

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

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

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

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(经典后端)