如何向下转发返回的对象?

时间:2015-12-13 23:30:09

标签: java

我在尝试向下转换方法返回的对象时遇到问题。 我知道我正在做的不正确,但我没有达到解决方案。

请参阅以下代码。

这是一个控制器类,我可以处理异常:

public class SubsystemFacade {

  public CustomClass1 method1() {
   try {
    //do something and return a new CustomClass1 object
   } catch (Exception e) {
    return (CustomClass1) this.handleExceptions(e); //Should return a CustomClass1 object but CastException is throwed
   }
  }

  public CustomClass2 method2() {
   try {
    //do something and return a new CustomClass2 object
   } catch (Exception e) {
    return (CustomClass2) this.handleExceptions(e); //Should return a CustomClass2 object but CastException is throwed
   }
  }

  private SuperCustomClass handleExceptions(Exception e) {
   //do something, log error...
   SuperCustomClass customClass = new SuperCustomClass(...);
   return customClass;
  }

}

我希望SubsystemFacade始终将对象作为CustomClass1或CustomClass2返回,而不是异常。

这是我的模特:

public class SuperCustomClass {...}
public class CustomClass1 extends SuperCustomClass {...}
public class CustomClass2 extends SuperCustomClass {...}

3 个答案:

答案 0 :(得分:1)

您不能将SuperCustomClass的对象转发为CustomClass2,因为它不是CustomClass2

转换的想法是您正在更改对象的静态类型(引用类型)。你没有改变对象的实际(动态)类型。

例如,

可以降级:

SuperCustomClass obj = new CustomClass2(...)

因为实际类型是CustomClass2。

在您的情况下,您正在创建new SuperCustomClass(..) - 因此您无法将其向下转换为CustomClass2

答案 1 :(得分:1)

在堆上,执行

SuperCustomClass customClass = new SuperCustomClass(...);

您已使用SuperCustomClass

创建了new类型的对象

相反,如果你已经完成了

SuperCustomClass customClass = new CustomClass1 (...);

即使引用的类型为CustomClass1

,堆上的对象也将属于SuperCustomClass类型

如果引用可以更改为堆上对象的类型,则向下转换将起作用,这不是这种情况。见下文。

实践示例

// Not possible
// Object on the heap is of type Object
Object o = new Object();
(String)o;

// Possible
// Object on the heap is of type String
Object o = new String();
(String)o;

答案 2 :(得分:1)

假设你的handleExceptions函数实际上正在解决导致异常的问题,那么你可以看一下重新调用method1 / method2

  private SuperCustomClass handleExceptions(Exception e, boolean callMethod1) {
   //do something, log error...
   if (callmethod1)
     return method1(); 
   return method2();
  }

当然最好传递对方法1/2的引用而不是布尔值,例如在Java8中。或者策略,如果你有一个更复杂的设置。

注意这是递归,所以请确保你的循环实际结束(即如果异常重新生成,你将获得无限递归) - 修复导致异常的问题。