generic java
¿Por qué el autoboxing Java no se extiende a las invocaciones de métodos de los tipos autoboxed? (8)
me parece una deficiencia de la especificación
Hay más deficiencias y este es un tema sutil. Mira this :
public class methodOverloading{
public static void hello(Integer x){
System.out.println("Integer");
}
public static void hello(long x){
System.out.println("long");
}
public static void main(String[] args){
int i = 5;
hello(i);
}
}
Aquí se imprimirá "largo" (no lo he verificado yo mismo), porque el compilador elige el ensanchamiento sobre el autoboxing. ¡Tenga cuidado al usar el autoboxing o no lo use en absoluto!
Quiero convertir un primitivo en una cadena, e intenté:
myInt.toString();
Esto falla con el error:
int cannot be dereferenced
Ahora, entiendo que las primitivas no son tipos de referencia (es decir, no son un Objeto) y, por lo tanto, no pueden tener métodos. Sin embargo, Java 5 introdujo autoboxing y unboxing (a la C # ... que nunca me gustó en C #, pero eso no viene al caso). Entonces, con autoboxing, esperaría que lo anterior convierta myInt en un entero y luego llame a toString () sobre eso.
Además, creo que C # permite dicha llamada, a menos que lo recuerde incorrectamente. ¿Es solo una desventaja desafortunada de la especificación de autoboxing / unboxing de Java, o hay una buena razón para esto?
Como todos han señalado, el autoboxing le permite simplificar algo de código, pero no puede pretender que las primitivas son tipos complejos.
También interesante: "autoboxing es un hack de nivel de compilador" en Java. El autoboxing es básicamente un extraño kludge agregado a Java. Mira esta publicación para obtener más detalles sobre lo extraño que es.
El autoboxing / unboxing de Java no llega al extremo de permitirle desreferenciar un primitivo, por lo que su compilador lo impide. Su compilador todavía conoce myInt
como primitivo. Hay un documento sobre este tema en jcp.org .
El autoboxing es principalmente útil durante la asignación o el paso de parámetros, ya que le permite pasar una primitiva como un objeto (o viceversa), o asignar una primitiva a un objeto (o viceversa).
Así que desafortunadamente, tendrías que hacerlo así: (felicitaciones Patrick, cambié a tu manera)
Integer.toString(myInt);
En C #, los enteros no son tipos de referencia ni tienen que estar encuadrados para poder llamar a ToString () . Sin embargo, se consideran objetos en el Marco (como ValueType, por lo que tienen una semántica de valor). En el CLR, los métodos sobre primitivas se llaman cargándolos "indirectamente" en la pila (ldind).
La sintaxis válida más cercana a su ejemplo es
((Integer) myInt).toString();
Cuando finaliza el compilador, eso es equivalente a
Integer.valueOf(myInt).toString();
Sin embargo, esto no funciona tan bien como el uso convencional, String.valueOf(myInt)
, porque, excepto en casos especiales, crea una nueva instancia de Integer, luego la descarta inmediatamente, lo que resulta en más basura innecesaria. (Se almacena en caché una pequeña gama de enteros y se accede a ellos mediante un acceso a matriz). Quizás los diseñadores de idiomas quisieron desalentar este uso por razones de rendimiento.
Editar: agradecería que el votante (s) comentara por qué esto no es útil.
Lo mismo ocurre con lo que dijo Justin, pero deberías hacer esto en su lugar:
Integer.toString(myInt);
Guarda una asignación o dos y es más legible.
Otra forma de hacerlo es usar:
String.valueOf(myInt);
Este método está sobrecargado para cada tipo primitivo y Object
. De esta manera, ni siquiera tiene que pensar en el tipo que está utilizando. Las implementaciones del método llamarán al método apropiado del tipo dado para usted, por ejemplo, Integer.toString(myInt)
.
Ver http://java.sun.com/javase/6/docs/api/java/lang/String.html .
Sería útil si Java definiera ciertos métodos estáticos para operar en tipos primitivos y construyera en el compilador algo de azúcar sintáctico para que
5.asInteger
sería equivalente a
some.magic.stuff.Integer.asInteger(5);
No creo que tal característica cause incompatibilidad con ningún código que se compila bajo las reglas actuales, y ayudaría a reducir el desorden sintáctico en muchos casos. Si Java fuera a primitivas de autobox que fueron desreferenciadas, la gente podría suponer que estaba mapeando la sintaxis de desreferenciación a llamadas a métodos estáticos (que es efectivamente lo que sucede en .NET), y por lo tanto las operaciones escritas en esa forma no fueron más costosas de lo que serían el método estático equivalente invocaciones. Agregar una nueva función de lenguaje que aliente a las personas a escribir código incorrecto (por ejemplo, primitivas desreferenciadas de auto-boxeo) no parece una buena idea, aunque permitir métodos de estilo de desreferenciación podría serlo.