Ingresar:

programacion java :: Blog :: Estos tipos primitivos ...

April 17, 2008

... siempre traen problemas.

Ejemplo:

  class Autoboxing   {     public void prueba()   {       Integer i = 4;       if (4 instanceof Integer)         System.out.println("Yes!");       else         System.out.println("No chango");       }   }    

Error de compilacion:

[macpablo:~/tmp] pablo% javac Autoboxing.java
Autoboxing.java:7: unexpected type
found   : int
required: reference
    if (4 instanceof Integer)
        ^
1 error
 

Palabras clave: autoboxing, irregularidades, ortogonalidad

Enviado por Pablo Azero @ programacion java



Comentarios

Página: 1 2
  1. Ese es un problema!!!

    Ya que no existe una forma armonica de utilizar el hecho de que en algunos casos es posible utilizar 4 para instanciar un objeto de la clase Integer y en otros contextos no  se considera una instancia.....

     

    user iconleticia on Thursday, 17 April 2008, 10:50 BOT # |

  2. La variable "i" para que se usa?

    una pregunta ingenua, como se hace para darle ese formato (como de un editor) a un texto que introduzcamos en el Ajayu? es que quiero colocar algunas cosas de programacion con Java3D pero me gustaria presentarlas en ese formato.

    user iconHappyFaceDead on Thursday, 17 April 2008, 11:38 BOT # |

  3. i no se usa sino para ilustrar que a veces 4 es Integer a veces es int, donde radica el problema.

    Para escribir codigo: [ c o d e = l e n g u a j e ]  y para cerrar [ / c o d e ]

    Hay que escribir las etiquetas sin espacios. 

    user iconPablo Azero on Thursday, 17 April 2008, 11:58 BOT # |

  4. Y en estos casos la mejor forma de solucionarlo es haciendo un casting a algo que se que es integer?

    user iconMarcelo Zambrana Villarroel on Thursday, 17 April 2008, 11:59 BOT # |

  5. Gracias por salvarme de mi ignorancia, eso de "tipos primitivos" me llego, por otro lado podria decirse que existimos los "tipos cavernicolas".

    user iconHappyFaceDead on Thursday, 17 April 2008, 12:19 BOT # |

  6. Supongo que es lo mismo que cuando harías:

    int i = 4;

    double d = i; //acepta perfectamente

    pero si te preguntarías: "¿4 es double?" la respuesta es "no, 4 es int".

    La verdad es que el autoboxing de Java es bastante artificial y parece encajado "a la fuerza" en el lenguaje; pa mí el autoboxing de C# es muucho más natural y mejor implementado.

    Aunque "fuera de tópico", todas las mejoras incluídas al Java desde la versión 5 (jdk1.5) son sólo eso, mejoras al lenguaje (lo que incluye tipos genéricos, tipos enumerados, anotaciones, autoboxing y las otras cosas que no me acuerdo ahorita) y no mejoras a la máquina virtual en sí. Por tanto, en Java:

    ArrayList<int> list1;

    ArrayList<Integer> list2;

    ArrayList<Object> list3;

    son exactamente lo mismo a nivel de bytecode, mientras que en C#, cada uno es un tipo diferente y un ArrayList<int> tiene mucho mejor rendimiento que un ArrayList<Integer> porque el primero no necesita instanciar ningún wrapper para almacenar los números enteros (es decir, la misma implementación del ArrayList<int> maneja int[] internamente).

     

    user iconErnesto Bascón Pantoja on Thursday, 17 April 2008, 13:16 BOT # |

  7. #6. Supongo que es lo mismo que cuando harías: int i = 4; double d = i; //acepta perfectamente pero si te preguntarías: "¿4 es double?" la respuesta es "no, 4 es int". -------------------------------------------------- Bueno no me pregunto si 4 es double bajo este contexto :) .. tipos de datos --- conjuntos, no veo problema. Mencionar "casting implicito".... Las "mejoras" al lenguaje, de acuerdo ... cosa que en Java 1.7, no sera tan cierta esta afirmación. Si podriamos hablar de seguridad Java vs C o C# ... mmmm tema de larga discusión. -------------------------------------------------- Sobre el tema, instanceof es un operador orientado a ser utilizado para referencias de objetos, entonces la pregunta donde queda el outboxing? mmmm tendre que pensar si es un error en el lenguaje o finalmente existen contextos por algún motivo en el que no se maneja el outboxing. Interesante apreciación..

    user iconWilfredo Vargas Almendras on Thursday, 17 April 2008, 14:40 BOT # |

  8. esto si compila por que instanceof es un comparador de objetos pero por algun motivo los int no son tratados como objetos y el compilador te dice "oye quiero una referencia y me pasas un int, que pasa pues?"

      class Autoboxing   {   public void prueba()   {   Integer i = (int)4;   if (i instanceof Integer)/*(i instanceof int) esto no compila*/   System.out.println("Yes!");   else   System.out.println("No chango");   }   }    

    user iconHappyFaceDead on Thursday, 17 April 2008, 15:16 BOT # |

  9. Por supuesto, int es un tipo primitivo. Una excepción a la regla para ser un lenguaje orientado a objetos.

    Un literal es de tipo sobrecargado ... a veces. Por ejemplo

          float f = 4 + 0.5;      

    da lo siguiente:

    [macpablo:~/tmp] pablo% javac Autoboxing.java
    Autoboxing.java:6: possible loss of precision
    found   : double
    required: float
        float f = 4 + 0.5;
                    ^
    1 error

    Entonces, ¿los literales son sobrecargados o no (si quieren llamarle autoconversión implícita)?

    user iconPablo Azero on Thursday, 17 April 2008, 16:07 BOT # |

  10. No se puede hacer parametrización de tipos primitivos 

      ArrayList<int> lista = .... => ERROR     

    En su lugar: 

      ArrayList<Integer> lista = .... => ERROR     

    Todos los tipos primitivos tienen sus equivalente en tipos de dato clase, y al parecer los literales no son totalmente sobrecargados. Lo correcto para el ejemplo del Dr. Pablo sería:

      float f = 4 + 0.5f; //especificamos que 0.5 es un float    

     Como dice #7(willy), no se si esto sea una ventaja o una desventaja, habría que analizar...

    user iconCristian Denis Mamani Torres on Thursday, 17 April 2008, 20:56 BOT # |

  11. Fue un error mio, decir que lo siguiente es un ERROR.

      ArrayList<Integer> lista = ....     

     Jeje... mil disculpas

    user iconCristian Denis Mamani Torres on Thursday, 17 April 2008, 20:58 BOT # |

  12. Cristian (y Wilfredo): es una desventaja. El programador no puede predecir cuales son las reglas de su lenguaje. El lenguaje deja de ser ortogonal y por tanto más difícil de aprender.

    user iconPablo Azero on Thursday, 17 April 2008, 22:11 BOT # |

  13. Por ejemplo cuando programas con Java3D
    y quieres instanciar un mugre punto en 3D haces
      Point3f point3f = new Point3f(1.0, 1.0, 1.0);     pero el compilador te dice "cannot find symbol constructor Point3f(double, double, double)"
    Y dices pero por que? si son numeros pequeños.
    y entonces debes hacer
      Point3f point3f = new Point3f(1f, 1f, 1f);     o haciendo un horrible casting
      Point3f point3f = new Point3f( (float)1, (float)1, (float)1);     Pero porque? si es un Point3f es obvio que recibe floats no podian haber hecho un metodo para que haga la conversion internamente sin fregarnos a los programadores, me gustaria agarrar al que programo esto.

    user iconHappyFaceDead on Thursday, 17 April 2008, 23:09 BOT # |

  14. #10, tienes toda la razón, pensé que funcionaba. De todas formas, me parece que no es nada consistente para el lenguaje proveer sólo genericidad en tipos de referencia y no en tipos primitivos.

     

    #13, lo ideal hubiera sido que provean un constructor tipo:

     Point3f(double x, double y, double z); 

     así llamar a

    new Point(1, 1, 1); 

    new Point(1f, 2f, 3f);

    ó new Point(1.0, 2.0, 3.0);

    funcionarían igual (aunque tendrías una representación interna demasiado grande). 

    user iconErnesto Bascón Pantoja on Friday, 18 April 2008, 00:05 BOT # |

  15. No lo veo como un gran inconveniente y seguramente está escrito en algún lugar cual es el orden para inferir el tipo de literales. Sino lo escribimos a groso modo:

    En tipos de datos numéricos al parecer: 

    1. Todo literal numérico por defecto es de un tipo de dato primitivo.
    2. Todo literal numérico entero (sin punto decimal) es un int. 
    3. Todo literal numérico real es un double por defecto a menos que se específique que es un float.

     Nunca he tenido ni se me ha hecho problema diferenciar un double de un float. Ni aun viendo el ejemplo de mi Tocayo pienso que es algo por lo que deberíamos sacarnos los cabellos...

    user iconCristian Denis Mamani Torres on Friday, 18 April 2008, 00:59 BOT # |

  16. Quisiera resaltar algo, veo que estan cometiendo un error de programación y no es un error del lenguaje

    Por ejemplo: (Tomando el ejemplo anterior)

    Si  el API dice new Point(double p1, double p2, double p3)

    y tu le pasas new Point (3, 4, 5)  -> 3, 4 ,5 son enteros es un error de programacion no del lenguaje

    no existe una auto conversion de enteros a doubles se debe usar 3.0 , 4.0 y 5.0

    Lo mismo con instanceof sus argumentos son objetos no primitivos, no existe una regla de autoboxing para int a object

     

    user iconAdrián Grajeda on Friday, 18 April 2008, 10:41 BOT # |

  17. # 14 no es un problema tener una representacion grande dentro de la clase (en VisualBasic de VisualStudio ya no es importante hacer un casting cuando manejas puntos porque internamente ya hace el "redondeo") el problema es de repeticion de codigo, para que montones de castings antes de llamar a la funcion si internamente la funcion podria hacerlo.

    Por que usar floats? para ahorar memoria y procesador pero se pierde exactitud si se tienen que hacer muchas operaciones.

    # 15 no es un problema de entender o no entender cuando usar floats o doubles es un problema de elegancia (entiendase codigo legible) por ejemplo el siguiente segmento de codigo crea un tetraedro en base a la longitud de un lado, antes de usar los puntos hay que hacer un casting (osea el programador debe controlar mas aspectos no relacionados con el algoritmo) lo cual claramente no es una ventaja.

      public static Shape3D crearTetraedro(float lado_, Appearance appearance)   {   Shape3D s3d_tetra_=new Shape3D();   s3d_tetra_.setUserData("Tetraedro:"+lado_);     float alto_parcial = (float) Math.sqrt(3.0)/2*lado_;   float alto_parcial_3 = alto_parcial / 3.0f;   float alto_total = (float) Math.sqrt( 3*2*Math.pow(lado_,2) ) / 3.0f;   float ycentro = 0.5f * alto_total;   float zcentro = alto_parcial_3;   Point3f p1 = new Point3f(-(float)(lado_/2), -ycentro, +zcentro);   Point3f p2 = new Point3f((float)(lado_/2), -ycentro, +zcentro);   Point3f p3 = new Point3f(0.0f, -ycentro, -alto_parcial + zcentro);   Point3f p4 = new Point3f(0.0f, alto_total - ycentro, 0.0f);   Point3f[] verts = {p1, p2, p4, // cara frontal   p1, p4, p3, // cara atras izquierda   p2, p3, p4, // cara atras derecha   p1, p3, p2, // cara de abajo   };   .................................................................    

    user iconHappyFaceDead on Friday, 18 April 2008, 12:18 BOT # |

  18. Te evitarías hacer el casting si al constructor le pasas una expresión float y no una expresión que por defecto es double.

      Point3f p1 = new Point3f(-lado_/2f, -ycentro, +zcentro);      

    user iconCristian Denis Mamani Torres on Friday, 18 April 2008, 12:36 BOT # |

  19. #18 es solo un ejemplo de que el programador debe controlar esa "autoconversión implícita" que parece ser una desventaja, porque hace que el programador tenga que contemplar aspectos del leguaje en desmedro del algoritmo.

      Point3f point3f = new Point3f(-lado_/Math.sqrt(2f), 1f, 1f);/*No compila*/   Point3f point3f = new Point3f((float)(lado_/Math.sqrt(2f)), 1f, 1f);/*Si compila*/    

    user iconHappyFaceDead on Friday, 18 April 2008, 12:57 BOT # |

  20. No es correcto que haya una auto conversión de double a float, estás perdiendo precisión y eso puede generar un error.

    Cuando se trata de operaciones matemáticas no es muy recomendable usar casting, deberías probar algo parecido a esto:

      Double dLado=new Double(lado);       Double result= dLado / Math.sqrt(2.0); // la división debe ser entre doubles       Point3f point3f = new Point3f(result.floatValue(), 1.0f, 1.0f);     

    En operaciones matemáticas es aconsejable que trabajes sobre un solo tipo de números

    y el resultado final lo expreses recién en el tipo requerido, no forzar resultados intermedios porque perderás precisión

    user iconAdrián Grajeda on Friday, 18 April 2008, 15:35 BOT # |

Página: 1 2

Debes iniciar sesión para enviar un comentario.