【问题标题】:cast to Type in java在java中强制转换为Type
【发布时间】:2016-07-04 17:47:31
【问题描述】:

我是泛型新手,正在查看这个答案:

https://stackoverflow.com/a/17165079/1632141

完美运行,但是我无法理解这部分代码是如何工作的。

 public T calories(int val) {
     calories = val;
     return (T) this;
 }

NutritionFacts的内部类中。

演员如何在这里工作?我在这里期待java.lang.ClassCastException,因为我们将一个纯超类对象转换为子类。

【问题讨论】:

  • “纯超类对象”是什么意思? this 总是以 T 类型结束。
  • 代码在public static class (GMOFacts.)Builder extends NutritionFacts.Builder<(GMOFacts.)Builder>的上下文中运行。 T 因此是建造者自己的类型,这使它成为合法的演员。 this 也不是超类类型,即使代码是在超类中声明的。 this 始终是具体的运行时(子类)类型。
  • @LouisWasserman:不正确。 this 可能不是 T 类型。
  • @zapl:this 可能不是T

标签: java generics casting


【解决方案1】:

其实那个答案有问题:

public static class Builder<T extends Builder> {...

T 类型是 原始 类型。应该是:

public static class Builder<T extends Builder<T>> {...

这被称为自引用类型,因为它在扩展自己。

通常这样使用:

public class SubBuilder extends Builder<SubBuilder> {...

在这种情况下,类型是子类本身的类型。

您可以将 Builder 的另一个子类编码为该类型,但这并不是特别有用。

【讨论】:

  • 我的意思是说Tsubtype本身的类型
  • T 不必是子类本身的类型
【解决方案2】:

您没有将超类对象转换为那里的子类。对于GMOFacts.Builder 对象,calories 方法的类型将被擦除为如下所示:

public GMOFacts.Builder calories(int val) {
        calories = val;
        return (GMOFacts.Builder) this;
    }

而且this 引用指向GMOFacts.Builder 对象,所以它是一个有效的类型转换。

【讨论】:

  • 仅仅因为类型擦除代码有效并不意味着泛型方法是类型安全的。
  • 就像我可以编写一个方法 &lt;T&gt; T foo(Object x) { return (T)x; } 一样,它在擦除时也会有一个有效的强制转换,但显然不是类型安全的。方法本身的擦除代码不包含可能失败的转换这一事实并不意味着泛型方法是类型安全的,因为泛型返回类型会导致在调用代码中插入转换以转换结果,并且这可能会失败。
  • 我不确定你想用这个答案解决什么问题。如果你想说在这个方法中没有ClassCastException,那么是的。但是泛型转换可能会在方法外部的代码中导致ClassCastException
  • 不,我也在谈论这个特殊情况。强制转换 is 不安全并且 可以 在某些情况下导致 ClassCastException,只是不在方法内部。
  • 您的意思是如果子类没有T 作为超类型?是的,这就是我的观点。
猜你喜欢
  • 2014-02-04
  • 2020-07-05
  • 1970-01-01
  • 2011-09-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-18
  • 1970-01-01
相关资源
最近更新 更多