Pregunta Genéricos de Java - a


En la forma de aprender Java Generics, me quedé atrapado en un punto.
Fue escrito "Java Generics solo funciona con Objects y no con los tipos primitivos".

p.ej

 Gen<Integer> gen=new Gen<Integer>(88);     // Works Fine ..  

Pero, con los tipos primitivos como int, char, etc.

 Gen<int> gen=new Gen<int>(88) ;    // Why this results in compile time error 

Quiero decir, dado que los genéricos de java tienen la función de auto-boxing y unboxing, ¿por qué esta característica no se puede aplicar cuando declaramos un tipo específico para nuestra clase?

Quiero decir, ¿por qué? Gen<int> no lo hace   se convierte automáticamente a    Gen<Integer> ?

Por favor, ayúdame a aclarar esta duda.
Gracias.


13
2018-02-15 06:26


origen


Respuestas:


Autoboxing no dice que puedes usar int en lugar de Integer. Autoboxing automatiza el proceso de boxeo y desempaquetado. P.ej. Si necesito almacenar alguna primitiva int en una colección, no necesito crear el objeto wrpper manualmente. Ha sido cuidado por el compilador de Java. En el ejemplo anterior estás instanciando un objeto genérico que es de tipo Integer. Este objeto genérico funcionará bien con int pero declarar int como un tipo genérico es incorrecto. Los genéricos solo permiten referencias a objetos, no las primitivas.


9
2018-02-15 06:39



Como ha descubierto, no puede mencionar un tipo primitivo como parámetro de tipo en los genéricos de Java. ¿Por qué es este el caso? Se discute extensamente en muchos lugares, incluyendo Error Java 4487555.


3
2018-02-15 06:29



La explicación simple: los genéricos se definen de esa manera.

Una buena razón desde la perspectiva de Java: simplifica el borrado de tipos y la traducción al código de bytes para el compilador. Todo lo que el compilador necesita hacer es algo de fundición.

Con los no primitivos, el compilador tendría que decidir si lanzar o a la bandeja de entrada / salida, necesitaría tener reglas de validación adicionales (extends y & no tendría sentido con primitivos, si un ? incluir primitivos, sí o no? etc.) y deben manejar las conversiones de tipo (supongamos que parametriza una colección con long y agrega un int...?)

Una buena razón desde la perspectiva de los programadores: ¡las operaciones con un mal rendimiento se mantienen visibles! Permitir primitves como argumentos de tipo requeriría oculto autoboxing (inboxing para almacenar, outboxing para operaciones de lectura. Inboxing puede crear nuevos objetos que es costoso. La gente esperaría rápido operaciones si parametrizan una clase genérica con primitivas, pero lo contrario sería cierto.


2
2018-02-15 07:14



Esa es una muy buena pregunta.

Como sospechaba, la abstracción seguramente podría extenderse a los parámetros de tipo y hacerlos transparentes para el programador. De hecho, eso es lo que hacen los lenguajes JVM más modernos (estáticos, por supuesto). Los ejemplos incluyen Scala, Ceylon, Kotlin, etc.

Así es como se vería tu ejemplo en Scala:

val gen: Gen[Int] = new Gen[Int](80)

Int es solo una clase regular, al igual que otras clases. No hay distinción de objeto primitivo en absoluto.

En cuanto a por qué la gente de Java no lo hizo ... en realidad no sé la razón, pero imagino que una abstracción como esa no encajaría con la especificación de Java existente sin complicar demasiado la semántica (o sin sacrificar la compatibilidad hacia atrás, que sin duda es no es una opción viable).


0
2017-08-07 09:23