在java中的向上转换和向下转换

时间:2010-10-25 09:18:43

标签: java

我可以理解向上转播是什么,但是向下倾斜有点令人困惑。我的问题是我们为什么要贬低?你能帮我一个实时的例子吗?倾向于那么重要吗?

8 个答案:

答案 0 :(得分:9)

向下转换是一种必要的恶魔,例如在处理返回非泛型集合的旧API时。另一个经典的例子是equals方法:

public class Phleem{

    public Phleem(final String phloom){
        if(phloom == null){
            throw new NullPointerException();
        }
        this.phloom = phloom;
    }

    private final String phloom;

    public String getPhloom(){
        return phloom;
    }

    @Override
    public boolean equals(final Object obj){
        if(obj instanceof Phleem){
            // downcast here
            final Phleem other = (Phleem) obj;
            return other.phloom.equals(phloom);
        }
        return false;
    }

    // ...

}

我想不出一个需要Upcasting的例子。好的,最好从方法中返回最不具体的可能Object,但这可以完全不用强制转换来完成:

public Collection<String> doStuff(){
    // no casting needed
    return new LinkedHashSet<String>();
}

答案 1 :(得分:2)

要在过滤器中访问ServletResponse的头方法,您必须向下转换为HttpServletResponse。

通过扩展的类声明对象是很好的,因此您可以动态更改实现。但是,如果您需要访问特定于实现的任何方法,则需要向下转发。

答案 2 :(得分:1)

你需要记住的是,当它有可能在运行时间成功时允许向下转换。

这将有效:

Object o = doStaff();
String s = (String) o; 

这将失败:

Object o = new Object();
String s = (String) s;

  

Q1:我们为什么要使用垂头丧气?

通常由开发人员来决定使用低价广告。有时候方法会返回对象或者像参数一样使用等于方法然后使用子广播我们可以返回特定类型。

  

Q2:贬低是否很重要?

作为编码中的一切,但更好的词会有用,恕我直言。

答案 3 :(得分:0)

您问题的最佳解决方案是阅读一本好书。您将了解多态,对象,模式......
好的开始是“Beginning java objects 2nd edition”

答案 4 :(得分:0)

当您收到一个您知道具有更具体(在类层次结构中)类型的对象并且您希望将其转换为该类型时,需要向下转换。

示例:您从某个服务接收Object并且您知道它实际上是String并且您将它向下转换为String。在向下转换之前,您应该始终检查类型,否则会冒着ClassCastException的风险:

Object receivedObject = receiveFromSomewhere();
if(receivedObject instanceof String){
    receivedString = (String) receivedObject;
}

答案 5 :(得分:0)

向下转型示例

//: RTTI.java
// Downcasting & Run-Time Type
// Identification (RTTI)
import java.util.*;

class Useful {
  public void f() {}
  public void g() {}
}

class MoreUseful extends Useful {
  public void f() {}
  public void g() {}
  public void u() {}
  public void v() {}
  public void w() {}
}

public class RTTI {
  public static void main(String[] args) {
    Useful[] x = {
      new Useful(),
      new MoreUseful()
    };
    x[0].f();
    x[1].g();
    // Compile-time: method not found in Useful:
    //! x[1].u();
    ((MoreUseful)x[1]).u(); // Downcast/RTTI
    ((MoreUseful)x[0]).u(); // Exception thrown
  }
} ///:~ 

查看source link了解详情。

答案 6 :(得分:0)

随着泛型的引入,它不像以前那么重要,但有时你需要它。

例如,当您从ObjectInputStream中读取对象时。

答案 7 :(得分:0)

您需要它的一个地方是覆盖从equals继承的Object方法。由于传递给方法的参数是Object类型,因此必须将其强制转换为类的类型才能访问其中定义的方法和变量。只需要特别注意提到的对象是什么。 也就是说,实例化的对象被传递给equals()方法,而不是它的引用。

class MySuperClass
{
    private int num1;

    public MySuperClass() {}

    public MySuperClass(int num1)
    {
        this.num1 = num1;
    }
}

class MySubClass extends MySuperClass
{
    private int num;

    public MySubClass(int num)
    {
        this.num = num;
    }

    public boolean equals(Object o)
    {
        if (!(o instanceof MySubClass))
            return false;

        MySubClass mySub = (MySubClass)o;

        return(mySub.num == num);
    }

    public static void main(String[] args)
    {
        Object mySub = new MySubClass(1);
        MySuperClass mySup = new MySubClass(1);

        System.out.println(mySub.equals(mySup));
    }

}