首页 > 编程语言 >泛型—JAVA基础学习

泛型—JAVA基础学习

时间:2022-12-03 21:00:24浏览次数:39  
标签:JAVA name List 学习 add 泛型 new public

泛型

泛型的简单了解

为什么引入泛型?

泛型可以视为编写代码时的语法检查

这里可以通过一个简单的例子来看

当不使用泛型时:

class Stove{
	public static Object heat(Object food){
        Systom.out.println(food + "is done");
        return food;
    }
    public static void main(String[] args){
        Meat meat = new Meat;
        meat = (Meat)Stove.heat(meat);
        Meat soup = new Soup;
        soup = (Soup)Stove.heat(soup);
    }
}

可以发现:由于heat方法不知道返回类型是什么,因此在进行强制转换时很容易出现转换错误。泛型主要就是为了解决转换错误产生的。我们看一下使用泛型后的代码

class Stove{
	public static <T> T heat(T food){//方法的泛型
        Systom.out.println(food + "is done");
        return food;
    }
    public static void main(String[] args){
        Meat meat = new Meat;
        meat = Stove.heat(meat);
        Meat soup = new Soup;
        soup = Stove.heat(soup);
    }
}

这里使用T作为泛型来限制了返回类型和参数类型,就有效避免了类型转换的问题。

泛型的注意事项

  1. 泛型中的中的E必须是引用类型

  2. 泛型中指定具体类型中,可以传入该类型或子类型

  3. 泛型的简化形式:

    List <Integer> list1 = new ArrayList<>();
    

自定义泛型类

基本语法

class 类名 <T,R...>{

成员

}

参考代码

package fanxing;

import java.util.Arrays;

/**
 * @author Dyb
 * @description TODO
 * @date 2022-12-03 16:52
 */
public class CustomGeneric_ {
    public static void main(String[] args) {
        Tiger<Double, String, Integer> hohn = new Tiger<>("hohn");//这里是对于泛型的实现
        hohn.setT(10.9);//由于是识别到了Double类型,因此成功
    }
}
class Tiger<T,R,M>{//这里是对于泛型的标识
    String name;
    R r;
    M m;
    T t;
    T[] ts;
    public Tiger(String name) {
        this.name = name;
    }

    public Tiger(R r, M m, T t) {
        this.r = r;
        this.m = m;
        this.t = t;
    }

    public Tiger(String name, R r, M m, T t) {
        this.name = name;
        this.r = r;
        this.m = m;
        this.t = t;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public R getR() {
        return r;
    }

    public void setR(R r) {
        this.r = r;
    }

    public M getM() {
        return m;
    }

    public void setM(M m) {
        this.m = m;
    }

    public T getT() {
        return t;
    }

    public void setT(T t) {
        this.t = t;
    }

    public T[] getTs() {
        return ts;
    }

    public void setTs(T[] ts) {
        this.ts = ts;
    }

    @Override
    public String toString() {
        return "Tiger{" +
                "name='" + name + '\'' +
                ", r=" + r +
                ", m=" + m +
                ", t=" + t +
                ", ts=" + Arrays.toString(ts) +
                '}';
    }
}

自定义泛型接口

基本语法

Interface 接口名 <T,R..>{

}

代码演示

//在继承接口时指定泛型类型
interface IA extends IUSb<String, Double> {
}
//在实现接口时指定接口类型
class BB implements IUSb<Integer,Float>{
    @Override
    public Float get(Integer integer) {
        return null;
    }
}
//接口的泛型
interface IUSb<U,R>{
    R get(U u);
}

集合与泛型(重点)

LIST&LIST(object)&List<?>

可参考以下代码

public class Generic03 {
        public static void main(String[] args) {
            //原始的集合定义方式
            ArrayList a1 = new ArrayList();
            a1.add(new Object());
            a1.add(new Integer(111));
            a1.add(new String("hello,world"));

            //list<object>
            List<Object> a2 = a1;
            a2.add(new Object());
            a2.add(new Integer(222));
            a2.add(new String("hello,world1"));

            //List<Integer>
            List<Integer> a3 = a1;

            //List<?>
            List<?> a4 = a1;
            a1.remove(0);
            a4.clear();
//            a4.add(new Object())×
        }
}

LIST的用法和LIST的用法一致,唯一的区别在于List在接受其他泛型赋值的时候会进行泛型检查,只能赋值为Object型。

List<?>则是接受任何类型的集合赋值,可以remove和clear,但是由于类型不知,不能够add。

List<?extends T>&List<? super T>

几条原则

  1. List<?extends T>可以赋值给T及其T子类的集合(上界为T)
  2. List<? super T>可以赋值给T及其T父类的集合(下界为T)
  3. List<?extends T>由于不知道子类的具体对象,因此就不能进行add操作,除了add null。List<? super T>只能添加T本身及其子类对象。
  4. 所有的List<?super T>都可以进行Get操作,但是会出现泛型丢失,只能返回Object对象,List<?extends T>能够返回T和其父类对象,但是没法返回子类对象(跟3是对应的

对应代码

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

/**
 * @author Dyb
 * @description TODO
 * @date 2022-12-03 20:37
 */
public class Generic04 {
    public static void main(String[] args) {
        //1.声明集合
        List<Animal> animal = new ArrayList<Animal>();
        List<Cat> cat = new ArrayList<Cat>();
        List<Garfield> garfield = new ArrayList<Garfield>();
        //2.测试赋值操作
//        List<? extends Cat> extendsCat = animal;编译不通过,因为animal不是Cat的子类
        List<? super Cat> superCatform = animal;//运动通过,因为是父类
        List<? extends Cat> extendsCat = cat;//运行通过,因为是本类
        List<? super Cat> extendsCat2 = cat;//运行通过,因为是本类
//        List<? super Cat> superCatform2 = garfield;//运行失败,因为不是父类
        //3.测试add方法
        //除了null对象,任何对象都不能添加进<? extends Cat>
        extendsCat.add(null);
//        extendsCat.add(new Animal());失败
//        extendsCat.add(new Cat());
//        extendsCat.add(new Garfield());
        //可以添加本类及子类对象 List<? super Cat>
//        extendsCat2.add(new Animal());失败
        extendsCat2.add(new Cat());
        extendsCat2.add(new Garfield());
        //测试get方法
        Cat cat1 = extendsCat.get(0);//extends可以返回cat及其父类对象
        Object object = extendsCat2.get(2);//super只能返回object对象(泛型消失)

    }
}

//首先定义一下类的继承关系
class Animal{
    public int age;
}
class Cat extends Animal{

}
class Garfield extends Cat{

}

泛型的优点

主要就是

1.类型安全:保证了类型转换的安全性。

2.提升可读性和重用性

标签:JAVA,name,List,学习,add,泛型,new,public
From: https://www.cnblogs.com/robyn2022/p/16948763.html

相关文章