簡體   English   中英

在java中的向上轉換和向下轉換

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM