简述Java、Go中的泛型

泛型

一、泛型、为什么需要泛型

  • 泛型

    泛型是一种参数化类型,泛型的核心作用是解除类或者方法所受类型的限制,使得代码能够更加的通用,极大的提高了代码的复用率。泛型的产生为程序员提供了便利,程序员可以充分发挥自己的想象,尽可能的抽象方法或者类的行为表达,使用较少的代码提供更为通用的功能。

  • 为什么需要泛型

    1、泛型提供了编译期检查的功能,代码在编译期就能发现其中的错误,增强了代码的健壮性

    2、泛型是自动化转型的,不同于Java中的继承等,会存在强制转型带来的不安全性,增加了代码的安全性

    3、增加了代码的可读性、通用性和稳健性,使得一套代码可以适用一类场景

二、泛型困境是什么

  • 泛型困境

    泛型其实是一把双刃剑,既可能给开发者带来了便利,但是同样会带来编译和效率的问题。

    要么苦了程序员,要么苦了编译器,要么降低运行时效率。

    即,要么程序员苦一些,编译器负担轻一些,要么就是编译器工作多一些,程序员使用舒服一些,当然运行的效率和不同语言泛型的编排有关。

三、Golang里面的泛型

  • Go语言中把泛型(Generic)叫做类型参数,Go语言在原来的函数名和函数参数列表之间插入了一组方括号,来表示类型参数。

  • 语法总结

    参考文档:https://taoshu.in/go/generics/design.html

    函数可以定义类型参数:
       可以在函数名称的后边,使用中括号声明一个额外的类型参数列表,例如 
       func F[T any](p T) { ... }
    可以在参数声明和函数体中使用类型参数指定类型。
    类型定义也可以指定类型参数: 
      可以在类型名称的后边,使用中括号声明一个额外的类型参数列表,例如
      type M[T any] []T。
      type Stack[T any] struct {
    		eles []T
    	}
    类型参数必须指定类型约束: func F[T Constraint](p T) { ... }。
    使用泛型函数或者类型需要传入类型参数。
    通过泛型推导可以减少指定类型参数,简化泛型的使用。	
    
  • 举例

    package main
    
    import (
    	"fmt"
    )
    
    type Addable interface {
    	int | int8 | int16 | int32 | int64 | uint | uint8 | uint16 | uint32 | uint64 | uintptr | float32 | float64 | complex64 | complex128 | string
    }
    
    func add[T Addable](a, b T) T {
    	return a + b
    }
    
    func main() {
    	fmt.Println(add(1, 2))
    
    	fmt.Println(add("foo", "bar"))
    }
    
    

四、Java里面的泛型

  • 在Java中,为了方便接收参数类型的统一,提供了一个统一的Object类,Object 类是所有类的父类,也就是说Java 的所有类都继承了Object,子类可以使用Object 的所有方法。 Object 类位于java.lang 包中,编译时会自动导入。因此可以利用Object类对象接收所有类型的数据。

    不过,使用Object类对象虽然可以接收所有类型的数据,但是由于Object类是一个顶级的父类,数据范围过大,在数据的使用过程中,容易出现数据类型的强制性向下转型,使得执行出现了不安全性。

  • Java泛型的设计意义在于:类中的属性或者方法的参数与返回值的类型采用动态标记,在对象实例化的时候动态配置需要使用的实际数据类型,有效避免了Object接收参数所带来的ClassCastException问题。

  • 举例:

    // 泛型接口
    interface T0 <T>{
        public void toString(T ...t);
    }
    
    // 泛型类
    class Point<T> implements T0<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 this.x;
        }
        public T getY(){
            return this.y;
        }
    
        // 泛型方法
        public void toString(T ...t){
            for (T p:t) {
                System.out.println("坐标:" + p);
            }
        }
    
        public String getPoint() {
            return "Point{" +
                    "x=" + x +
                    ", y=" + y +
                    '}';
        }
    }
    
    public class Test {
        public static void main(String[] args) {
            Point<Integer> point = new Point<>();
            point.setX(10);
            point.setY(10);
            point.toString(point.getX(),point.getY());
            System.out.println(point.getPoint());
        }
    }
    
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

玉言心

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值