自定义泛型类时的注意点 [Java]

自定义泛型类时的注意点 [Java],第1张

自定义泛型类时的注意点 [Java] 自定义泛型类时的注意点:
  1. 泛型类中可能有多个类型参数,此时我们要将多个类型参数放到一个尖括号中,中间使用逗号隔开

    public class Demo  {}
    
  2. 泛型不同的引用之间不可以相互赋值

    ArrayList list1 = null;
    ArrayList list2 = new ArrayList<>(); 
    list1 = list2; //这里编译会出错(list1的泛型为String,list2的泛型为Integer,两个引用泛型不同,不可                //以相互赋值)
    
    • 上面我们声明的list1 为 null, 声明的list2为 new ArrayList<>(); ,然后又将list2赋值给list1,这个时候我们的list1也会指向 list2指向的对象?
      • 哈哈哈,不是的这个时候我们的编译都不会通过,因为不同泛型引用之间不可以相互赋值
那么为什么泛型不同的引用之间不可以相互赋值? 很多人在这个问题中都会有一个错误理解:

错误理解: ArrayList< String> 和 ArrayList< Integer>在运行期间不是都是以ArrayList进行存储的?不是我们的不同泛型在底层运行时都是以Object类型存储的?,那么为什么不同泛型类型的两个相同类创建出来的对象不可以相互赋值

上面的错误理解中的理解是正确的,但是观点是错误的,为什么呐?

因为我们虽然泛型就是编译期间的一个检查,到了运行期间都是以Object类型进行存储的,但是你根本就运行不了啊,我们编译器你都通过不了还谈什么运行?

  1. 泛型如果我们不指明,将会被擦除,泛型对应的类型均按照Object类型处理,但是要注意: 我们如果不指明,这个时候默认为Object类型,但是这个时候默认的Object类型和我们指明为Object类型还是有区别的: 区别就在我们的泛型类在继承关系中(后面细讲)

  2. 泛型的简化 *** 作:

    ArrayList list = new ArrayList<>();
    
    • 注意我们的泛型简化的时候可以"左加右不加",但是不可以"右加左不加"
      • 因为我们右面是编译期,而左边是运行期,而我们的泛型其实就是在编译器的一个检查,所以运行期加不加无所谓,但是编译器要加
  3. 泛型的指定不能使用基本数据类型,我们要使用包装类替换

  4. 静态方法中不能使用类的泛型

    类声明时创建的泛型可以作为非静态属性的类型,非静态方法的参数类型,非静态方法的返回值,但是在静态方法中不可以使用类的泛型

    为什么静态方法中不可以使用类的泛型?{
    • 因为我们的静态方法是随着类的加载而加载的,而类的泛型呐?类的泛型在类创建对象的时候指明,那么这个我们的静态方法加载的时候我们的泛型还没有制定,这个时候就会冲突,这个就像我们的静态方法中不可以使用非静态成员一样 — 所以我们搞清楚类中各个部分,各个成员的加载顺序很重要
  5. 泛型类不能继承异常类

    • 如果一个类继承了现有的异常体系,也就是一个类如果继承了一个异常类,那么这个类就也是一个异常类

      所以也就可以说我们的异常类不可以加泛型

    那么为什么泛型类不可以继承异常类? 如果泛型类可以继承异常类会出现什么问题?

    这里我们举一个例子:

    这里例子是错误的,我们只是使用这个例子来说明问题所在

    public class MyException extends Exception{
        ......
            .....
    }
    //首先我们说明,前面的代码是通过不了编译的,因为我们继承一个异常类时这子类不可以加泛型
    ......
    ......
        
    try{
        //这里有一些代码,这些代码可能会出现一些异常
    }catch(MyException e){
        ......
    }catch(MyException e){
        .....   
    }
    

    如果异常类可以加泛型就会出现这种情况,这个时候编译器会通过,但是到了运行期,这里的MyException< String>和MyException< Integer>都是一样的,都是MyException,这个时候那么到运行期间前面如果发生了异常,这个时候我们究竟要走哪个个catch?

    • 这个时候就会出现编译时看起来是不同的两个异常,但是到了运行期,哎,又变成一样的了,这个时候就会出现不知道选哪个?哈哈哈
  6. 如果一个子类在继承了一个带泛型的父类时,根据子类是否继承父类的泛型分为以下几种情况:

    • class Father{ }
    1. class Son extends Father { }
    2. class Son extends Father
    3. class Son< T2> extends Father
    4. class Son extends Father
补充:

如果我们要new一个泛型类型的数组时,这个时候我们需要注意:

错误方式:

T [] arr = new T[10];
  • 这个时候编译就会出错

正确方式:

T [] arr = (T [])new Object[10];
为什么第一种情况会编译出错?
  • 这里我们要记住: new后面必须加一个具体的类类型,不能是加一个泛型,泛型只是一个参数
  • 我们可以使用泛型来声明变量,但是不可以使用泛型来创建对象

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5672324.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存