2010-03-16 17 views
5

Mam trudności z zawijaniem głowy wokół typów ogólnych Javy. Oto prosty fragment kodu, który w mojej głowie powinien zadziałać, ale oczywiście robię coś nie tak.Konstruktor Java używający generycznych typów

Eclipse zgłasza ten błąd w BreweryList.java:

The method breweryMethod() is undefined for the type <T> 

Chodzi o to, aby wypełnić Vector z wystąpień obiektów, które są podklasą klasy browar, więc wywołanie byłoby coś jak:

BreweryList breweryList = new BreweryList(BrewerySubClass.class, list); 

BreweryList.java

package com.beerme.test; 

import java.util.Vector; 

public class BreweryList<T extends Brewery> extends Vector<T> { 
    public BreweryList(Class<T> c, Object[] j) { 
     super(); 
     for (int i = 0; i < j.length; i++) { 
      T item = c.newInstance(); 

      // breweryMethod() is an instance method 
      // of Brewery, of which <T> is a subclass (right?) 

      c.breweryMethod(); 

      // "The method breweryMethod() is undefined 
      // for the type <T>" 
     } 
    } 
} 

Brewery.java

package com.beerme.test; 

public class Brewery { 

    public Brewery() { 
     super(); 
    } 

    protected void breweryMethod() { 
    } 
} 

BrewerySubClass.java

package com.beerme.test; 

public class BrewerySubClass extends Brewery { 
    public BrewerySubClass() { 
     super(); 
    } 

    public void brewerySubClassMethod() { 
    } 
} 

Jestem pewien, że jest to kwestia Complete-rodzajowych-noobem, ale utknąłem. Dzięki za wszelkie wskazówki!

+2

Zdecydowanie zalecamy użycie własnego 'BreweryFactory' zamiast nadużywania' Klasy'. Jeśli możesz rozsądnie uniknąć refleksji, zrób to. –

+4

http://stackoverflow.com/ jest znacznie lepszy do programowania powiązanych pytań. –

+0

Widziałem to pytanie kilka godzin temu. – Roman

Odpowiedz

9
item.breweryMethod(); 

zamiast

c.breweryMethod(); 

Państwo próbowali wywołać metodę na Class<T>, a nie na przykład.

I rzeczywiście, Eclipse informuje

Sposób breweryMethod() jest zdefiniowana dla typu klasy <T>

i powinno być jasne, z tej wiadomości, co się stało.

(I po to naprawić, trzeba będzie również obsługiwać wyjątki zgłoszone przez Class.newInstance())

Jak Tom Hawtin sugerowane w komentarzu, to lepiej użyć factory method zamiast używania odbicie w sposobie, w celu utworzenia twojego obiektu.

+0

Ach! Masz oczywiście rację: przedmiot zamiast c. Kompiluje się teraz po dodaniu odpowiednich klauzul "throws". Zbadam metody fabryczne. Dzięki za wskazówkę. –

+0

@Beer Me on SO jest wskazane, aby zaakceptować odpowiedź, która zadziałała dla ciebie (poprzez kliknięcie poniżej licznika głosów) – Bozho

+0

Mam ... dzięki. –

4

Nie chodziło Ci o:

item.breweryMethod(); 

zamiast:

c.breweryMethod(); 

?

+0

Tak. Dzięki. Oczywiste błędy są często najtrudniejsze do zauważenia. –

2

Przede wszystkim, aby odpowiedzieć na pytanie: W pętli powinno być item.breweryMethod(); zamiast c.breweryMethod();

Nie wiem, co masz zamiar zrobić, ale nie wydaje się być najlepszym rozwiązaniem. Oto kilka wskazówek, jak można poprawić swój kod:

  • Replace Vector z ArrayList jeśli nie potrzebujemy listy mają być synchronizowane
  • Zamiast przedłużenia realizacji listy, należy rozważyć użyciu listę, lub czy twój BrowarLista zapewnia większą funkcjonalność niż standardowa lista?
+0

+1 Za rekomendowanie kompozycji nad dziedziczeniem. – helpermethod

+0

kolejny +1 z tego samego powodu – Alb

+0

BreweryList zapewni większą funkcjonalność, ponieważ jest to interfejs między zdalną bazą danych MySQL a wyświetlaczem smartfona. Rzucę okiem na ArrayList; to w rzeczywistości może działać lepiej. Dzięki. –

1

Oprócz prawdopodobnej literówki powyżej ... Nie widzę żadnej takiej metody zdefiniowanej w dowolnym miejscu w kodzie przykładowym. To jest błąd, nie?

Powiązane problemy