有没有一种干净的方法可以将泛型类型的类分配给变量?

2022-09-04 22:12:38

给定此代码:

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

// Type mismatch: 
// cannot convert from Class<capture#1-of ? extends List> to Class<List<Integer>>       
Class<List<Integer>> typeTry1 = ints.getClass(); 

// Type safety: 
// Unchecked cast from Class<capture#2-of ? extends List> to Class<List<Integer>>
Class<List<Integer>> typeTry2 = (Class<List<Integer>>) ints.getClass();

// List is a raw type. References to generic type List<E> should be parameterized
Class<? extends List> typeTry3 = ints.getClass(); 

有没有办法在没有错误或警告的情况下获得 a?我可以很容易地禁止警告,但是如果Java要求我禁止显示这个有效代码的警告,我非常失望ClassList<Integer>

另一方面,如果警告抑制是唯一的方法,那么最安全的抑制方法是什么?


答案 1

这是Java中真正的Catch-22。

如果您不向 以下位置添加泛型类型,编译器会向您发出警告:List

// WARN: List is not typed
Class<? extends List> typeTry3 = ints.getClass();

这是因为,在大多数情况下,最好键入列表。

但是,由于类型擦除,Java 无法在运行时找出泛型类型,编译器知道这一点。因此,没有将返回类型化对象的方法:ListClass

// ERROR: ints.getClass() doesn't return a Class<List<Integer>>, it returns a Class<List>
Class<? extends List<? extends Integer>> var = ints.getClass();

因此,您必须将其强制转换为类型化列表。但是,如您所知,由于没有运行时类型检查,因此Java会警告您有关类型化变量的任何强制转换:

// WARN: Casting to typed List
Class<List<Integer>> typeTry2 = (Class<List<Integer>>) ints.getClass();

任何试图解决这个问题的尝试本质上都是混淆编译器的一种手段,并且不可避免地会变得复杂。

那么你最好的选择是选择B:

另一方面,如果警告抑制是唯一的方法,那么最安全的抑制方法是什么?

禁止显示此警告的最安全方法是使批注尽可能本地化。将它们放在每个未经检查的演员表上方。这样就绝对清楚是谁导致了警告。@SuppressWarnings("unchecked")


答案 2

执行此操作的一种方法是创建自己的类。我不确定这是否能满足您的需求。

我真的不确定你想实现什么。所以也许通配符是答案。

import java.util.*;

class Main
{
      public static void main(String[] args)
      {
            List<Integer> list = new ArrayList<Integer>();
            Class<?> clazz = list.getClass();
            System.out.println(clazz) ;
      }
}

推荐