[英]Upcasting and Downcasting in java
我可以理解向上转播是什么,但是向下倾斜有点令人困惑。 我的问题是我们为什么要贬低? 你能帮我一个实时的例子吗? 倾心那么重要吗?
向下转换是一种必要的恶魔,例如在处理返回非泛型集合的旧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>();
}
要在过滤器中访问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
}
} ///:~
检查源链接以获取更多信息。
随着泛型的引入,它不像以前那么重要,但有时候你需要它。
例如,当您从ObjectInputStream中读取对象时。
您需要它的一个地方是覆盖从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));
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.