【问题标题】:Seeking explanation for Auto-Casting寻求自动铸造的解释
【发布时间】:2009-07-15 21:47:37
【问题描述】:

所以我只花了大约一个小时试图揭开并解决一个非常奇怪的错误,这是我以前从未见过的。

我或多或少地询问这种从枚举到字符串的随机转换的潜在原因,而不是“请为我修复我的代码”

问题的要点如下:

我有一个接口,叫它IFoo,在这个接口里面,它有一个静态枚举,叫Bar

public interface IFoo {
  static enum Bar{
    A,
    B,
    C,
  }

  Bar doGetBar();
}

我当然有一个实现IFooFoo 类。

public class Foo implements IFoo{
  public Bar getBar(){
    return Bar.A; // for example
  }
}

在其他地方,我有一个名为

的对象数组
Object[] result;

还有一个辅助方法,它返回Objects 的数组,保存getBar()方法的结果,调用它

public Object[] getBars()

现在,当我这样做时

result = getBars();

result 神奇地持有Strings 而不是Bars,字符串的值是Bar 的外部类(不是真正的外部类,更像是一个包装类?)的实现类,即“Foo”。

有人可以向我解释这怎么可能吗?

一些线索: 1.结果是在分配之前保持字符串。 2. IFoo 中的静态枚举是有问题的,它是非静态的,但是当我尝试将它从 Foo.Bar (或类似的东西)强制转换为 IFoo.Bar 时,它导致了ClassCastExceptions。

【问题讨论】:

  • 您需要发布一段我们可以查看的实际工作代码
  • 如果我不能这样做,我应该关闭线程吗?
  • 为什么不可能?
  • 我不是要你重现整个代码库 :-) 只需编写一个像上面这样的小程序来演示错误并且只显示错误。毕竟,您似乎在问“我编写的某些代码中有错误但无法显示给您”。有人应该如何提供帮助?
  • 不可能通过查看完全不同(且不一致)的代码来诊断问题,而您认为包含导致实际出现这种奇怪行为的原因的本质代码。要么发布实际代码,要么尝试在一个最小示例中重现问题 - 您可能会在构建该示例时发现潜在问题。

标签: java exception


【解决方案1】:

你的Object[] 里面有Strings,因为你把它们放在那里。如果您发布一个小示例代码,清楚地表明您将Bars 放入但将Strings 取出,我会感到非常惊讶。

解决此类错误的方法是从头开始,制作一个简单的工作示例(可能不会显示错误)。然后继续添加代码以使其更像您的真实应用程序,直到错误出现。然后,您将能够确定您最近的更改是错误的来源。

【讨论】:

  • 好吧,我查看了调试器,并在赋值后直接评估了右侧的输出。一个持有 String 对象,一个持有枚举。
  • 有几个选项。 1)您对您认为在调试器中看到的内容犯了错误。 2)您对您认为在调试步骤中执行的代码有误。 3) JVM 存在一个基本问题。在你的机器上。没有其他人。听我的建议——你需要从头开始慢慢地、有条不紊地重新提出你的问题。我知道这是一种痛苦。但它会起作用
【解决方案2】:

尚不清楚getBars() 方法中包含什么“魔法”,如果没有更多信息,不可能生成示例实现来验证此行为。具体来说,不清楚“返回对象数组的辅助方法,保存 getBar() 方法的结果”是什么意思。

如果可以,请按照建议隔离包含该行为的最小测试用例。 oxbow_lakes 的建议也不错;让简单的测试尽可能接近真实行为。

如果您真的无法生成一个简化的场景来向我们展示,那么我们帮助您的能力将受到严重限制,因为 getBar() 方法是填充 Object[] 的地方。在这种情况下,如果您无法解决,那么我建议您可能需要向知识更渊博的同事寻求一些帮助 - 可能第二双眼睛会发现它。

【讨论】:

    【解决方案3】:

    改为使用集合和泛型来确保类型安全。

    编辑现在问题变成了概念层面的问题,我会用我的远程感知来找出原因。

    看来您在第 252 行重用了一个 Object[] 数组用于完全不同的目的。编译器接受

    Object[] objs = Bar.values();
    //...
    objs = "A B C".split("\\s+");
    //...
    return objs;
    

    这种代码是因为 Java 中的数组是协变的(例如 String[] 是 Object[] 的子类)。以这种方式重用基类对象数组很麻烦。

    【讨论】:

    • 第一个问题:“为什么我不能将ArrayList<String> 分配给List<Object>?”?
    【解决方案4】:

    我假设您的 getBars() 方法如下所示:

         public Object[] getBars() {
         return Bar.values();
     }
    

    如果您想知道应该从 'Bar.values()' 方法收到什么,请查看 the JavaDoc。在您的情况下,values() 将返回类型 FooI$Bar

    发布可能有用的不仅是您放在一起的引发异常的代码,还有 ClassCastException。

    【讨论】:

      猜你喜欢
      • 2014-09-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多