¿Qué es una conversión de captura en Java y puede alguien que me dan ejemplos?

StackOverflow https://stackoverflow.com/questions/4431702

  •  09-10-2019
  •  | 
  •  

Pregunta

Me he dado cuenta de JLS habla de 5.1 0.10 Captura de conversión , pero no entienden lo que son.

Puede alguien que me explique / dar ejemplos?

¿Fue útil?

Solución

conversión de captura fue diseñado para hacer comodines (en genéricos), ? útil.

Supongamos que tenemos la siguiente clase:

public interface Test<T> {
    public void shout(T whatever);
    public T repeatPreviousShout();

}

y en algún lugar de nuestro código tenemos,

public static void instantTest(Test<?> test) {
    System.out.println(test.repeatPreviousShout());
}

Debido a que no es un test Test cruda y desde repeatPreviousShout() en "retrospectiva" devuelve un ?, el compilador sabe que hay una T que sirve como un parámetro de tipo para Test. Este T es para algunos T desconocido lo que el compilador borra el tipo desconocido (por comodín, que sustituye con Object)., Devoluciones por lo tanto repeatPreviousShout() un Object.

Pero si tuviéramos,

public static void instantTest2(Test<?> test) {
    test.shout(test.repeatPreviousShout());
}

El compilador nos daría un error de algo así como Test<capture#xxx of ?> cannot be applied (donde xxx es un número, por ejemplo 337).

Esto se debe a los intentos del compilador para hacer el control de seguridad de tipo de shout() pero ya que recibió un comodín, que no sabe lo que T representa, por lo tanto, crea un marcador de posición llamado captura de .

aquí (teoría y la práctica de Java: salvaje Ir con los genéricos, Parte 1) , se indica claramente:

Captura de conversión es lo que permite la compilador para la fabricación de un marcador de posición escriba el nombre para el comodín capturado, de manera que la inferencia de tipos puede inferir que a ser ese tipo.

Espero que esto le ayuda.

Otros consejos

Un tipo parametrizado que implica argumentos de tipo comodín es realmente un tipo de unión. Por ejemplo

List<? extends Number> = Union{ List<S> | S <: Number }

En 2 casos, en lugar de utilizar List<? extends Number>, Java utiliza el List<S> versión capturada, donde S es una variable de tipo recién creado con Number límite superior.

(1) http://java.sun.com /docs/books/jls/third_edition/html/expressions.html

Para delimitar el tipo de una expresión. Si el tipo de una expresión es List<? extends Number>, estamos seguros de que el tipo de ejecución del objeto es en realidad un List<S> para algún tipo concreto S (S <: Number>). Así usos compilador List<S> lugar, para llevar a cabo análisis de tipo más precisa.

conversión Capture se aplica a cada expresión individual; Esto lleva a algunos resultados mudos:

<T> void test1(List<T> a){}
<T> void test2(List<T> a, List<T> b){}

List<?> x = ...;
test1(x);    // ok
test2(x, x); // error

(2) http: // java .sun.com / docs / libros / JLS / third_edition / html / typesValues.html # 4.10.2

En subtipo comprobar A :< B donde A implica argumentos comodín. Por ejemplo,

List<? extends Number>  :< B
<=>
Union{ List<S> | S <: Number}  :< B
<=>
List<S> :< B, for all S <: Number

Así pues, en efecto, estamos comprobando la versión capturada de tipo A

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top