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

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

向下转换是一种必要的恶魔,例如在处理返回非generics集合的遗留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 doStuff(){ // no casting needed return new LinkedHashSet(); } 

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

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

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

这将有效:

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

这将失败:

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

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

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

Q2:垂头丧气吗?

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

你的问题的最佳解决方案是阅读一本好书。 您将了解多态,对象,模式……
好的开始是“开始java对象第2版”

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

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

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

向下转型的例子

 //: 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 } } ///:~ 

检查源链接以获取更多信息。

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

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

你需要它的一个地方是你重写从Objectinheritance的equals方法。 由于传递给方法的参数是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)); } }