一:JAVA 泛型

2021/4/16 14:25:48

本文主要是介绍一:JAVA 泛型,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

最近温习完泛型准备写博客对前其进行加深印象,下面简单的对泛型进行介绍,有错误的地方希望大家能指出:

 

泛型的作用:把类型参数化。

       优点:1、在编译期间实现类型检查,提前发现错误,让错误在编译期间就得以解决。举例如下:

     创建泛型类Test1

public class Test1<T> {
    
    public void judge(T a){
        
    }
    
}

 创建泛型类Test1示例,并调用它的方法,在创建的时候指定了泛型为String,如果传递参数的时候传成非String,那么在编译的时候就会报错,比如test1.judge(1234);

public class GenericityTestClass {

    public static void main(String[] args) {
        Test1<String> test1 = new Test1();
        test1.judge("test");
        test1.judge(1234);
    }
}

 

                  2、复用性,多种条件用同一种逻辑进行处理。举例如下:封装服务器返回的javabean

     创建泛型

public class BaseBean<T> {


    private int code;
    private String msg;
    private T data;

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }
}

     创建实际的data类

public class GoodBean {
    private String name;
    private int size;
    private String productDate;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getSize() {
        return size;
    }

    public void setSize(int size) {
        this.size = size;
    }

    public String getProductDate() {
        return productDate;
    }

    public void setProductDate(String productDate) {
        this.productDate = productDate;
    }
}

     进行数据解析:

// 示例json
String resultJson = "{\"code\":200,\"data\":{\"name\":\"apple\",\"productDate\":\"2021-04-15\",\"size\":10000},\"msg\":\"success\"}";
// fastjson 对数据进行解析  这里的TypeReference的作用是通过反射拿到泛型的具体类型,因为泛型在编译的时候会进行类型擦除,TypeReference后面的{}的作用是作为一个匿名内部类,如果没有{}则他是一个对象,在编译的时候还是会进行类型擦除,如果是内部类则会保留一个类型。
BaseBean<GoodBean> resultData = JSON.parseObject(resultJson, new TypeReference<BaseBean<GoodBean>>() {
        }.getType());

 

二、泛型种类:

     1、泛型类: 在类名后面有一个   <T>  作为标识

public class Test1<T> {
    
    public void judge(T a){
        
    }
    
}

     2、泛型接口: 在接口名后面有一个 <T>

// 泛型接口
public interface GenericityInterface<T> {

}


// 实现泛型接口方式一:
class Test<T> implement GenericityInterface<T>{

}


// 实现泛型接口方式二:
class Test implement GenericityInterface<String>{

}

     3、泛型方法: 在返回类型前面有一个  <T>

// 这种是泛型方法 
public <T> void genericityMethod(T value) {
        System.out.println("这是泛型方法");
}


// 这种不是泛型方法 
public  void genericityMethod(T value) {
        System.out.println("这不是泛型方法");
}

三、限定符

// 限定符    在这里对T的类型做了限制只能传递  Number的子类
public static <T extends Number> void test(T a){

}


// 使用
public static void main(String[] args) {
     
    test(1);
    test(1.0);
    test("4as5dasd"); // 这里会报错,因为字符串的不是继承之Number
}

四、通配符

     

 Integer a = 1;

 // 上边界,所有类型继承之Number,无法往里面添加元素,只能获取元素。  可以称为生产者,或者只读,所以在创建list的时候就需要把元素添加进去。
 List<? extends Number> list = new ArrayList<>();
 list.add(a);   //  这里会报错。
 Number b = list.get(0);
        
 // 下边界,所有元素都是Number的超类,可以往里面加元素和取元素,不过取出来的元素类型都是object,在加元素的时候只能添加Number以及Number的子类,Number的同级和超类的超类是无法进行添加的。这里可以理解为消费者,或者只写
 List<? super Number> list1 = new ArrayList<>();
 list1.add(a);
 Object bs = list1.get(0);

 

五、类型擦除、桥接方法

     java在1.5之前没有泛型,在1.5之后才引入泛型,为了兼容以前的jdk版,所以在编译的时候会对泛型做处理,也就是擦除,用object来进行表示,当然擦除之后会用一个标签对原始类型进行保存(signature)

下面是源文件

public class Test<T> {


    private T data;


    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }
}

下面是编译文件 

// class version 51.0 (51)
// access flags 0x21
// signature <T:Ljava/lang/Object;>Ljava/lang/Object;
// declaration: com/xhs/testjava/Test<T>
public class com/xhs/testjava/Test {

  // compiled from: Test.java

  // access flags 0x2
  // signature TT;
  // declaration: T
  private Ljava/lang/Object; data

  // access flags 0x1
  public <init>()V
   L0
    LINENUMBER 3 L0
    ALOAD 0
    INVOKESPECIAL java/lang/Object.<init> ()V
    RETURN
   L1
    LOCALVARIABLE this Lcom/xhs/testjava/Test; L0 L1 0
    // signature Lcom/xhs/testjava/Test<TT;>;
    // declaration: com.xhs.testjava.Test<T>
    MAXSTACK = 1
    MAXLOCALS = 1

  // access flags 0x1
  // signature ()TT;
  // declaration: T getData()
  public getData()Ljava/lang/Object;
   L0
    LINENUMBER 10 L0
    ALOAD 0
    GETFIELD com/xhs/testjava/Test.data : Ljava/lang/Object;
    ARETURN
   L1
    LOCALVARIABLE this Lcom/xhs/testjava/Test; L0 L1 0
    // signature Lcom/xhs/testjava/Test<TT;>;
    // declaration: com.xhs.testjava.Test<T>
    MAXSTACK = 1
    MAXLOCALS = 1

  // access flags 0x1
  // signature (TT;)V
  // declaration: void setData(T)
  public setData(Ljava/lang/Object;)V
   L0
    LINENUMBER 14 L0
    ALOAD 0
    ALOAD 1
    PUTFIELD com/xhs/testjava/Test.data : Ljava/lang/Object;
   L1
    LINENUMBER 15 L1
    RETURN
   L2
    LOCALVARIABLE this Lcom/xhs/testjava/Test; L0 L2 0
    // signature Lcom/xhs/testjava/Test<TT;>;
    // declaration: com.xhs.testjava.Test<T>
    LOCALVARIABLE data Ljava/lang/Object; L0 L2 1
    // signature TT;
    // declaration: T
    MAXSTACK = 2
    MAXLOCALS = 2
}

 



这篇关于一:JAVA 泛型的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程