将泛型类型分配给类类型的变量


// I would like to create a variable of Class type and assign a pattern into it like that:
Class clazz = HashMap<Long,HashMap<String, Semaphore>>.class; // does not work!
// I need it in order to be able later use it in .isInstance() expression, like:
if (clazz.isInstance(myVariable)) {
// do something
}

,因为通常的"实例"也不适用于模式类型。

对于简单的类型(非模式类型(,它可以工作:

Class clazz = Long.class; // this works fine

我怎样才能实现我想要的,即分配一个模式而不是一个简单的类型? 如果在 Java 中不允许这样做,是否有另一种正确的方法来测试变量是否是定义为模式的类型实例?

您无法检查是否有HashMap<Long,HashMap<String, Semaphore>>的实例。

尽管语法暗示HashMap<Long,HashMap<String, Semaphore>>是单一的东西,但该类型实际上意味着:

  • 此类型的变量将在运行时保存HashMap(或 null(
  • 我希望编译器在我尝试输入或取出不是Long的键时阻止我,如果我尝试输入或取出任何不是键和值属于该特定类型的HashMap的东西,则阻止我。

<>s 之间的位纯粹是编译时提示。在运行时没有什么可以测试的。

如果映射不为空,则可以检查它是否包含任何违反类型约束的键或值。

但是,除了您只能在映射为非空且包含非空键和值的情况下执行此操作之外,它不会告诉您它是否是HashMap<Long,HashMap<String, Semaphore>>,而是它是一个HashMap<? extends Long, ? extends HashMap<? extends String, ? extends Semaphore>>

您可以安全地使用此类映射中保存的内容,但无法安全地添加到其中,只能通过重新添加该映射中已包含的键和值或 null。

泛型在编译后被删除。
因此,即使此代码有效,也无法进一步帮助您:

HashMap<Long, HashMap<String, Semaphore>> map = new HashMap<>();
Class<?> clazz = map.getClass();

clazzjava.util.HashMap"仅"而不是其泛型

。关于您的要求,如果碰巧您必须编写这样的代码,并且还要检查泛型的类型:

if (clazz.isInstance(myVariable)) {
// do something
}

我认为这应该重新考虑你的逻辑。
泛型主要用于提高类型安全性,从而机械地减少对instanceof测试和下降的要求。

如果在 Java 中不允许这样做,是否有另一种正确的方法来测试是否 变量是定义为模式的类型的实例?

通过在泛型类中添加class字段,可以存储泛型实例中指定的类型。但是当你使用内置类型时,你会卡住。
使用您自己的类,您可以通过这种方式捕获信息,例如:

public class Foo<T, U, V> {
private Map<T, HashMap<U, V>> map = new HashMap<>();
private Class<T> tClass;
private Class<U> uClass;
private Class<V> vClass;
public Foo(Class<T> t, Class<U> u, Class<V> v) {
this.tClass = t;
this.uClass = u;
this.vClass = v;
}
}

因此,您可以使用tClassuClassvClass来执行所需的检查。
但如前所述,继续以这种方式可能不是最好的做法。

最新更新