java——泛型

1、泛型的引入

假设现在有一个坐标类Point,有两个属性,x坐标和y坐标;x y取值共有三种情况
case1:x=10.1 y=18.9(double)
case2:东经101度,北纬30度(字符串)
case3:x=10 y=49(整型)

Point{
x;
y;
}
此时问题就来了,定义x y时应该定义为什么类型?
我们都知道Object类是所有类的父类,因此可以接受所有类型,有包装类的自动拆装箱,基本类型自动装箱变为Integer或Double让Objext类接收。

// 坐标类
public class Point {
    private Object x;
    private Object y;
    public Object getX() {
        return x;
    }
    public Object getY() {
        return y;
    }
    public void setX(Object x) {
        this.x = x;
    }
    public void setY(Object y) {
        this.y = y;
    }
    public static void main(String[] args) {
        Point point=new Point();
        point.setX(10.2); // 自动装箱,把double类型变为包装类的double类型,用Object接收
        point.setY(12.3);
        // 自动拆箱
        double x=(double) point.getX();
        double y=(double) point.getY();
        System.out.println("x = " + x + " y = " + y );
        Point point1=new Point();
        // 自动拆箱
        point1.setX("东经101度");
        point1.setY("北纬30度");
        String x1=(String) point1.getX();
        String y1=(String) point1.getY();
        System.out.println("x = " + x1 + " y = " + y1);
    }
}

运行结果
x = 10.2 y = 12.3
x = 东经101度 y = 北纬30度

此时可以接收不同类型,但依然存在风险,自动拆箱时的强制类型转换。x y都是相同的类型,若用户不小心输入的x和y 类型不同时,就会在强转时发生错误。

package java1_22_inner_and_rawtype;
// 坐标类
public class Point {
    private Object x;
    private Object y;
    public Object getX() {
        return x;
    }
    public Object getY() {
        return y;
    }
    public void setX(Object x) {
        this.x = x;
    }
    public void setY(Object y) {
        this.y = y;
    }
    public static void main(String[] args) {
        Point point=new Point();
        point.setX(10.1);
        point.setY("北纬30度");
        String x=(String) point.getX();
        String y=(String) point.getY();
        System.out.println("x = " + x + " y = " + y);
    }
}

运行结果
在这里插入图片描述

2、泛型定义

泛型:类定义时不会设置类中属性或方法参数的具体类型,而是在类使用时(创建对象)再进行类型的定义。
泛型的基本使用:守门员,在编译期检查错误。
类声明后的<>中的T被称为类型参数,用于指代任意类型,实际上这个T只是个代表,写啥都行。表示此时value1, value2都是在类定义时没有明确类型,只有在使用时才告知编译器类型。就像定义坐标x,y 时,并不知道x.y 是什么类型,赋值使用才能明确类型。出于规范而言,类型参数用单个的大写字母来代替。常见的如下:
T :代表任意类
E:表示Element的意思,或是异常
K:与V搭配使用,Map<Integer,String>
V:

// 泛型类
public class Generic<T> {
    T value1;
    T value2;
    public void setValue1(T value1) {
        this.value1 = value1;
    }
    public void setValue2(T value2) {
        this.value2 = value2;
    }
    public T getValue1() {
        return value1;
    }
    public T getValue2() {
        return value2;
    }
}

当类型明确后,赋值为其他类型,编译器就会报错,这也是泛型的意义。
在这里插入图片描述
若value1与value2类型不同,可定义多个类型参数

// 泛型类
// T和E表示两种类型参数,在具体使用时可以相同也可以不同
public class Generic<T,E> {
    T value1;
    E value2;
    public static void main(String[] args) {
        // 创建这个泛型类的时候才明确类型为整型
        Generic<Integer,String> generic=new Generic<>();
        generic.value1=10;
        generic.value2="123";
        Generic<Integer,Integer> generic1=new Generic<>();
        generic1.value1=10;
        generic1.value2=30;
    }
}

使用泛型改造Point类

package java1_22_inner_and_rawtype;

// 泛型坐标类
public class GenericPoint<T> {
    private T x;
    private T y;

    public void setX(T x) {
        this.x = x;
    }

    public void setY(T y) {
        this.y = y;
    }

    public T getX() {
        return x;
    }

    public T getY() {
        return y;
    }
    public static void main(String[] args) {
        GenericPoint<String> genericPoint=new GenericPoint<>();
        genericPoint.setX("北纬20度");
        genericPoint.setY(10);
    }
}

当创建GenericPoint对象时设置的类型与实际存储类型不同时,编译就会报错,提前将问题暴露。
在这里插入图片描述
泛型不光可使问题提前暴露。还可以不用强制类型转换。

 public static void main(String[] args) {
        GenericPoint<String> genericPoint=new GenericPoint<>();
        genericPoint.setX("北纬20度");
        genericPoint.setY("东京49度");
        // 不需要强制类型转换
        String x= genericPoint.getX();
        String y= genericPoint.getY();
    }

3、泛型方法

此处的泛型方法指的是有自己的类型参数

之前的这个不是泛型方法,只不过是返回值或参数使用了泛型变量而已,此时T是泛型类的参数
public void setY(T y) {
this.y = y;
}
public T getY() {
return y;
}

泛型方法

package java1_22_inner_and_rawtype;

public class GenericMethod<T,E> {
    T value1;
    E value2;
    // 泛型方法
    public <T> void test(T t){
        System.out.println(t);
    }
    public static void main(String[] args) {

    }
}

在这里插入图片描述
泛型方法始终以自己的类型参数为准,与类中类型参数无关,为了避免混淆,定义泛型方法时,尽量避免使用类中使用过的类型参数字母。

package java1_22_inner_and_rawtype;

public class GenericMethod<T,E> {
    T value1;
    E value2;
    // 泛型方法
    public <S> void test(S t){
        System.out.println(t);
    }
    public static void main(String[] args) {
        GenericMethod<Integer,String> genericMethod=new GenericMethod<>();
        genericMethod.value1=10;
        // genericMethod.value1="123";
        genericMethod.test("123");
    }
}

泛型方法有返回值时

 // 泛型方法
    public <S> S test(S t){
        System.out.println(t);
        return t;
    }

9

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值