泛型

来源:互联网 发布:淘宝用什么打折软件 编辑:程序博客网 时间:2024/05/29 18:35

对于泛型的基本概念就不多讲,需要了解泛型的知识点可以看下图:
这里写图片描述
泛型解决了java中对Object的任意化操作所产生的问题,这种任意化操作就是Object引用进行“向上转型”或者“向下转型”操作,但是某些操作强制类型转换的错误也许不会被编译器捕捉,而在运行的时候出现异常,可见类型转换存在安全隐患,所以在此提供安全省心的泛型类型。

泛型的初步了解

1、泛型类:

class 类名<字母,字母......>{        private 字母 属性名;        …setter与getter.}

需要注意的是:
          a) 泛型不能使用在基本类型上
          b) 泛型不能使用在静态属性上

public class Student<T,T1> {   private T javase;   public Student() {   }   public Student(T javase) {      this.javase =javase;   }   public T getJavase() {      return javase;    }   public void setJavase(T javase) {       this.javase = javase;   }}

2、泛型接口
接口中泛型字母只能使用在方法中,不能使用在全局常量中

public interface Comparator<T> {    void compare(T t);      //T Max_Value = 100;  //会报错 }

3、泛型方法
泛型方法一般都是在返回值之前加<字母>,泛型方法可以在非泛型类中

public class TestMethod {    public static void main(String[] args) {        test("a"); //T -->String    }    //定义泛型方法    public static <T> void test(T a){               System.out.println(a);    }    // extends表示上限<=   ...表示可变参数,例如将其换成[]就成了数组    public static <T extends Closeable> void test(T... a){        for(T temp:a){            try {               if(null!=temp){  temp.close();}            } catch (IOException e) {                e.printStackTrace();            }        }    }}

泛型的深入

泛型的继承
当父类为泛型的话,子类也必须要保留父类的泛型或者实现父类的泛型,而且子类泛型必须>=父类泛型,也就是会所子类的泛型可以比父类多。当子类没写父类的具体实现的话,就会默认为Object,而泛型的接口和类的继承是一样的

  /**     * 泛型父类,子类为富二代      * 1、保留父类泛型 -->子类为泛型     * 2、不保留父类泛型 -->子类按需实现     *      * 属性 及方法 类型 -->随位置而定     * 1)、子类重写方法的类型 -->随父类而定     * 子类新增方法的类型 -->随子类而定     * 2)、子类中使用父类的属性 -->随父类而定     * 子类中使用自己的属性 -->随子类而定     * @author bj     *     */public class Class_Extends{    public abstract class Father<T1,T2> {        T1 age;        public abstract void test(T2 name);    }    //保留  -->泛型子类    //1)、全部保留    class Child1<T1,T2,A,B> extends Father<T1,T2>{        T1 age;//this.age -->T1        A Sex;        @Override        public void test(T2 name) {        }        public void test2(B b){        }       }    //2)、部分保留    class Child2<T2,A,B> extends Father<Integer,T2>{        Integer age;//this.age -->Integer        A Sex;        @Override        public void test(T2 name) {        }        public void test2(B b){        }       }    //不保留  -->按需实现    //1)、具体类型    class Child3 extends Father<Integer,String>{        Integer age;//this.age -->Integer        @Override        public void test(String name) {         }    }    //2)、没有类型 擦除 Object    @SuppressWarnings("rawtypes")    class Child4 extends Father/*<Object,Object>*/{        Object age;//this.age -->Object        @Override        public void test(Object name) {         }    }}

泛型的擦除

public class MyStudent<T> {    private T javase;    //private static T test; //泛型不能使用在静态属性上    public MyStudent() {    }    public MyStudent(T javase) {        this.javase = javase;    }    public T getJavase() {        return javase;    }    public void setJavase(T javase) {        this.javase = javase;    }}
public class MyStudentImpl {    /**     * 泛型的擦除: 使用时 |实现|继承 没有指定类型 ,     * 类似于 Object ,不等同于 Object     */    public static void main(String[] args) {        //擦除 -->没有指定 泛型的具体类型        MyStudent student =new MyStudent();        student.setJavase(100); //100 -->int -->Integer -->Object        Object obj=student.getJavase();        System.out.println(obj);        test(student);//编译不会类型检查,此处不会报错,因为Object类型相当于被擦除了        MyStudent<Object> student2 =new MyStudent<Object>();        //不等于 Object        //test(student2); -->会报错,因为这个地方已经申明了Object类型,就只能是Object类型    }    public static void test(MyStudent<Integer> stu){    }}
import java.util.ArrayList; public class ErasedTypeEquivalence {       public static void main(String[] args) {           //我们分别定义了一个接受String类型的List和一个接受Integer类型的List,          //按照我们正常的理解,泛型ArrayList<T>虽然是相同的,但是我们给它传了不同的类型参数,          //那么c1和2的类型应该是不同的。但是结果恰恰相反,运行程序发现二者的类型时相同的。这是为什么呢?          //这里就要说到Java语言实现泛型所独有的——擦除            Class c1 = new ArrayList<String>().getClass();             Class c2 = new ArrayList<Integer>().getClass();        System.out.println(c1 == c2);       }  }
原创粉丝点击