有没有一种干净的方式将泛型类的类赋值给变量? [英] Is there a clean way to assign the Class of a generic type to a variable?

查看:102
本文介绍了有没有一种干净的方式将泛型类的类赋值给变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给出以下代码:

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

//类型不匹配:
//无法从Class< capture#1-of?扩展列表>到类< List< Integer>>
Class< List< Integer>> typeTry1 = ints.getClass();

//类型安全性:
//未选中从类 Class< List< Integer>> typeTry2 =(Class< List< Integer>>)ints.getClass();

//列表是一种原始类型。对泛型类型的引用< E>应该被参数化
Class< ;?扩展列表> typeTry3 = ints.getClass();

有没有办法让 Class List< Integer> 没有错误或警告?我可以很容易地禁止这些警告,但是如果Java需要我为这个有效的代码取消警告,那么我就是失望。另一方面,如果警告抑制是唯一的方法,那么最安全的压制方法是什么?

解决方案

这是一个真正的Catch-22 Java。



编译器警告你if您不要为 List 添加泛型:

  //警告:列表中没有输入
Class <?扩展列表> typeTry3 = ints.getClass();

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



然而,由于类型擦除,Java无法在运行时找出 List 的通用类型,编译器知道。因此, Class 中没有方法返回类型化对象:

  //错误:ints.getClass()不返回一个Class< List< Integer>> ;,它返回一个Class< List> 
Class <?扩展List <?扩展Integer>> var = ints.getClass();

所以你必须将它转换为一个类型列表。但是,正如您所知,由于没有运行时类型检查,因此Java会警告您将任何类型转换为类型化变量:

  / / WARN:投入输入列表
Class< List< Integer>> typeTry2 =(Class< List< Integer>>)ints.getClass();

任何解决此问题的尝试本质上都是混淆编译器的一种手段,并且不可避免地会令人费解。



最好的选择就是选择B:


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


禁止此警告的最安全方法是尽可能地本地化你的 @SuppressWarnings(unchecked)注释。把它们放在每个单独的未经检查的演员上方。这样,完全清楚是谁引起了警告。


Given this code:

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(); 

Is there a way to get the Class of a List<Integer> without an error or warning? I can suppress the warnings easily enough, but if Java requires me to suppress a warning for this valid code, I am very disappoint.

On the other hand, if warning suppression is the only way, what is the safest to suppress?

解决方案

This is a real Catch-22 in Java.

The compiler warns you if you don't add a generic type to List:

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

That's because, in most cases, it's really best to type your Lists.

However, because of type erasure, there's no way for Java to figure out the generic type of List at runtime, and the compiler knows that. Therefore, there is no method on Class that will returned a typed object:

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

So you must cast it to a typed list. However, as you know, since there is no runtime type checking, Java warns you about any casts to a typed variable:

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

Any attempt to get around this is essentially a means of confusing the compiler, and will inevitably be convoluted.

Your best bet then is to go with Option B:

On the other hand, if warning suppression is the only way, what is the safest to suppress?

The safest way to suppress this warning is to make your @SuppressWarnings("unchecked") annotation as localized as possible. Put them above each individual unchecked cast. That way it's absolutely clear who's causing the warning.

这篇关于有没有一种干净的方式将泛型类的类赋值给变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆