Java 泛型:仅定义为返回类型的泛型类型

2022-08-31 14:01:30

我正在查看GWT的一些GXT代码,我遇到了泛型的这种用法,我在Java教程中找不到另一个示例。类名是 com.extjs.gxt.ui.client.data.BaseModelData 如果你想查看所有代码。以下是重要部分:

private RpcMap map;

public <X> X get(String property) {
  if (allowNestedValues && NestedModelUtil.isNestedProperty(property)) {
    return (X)NestedModelUtil.getNestedValue(this, property);
  }
  return map == null ? null : (X) map.get(property);
}

X在类中或层次结构中的任何地方都没有定义,当我在eclipse中点击“转到声明”时,它只是转到公共方法签名中。<X>

我尝试使用以下两个示例调用此方法,以查看会发生什么情况:

public Date getExpiredate() {
    return  get("expiredate");
}

public String getSubject() {
    return  get("subject");
}

它们编译并显示没有错误或警告。我会想,至少我必须做一个演员才能让它发挥作用。

这是否意味着泛型允许一个神奇的返回值,它可以是任何东西,并且在运行时就会爆炸?这似乎与泛型应该做的事情背道而驰。任何人都可以向我解释这一点,并可能给我一些文档的链接,以更好地解释这一点?我已经浏览了Sun关于泛型的23页pdf,每个返回值的示例都是在类级别定义的,或者在传入的参数之一中定义。


答案 1

该方法返回您期望它成为的任何类型(在方法中定义并且绝对无界)。<X>

这是非常非常危险的,因为没有规定返回类型实际上与返回值匹配。

这样做的唯一优点是,您不必强制转换可以返回任何类型的泛型查找方法的返回值。

我会说:小心使用这样的结构,因为你几乎失去了所有的类型安全性,并且只得到你不必在每次调用时编写显式的强制转换。get()

是的:这几乎是黑魔法,在运行时爆炸,打破了泛型应该实现的整个想法。


答案 2

该类型在方法上声明。这就是“”的意思。然后,该类型的作用域仅为方法,并且与特定调用相关。测试代码编译的原因是编译器尝试确定类型,并且只有在无法确定时才会报告。在某些情况下,您必须明确说明。<X>

例如,Collections.emptySet() 的声明是

public static final <T> Set<T> emptySet()

在这种情况下,编译器可以猜测:

Set<String> s = Collections.emptySet();

但是,如果不能,则必须键入:

Collections.<String>emptySet();

推荐