java泛型学习

设计目的

当我们将一个对象放入集合中,集合不会记住此对象的类型,
当再次从集合中取出此对象时,改对象的编译类型变成了Object类型,但其运行时类型任然为其本身类型
取出集合元素时需要人为的强制类型转化到具体的目标类型,强转的时候容易报错"java.lang.ClassCastException"

引出泛型

使集合能够记住集合内元素各类型,且能够达到只要编译时不出现问题,运行时就不会出现“java.lang.ClassCastException”异常呢

字母代表规则

一般Java中,使用变量E表示集合元素类型。K表示关键字,V表示值。T(或者U、S)表示"任意类型"。

类型

1.集合中用到泛型

Map<String, Integer> hm = new HashMap<String, Integer>();
List<String> list = new ArrayList<String>();

2.类中用到泛型
2.1成员变量可以使用泛型

/**
 * @description: ${description}
 * @create: 2019-02-16
 * 泛型类
 * 用在成员变量上,只能使用引用类型
 **/
public class Lottery<T> {
    private T number;

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

    public T getNumber() {
        return number;
    }

    public void setNumber(T number) {
        this.number = number;
    }

    public static void main(String[] args) {
        Lottery<String> lottery1=new Lottery<String>("123abc");
        Lottery<Integer> lottery2=new Lottery<Integer>(123);
        System.out.println(lottery1.getNumber());
        lottery2.setNumber(456);
        System.out.println(lottery2.getNumber());
    }
}

运行结果:
在这里插入图片描述
2.2类中方法的参数或者返回值可以使用泛型

package fanxing;

/**
 * @description: ${description}
 * @create: 2019-02-17
 **/
public class Iphone<K,V>{
    void method1(K k){
        System.out.println(k.toString());
    }
    V method2(V v){
        return v;
    }
    K method3(String s){
        System.out.println(s.length());
        return (K) (s+s);
    }

    public static void main(String[] args) {
        Iphone<String,Integer> iphone6=new Iphone<>();
        iphone6.method1("kakaka");
        Integer integer = iphone6.method2(9999);
        System.out.println(integer);
        String s = iphone6.method3("6666");
        System.out.println(s);
    }
}

运行结果:
在这里插入图片描述
3.接口使用泛型
3.1接口

public interface Fruit <T> {
    public T get();
}

3.2接口的实现类1

public class PriceFruit implements Fruit<Integer> {
    @Override
    public Integer get() {
        return 666;
    }
}

3.3接口的实现类2

public class RedFruit implements Fruit<String> {
    @Override
    public String get() {
        return "red apple";
    }
}

4泛型方法
普通方法、构造方法和静态方法中都可以使用泛型

package fanxing;

/**
 * @description: ${description}
 * @create: 2019-02-17
 **/
public class Swap {
    static <T> void swap(T[] a,int i,int j){
        T temp=a[i];
        a[i] = a[j];
        a[j]=temp;
    }
    public static void main(String[] args) {
        Swap s=new Swap();
        String[] a1={"a","b","c","d"};
        s.swap(a1,1,2);
        for (String string:a1
             ) {
            System.out.print(string+" ,");
        }
        System.out.println();
        Integer[] a2={1,2,3,4,5,6};
        s.swap(a2,1,2);
        for (Integer i:a2
        ) {
            System.out.print(i);
        }
    }
}

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

知识点记忆

1,泛型通配符
使用"?“通配符可以引用其他各种参数化的类型,”?"通配符定义的变量主要用作引用,可以调用与参数化无关的方法,不能调用与参数化有关的方法。
例:Collection<?>可以适配Collection、Collection或Collection等

2,限定通配符的上边界

用于匹配Number及Number的子类
<? extends Number>

3,限定通配符的下边界

//用于匹配Integer及Integer的父类。
<? super Integer>

4,Java 中的泛型基本上是在编译器中实现。编译器进行执行类型检查和类型推断,然后生成普通的非泛型的字节码。编译器使用泛型类型信息保证类型安全,然后在生成字节码之前将其清除。这种实现技术称为擦除(erasure)

5,泛型实际是提供给Javac编译器使用的。限定输入类型,让编译器挡住源程序中的非法输入,编译器编译带类型说明的集合时会去除掉"类型"信息。程序运行期间,没有任何泛型泛型的痕迹。使程序运行效率不受影响,对于参数化的泛型类型,getClass()方法的返回值和原始类型完全一样

6,成功编译过后的class文件中是不包含任何泛型信息的。泛型信息不会进入到运行时阶段

7,Java中没有所谓的泛型数组一说

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值