美文网首页
Java中的泛型

Java中的泛型

作者: 放码过来吧 | 来源:发表于2019-05-20 19:12 被阅读0次
快扶我去看书.jpg

由浅入深,没时间解释了,快上车,fuck car!!!

Java中的泛型,相信很多人在开发中都用到,像下面的

public  class  Test <T> {
    private T  t;
    private  <T> T getData() {
    };
    private interface ITest <T> {
        T getData();
        T getDatas(T a);
    }
}

是不是很熟悉,很好,觉得熟悉就对了,那下面这个呢,涉及到了泛型的限制,通配符之类的,是不是很眼熟呢~。

//通配符(还有super)
public void  method4(Person<? extends Fruit> p) {
}

public  class  Test <T exstends Serializable> {}

//正确
public  class  Test <T exstends  ArrayList&Serializable> {}
//下个却是错的,如果有多个,类要放在第一(ArrayList),接口放在后面(Serializable),语法限制。。。
public  class  Test <T exstends  Serializable&ArrayList> {}

上面的错误的原因,请看下图:


image.png

......

唠嗑了下曾经碰到过的,那么,开始吧,提出问题。

1. 什么是泛型
2. 为什么要用泛型
3. 泛型的使用
4. 限定类型变量
5. 泛型使用中的局限性
6. 泛型中的通配符类型
7. 虚拟机是如何实现泛型的

问题提出来了,喝瓶阔落压压惊。


image.png
  1. 什么是泛型

可以这么理解:参数化类型或者类型参数化。什么意思呢?用过方法吧,方法里面传的参数,举个例子:

//方法1
public  int getData(int a) {
}
//方法2
public <T>  T  getData(T a) {
}

方法1把类型参数化,变成方法2,就不再局限于该方法的参数类型只能是int,你可以是String,double等之类的。

  1. 为什么要用泛型
1.多种数据类型使用相同的代码。
2.使用泛型,在编码过程中指定数据类型,不需要强制转换。

3.泛型的使用
泛型主要用在类,接口,方法。

泛型类

public class  Fruit{
}
public class Apple extends Fruit {
}

public class Person <T> {
}
//派生类
public  class  Demo  <T>  extends Person <T> {
  private List<T> list;
}

 泛型类是可以继承或者扩展其他泛型类的,正确的写法是:
 Person<Apple> p1 = new Demo<Apple>(); //里面的类型Apple不能换  成Fruit 
注意: 
  Person<Fruit> p1 = new Person<>();
  Person<Apple> p2 = new Person<>();
  p1跟p2没有继承关系,如何证明呢,看下面:
  Person<Apple> p1 = new Person<Fruit>();
  上面代码会报错了~
 

泛型接口

public interface CallBack <T> {
  void callBack(T a);
}
//接口实现
public class ImpCallBack  <T> implements CallBack <T> {
...
}
或者具体某个
public class ImpCallBack  implements CallBack <String> {
...
}

泛型方法

//泛型方法
public <T> T  methodTest(T t) {
...
}

//注意:下面的method1并不是泛型方法,他只是引用了Demo中的泛型
public  class  Demo  <T>  extends Person <T> {
  public void method1(Demo<T>  demo) {
    ...
  }
}

4.限定类型变量

泛型的限定类型变量,就是限定可以传递的类型。
举个例子(这里就拿  泛型方法做例子, because,泛型类,泛型接口与泛型方法类似。)
public class Person{
}
public class Boy extends Person{
}

public class Aa{
}

此时,我这里有个方法
public <T extends Person> void method2( T t) {
  ...
}
如果需要调用这个方法,只能传递Person或者Person的子类:
  method2(new Boy());
  method2(new Person());
  method2(new Aa());    //错误,这个不行
如果传递的是别的对象,sorry,不行

5.泛型使用中的局限性

不能实例化类型变量
public class Person <T>{
  private T t = new T();
}
上面这情况是不阔以的,语法不允许(报错:type parameter "T" cannot be instantiated directly)
静态域或者静态方法是不能引用类型变量
public class Person <T>{
  private static void method3(T t){
  ...
  }
 private static <T> void method4(T t){
  ...
  }

}
 //注意
 上面的method3写法是不可以,原因:静态方法的执行比对象的创建 
 要早, 然而new Person<String>()的时候,才知道T的类型。

 当然了,静态方法本身是泛型方法就可以。看method4()方法。
泛型里面不能是基本数据类型
public class Person <T>{
}
使用: new Person<int>() ,是错误的,int需要装箱后放进去。
也就是说,只能是对象,不能是基本数据类型
泛型是不能用instanceof关键字的
举个例子
public class Person <T>{
}
public static void main(String[] args) {
    Person <T> person;
    if(person instanceof  Person <T>) {
    }
//是不允许的,不支持
}
泛型类不能继承Exception
//下面这样写,直接就给你飘红了
public class Person<T> extends Exception {
}

看图


image.png
泛型其他有趣的限制
Person<Long>[]  person;  //定义可以,没问题,but
person = new Person<Long>[5];  //初始化,对不起,不行~

不要问为什么。。。语法限制

6.泛型中的通配符类型
我们来看个例子

//普通类
public class Food {
}
public class  Fruit extends Food{ 
}
public class Apple extends Fruit {
}
//泛型类
public class Person <T> {
}
....
public void  method3(Person<Fruit> p) {
}
//使用了通配符的
public void  method4(Person<? extends Fruit> p) {
}
public void  method5(Person<? super  Fruit> p) {
}
public static void main(String[] arg) {
   Person<Food> p0 = new Person<>();
   Person<Fruit> p1 = new Person<>();
   Person<Apple> p2 = new Person<>();
  //方法调用
  method3(p1); //这个毫无疑问,是可以的
  method3(p2); // 不可以!!! 
  //这个时候就要使用通配符了
  method4(p1); .// you can
  method4(p2); // 哎,这个也可以了
  method4(p0); //这个不行,看下面说明
  //说明:通配符 extends 限制了上界,比如上面的,上届就是Fruit,
  //只要是派生自Friut或者本身,都可以,Food就不行了(也就是说,只要是 Friut的子类都可以)

  //还没完事呢,通配符除了extends ,还有 super,
  //用法刚好跟extends相反,看method5,只要是 Fruit的超(父)类或者其本身,都可以。
}

7.虚拟机是如何实现泛型的
实不相瞒,进行了泛型擦除。什么意思呢,我举个例子

public class Person<T> {
  private T t;
}
上面的类泛型擦除后,会是下面这个:
public class Person<T> {
  private Object t;
}
继续看
public class Person<T extends ArrayList&Comparable> {
  private T t;
  public void test(){
     // t.compareTo()
  }
}
擦除后这样的:
public class Person<T extends ArrayList&Comparable> {
  private ArrayList t;
  public void test(){
     // (Comparable)t.compareTo()
  }
}
开头就提出来了,如果有继承的,必须放在第一(ArrayList放在Comparable前面),
类只能有一个(因为在java里面,是单继承的),接口可以多个。对于后面的Comparable,什么时候体现呢?
当你在某个方法用到了Comparable接口的时候,编译器会插入一个强制转型的代码,看test()方法。
感兴趣的可以看编译后的.class文件。

over,记录下。

相关文章

  • JAVA泛型的理解

    泛型大家都接触的不少,但是由于Java历史原因,Java中泛型一直被称为伪泛型,因此对Java中的泛型,有很多不注...

  • Kotlin 泛型

    Kotlin 支持泛型, 语法和 Java 类似。例如,泛型类: 泛型函数: 类型变异 Java 的泛型中,最难理...

  • Java泛型教程

    Java泛型教程导航 Java 泛型概述 Java泛型环境设置 Java泛型通用类 Java泛型类型参数命名约定 ...

  • Java泛型

    参考:Java知识点总结(Java泛型) 自定义泛型类 自定义泛型接口 非泛型类中定义泛型方法 继承泛型类 通配符...

  • Android 开发也要掌握的Java知识 - Java泛型

    如果需要看泛型擦除Java泛型擦除 1.Java泛型有什么用?为啥要使用泛型? Java中数组的类型是定义的时候就...

  • 15、泛型常用特点

    泛型常用特点 泛型是Java SE 1.5之后的特性,《Java 核心技术》中对泛型的定义是: “泛型” 意味着编...

  • 泛型中 ? super T和 ? extends T的区别

    首先, 说到 Java 的泛型, 我们必须要提到的是Java 泛型的类型擦除机制: Java中的泛型基本上都是在编...

  • java 泛型解析

    Java 泛型 1、泛型的精髓是什么 2、泛型方法如何使用 概述: 泛型在java中具有重要地位,在面向对象编程模...

  • Java 泛型

    一、概述 1.1 什么是Java泛型 Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型...

  • 泛型(一)

    1. Java中的泛型是什么 ? 使用泛型的好处是什么? 泛型是Java SE 1.5的新特性,泛型的本质是参数化...

网友评论

      本文标题:Java中的泛型

      本文链接:https://www.haomeiwen.com/subject/vlwiaqtx.html