举报投诉联系我们 手机版 热门标签 编程学
您的位置:编程学 > java泛型类型擦除 Java 泛型类型

java泛型类型擦除 Java 泛型类型

2023-03-05 23:18 Java教程

java泛型类型擦除 Java 泛型类型

java泛型类型擦除

Java泛型类型擦除是指在编译时,将泛型类型参数转换为它的限定类型,以便在运行时可以使用。这是因为Java虚拟机(JVM)不能直接处理泛型类型,因此必须将其转换为其他形式才能在JVM上运行。

Java泛型类型擦除的好处是它可以使代码变得更加通用,因为它不会强制要求使用特定的数据类型。例如,如果你想要创建一个方法来处理任意数量的对象,你可以使用泛型来定义该方法,而不必明确地声明要处理的对象的数量或类型。

此外,Java泛型类型擦除也有一些弊端。例如,当你尝试在运行时检测一个对象的数据类型时(例如使用instanceof关键字),你会遇到问题。这是因为在运行时所有的泛型都已被“擦除”了(即已被转化成Object或原始数据类型)。

public class GenericTypeErasure { 

    public static void main(String[] args) { 

        List<Integer> list = new ArrayList<Integer>(); 

        list.add(1); 

        if (list.get(0) instanceof Integer) { 

            System.out.println("It is an Integer"); 

        } else { 

            System.out.println("It is not an Integer"); 

        } 

    } 
}

上面的代码中list中存储了一个Integer对象(即1)。然而当我们尝试使用instanceof关键字来测试list中存储的对象是否是Integer时会出问题。这是因为instanceof关键字会尝试匹配原始数据类型而不是泛型数据类型。因此上述代码将打印“It is not an Integer”而不是“It is an Integer”。

Java 泛型类型

Java教程 - 什么是Java中的泛型类型


术语泛型意味着参数化类型。使用泛型,可以创建与不同类型的数据一起使用的单个类。在参数化类型上操作的类,接口或方法称为通用。

语法

以下是声明通用类的语法:

class className<type-param-list> {}

下面是声明对一个泛型类的引用的语法:

例子

简单泛型示例

// T is a type parameter that will be replaced by a real type 
// when an object of type Gen is created. 
class Gen<T> {
  T ob; // declare an object of type T
  Gen(T o) {
    ob = o;
  }
  // Return ob.
  T getob() {
    return ob;
  }
  // Show type of T.
  void showType() {
    System.out.println("Type of T is " + ob.getClass().getName());
  }
}

public class Main {
  public static void main(String args[]) {
    Gen<Integer> iOb = new Gen<Integer>(88);
    iOb.showType();
    int v = iOb.getob();
    System.out.println("value: " + v);
    Gen<String> strOb = new Gen<String>("Generics Test");
    strOb.showType();
    String str = strOb.getob();
    System.out.println("value: " + str);
  }
}

T 是类型参数的名称。 T 用于声明一个对象。泛型只与对象一起工作通用类型根据其类型参数而有所不同。

上面的代码生成以下结果。


例2

您可以在泛型类型中声明多个类型参数。

// A simple generic class with two type parameters: T and V. 
class TwoGen<T, V> {
  T ob1;
  V ob2;
  TwoGen(T o1, V o2) {
    ob1 = o1;
    ob2 = o2;
  }
  void showTypes() {
    System.out.println("Type of T is " + ob1.getClass().getName());
    System.out.println("Type of V is " + ob2.getClass().getName());
  }

  T getob1() {
    return ob1;
  }

  V getob2() {
    return ob2;
  }
}

public class Main {
  public static void main(String args[]) {
    TwoGen<Integer, String> tgObj = new TwoGen<Integer, String>(88, "Generics");
    tgObj.showTypes();
    int v = tgObj.getob1();
    System.out.println("value: " + v);
    String str = tgObj.getob2();
    System.out.println("value: " + str);
  }
}

上面的代码生成以下结果。

例3

以下代码声明并使用队列<E> 通用类型。

class Queue<E> {
  private E[] elements;
  private int head=0, tail=0;

  Queue(int size) {
    elements = (E[]) new Object[size];
  }

  void insert(E element) throws QueueFullException {
    if (isFull())
      throw new QueueFullException();
    elements[tail] = element;
    tail = (tail + 1) % elements.length;
  }

  E remove() throws QueueEmptyException {
    if (isEmpty()){
      throw new QueueEmptyException();
    }
    E element = elements[head];
    head = (head + 1) % elements.length;
    return element;
  }

  boolean isEmpty() {
    return head == tail;
  }

  boolean isFull() {
    return (tail + 1) % elements.length == head;
  }
}
class QueueEmptyException extends Exception {
}

class QueueFullException extends Exception {
}
public class Main{
  public static void main(String[] args) 
      throws QueueFullException, QueueEmptyException {
    Queue<String> queue = new Queue<String>(6);
    System.out.println("Empty: " + queue.isEmpty());
    System.out.println("Full: " + queue.isFull());
    queue.insert("A");
    queue.insert("B");
    queue.insert("C");
    queue.insert("D");
    queue.insert("E");
    System.out.println("Empty: " + queue.isEmpty());
    System.out.println("Full: " + queue.isFull());
    System.out.println("Removing " + queue.remove());
    System.out.println("Empty: " + queue.isEmpty());
    System.out.println("Full: " + queue.isFull());
    System.out.println("Adding F");
    queue.insert("F");
    while (!queue.isEmpty()){
      System.out.println("Removing " + queue.remove());
    }
      
    System.out.println("Empty: " + queue.isEmpty());
    System.out.println("Full: " + queue.isFull());
  }
}

输出:

处理旧代码

为了处理向泛型的转换,Java允许使用没有任何类的通用类类型参数。

下面是一个显示原始类型的示例:

class MyClass<T> {
  T ob;
  MyClass(T o) {
    ob = o;
  }
  T getob() {
    return ob;
  }
}
public class Main {
  public static void main(String args[]) {
    MyClass raw = new MyClass(new Double(98.6));
    double d = (Double) raw.getob();
    System.out.println("value: " + d);
  }
}

输出:

阅读全文
以上是编程学为你收集整理的java泛型类型擦除 Java 泛型类型全部内容。
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。
相关文章
© 2024 编程学 bianchengxue.com 版权所有 联系我们
桂ICP备19012293号-7 返回底部