2014-12-15 11 views
6

naprawdę nie mogę zrozumieć, dlaczego ta linia kodu nie kompilacji:Ciąg do obiektu, ale nie obiekt do ciąg?

String str = new Object(); 

natomiast następujące robi:

Object o = new String("Hello"); 

do mojego zrozumienia, String, podobnie jak każdej innej klasy, rozszerza Object . Dlaczego więc nie kompiluje się pierwszy wiersz?

+0

Typ obiektu po prawej stronie musi być lub rozciągnąć typ po lewej stronie. Obiekt nie jest ciągiem ani nie rozszerza łańcucha. – csmckelvey

+19

Musisz znaleźć podstawowy tekst dotyczący programowania obiektowego i go przestudiować. (Poważnie, nie zrozumiesz pojęć z odpowiedzi na 100 słów na SO). –

Odpowiedz

23

Ponieważ String jest Object, ale Object nie jest String, podobnie jak każdy pomarańczowy jest owoce, ale nie każdy owoce jest pomarańczowy.

String jest klasa, która rozszerza Object, więc można po prostu napisać:

Object obj = "string"; 

Ale Object nie rozciąga String, więc:

String str = new Object(); 

nie będzie skompilować.

Chociaż, jeśli masz Object, i to jest String, można zrobić coś, co nazywa się typu odlew lub po prostu odlewania:

String str = (String) myObject; 

Ale to może rzucić ClassCastException jeśli myObject nie jest oryginalnie typu String

Tutaj można znaleźć więcej informacji na temat Obiekt Casting w Javie: http://www.javabeginner.com/learn-java/java-object-typecasting

+0

Tak więc wyrażenie String str = new Object(); z grubsza tłumaczy na: str jest obiektem typu String? Próbuję uzyskać intuicyjne zrozumienie tego, jak czytać ten wiersz kodu. – wonggr

+0

Jeśli twój obiekt jest ciągiem znaków, to możesz zrobić obiekt String str = (String); Znany jako "Casting" – Victor2748

+0

Awesome clear answer. Rozumiem to teraz, dzięki! – wonggr

4

Dla tego rodzaju rzeczy przydatne jest rozróżnienie między typem zmiennej, ustalonej w jej deklaracji, a klasą obiektu ustaloną podczas tworzenia obiektu.

Zmienna może mieć wartość null lub wskazywać dowolny obiekt, którego klasa jest zgodna z typem, lub jest podklasą bezpośrednią lub pośrednią tej klasy. Ponieważ String jest podklasą Object, zmienna typu Object może wskazywać obiekt klasy String.

W przykładzie kompilator wie, że wyrażenie String musi być null lub punkt do String obiektu, więc Object o = new String("Hello"); jest znany w czasie kompilacji za prawidłowe.

Z drugiej strony wyrażenie lub zmienna typu Object może odwoływać się do ciągu, ale może odwoływać się do czegoś zupełnie innego. Kompilator wymaga jawnego rzutowania, aby powiedzieć, że konwersja jest OK.

public class Test { 
    public static void main(String[] args) { 
    Object stringObject = "xyzzy"; 
    Object integerObject = new Integer(3); 
    String test1 = (String)stringObject; 
    System.out.println(test1); 
    String test2 = (String) integerObject; 
    System.out.println(test2); 
    } 
} 

Ten program kompiluje się, ponieważ powiedziałem kompilatorowi, że konwersje są prawidłowe w przypadku moich rzutów.Działa przez pierwsze wywołanie println, ponieważ stringObject naprawdę wskazuje na String. Nie powiedzie się z ClassCastException na linii String test2 = (String) integerObject;. O ile kompilator wie, integerObject może wskazywać na String, więc zaakceptował moją obsadę. W czasie wykonywania JVM stwierdza, że ​​naprawdę wskazuje na Integer i zgłasza wyjątek.

Użycie typu Object dla parametru integerObject jest znaczące. To sprawia, że ​​konwersja wyrażenia typu typu na typ String jest konwersją, która może się powieść, w zależności od tego, co faktycznie odwołuje się do. Jeśli integerObject zadeklarował typ Integer, kompilator odrzuciłby program. Nie ma obiektu, do którego można odwoływać się za pomocą obu wyrażeń Integer i String.

Powiązane problemy