2011-02-23 34 views
3

這是我無法理解的東西。從java.lang.Object訪問clone()

java.lang.Object中,clone()protected修飾符定義。根據定義,它可以通過名稱在其自己的類定義中進行訪問,也可以通過名稱在派生自它的任何類中進行命名,也可以通過同名包中任何類的定義中的名稱來進行訪問。

這裏Sample類是在另一個包中,顯然它不能從Object類訪問clone()。但由於Sample隱含地從Object派生,爲什麼它無法訪問它?該定義並沒有說它必須滿足這兩個條件(在同一個包中,也是一個子類)。

public class Sample { 

    public Object foo() throws CloneNotSupportedException { 
    ... 
    return someObject.clone(); 
    } 
} 

回答

9

在你的情況,因爲你不是在一個子類調用它的clone()方法是不可見的。 Sample來自Object,所以它可以訪問自己的clone()方法,但不能訪問其他對象。

對象clone()被設計了幾個錯誤。因此,它是不使用它一個很好的做法 - 這是很難得到正確的事:

  • 的假設是,並不是每一個對象在默認情況下可克隆
  • 如果重寫clone()使其成爲公共的,它會仍然失敗,因爲每個類必須實現Cloneable
  • Cloneable,但是,沒有定義任何方法,因此對象的用戶不能將其引用爲Cloneable並期望克隆方法。
  • 在每一個類中必須調用super.clone()默認克隆的工作機制

檢查this question替代品。

0

someObject的班級類型在這裏很重要。對象someObject可能不會覆蓋Object類的clone()方法,從而使類Sample不可見。

0

你是什麼意思「無法訪問它」?你的意思是它不會編譯,或者你的意思是它會拋出CloneNotSupportedException異常。如果你的類沒有實現Cloneable接口,則會拋出。

3

工作對我來說:http://ideone.com/eST8Y

import java.util.*; 
import java.lang.*; 

class Main 
{ 
    public Object foo() throws CloneNotSupportedException 
    { 
     return this.clone(); 
    } 

    public static void main (String[] args) throws java.lang.Exception 
    { 
     new Main().foo(); 
    } 
} 

此編譯沒有錯誤。它仍會拋出運行時CloneNotSupportedException,因爲Main未執行Cloneable

一個類實現Cloneable接口,以指示Object.clone()方法,它是合法的,該方法使該類的實例的現場換場的副本。

在未實現接口Cloneable的實例上調用對象的克隆方法會導致拋出異常CloneNotSupportedException


@Bozho's answer是真的在這裏正確的答案,雖然。 只要不使用Object.clone()

Effective Java, Item 10: Override clone judiciously(在以後的版本項目11)。