简体   繁体   English

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

[英]Upcasting and Downcasting in java

I can understand what upcasting is but Downcasting is a little confusing. 我可以理解向上转播是什么,但是向下倾斜有点令人困惑。 My question is why should we downcast? 我的问题是我们为什么要贬低? Can you help me with a real time example ? 你能帮我一个实时的例子吗? Is downcasting that important? 倾心那么重要吗?

Downcasting is a necessary evil, for example when dealing with legacy APIs that return non-generic collections. 向下转换是一种必要的恶魔,例如在处理返回非泛型集合的旧API时。 Another classic example is an equals method: 另一个经典的例子是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;
    }

    // ...

}

I can't think of an example where Upcasting is necessary though. 我想不出一个例子,其中Upcasting是必要的。 OK, it's good practice to return the least specific possible Object from a method, but that can be done entirely without casting: 好的,从方法中返回最不具体的可能Object是一个好习惯,但这可以完全不用强制转换完成:

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

To access the header methods of of the ServletResponse in a filter, you have to downcast to to an HttpServletResponse. 要在过滤器中访问ServletResponse的头方法,您必须向下转换为HttpServletResponse。

It's good to declare objects by the class they extend, so you can change the implementation on the fly. 通过它们扩展的类声明对象是很好的,因此您可以动态更改实现。 However if you need to access any of the methods that are specific to the implementation, you need to downcast. 但是,如果您需要访问特定于实现的任何方法,则需要向下转换。

What You need to remember is that downcasting is allowed when there is a possibility that it suceeds at run time. 你需要记住的是,当有可能在运行时它成功时,允许向下转换。

This will work: 这将有效:

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

This will fail: 这将失败:

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

Q1: Why we should use downcast ? Q1:为什么我们应该使用垂头丧气?

It is generally up to developer, to used the downcast. 通常由开发人员来使用向下转发。 Sometimes methods return Objects or use as parameter like equal method and then using subcast we can back to specific type. 有时候方法会返回对象或者像参数一样使用等于方法然后使用子广播我们可以返回特定类型。

Q2: Is downcast important ? Q2:垂头丧气吗?

As everything in coding, but better word would be useful, IMHO it is. 作为编码中的一切,但更好的词会有用,恕我直言。

The best solution for your question is to read a good book. 你的问题的最佳解决方案是阅读一本好书。 You will learn about polymorphism, objects, patterns ... 您将了解多态,对象,模式......
Good start is "Beginning java objects 2nd edition" 好的开始是“开始java对象第2版”

Downcasting is needed when you receive an object that you know has some more specific (down the class hierarchy) type and you want to cast it to that type. 当您收到一个您知道具有更具体(在类层次结构中)类型的对象并且您希望将其转换为该类型时,需要向下转换。

Example: you receive Object from some service and you know that it is actually String and you downcast it to String. 示例:您从某个服务接收对象,并且您知道它实际上是String,并且您将其向下转换为String。 Before downcasting you should always check the type otherwise you risk the ClassCastException: 在向下转换之前,您应该始终检查类型,否则会冒着ClassCastException的风险:

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

Downcasting Example 向下转型的例子

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

Check source link for more information. 检查源链接以获取更多信息。

With the introduction of generics, it is less important than it was before, but there are times when you need it. 随着泛型的引入,它不像以前那么重要,但有时候你需要它。

For instance, when you read an object from an ObjectInputStream. 例如,当您从ObjectInputStream中读取对象时。

One place you need it is if you override the equals method inherited from Object . 您需要它的一个地方是覆盖从Object继承的equals方法。 Since the parameter passed to the method is of type Object , you have to cast it to the type of the class to be able to access methods and variables defined in it . 由于传递给方法的参数是Object类型,因此必须将其强制转换为类的类型才能访问其中定义的方法和变量 Just pay special attention to what referred to object is. 只需要特别注意提到的对象是什么。 That is to say, instantiated object is passed to the equals() method, not its reference. 也就是说,实例化的对象被传递给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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM