9

每当我尝试将 BufferedImage (父级)转换为我自己扩展的 AdvancedBufferedImage (子级)时,我都会得到一个ClassCastException,我没有重写任何方法,并且我已经实现了所有承包商而不修改它们

每当我尝试使用 ImageIO.read() 方法从文件中创建 AdvancedBufferedImage 时,我都会遇到此异常。

File file = new file(path);
AdvancedBufferedImage image = (AdvancedBufferedImage) ImageIO.read(file);

好像应该没有问题,请问是什么问题?

4

7 回答 7

15

不允许这样的向下转换。

首选的解决方案是创建 AdvancedBufferedImage 的构造函数,将 BufferedImage 作为参数。有了它,您可以执行以下操作。

File file = new file(path);
AdvancedBufferedImage image = new AdvancedBufferedImage(ImageIO.read(file));

在这里,AdvancedBufferedImage 的构造函数可以决定如何将 BufferedImage 正确转换为高级图像。

于 2012-08-03T15:47:03.500 回答
4

除非 PARENT 类的引用包含 CHILD 类或其派生类的实例,否则不能将 PARENT 类强制转换为 CHILD 类。

在您的情况下,ImageIO.read(file)返回一个实例BufferedImage,它是基类。这只有在ImageIO.read(file)返回实例AdvancedBufferedImage或其子类时才有效。

当你扩展某个类时,派生类会从基类继承一些属性,但是,基类什么也得不到。因此,由于派生类的实例具有基类的所有属性,因此基类的引用可以保存派生类的实例,即可以将派生类强制转换为基类。现在,派生类可能会添加一些新属性,而基类永远不会知道这些属性。所以从 BASE 类转换为 DERIVED 显然是不正确的。

于 2012-08-03T15:43:18.210 回答
3

Java中的向下转型

向下转型不会像这样工作。请参阅上面帖子中的答案。作为替代方案,如何创建一个静态工厂方法,该方法接受BufferedImage并返回使用返回的对象构建的类的实例ImageIO.read()

例如:

private AdvancedBufferedImage(BufferedImage bi) {
    //  build your AdvancedBufferedImage from bi
    ...
}

public static AdvancedBufferedImage buildABI(BufferedImage bi) {
    return new AdvancedBufferedImage(bi)
于 2012-08-03T15:43:57.830 回答
2

通常,您不能将父类转换为子类。就像强迫将动物投给狗一样。Dog 是一种动物,但另一种方式并不总是如此,因此 Java 编译器不允许您这样做。

请参阅对象继承

于 2012-08-03T16:06:26.150 回答
2

向下转型是允许的,但它必须是孩子的实际实例:

class A {
  String name = "a";
  A(){};
}

class B extends A {
}

public class Main {
  public static void main(String[] args) {
    A a = new B(); // must a b instance
    B b = new B();
    b = (B)a;
    System.out.println(b.name);

  }
}
于 2016-06-29T06:45:10.887 回答
0

BufferedImage 不是一个 AdvancedBufferedImage,所以演员表失败了。

您可以扩展 的功能BufferedImage,但该read方法仍然只返回一个BufferedImage. 强制转换不会强制引用成为或表现为所需的类型。

你可能想BufferedImage在你的AdvancedBufferedImage类中包装一个,然后你可以传递和操作你的高级类。

于 2012-08-03T15:44:01.470 回答
-1

只有当您尝试转换的对象实际上是您要转换的类的实例时,您的向下转换才会成功。

于 2012-08-03T15:41:14.203 回答