java中的泛型类

我们为什么要使用泛型?

答:因为当我们将一个对象放入集合中时,集合不会记住此对象的类型,当再次从集合中取出此对象时,该对象的编译类型变成了Object类型,但其运行时类型依然是本身类型。
因此,当我们取出集合元素的时候就需要人为地强制转换类型,然后很容易就出现“java.lang.ClassCastException”异常,因为要避免类型转换异常,所以我们就需要使用泛型!

注:当我们使用泛型时,如果添加的值与泛型中的值不同时,那么就会编译错误!

泛型类

public class Generic {//定义泛型类
    private T name;//泛型变量,但为了测试,提前写好了变量名
    private T age;//泛型变量,但为了测试,提前写好了变量名
    //Set和Get方法
    public void setAge(T age) {
        this.age = age;
    }
    public T getAge() {
        return age;
    }
    public void setName(T name) {
        this.name = name;
    }
    public T getName() {
        return name;
    }
}

调用泛型类

public class TestGeneric {
    public static void main(String[] args){
      //声明一个泛型为String类型的对象
       Generic gg = new Generic();
       gg.setName("路人甲");//调用set方法
        //声明一个泛型为Integer类型的对象
        Generic g = new Generic();
        g.setAge(15);//调用set方法
      //调用get方法
       System.out.println(gg.getName() + "今年" + g.getAge() + "岁!");
    }
}

泛型方法与泛型静态方法

//声明一个泛型类
public class GenericMethod {
    //声明一个泛型普通方法
    public void show(T t){
        System.out.println(t);
    }
    //声明一个泛型静态方法
    public static void StaticMethod(T t){
        System.out.println("静态方法中的t:" + t);
    }
}

调用泛型方法与泛型静态方法

public class TestGM {
    public static void main(String[] args){
          //声明一个String类型的泛型对象
        GenericMethod g = new GenericMethod();
        //调用普通的泛型方法
        g.show("name1");
        //调用静态的泛型方法
        g.StaticMethod("name");
    }
}

如何可以获取泛型中的类型

/*
*需要导入这两个包
* import java.lang.reflect.ParameterizedType;
* import java.lang.reflect.Type;
* */
abstract class Foo {
    public Class getTClass() {
        Class tClass = (Class) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
        return tClass;
    }
}

调用方法(不懂,先记下!)

 Foo foo = new Foo() {};
        // 在类的外部这样获取
        Type type = ((ParameterizedType)foo.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
        System.out.println(type);
        // 在类的内部这样获取
        System.out.println(foo.getTClass());

泛型接口

//声明一个泛型接口!
public interface GenericInterface {
    //定义一个抽象方法,方法名为show,参数列表:类型为T,值为t
    public abstract void show(T t);
}

类实现接口

//继承泛型接口
public class TestGI implements GenericInterface {
    //重写方法
    @Override
    public void show(String s) {//规定了泛型为String类型
        System.out.println("实现泛型接口中的方法:" + s);
    }
}

调用接口中的方法

public class TestGI1  {
    public static void main(String[] args){
        //因为在实现类中已经定义了泛型,所以直接使用便是,定义类型为String类型
        TestGI tgi = new TestGI();
        tgi.show("路人甲!");
        //下方的代码是要报错的,因为在泛型中已经规定了泛型为String类型
        //TestGI tgi2 = new TestGI();
        //tgi2.show(10);
    }
}

接口,如果实现类不明确子类的参数类型时,也可以使用泛型来规定值!

//实现泛型接口,在类名后定义泛型
public class TestGI implements GenericInterface {
    @Override
    //因为不确定子类的参数类型,所以参数列表为泛型
    public void show(T t) {
        System.out.println("子类不明确泛型类的类型参数变量,实现类的时候也要定义出类型的:" + t);
    }
}

实现泛型接口

TestGI tgi = new TestGI();
tgi.show(10);

通配符

?代表任意类型,使用通配符定义泛型类型,此时只能输出,不能修改!

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

public class GenericTPF {
        public static void main(String[] args){
            //定义一个Integer类型的集合
            List list = new ArrayList();
            list.add(10);
            list.add(20);
            list.add(30);
            list.add(40);
            list.add(50);
            //调用静态方法,遍历list集合
            test(list);
            System.out.println();
            //定义一个String类型的集合
            List list1 = new ArrayList();
            list1.add("路人甲");
            list1.add("路人乙");
            list1.add("路人丙");
            list1.add("路人丁");
            //调用静态方法,遍历list1集合
            test(list1);
        }
    //写一个用来遍历集合的静态方法
    public static void test(List list){
        //迭代器,需要加载java.util.Iterator;
        Iterator it = list.listIterator();
        while(it.hasNext()){
        Object o  = it.next();
        System.out.print(o + "\t");
        }
    }
}

泛型上限

只能调用本身及本身一下的类型,关键字为:<? extends 本身>,只能输出,不能修改!

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/*
* ?相当于是子,Number相当于是父
* 只要是继承于Number的便可以
*/
public class GenericTPFE {
    public static void main(String[] args){
        /*
        * 因为Integer是Number下面的子类,所以可以正常调用
        * */
        List list = new ArrayList<>();
        list.add(10);
        list.add(20);
        list.add(30);
        list.add(40);
        test(list);
        /*
        * Object远大于Number,所以会报错
        * */
        List list1 = new ArrayList<>();
        list1.add("路人甲");
        list1.add("路人乙");
        list1.add("路人丙");
        list1.add("路人丁");
//        test(list1);//报错啦!


    }
    public static void test(List list){
        Iterator it = list.listIterator();
        while(it.hasNext()){
            Object o = it.next();
            System.out.print(o + "\t");
        }
    }
}

泛型下限

只能设置具体的类或者是父类,写法

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

public class GenericTPFS {
    /*
    * ? super 下限类
    * 太阳为最高类,地球继承了太阳,月亮继承了地球
    * */
    static class Sun{}
    static class Earth extends Sun{}
    static class Moon extends Earth{}
    public static void main(String[] args){
        List list = new ArrayList();
        test(list);//因为Earth继承了Sun,所以,满足Earth是下限的要求
        List list1 = new ArrayList();
//        test(list1);
        /*
        * 因为Moon继承了Earth,所以,不满足Earth是下限的要求
        * */
    }
    public static void test(List list){
        System.out.println(list + "是权限高于Earth的类!");
    }

}

好烦啊!!!!!本文为个人随笔,为方便日后自己查看所写,如有错误和不足的地方,请尽早联系!

你可能感兴趣的:(java中的泛型类)