Java——泛型

从JDK1.5以后引入了三大常用新特性:泛型、枚举(enum)、注解(Annotation)。其中在JDK1.5中泛型是一件非常重要的实现技术,它可以帮助我们解决程序的参数转换问题。

一、泛型

泛型问题的引出

我们有这样一个场景,我需要给一个描述坐标的类提供一个参数,这个参数我们可以传入80,也可以传入东经80度,如何才能接收2种不同的类型呢?我们很容易想到使用Object来接收。

public class Test {
    public static void main(String[] args) {
        Point p = new Point();
        p.setX(20);
        int x = (Integer) p.getX();//取出数据
    }
}
class Point{
    private Object x;
    public Object getX() {
        return x;
    }

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

但是如果我们设置数据的时候类型有错而接收方不知道会是什么情况呢?

        p.setX("东经80度");
        int x = (Integer) p.getX();//取出数据

这个操作就会出现java.lang.ClassCastException,类型转换异常。

这个时候语法不会对其做任何限制,但执行的时候出现了程序错误,所以得出结论:向下转型是不安全的操作,会带来隐患。

为了避免这样的情况,引出了泛型。所谓的泛型,指的是在类定义的时候并不会设置类中的属性或方法的参数的具体类型,而是在类使用时在定义。

1.泛型类

语法:

class MyClass<T>{
    T value;
}

<>中的T被称为类型参数,用于指代任何类型,实际上这个T你可以任意写,出于规范起见,类型参数一般由单个大写字母来表示常见的如:

T :用在泛型类声明上,指代泛型类

E:一般用于属性

K、V :键值对

如果一个类被  <T> 的形式定义,那么它就被称为是泛型类。

泛型类的使用方法

class Point<T>{
    private T x;
    public T getX() {
        return x;
    }

    public void setX(T x) {
        this.x = x;
    }
}
public class Test {
    public static void main(String[] args) {
        Point<Integer> p = new Point<>();
        p.setX(80);
        int x = p.getX();
    }
}

我们发现在获取值时我们不需要向下转型了,泛型的出现彻底解决了向下转型带来的ClassCastException问题。引入泛型后,如果明确设置了类型,则为设置类型;如果没有设置类型,则默认为Object类型。

注意:泛型只能接受类,所有的基本数据类型必须使用包装类!

泛型类可以引入多个类型参数,当泛型类中需要多个不同类型变量时,<>以“,”分割声明不同大写字母即可。如:

class MyClass<T,E>{
    T value;
    E value2;
}

2.泛型方法

泛型不仅可以用于定义类,还可以单独来定义方法。

语法:

class MyClass{
    public <T> void method(T t){
        System.out.println(t);
    }
}

泛型方法与泛型类稍有不同的地方是,类型参数也就是尖括号那一部分是写在返回值前面的。 <T> 中的 T 被称为类型参数,而方法中的 T 被称为参数化类型,它不是运行时真正的参数。

当然,声明的类型参数,其实也是可以当作返回值的类型的。

class MyClass{
    public <T> T method(T t){
        return t;
    }
}

泛型方法与泛型类可以共存:

class MyClass<T>{
    public void method(T t){
        System.out.println(t);
    }
    public <T> T method2(T t){
        return t;
    }
}
class Test{
    public static void main(String[] args) {
        MyClass<String> myClass = new MyClass<>();
        myClass.method("泛型类");
        Integer s = myClass.method2(100);
        System.out.println(s);
    }
}

当泛型类与泛型方法共存时,泛型方法中的类型参数与泛型类的类型参数无关,泛型方法始终以自己的的类型参数为准。上面代码中,MyClass <T> 是泛型类,method 是泛型类中的普通方法,而 method2 是一个泛型方法。而泛型类中的类型参数与泛型方法中的类型参数是没有相应的联系的,泛型方法始终以自己定义的类型参数为准。泛型类的实际类型参数是 String,而传递给泛型方法的类型参数是 Integer,两者不相干。规范起见,当泛型类与泛型方法共存时,使用不同的类型参数来区分彼此。

class MyClass<T>{
    public void method(T t){
        System.out.println(t);
    }
    public <E> E method2(E e){
        return e;
    }
}

三、泛型接口

泛型除了可以定义在类中,也可以定义在接口里面,这种情况我们称之为泛型接口。

定义一个泛型接口

interface IMyinterface<T>{
    void print(T t);
}

对于这个接口的实现子类有两种做法:

1.子类实现接口时继续保留泛型

2.子类实现接口时就确定好泛型

第一种情况:子类实现接口时继续保留泛型

interface IMyinterface<T>{
    void print(T t);
}

class myClassImpl<T> implements IMyinterface<T>{
    @Override
    public void print(T t) {
        System.out.println(t);
    }
}
class Test{
    public static void main(String[] args) {
        IMyinterface<String> iMyinterface = new myClassImpl<>();
        iMyinterface.print("Hello");
    }
}

第二种情况:子类实现接口时就确定好泛型

interface IMyinterface<T>{
    void print(T t);
}
class myClassImpl implements IMyinterface<String>{
    @Override
    public void print(String t) {
        System.out.println(t);
    }
}
class Test{
    public static void main(String[] args) {
        IMyinterface<String> iMyinterface = new myClassImpl();
        iMyinterface.print("Hello");
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值