对于泛型类,泛型方法,泛型接口的初步认识

10 篇文章 0 订阅

泛型的学习

泛型类:

先看下面这个例子:

先写一个不是泛型的(定义构造方法和一个方法,来进行引用)。

package com.FanXing.Contrast;

public class Ordinary {
    private int number;//这里的number定义类型为:int

    public Ordinary(int number) throws Exception {
        this.number = number;
    }

    public int getnumber() {
        return number;
    }
}

测试类:

class TestSimple {
    public static void main(String[] args) {
        Ordinary Ord1 = new Ordinary(1111);
        try {
            Ordinary Ord2 = new Ordinary("整型类型的number");//这个是编译都通过不了吗?
            // 所以这里的try catch都直接不能输出。
        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            System.out.println(Ord1.getnumber());
        }

    }
}

输出为:
在这里插入图片描述

这里明显就能看出来错误,Ord2 里面输入"整型类型的number"是String类型的怎么可以转换成int嘛。改为int类型(或者这里直接把他删掉,就是对的了。)

class TestSimple {
    public static void main(String[] args)  {
        Ordinary Ord1 = new Ordinary(1111);
        System.out.println(Ord1.getnumber());
    }
}

输出为:

1111

然后是一个为泛型类型的类。

package com.FanXing.Contrast;

public class GenericsTest1_1<T> {
    private T number;//这次把这里的number改为泛型了。

    public GenericsTest1_1(T number) {
        this.number = number;
    }

    public T getnumber() {
        return number;
    }
}

泛型测试类:

class show {
    public static void main(String[] args) {
        GenericsTest1_1 t1 = new GenericsTest1_1(1111);
        GenericsTest1_1 t2 = new GenericsTest1_1("1111");
        System.out.println(t1.getnumber());
        System.out.println(t2.getnumber());
    }
}

输出为:

1111
1111

这里的String类型的为泛型,所以intString都可以。

但是对于intT(泛型)类型直接转换会报错。(如下方将参数的T改为int类型)

 private T number;

    public GenericsTest1_1(int number) {
        this.number = number;
    }
//下面左边的number与上面的 private T number对应。
//下面右边的number与形参的 int number 对应。
//也就是左边的T 不能转换成右边的 int

会报错。(这里用强转也是可以。不过下面测试类中的使用,又可以即用int又可以用String,但是为什么T这个泛型却不能直接转换成int或是String?)

对于泛型经常看到的肯定不只有用T的,常见的还有EKV。这几个符号都是用来表示泛型的。而且不仅仅只有这几中类型。用其他的大写字母,小写字母,字符串(AD ,a1),甚至是中文都行。但是以数字为开头却不行。
    
(那这里是不是得规避那些已经定义好了的数据结构类型,才能算作泛型。比如我定义String 肯定就不是泛型了对吧。)
    尝试了一下,发现并不是,尝试的几个封装类型Integer,Boolean,Double的都可以。基本数据类型像 int double反而不行。

这里给出一个改为String类型的例子。(发现是可以的,所以上面的说法是错的。String可以作为泛型类型来。)

package com.FanXing.Contrast;

public class GenericsTest1_1<String> {
    private String number;//以String来作为泛型字段。

    public GenericsTest1_1(String number) {
        this.number = number;
    }

    public String getnumber() {
        return number;
    }
}

对于常用的 意思是 :不确定的类型。

T :表示具体的一个类型。

K V :键和值的类型。

E : 元素(element)类型。

不仅是一个参数适用于泛型,对于多个参数也是可以用泛型来定义类型的,这样还省去了后续可能出现的类型转换问题。(比如map。) (那这么看来Object,也是泛型的一种咯。之前还对Object类型的参数不太了解。)
泛型接口。

定义接口:

package com.FanXing.interfaceTKEV;

public interface interfaceGenerics<T> {
    public T getShow(T t);//其中包括一个getShow()的方法。
}

测试类:(感觉这个泛型有包含的关系,跟String啊这些数据类型。)

package com.FanXing.interfaceTKEV;

public class interfaceGenericsTest<T> implements interfaceGenerics<String> {
    private String t;
    @Override
    public String getShow(String t) {
        this.t = t;
        return  t;
    }
    public void show() {
        getShow("pz");
        System.out.println(t);
    }

    public static void main(String[] args) {
        interfaceGenericsTest<String> test = new interfaceGenericsTest<>();
        test.show();
    }
}

输出为:

pz

上面这个测试类,有多次不直接使用T来充当泛型,在尝试过程中容易报错。(就像下面这样。)

 public static void main(String[] args) {
        interfaceGenericsTest<T> test = new interfaceGenericsTest<T>();
 }
如果把语句的泛型改为T。就会报错。(那是不同的方法没有static修饰,但是由于接口的方法是没用static修饰的,所以改起来要改的地方较多。)

在这里插入图片描述

如果就是要把其中的String全改为T呢。//(接口还是不变。)

package com.FanXing.interfaceTKEV;

public class interfaceGenericsTest<T> implements interfaceGenerics<T> {
    private T t;//因为this赋不上值了。类型不同,不强转的话。
    @Override
    public T getShow(T t) {//这个是用泛型来当作返回类型。
        return  t;
    }
    public void show() {
        getShow((T) "pz");//这里需要强转,不然会报错。
        System.out.println(t);
    }

    public static void main(String[] args) {
        interfaceGenericsTest<String> test = new interfaceGenericsTest<>();
        test.show();
    }
}

输出为:

null

这输出为null 是因为下面定义的类型中使String吗?(不过了解到在编译后会去泛型化,泛型不会进入运行时阶段。)所以就是上面因为不能定义 this.t = t。所以传的pz是没有赋值上的。

所以,在class interfaceGenericsTest<T>这个类中的private T t;属性t是没有被赋值上。所以是默认的初始值:null

那我要想输出,就直接把输出语句放getShow()里面就行了。

public T getShow(T t) {
    System.out.println(t);
    return  t;
}
//其他不变。

输出为:

pz
null

所以上面的猜测是正确的。

泛型通配符是什么?

还有Object ? 的区别。

泛型方法(可变参数,数组类型的泛型,静态的泛型类型)。

泛型方法。

粗略的说,也就是在返回值前有一个<T>修饰的方法,称为泛型方法。(一个非常简单的例子)

package com.FanXing.Gmethod;

public class GmethodTest1_1 {
    public static <T> void show() {// <-----这就是泛型方法。
        System.out.println("普通的show泛型方法");
    }

    public static void main(String[] args) {
        show();
    }
}

输出为:

普通的show泛型方法

是不是乍一看跟普通的方法没有什么区别。(至少这个例子看起来完全显示不出来区别(哭笑)主要是没有参数不好体现吧)。

package com.FanXing.Gmethod;

public class GmethodTest1_1 {//定义的泛型方法,带一个泛型参数。
    public static <T> String show(String name, T t) {
        System.out.println("稍微不普通的show泛型方法");
        String str = name + "    " + t;
        return str;

    }

    public static void main(String[] args) {
        GmethodTest1_1 method = new GmethodTest1_1();
        method.show("002", "200");//这个后面的类型是String
        System.out.println("----------------");
        System.out.println(method.show("002", "200"));
        String str1 = method.show("001", 100);//这个后面的类型是int或是Integer
        System.out.println(str1);
    }
}

输出为:

稍微不普通的show泛型方法
----------------
稍微不普通的show泛型方法
002    200
稍微不普通的show泛型方法
001    100

这样还是能体现一下泛型方法的特点了。但是这是不是容易跟只是有一个参数为泛型的,而本身却不是泛型方法的弄混。(所以这里我还把<T>去掉了来看看。会报错。)

通过上面的测试,需要清楚的是,泛型 所在的位置:

1.类后面,2.是返回值类型(这就单是T连尖括号都没有。),3.参数类型,4.返回值前。

可以看出,如果类不是泛型类,而且返回值前没有泛型的话,本身也不是返回值类型,再使用T作为参数类型的话,会报错的。

public void showTest1_2(T t) {
    }

就是上面这个形式。
(以下为对泛型作为参数时的小测试。)

package com.FanXing.Gmethod;

public class GmethodT<T> {
}

测试类:

package com.FanXing.Gmethod;

public class GmethodTest1_2 {
    public void showTest1_2(GmethodT<T> t) {
        
    }
    public static void main(String[] args) {
        
    }
    
    private class T {
    }
}

但是写成这个样子不会报错。(而且如果把GmethodT<T>T换成Number或是别的。连下面那个T的class都不需要定义。)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值