我可以理解什么是向上转型,但是向下转型有些困惑。我的问题是为什么我们需要进行向下转型?你能给我一个现实世界的例子吗?向下转型那么重要吗?
我可以理解什么是向上转型,但是向下转型有些困惑。我的问题是为什么我们需要进行向下转型?你能给我一个现实世界的例子吗?向下转型那么重要吗?
向下转型是一种必要的恶,例如在处理返回非泛型集合的遗留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;
}
// ...
}
我无法想象出必须使用向上转型的例子。当然,从方法中返回尽可能不太具体的对象是一种好的实践,但这完全可以在没有强制类型转换的情况下完成:
public Collection<String> doStuff(){
// no casting needed
return new LinkedHashSet<String>();
}
在过滤器中访问ServletResponse的头方法,您需要将其向下转换为HttpServletResponse。
按其扩展类声明对象是很好的,这样您可以随时更改实现。但是,如果您需要访问任何特定于实现的方法,则需要向下转换。
Object o = doStaff();
String s = (String) o;
Object o = new Object();
String s = (String) s;
当你接收到一个对象,你知道它有更具体的类型(在类层次结构中向下),并且你想将其转换为该类型时,就需要进行向下转型。
例如:你从某个服务接收到 Object,你知道它实际上是 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
}
} ///:~
请查看源链接以获取更多信息。
你需要使用它的一个场景是当你重写从Object
继承的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));
}
}
你问题的最佳解决方案是阅读一本好书。你将学习关于多态性、对象、模式...
一个很好的开始是"Beginning java objects 2nd edition"
随着泛型的引入,它比以前不那么重要了,但有时你仍然需要它。
例如,当你从ObjectInputStream读取一个对象时。