2010-03-16 21 views
5

Me está costando trabajo dominar los tipos genéricos de Java. Aquí hay un código simple que en mi opinión debería funcionar, pero obviamente estoy haciendo algo mal.Constructor de Java usando tipos genéricos

Eclipse informa de este error en BreweryList.java:

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

La idea es llenar un vector con las instancias de objetos que son una subclase de la clase fábrica de cerveza, por lo que la invocación sería algo así como:

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() { 
    } 
} 

Estoy seguro de que esto es una pregunta completas-genéricos-novato, pero estoy atascado. Gracias por cualquier consejo!

+2

A recomendamos encarecidamente usar su propia 'BreweryFactory' en lugar de abusar de' Class'. Si puede evitar razonablemente la reflexión, hágalo. –

+4

http://stackoverflow.com/ es mucho mejor para programar preguntas relacionadas. –

+0

He visto esta pregunta hace unas horas. – Roman

Respuesta

9
item.breweryMethod(); 

en lugar de

c.breweryMethod(); 

Estabas intentando llamar al método en el Class<T>, no en la instancia.

Y, de hecho, Eclipse informa

El método breweryMethod() está definido para la clase de tipo T < >

y debe quedar claro a partir de este mensaje lo que ha sucedido.

(Y después de arreglar eso, también tendrá que manejar las excepciones declaradas por Class.newInstance())

Como Tom Hawtin sugirió en un comentario, es mejor utilizar una factory method en lugar de utilizar la reflexión en su método, para crear tu objeto

+0

Ach! Tienes razón, por supuesto: elemento en lugar de c. Se compila ahora después de agregar las cláusulas apropiadas "throws". Investigaré los métodos de fábrica. Gracias por el consejo. –

+0

@Beer Me en SO es recomendable aceptar una respuesta que le haya funcionado (mediante el tick debajo del contador de votos) – Bozho

+0

Entendido ... gracias. –

4

No quiere decir:

item.breweryMethod(); 

en lugar de:

c.breweryMethod(); 

?

+0

Sí. Gracias. Los errores obvios a menudo son los más difíciles de ver. –

2

En primer lugar, para responder a su pregunta: En el bucle debe ser item.breweryMethod(); en lugar de c.breweryMethod();

No sé lo que va a hacer, pero no parece ser el mejor enfoque. Aquí están algunas sugerencias de cómo se podría mejorar su código:

  • Reemplazar Vector con ArrayList si usted no necesita la lista para ser sincronizado
  • En lugar de extender una aplicación de lista, considere usando una lista, o ¿su BreweryList proporciona más funcionalidad que una lista estándar?
+0

+1 Para recomendar Composición sobre Herencia. – helpermethod

+0

otro +1 por la misma razón – Alb

+0

BreweryList proporcionará más funcionalidad, ya que es una interfaz entre una base de datos MySQL remota y una pantalla de teléfono inteligente. Echaré un vistazo a ArrayList; eso de hecho podría funcionar mejor. Gracias. –

1

Aparte de la errata probable mencionan por encima ... no veo cualquiera de estos métodos initBreweryFromObject() definido en cualquier parte del código de ejemplo. Este es el error entonces, ¿no?