2016-08-10 8 views
12

Próbowałem swoich sił na wektorach i napisałem prosty kod, aby uzyskać dostęp do jego elementów poprzez wyliczenie.Otrzymuję wyjątek ClassCast, gdy wyliczam wektor z parametrem typu String, ale nie ma wyjątku z liczbą całkowitą jako parametrem typu

Vector v = new Vector(); 
    v.add("Some String"); 
    v.add(10); 

    Enumeration e = v.elements(); 
    while(e.hasMoreElements()) System.out.println(e.nextElement()); 

Praca z typami nieprzetworzonymi daje wyniki zgodnie z oczekiwaniami (wypisuje elementy). Ale kiedy używam generycznego typu modułu wyliczającego, robi się to trudne.

sznurkiem jako typ parametru:

Vector v = new Vector(); 
    v.add("Some String"); 
    v.add(10); 

    Enumeration<String> e = v.elements(); 
    while(e.hasMoreElements()) System.out.println(e.nextElement()); 

wyjściowa:

Niektóre String

Wyjątek w wątku "main" java.lang.ClassCastException: java.lang.Integer nie można rzutowany na java.lang.String

Z liczbą całkowitą jako typ Parametr:

Vector v = new Vector(); 
    v.add("Some String"); 
    v.add(10); 

    Enumeration<Integer> e = v.elements(); 
    while(e.hasMoreElements()) System.out.println(e.nextElement()); 

wyjściowa:

Niektóre String

Co się tu dzieje? Czy oba przypadki nie powinny generować wyjątku ClassCast?

+1

'Wyliczenie <> e = v.elements();' Jak to się kompiluje? –

+0

@KonstantinYovkov Myślę, że to literówka i OP oznaczało 'Enumeration '. – Mena

+0

Używasz typu surowego 'Vector': http://stackoverflow.com/a/2770692/1608594 Nie powinieneś używać typów surowych. – carbolymer

Odpowiedz

5

Należy pamiętać, że wszystkie generyczne są kasowane podczas kompilacji, aby pomóc kompilatorowi potwierdzić, że nie popełniono żadnego błędu. Prawdopodobnie dostaniesz kilka ostrzeżeń w tym punkcie, mówiąc, że nie powinieneś używać surowych typów (surowy oznacza Vector zamiast Vector<String> itd.). Rodzajowy odpowiednik typu surowego to <?>, co oznacza, że ​​zezwalasz na dowolny typ (pamiętaj, że spowoduje to, że nie będziesz już kodować kompilatora).

Zachowanie widać jest, ponieważ istnieją dwa (a właściwie kilka więcej, ale w przypadku dwóch służą) funkcje z nazwą System.out.println() i różnych typów parametrów, to się nazywa (metoda przeciążenie):

  1. System.out.println (String)
  2. System.out.println (Object)

w czasie kompilacji to decyduje, który nazywa na kodzie.

W przykładzie łańcuchowym wyliczenie ma typ ogólny String i zostanie wywołane jako pierwsze. Jednak po przejściu obiektu Integer z Twojego Vector powoduje to błąd podczas przesyłania go do String. Więc w tym przypadku, kompilator konwertuje kod do następujących (w przybliżeniu):

Enumeration e = v.elements(); 
while(e.hasMoreElements()) System.out.println((String)e.nextElement()); 

W przykładzie Integer wyliczenie ma ogólny typ Integer która będzie mapować do System.out.println(Object), który akceptuje zarówno String i Integer, więc wszystko idzie dobrze.

Na stronie internetowej: domyślnie powinieneś używać ArrayList zamiast Vector, ma znacznie czystszy interfejs, ze względu na starsze metody w Vector. Również Vector jest zsynchronizowany, powodując niepotrzebne obciążenie.

Powiązane problemy