Java拾贝第九天——泛型

Java拾贝不建议作为0基础学习,都是本人想到什么写什么

如果一个类中,不想限定一个属性的数据类型,或某个方法的返回值和传参。

可以在类声明时通过一个标识来表示。

这样只需要在实例化类的时候声明具体的数据类型即可,这就是泛型

也可以理解为广泛的数据类型,即不限制的数据类型

泛型类

泛型作用于类上就是泛型类。

声明一个泛型类

class 类名<泛型标识符>{//拥有标识符的类就是泛型类
 访问修饰符 泛型标识符 变量名;
 访问修饰符 泛型标识符 方法名(){};
 ....
}

栗子:

public class Test9 {
    public static void main(String[] args) {
        MyF<String> f = new MyF<String>();
	//外部指定数据类型  第二个<>中的String可以省略
        f.setName("泛型");
    }
}
class MyF<T> {//泛型类
    private T name;//属性不定义具体类型,使用泛型替代数据类型

    public MyF() {
    }
    public MyF(T name) {//构造方法也可也使用泛型
        this.name = name;
    }
    public T getName() {//返回类型使用泛型
        return name;
    }
    public void setName(T name) {//传参使用泛型
        this.name = name;
    }
}

上门的MyF类就是泛型的具体体现。其调用了"<T>"形式,泛型表示具体类型是由外部实例化MyF类时指定的。

<>中可以是任意的大写字母,<A>、<B>都可以。这里采用T仅仅是取type的开头而已。

泛型类在被初始化时指定类型

基本类型是无法指定的,只能指定引用类型

栗子:

MyF<int> f = new MyF<>();//错错错

传入的类型与泛型不一致。

栗子:

public class Test9 {
    public static void main(String[] args) {
        MyF<Integer> f = new MyF<>();
        f.setName("传入String类型");//编译错误 初始化时指定的是Integer类型
    }
}
class MyF<T> {
    private T name;

    public MyF() {
    }
    public MyF(T name) {
        this.name = name;
    }
    public T getName() {
        return name;
    }
    public void setName(T name) {
        this.name = name;
    }
}

传入的类型可以是某个类或其子类

栗子:

public class Test9 {
    public static void main(String[] args) {
        Point<Son> point = new Point<>();
	//Point<Dad> point = new Point<>();一样没问题的
    }
}
class Dad{
    
}
class Son extends Dad{
    
}
class Point<T>{
    private T name;

    public Point() {
    }

    public Point(T name) {
        this.name = name;
    }

    public T getName() {
        return name;
    }

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

静态属性不能使用泛型
栗子:

class Point<T>{
    static T t;//错错错

因为静态处于全局内存区,JVM对静态的初始化会在类实例化之前。

此时使用泛型会导致JVM初始化全局内存不成功。因为泛型是不确定的数据类型

多个泛型

栗子:

public class Test9 {
    public static void main(String[] args) {
        Point<String, Integer> point = new Point<>("小明",18);
	//外部指定属性name数据类型为String,属性age数据类型为Integer
    }
}

class Point<T,K>{//任意字母都行
    private T name;
    private K age;

    public Point() {
    }

    public Point(T name, K age) {
        this.name = name;
        this.age = age;
    }

    public T getName() {
        return name;
    }

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

    public K getAge() {
        return age;
    }

    public void setAge(K age) {
        this.age = age;
    }
}

泛型擦除

即外部不指定具体类型。
栗子:

public class Test9 {
    public static void main(String[] args) {
        Point point = new Point();
        point.setName("小明");
    }
}

class Point<T>{
    private T name;

    public Point() {
    }

    public Point(T name) {
        this.name = name;
    }

    public T getName() {
        return name;
    }

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

上述栗子会出现不安全警告信息。

虽然不指定泛型类型后编译出现了警告,但是并不影响程序运行。

这是因为Java在这种情况(不指定泛型类型)下默认采用Object进行接收。也称泛型擦除

泛型接口

泛型作用于接口上就是泛型接口。

interface 接口名<泛型标识符>{//泛型接口
}

栗子:

interface Cat<T>{
   void getCat(T t);
}

泛型接口在被继承,或被实现时需指定类型

栗子:

interface Cat<T>{
   void getCat(T t);
}
interface Dog extends Cat<String>{//被继承
}
class tc implements Cat<String>{//被实现
    @Override
    public void getCat(String s) {
        System.out.println("不定义会泛型擦除,记得确定数据类型");
    }
}

泛型方法

泛型作用于方法上就是泛型方法。

栗子:

    public <T> void opq(T temp1) {
        System.out.println(temp1);
    }

可以使用泛型类中的泛型标识符,或泛型方法中的泛型标识符。

栗子:

class Gen<T>{
    public <K,V> void tell(T t,K k){//可以使用泛型类中的泛型标识符,或泛型方法中的泛型标识符。
        System.out.println("泛型类中的泛型方法");
    }
}

泛型方法不光可以在泛型类中,还可以在普通类中:

栗子:

class Pen{
    public <K,V> void tell(K k){//泛型不一定要全部使用
        System.out.println("普通类中的泛型方法");
    }
}

普通方法也可也使用泛型:
栗子:

class Gen<T>{
    public <K> void tell(T t){//泛型方法
        System.out.println("泛型类中的泛型方法");
    }
    public void say(T t){//只是传参使用泛型而已 这不是泛型方法!!!
        System.out.println("普通方法使用泛型");
    }
}

补充
泛型方法中一个泛型可以当多个数据类型使用。
栗子:

public class Test10 {
    public static void main(String[] args) {
        opq("张三", 18);
    }

    public static <T> void opq(T temp1, T temp2) {
        System.out.println(temp1 + " + " + temp2);
    }
}

程序运行结果:

张三 + 18

静态方法的返回值不能使用泛型!
栗子:

    public static <T> opq(T temp1) {//错错错
        System.out.println(temp1);
    }
posted @ 2023-10-23 21:56  rowbed  阅读(1)  评论(0编辑  收藏  举报