2009-07-07 20 views
5

vi una función de Java que parecía algo así como esto:Java: ¿Qué es - público estático <T> foo() {...}?

public static<T> foo() {...} 

sé lo que son los genéricos, pero puede alguien explicar el en este contexto? ¿Quién decide qué es T? ¿Que está pasando aqui?

EDITAR: ¿Puede alguien por favor mostrarme un ejemplo de una función como esta.

+0

que quieres decir: public static int binarySearch (Lista > lista, tecla T) en Colecciones? Es solo un tipo genérico, en este caso si su clave es una Cadena, entonces su Lista debe ser de elementos que implementen Comparable que pueda comparar Cadenas. No hay nada que decida sobre qué es T igual, solo se trata de verificaciones de tiempo de compilación. – JeeBee

+0

Sí, eso es lo que quiero decir. – quilby

Respuesta

11

Te has perdido el tipo de devolución, pero aparte de eso, es un método genérico. Al igual que con los tipos genéricos, T representa cualquier tipo de referencia (dentro de los límites, si corresponde).

Para los métodos, los parámetros genéricos son típicamente inferidos por el compilador. En determinadas situaciones, es posible que desee especificar los argumentos genéricos sí mismo, utilizando una sintaxis poco peculiar:

List<String> strings = Collections.<String>emptyList(); 

En este caso, el compilador pudiera deducir el tipo, pero no siempre es obvio si el compilador puede o puede' t. Tenga en cuenta que el <> está detrás del punto. Por razones sintácticas siempre se debe especificar el nombre del tipo o el objeto de destino.

Es posible tener constructores genéricos, pero nunca he visto ninguno en la naturaleza y la sintaxis empeora.

Creo que las sintaxis C++ y C# colocan los tipos genéricos después del nombre del método/función.

+0

Agh! ¡Mis ojos! ¡Quema! – skaffman

+0

tu rock. ¡Mira, verdadero java guru!/bows down /: D – jrharshath

0

T es el parámetro de tipo formal que será reemplazado por el argumento real tipo utilizado en la instanciación del objeto.

Por ejemplo, aquí está la lista de definitios e Iterator en paquete java.util:

public interface List<E>{ 
    void add(E x); 
    Iterator<E> iterator(); 
} 

public interface Iterator<E>{ 
    E next(); 
    boolean hasNext(); 
} 

A continuación, puede crear una instancia de una lista de la siguiente manera:

List<String> ls = new ArrayList<String>() 

¿Dónde se puede imaginar esa lista gradas para una versión de List donde E tiene sido reemplazado uniformemente por String:

public interface StringList{ 
    void add(String x) 
    Iterator<String> iterator(); 
} 
+0

No necesariamente se crea una instancia de ningún objeto. (Usando una conjetura razonable sobre cuál debería haber sido el ejemplo). –

+0

Hhmm ... tienes razón, el reemplazo se realiza en _compilation_time (pero de todos modos, esto se usará para crear una instancia del objeto más adelante) –

+0

No es necesario que esté cualquier ejemplificación de objetos pasando en absoluto. La sintaxis parece ser para métodos genéricos, no genéricos. (Técnicamente, el ejemplo del cuestionario necesita un reemplazo para llegar a una sintaxis válida que podría ser 'public foo() {...}' que es sintaxis técnicamente válida para una clase llamada 'foo' (o el compilador se queja de no usar el parámetro genérico?).) –

2

El contexto es un método genérico en comparación con una clase. La variable <T> se aplica solo a la llamada del método. La clase Colecciones tiene un número de estos; la clase en sí no es genérica, pero muchos de los métodos sí lo son.

El compilador decide qué T es igual a, es igual a lo que sea que los tipos funcionen. A veces esto es más fácil que otros.

Por ejemplo, el método de static <T> Set<T> Collections.singleton(T o) el tipo se define en el parámetro:

Collections.singleton(String T) 

devolverá un Set<String>.

Algunas veces el tipo es difícil de definir. Por ejemplo, a veces no hay suficiente información para escribir Collection.emptyList(). En ese caso, puede especificar el tipo directamente: Collection.<String>emptyList().

+0

Por favor, mira mi edición – quilby

Cuestiones relacionadas