泛型的小千世界(java)

Posted 栗子~~

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了泛型的小千世界(java)相关的知识,希望对你有一定的参考价值。

文章目录


前言

  如果您觉得有用的话,记得给博主点个赞,评论,收藏一键三连啊,写作不易啊^ _ ^。
  而且听说点赞的人每天的运气都不会太差,实在白嫖的话,那欢迎常来啊!!!


泛型的小千世界(java)

1、泛型

1.1 概述

本质上就是类型参数化。


1.2 好处

1)、对于开发的功能,代码更加灵活
2)、使代码更加简洁
3)、避免强制转换,造成的程序异常


1.3 泛型的特点

【类型擦除】
代码在进入jvm后,泛型会被擦除掉,这时如果该泛型设置了类型上限,那么转换成该类型上限,否则转换成object类型

代码如下(示例)

//未指定上限
public class Test1<T> 
    T t;
    public T getValue() 
        return t;
    
    public void setVale(T t) 
        this.t = t;
    

//指定上限
public class Test2<T extends String> 
    T t;
    public T getT() 
        return t;
    
    public void setT(T t) 
        this.t = t;
    


2、泛型的用法

2.1 泛型接口的列子

利用泛型类声明接口来唱歌

代码如下(示例)

package com.yzy.text;
/*
* 泛型接口
* 
* */
interface Computer<E,F>  //定义两个泛型
      void makechorue(E x,F y);

class Chorus<E,F>implements Computer <E,F>
      public void makechorue(E x, F y) 
            x.toString();  //因为不知道什么类型,所以统一变成字符串
            y.toString();
            
      
      

class Musical
      public String toString()
            System.out.println("| 5 6 3-| 5  17  56|");
            return "";                                  //弹出String型
      

class Singer
      public String toString()
            System.out.println("好一朵茉莉花");
            return "";
      

public class Text57OOP35 
public static void main(String[] args) 
      Chorus<Singer, Musical> model = new Chorus<Singer,Musical>();
      Singer singer = new Singer();
      Musical musical= new Musical();
      model.makechorue(singer, musical);


效果:


2.2 泛型类例子

利用泛型类来实现求取锥类的体积

代码如下(示例)

/**
* 锥类
* */
class Cone<E>                    
      double height;
      E bottom;                           //低
      public Cone(E bottom) 
            this.bottom = bottom;
      
      public double computeVolume()
            String  s = bottom.toString();
            double ss =Double.parseDouble(s);
            return 1.0/3.0*ss*height;
      

/**
* 圆锥底面积
* */
class CircleA
      double  radius, area;
      public CircleA(double r) 
            
            radius = r;
      
      public String toString()                           
            
            area=radius*radius*Math.PI;    //Math.PI           π的意思
            return  ""+area;           //double型转换成String型
      

/**
* 四角锥 底面积
* */
class Rectangle
      double sidA,sidB,area;
      public Rectangle(double sidA, double sidB) 
            this.sidA = sidA;
            this.sidB = sidB;
      
      public String toString()                       
            
            area =sidA*sidB;
            return ""+area;
      
      

public class Text56OOP34 
      public static void main(String[] args) 
            CircleA circle = new CircleA(10);
            Cone<CircleA> coneone = new Cone<CircleA>(circle);
            coneone.height = 30;
            System.out.println("圆锥体积:"+coneone.computeVolume());
            Rectangle rectangle = new Rectangle(10, 20);
            Cone<Rectangle>  conetwo = new Cone<Rectangle>(rectangle);
            conetwo.height = 40;
            System.out.println("四角锥体积:"+conetwo.computeVolume());
      

效果:


3.其他

3.1 自定义生成泛型对象

代码如下(示例)

public <E> E objectNewInstance(Class<E> clazz) 
              E a = null;
              try 
                      a=clazz.newInstance();
               catch (Exception e1) 
                     log.error("创建自定义泛型对象错误:",e1);
              
              return a;
       

使用:

 E e =  (E)  objectNewInstance(DeclaredDlCurveCompanyTimeVo.class);

3.2 泛型对象 转成 class 对象

代码如下(示例)

public void test(List<F> records) 
              records.forEach(vo->
                     try 
                           //泛型对象 转成 class 对象
                           Class<? extends Object> clazz = vo.getClass();         
                      catch (Exception e) 
                           log.error("反射错误:",vo);
                     
              );    
       

3.3 继承关系的使用

即设置泛型上限,传入的泛型必须是String类型或者是他的子类

代码如下(示例)

public <T extends String> void test(T t) 

3.4 依赖关系的使用

F是继承自E。即传入的类型是E类型或者是E类型的子类

代码如下(示例)

public <E, F extends E> void test(E e, F c) 

3.5 通配符

注意: 通配符不能用作返回值
如果返回值依赖类型参数,不能使用通配符作为返回值。可以使用类型参数返回:

public <T> T test (T t)
  return t;

(1) <?> 无限通配符
注意: 无限通配符只能读的能力,没有写的能力。

代码如下(示例)

public void test(List<?> list) 
     //只允许读数据
      Object o = list.get(0);
     //不允许写数据
     // list.add("1111");

(2) <? extends T> 定义上限 表示参数化类型可能是T 或是 T的派生类(子类);
频繁往外读取内容的,适合用上界Extends。

(3) <? super T> 定义下限 表示参数化类型可能是T 或是 T的基类(父类);
经常往里插入的,适合用下界Super

代码如下(示例)

class A    

class B extends A

class C extends B

public class Test 
      public static List<B> b = new ArrayList<>();
      public static List<C> c = new ArrayList<>();
      public static List<A> a = new ArrayList<>();
      
      public static void main(String[] args) 
            List<? extends B> listextends = null;
            List<? super B> listsuper = null;
            //? extends B   表示参数化类型可能是T 或是 T的派生类(子类);
            listextends = Test.a;  //报错
            listextends = Test.b;
            listextends = Test.c;
            //<? super T> 表示参数化类型可能是T 或是 T的基类(父类);
            listsuper  = Test.a;
            listsuper  = Test.b;
            listsuper  = Test.c;  //报错
      

效果:

(4) <? super T>和<? extends T> 经典用法

public <T> void copy(List<? super T> dest, List<? extends T> src) 
            for (int i = 0; i < src.size(); i++)
                dest.set(i, src.get(i));
            
       

以上是关于泛型的小千世界(java)的主要内容,如果未能解决你的问题,请参考以下文章

java 泛型的上限与下限

JAVA-初步认识-常用对象API(集合框架-泛型-泛型限定-上限)

关于Java泛型的小知识点

java泛型中的下限

泛型的上限和下限的Demo

Java 泛型上限规则不会破坏 Liskov 替换吗? [复制]