sábado, 13 de mayo de 2017

¿Cual es la diferencia entre una Clase y un Objeto en JAVA?


Este articulo esta especialmente dirigido para programadores principiantes, que estan aprendiendo algún lenguaje de programación orientado a objetos, como por ejemplo: Java, C++ o C# y aspiran estar bien preparados para cualquier entrevista para un puesto como programador. Ahora bien, la diferencia entre Clases y Objetos es una de las las preguntas mas comunes dentro de la Programación Orientada a Objetos (POO), incluso podríamos preguntarle a personas recién graduadas de alguna universidad o instituto tecnologico y te sorprenderás al ver el conflicto que incluso para estas personas supone esta pregunta. Clase ("Class") y Objeto ("Object") son dos pilares de la POO y saber identificarlos y diferenciarlos bien es necesario, pero cuando buscas respuestas a esta preguntas desde lo teórico te encuentras con que "una clase es una plantilla y los objetos son cosas reales creadas a partir de esa plantilla", difícilmente con ese concepto queda todo explicado. Aunque la respuesta es correcta y funciona perfectamente, no la entenderá de la misma forma un programador que acaba de hacer la pregunta a otro que realmente entiende la diferencia entre una Clase y un Objeto.

Por lo tanto, si recibo una respuesta así, les pido entonces que creen una clase y expliquen cómo se crean los objetos en el programa, digamos para representar a un "Empleado", "Estudiante" o simplemente un "Carro". Si el programador entiende verdaderamente que es una clase y que es un objeto, no tardará mucho tiempo en hacerlo, pero si aun tiene dudas al respecto probablemente tarde mas de lo esperado.

El punto es entender la diferencia entre una clase y un objeto, no para tomar una entrevista, ¿por qué?, porque si conoces la clase y el objeto será mucho mas sencillo para ti trabajar con un lenguaje de programación orientado a objetos como Java o C#.

Entonces para darte una idea mas clara de lo que es una clase y un objeto, te mostramos algunos ejemplos: si "Carro" es una clase entonces "Merc", "Audi" y "BMW" son objetos. Si "Televisión" es una clase entonces "Sony Bravia", "Samsung Smart TV" son objetos de esa clase.

Sí "Smartphone" es una clase entonces "iPhone", "Samsung Galaxy" y "Nokia" son objetos de esa clase. Pero en aplicaciones orientadas a objetos, generalmente los sustantivos representan las clases, por ejemplo en una aplicación financiera "Orden", "Transacción", "Instrumentos" son clases. De igual forma en temas de comercio electrónico "Pago", "Orden", Producto" son algunos ejemplos de clases.

Clase Vs. Objeto en JAVA.
Algunas diferencias entre Clases y Objetos , se basan totalmente en la práctica y la experiencia:

1.- Una Clase se crea mientras tu codificas, pero el objeto es creado al momento en el que el programa es ejecutado, por ejemplo: La máquina virtual de Java o JVM de sus siglas en inglés Java Virtual Machine. Aunque al escribir tu código, es necesario para crear un objeto, como: new Student(); , el objeto no es creado en ese momento. Este se crea al momento en que el programa es ejecutado y cuando se ejecuta específicamente esa línea de código. Usualmente para crear dicho objeto en Java se llama a un constructor de la clase, pero se pueden presentar algunas anomalías, como la Serialización (se llama "serializar un objeto" al proceso de convertir en bytes, para poder enviarlo por una red, y reconstruirlo luego a partir de esos bytes.)

2.- Las diferencia mas importante entre una Clase y un Objeto es que este ultimo normalmente tiene un estado (aunque  el objeto sin estado tambien es posible). Este se utiliza para diferenciarse de otros objetos. Por ejemplo, si tienen una clase para representar "Estudiantes", entonces "Johan" y "Mohan" son dos objetos de la clase, los cuales tienen nombres diferentes, un atributo que los diferencia. Una imagen vale mas que mil palabras, y la diferencia entre una Clase y un Objeto puede entenderse mejor a través de esta imagen:

Ejemplo entre una Clase y un Objeto. Ejemplo grafico.

En este ejemplo, "Jugador" es una clase, la cual actualmente es como la plantilla de creación de jugadores y los dos jugadores: "Scooby" y "Tabby" son los objetos que se crearon en el entorno de ejecución, en este caso la máquina virtual de Java (JVM). Cada jugador tiene valores diferentes para sus atributos, tambien conocido como estado del objeto. Por ejemplo la posición de Scooby es la 5° y tiene $341, mientras que la posición de Tabby es la 18° y tienen $87. Si aún no entiendes por completo la diferencia entre una Clase y un Objeto, te mostramos otro ejemplo un poco mas interesante que el anterior.

Ejemplo grafico de diferencia entre Clase y Objeto.

En este caso el "Cortador de galletas" es una clase que es una plantilla o modelo para crear objetos: las galletas. Puedes ver que hay tres galletas, una para ti y dos para mi obviamente xD.

3.- Aunque Java no es un Lenguaje orientado a objetos puro, la mayoría de las cosas son objetos en Java, por ejemplo las variables primitivas y operadores no son objetos. En Java, los objetos son creados en un espacio de memoria especial conocida como "Memoria Heap" (conoce mas aquí). No importa en que amito los crees, localmente o globalmente siempre se crearán en el espacio "heap". Por otro lado, las clases son cargadas dentro de otra area especial de la memoria de la máquina virtual de Java (JVM), conocida como "permgen space". Para Java 8 en adelante, ese espacio es tambien conocido como "Metaspace". Tu puedes crear tantos objetos de una clase como desees, sujeto al límite de tu memoria heap, ya que cada objeto toma una parte de la memoria. Una vez que la memoria se llena por completo, no puedes seguir creando mas objetos y la maquina virtual de Java (JVM) lanzará el error java.lang.OutOfMemoryError: Java Heap Space : si sigues tratando de crear mas objetos.

4.- Los objetos tambien son conocidos como instancias en el lenguaje de programación de JAVA, y en la clase JVM tambien se representa por una instancia de java.lang.class. Por otro lado la Clase tambien es conocida como un tipo de dato. Un variable de referencia que guarda la referencia de un objeto tiene un tipo de dato, que denota a qué tipo de objeto puede hacer referencia. Por ejemplo, en el siguiente código ConstructorDemo es el nombre de la clase, conocido tambien como un tipo de dato, cd es una variable de referencia de tipo ConstructorDemo, lo que significa que este puede apuntar a un Objeto de la clase ConstructorDemo o a sus clases hijas. Cuando se crea un objeto usando el operador new(), tambien clasifica automáticamente al constructor de esa clase.


5.- La Clase es una abstracción que contiene código, principalmente atributos y métodos que operan sobre ellos. Por otro lado el objeto es una cosa real que operan sobre ellos, pero ahí viene el método estático, el cual pertenece a la clase.

Eso es todo en esta pregunta sobre la diferencia entre las Clases y los Objetos en Java. Como ya se ha dicho, respuestas como: una clase es una plantilla y los objetos son cosas reales creadas a partir de esa plantilla, es completamente correcto, sin embargo, es recomendable examinar mas a fondo el aspecto práctico de la clase y el objeto. Si un programador puede diferenciar una clase de un objeto en código, puede dar un par de ejemplos de lo que las Clases y los Objetos son entonces su comprensión sobre este importante concepto es lo suficiente bueno para ser considerada.

***El Artículo fue obtenido de Java67 y fue modificado ligeramente para su traducción. Para revisar el contenido original dar clic aquí.

lunes, 24 de abril de 2017

Diferencias entre Abstracción y Encapsulación en Java. POO

Tanto la Abstracción como la Encapsulación son dos de los cuatros conceptos básicos de la Programación Orientada a Objetos (POO) con los cuales puedes modelar las cosas del mundo real en objetos y puedas implementarlas en tu programa y código. Muchos principiantes tienden a confundir estos términos por lo similar que pueden llegar a lucir. Si tu le preguntas a alguien ¿que es la Abstracción?, esa persona te responderá que es un concepto de la POO que se centra en la información pertinente ocultando detalles innecesarios, y cuando preguntas acerca de la Encapsulación, muchos te responden que es otro concepto de la POO el cual oculta datos del mundo exterior. Las definiciones no son erróneas ya que tanto la Abstracción como la Encapsulación ocultan algo, pero la diferencia clave esta en la intención.

La abstracción oculta la complejidad para dar una imagen mas abstracta, mientras que la encapsulación oculta el trabajo interno para que puedas cambiarlo posteriormente. En otras palabras, la Abstracción oculta detalles a nivel de diseño, mientras que la Encapsulación oculta detalles a nivel de implementación.

Por ejemplo, cuando describes un objeto por primera vez, hablas en términos mas abstractos, como: "Vehículo que se puede mover", no dices cómo se moverá el vehículo, si se moverá usando neumáticos, si volará o si navegará. Solo se mueve. A esto llamamos Abstracción. Estamos hablando de una de las cosas mas esenciales, y es que esta en movimiento, en vez de centrarse en detalles sobre cómo se mueve, si por tierra, volando o por agua.

Están también los diferentes niveles de Abstracción y es una buena práctica que las clases deberían interactuar con otras clases con un mismo nivel de Abstracción o mayor nivel de Abstracción. De manera que a medida que incrementa el nivel de Abstracción, las cosas empiezan a ser cada vez mas simples, dejando a un lado los detalles.

Por otro lado, la Encapsulación trata sobre la implementación. Su único propósito es ocultar el trabajo interno de los objetos del mundo exterior para que pueda cambiarlo mas tarde sin afectar a los clientes externos.

Por ejemplo, tenemos un HashMap que permite almacenar el objeto utilizando el método put() y recuperar el objeto utilizando el método get(). Cómo HashMaps implementa este método (lee mas aquí) es un detalle interno de HashMap, el cliente solo se preocupa por almacenar los objetos y devolverlo, a él no le concierne si HashMap esta usando un arreglo, cómo esta resolviendo la colisión, si esta usando una lista o un árbol binario para almacenar el intercambio de los objetos en la memoria, etc.

Debido a la Encapsulación, tu puedes cambiar el funcionamiento interno de HashMap con facilidad sin interferir con los clientes que están usando HashMap. Por ejemplo, en Java 8, el java.util.HashMap cambia su implementación para usar un árbol binario en lugar de una lista para almacenar los objetos en el mismo lugar después de cierto punto (lee mas aquí).

El cliente no necesita hacer ningún cambio para beneficiarse de este cambio de código porque esos detalles no están expuestos a ellos. Si el cliente tuviera conocimiento de ello, es decir, que de alguna manera pudiesen tener referencia del arreglo interno del HashMap, no habría sido posible cambiar la implementación sin afectar a los demás clientes. 

Existen muchos principios de diseño basados en la Abstracción, como por ejemplo, "Codificación para interfaces después de la implementación" que ayuda a escribir código flexible en Java o C++. La idea es que una clase dependa de una interfaz, un nivel de abstracción mas alto que la clase, un un menor nivel de abstracción. Esto resulta en un código flexible que puede funcionar con cualquier implementación de la interfaz. 

Por ejemplo, si tu necesitas HashMap, tu clase debe depender de Map en lugar de HashMap. De igual forma, si tu necesitas ArrayList, asegúrate de usar la List. Afortunadamente, el tío Bob ha compartido varios principios de diseño sobre Clean Code, conocidos colectivamente como principios de diseño SOLID, que es algo que cada programador POO debe aprender y entender. 
Clean Code

Abstracción Vs. Encapsulación. 

A continuación y a modo de resumen, desglosamos por puntos las principales diferencias entre Encapsulación y Abstracción.
  1. La diferencia mas importante entre Abstracción y Encapsulación es que la Abstracción resuelve el problema en un nivel de diseño mientras que la Encapsulación lo resuelve en un nivel de implementación. 
  2. La Abstracción busca esconder detalles no deseados mientras genera detalles mas esenciales, mientras que la Encapsulación busca ocultar el código y los datos dentro de una sola unidad, es decir, una clase o un método protegen su trabajo interno de objetos externos. En otras palabras, la Abstracción solo extrae detalles comunes o generaliza cosas. 
  3. La Abstracción permite centrarse en lo que el objeto hace en lugar de como lo hace, mientras la Encapsulación busca ocultar los detalles internos o forma de trabajar de un objeto. Cuando mantienes privados los detalles internos de trabajo de un objeto, se pueden editar posteriormente por un método mejor. El libro Head First Object Oriented Analysis and Design tiene algunos ejemplos excelentes de estos conceptos de POO, le sugiero que lean este libro al menos una vez para revisar los fundamentos de la POO. 
     Head First Object Oriented Analysis and Design
  4. El enfoque de la abstracción es externo, por ejemplo: Desplazamiento del vehículo. Mientras que la encapsulación se ocupa del trabajo interno, por ejemplo: como se mueve exactamente el vehículo. 
  5. En Java, la Abstracción esta apoyada por el uso de interfaces y clases abstractas mientras que la Encapsulación esta soportada por el uso de los modificadores de accesos: public, private and protected. 
En la siguiente tabla se destacan las principales diferencias entre la Abstracción y la Encapsulación en Programación Orientada a Objetos:
Cuadro comparativo. Abstracción Vs. Encapsulación.
Esto es todo acerca de las diferencias entre la Abstracción y la Encapsulación en Java y POO. Yo entiendo, ambos parecen muy similares, pero como he dicho son conceptos totalmente diferentes. Solo recuerda que la Abstracción resuelve los problemas en el nivel de diseño mientras la Encapsulación los resuelve en el nivel de implementación. Ambos son muy importantes para un programador POO pero algunas veces resulta difícil de explicar.

Como dije anteriormente, la mejor manera de aprender y volverse un master de la Programación Orientada a Objetos es escribiendo código y leyendo el código de otros. Cuanto mas se exponen al código, mas se dan cuenta de cómo funcionan estos conceptos en la práctica. Hay varios principios de diseño que se basan en términos de abstracción, por ejemplo, codificación de interfaz en lugar de implementación, el cual permite escribir codigo flexible. 

Otras entradas sobre POO que podrían gustarte: 
  • Diferencias entre Clase y Objeto en Java y POO (haz clic aquí).
  • Diferencias entre Herencia y Polimorfismo en Java (Pronto traducido aquí).
  • Diferencias entre Agregación, Composición y Asociación en POO (Pronto traducido aquí).
  • Diferencias entre patrones de diseño de Estado y Estrategia (Pronto traducido aquí).
  • ¿Que es el Polimorfismo?¿Sobrecarga o Anulación? (Pronto traducido aquí).
  • ¿Cual es la diferencia entre Sobrecarga y Anulación en POO? (Pronto traducido aquí).
  • Diferencias entre instancia y objetos en Java (Pronto traducido aquí).
  • ¿Cual es la diferencia entre un descubrimiento estático y dinámico en Java? (Pronto traducido aquí).

Gracias por leer este articulo, si de verdad te gusto, no dejes de compartirlo con tus amigos y colegas. Si tienes alguna pregunta o sugerencia, por favor déjala en los comentarios. Y si quieres saber mas sobre conceptos de POO, principios de diseño SOLID y  aplicación de los conceptos de POO en la vida real, no dejes de leer Clean Code

***El Artículo fue obtenido de JavaRevisited y fue modificado ligeramente para su traducción. Para revisar el contenido original dar clic aquí.

martes, 17 de enero de 2017

Unit Tests & Integration test : Spring Boot Tests - Jacoco - Maven

Esta vez explicaré de manera muy básica como configurar un proyecto hecho en Spring Boot para ejecutar sus test unitarios y ademas generar un reporte utilizando el Plugin de Jacoco para Maven.

Comenzaré explicando que en todo proyecto es importante tener una suite de test bien definida, para esto existen una gran cantidad de librerías, que nos pueden ayudar.

En el caso de Spring, el framework nos proporciona ya un conjunto de librerías(módulo) que nos resuelven el tema de importar las dependencias.


                                     Configurar spring-boot-starter-test


Este módulo es spring-boot-starter-test y aunque existen otros módulos en Spring Boot para hacer test, este es el que contiene lo necesario y más básico para trabajar. Pues entre otras cosas nos proporciona lo siguiente: 

  • JUnit — La librería de testing unitario básica en todos los proyectos java.
  • Spring Test & Spring Boot Test —Algunas utilidades para testing de aplicaciones de Spring
  • AssertJ — Librería para Asserts
  • Hamcrest — Librería para crear matchers entre objetos
  • Mockito — Framework para crear objetos simulados para pruebas
  • JSONassert — Librería para realizar asserts sobre Json
  • JsonPath — XPath para JSON.


Para añadir el módulo de Spring es necesario añadir la siguiente dependencia al archivo pom.xml:


<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-test</artifactId>
 <scope>test</scope>
</dependency>


Una vez añadida la dependencia, se deben crear los paquetes necesarios para contener las clases donde se escribirán los tests. Una forma sencilla de crear los paquetes es apoyándose en el IDE, en mi caso utilicé IntelliJ para configurar este proyecto, lo único que debes hacer es crear el paquete test dentro de la carpeta src/main dentro de tu proyecto y configurar el paquete /test/java como tipo test de los sources de tu aplicación.

Estructura del proyecto Spring Boot- Test- Jacoco

Modificar sources de proyecto java en IntelliJ

Después de eso al seleccionar un método o una clase basta con presionar Alt+Enter y seleccionar la opción "create test" lo que generará la estructura de paquetes necesarios en el proyecto.

Suponiendo que ya implementaste los tests y quieres ejecutarlos completos basta con escribir en la consola a nivel del root(donde se encuentra el pom) de tu proyecto para ejecutar los tests:

$mvn test

Pero esto aún no generará ningún reporte, para eso es lo siguiente:

Configurar Jacoco

Jacoco es una librería de java que nos permite generar reportes de análisis de cobertura de testing y entre sus características están que maneja diferentes tipos de reportes, está escrito en java y además es open source.

Otra característica importante es que se integra fácilmente con maven pudiendo ser configurado mediante un pluging en el pom.

Si quieres saber más del proyecto aquí está la documentación de Jacoco, Para este proyecto en particular utilizaremos la configuración básica.

Primero se añade la dependencia de Jacoco en el pom.xml:


<dependency>
 <groupId>org.jacoco</groupId>
 <artifactId>jacoco-maven-plugin</artifactId>
 <version>0.7.?</version>
</dependency>

La versión depende del momento en el que estés leyendo este tutorial, por lo que debes buscar la versión más actual en el sito oficial de Jacoco.

Posterior a esto debes configurar el pluging:



<build>
  <plugins>
   <plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.7.8</version>
    <executions>
     <execution>
      <id>default-prepare-agent</id>
      <goals>
       <goal>prepare-agent</goal>
      </goals>
     </execution>
     <execution>
      <id>default-report</id>
      <phase>prepare-package</phase>
      <goals>
       <goal>report</goal>
      </goals>
     </execution>
     <execution>
      <id>default-check</id>
      <goals>
       <goal>check</goal>
      </goals>
      <configuration>
       <rules>
        <rule implementation="org.jacoco.maven.RuleConfiguration">
         <element>BUNDLE</element>
         <limits>
          <limit implementation="org.jacoco.report.check.Limit">
           <counter>COMPLEXITY</counter>
           <value>COVEREDRATIO</value>
           <minimum>0.60</minimum>
          </limit>
         </limits>
        </rule>
       </rules>
      </configuration>
     </execution>
    </executions>
   </plugin>
  </plugins>
 </build>

Con lo anterior listo, lo único que tienes que hacer es escribir en consola y ejecutar:

$mvn clean test

La sentencia anterior generará los files con los resultados de los tests, después ejecutar el pluging de jacoco, lo que generará el reporte con la información de cobertura.

$mvn jacoco:report


**El reporte de cobertura se podrá ver dentro del paquete /src/resources/site/jacoco, basta con abrir el file index.html para ver el reporte


El siguiente es el pom.xml del proyecto, como verán no es necesario añadir las dependencias de las librerías de la lista, pues todo se encuentra incluido dentro de spring-boot-starter-test:


<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <parent>
  <!-- Your own application should inherit from spring-boot-starter-parent -->
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>1.4.3.RELEASE</version>
 </parent>
 <artifactId>spring-boot-sample-test</artifactId>
 <name>Spring Boot Test Sample</name>
 <description>Spring Boot Test Sample</description>
 <url>http://projects.spring.io/spring-boot/</url>
 <organization>
  <name>Pivotal Software, Inc.</name>
  <url>http://www.spring.io</url>
 </organization>
 <properties>
  <main.basedir>${basedir}/../..</main.basedir>
 </properties>
 <dependencies>
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-jpa</artifactId>
  </dependency>
  <dependency>
   <groupId>com.h2database</groupId>
   <artifactId>h2</artifactId>
  </dependency>
  <dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
  </dependency>
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-test</artifactId>
   <scope>test</scope>
  </dependency>
  <dependency>
   <groupId>org.seleniumhq.selenium</groupId>
   <artifactId>selenium-htmlunit-driver</artifactId>
   <version>2.52.0</version>
   <scope>test</scope>
  </dependency>
  <dependency>
   <groupId>net.sourceforge.htmlunit</groupId>
   <artifactId>htmlunit</artifactId>
   <scope>test</scope>
  </dependency>
  <dependency>
   <groupId>org.jacoco</groupId>
   <artifactId>jacoco-maven-plugin</artifactId>
   <version>0.7.8</version>
  </dependency>
 </dependencies>
 <build>
  <plugins>
   <plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.7.8</version>
    <executions>
     <execution>
      <id>default-prepare-agent</id>
      <goals>
       <goal>prepare-agent</goal>
      </goals>
     </execution>
     <execution>
      <id>default-report</id>
      <phase>prepare-package</phase>
      <goals>
       <goal>report</goal>
      </goals>
     </execution>
     <execution>
      <id>default-check</id>
      <goals>
       <goal>check</goal>
      </goals>
      <configuration>
       <rules>
        <!--  implementation is needed only for Maven 2  -->
        <rule implementation="org.jacoco.maven.RuleConfiguration">
         <element>BUNDLE</element>
         <limits>
          <!--  implementation is needed only for Maven 2  -->
          <limit implementation="org.jacoco.report.check.Limit">
           <counter>COMPLEXITY</counter>
           <value>COVEREDRATIO</value>
           <minimum>0.60</minimum>
          </limit>
         </limits>
        </rule>
       </rules>
      </configuration>
     </execution>
    </executions>
   </plugin>
  </plugins>
 </build>
</project>

El proyecto que se está probando en este caso se trata de una aplicación básica que expone un servicio REST y que accede a una base de datos configurada con MongoDB. Dado que la finalidad del proyecto es solo ejecutar los test y generar los reportes de Jacoco, no es necesario tener la base de datos instalada, ni configurar ningún servidor.


El código probado, proviene de los ejemplos obtenidos de de spring-boot. Por lo que es código accesible para todos.

https://gitlab.com/curiotechnology/spring-boot-sample-test




lunes, 24 de octubre de 2016

¿Para qué se usa la clase "java.lang.Class" en Java?

java.lang.Class es una de las clases más importantes pero ignoradas por los desarrolladores Java. Es muy importante en el sentido de que provee muchos métodos de utilidad. Por ejemplo los métodos getClass(), forName() que son usados para encontrar y cargar una clase, quizá tu las has usado para cargar los drivers de Oracle o MySQL.



También provee métodos como Class.newInstance() la cual es el corazón de reflection y te permite crear una instancia de una clase sin utilizar el operador new(). La clase no tiene constructores públicos y sus instancias son creadas por la JVM cuando la clase es cargada. El objeto de clase tipo Class también es usado para representar clases, enumeraciones, interfaces, y anotaciones corriendo en una aplicación Java. Los tipos primitivos como byte, short, char, int, float, double, boolean así como la palabra reservada void también son representados como instancias de Class.

Puedes obtener la instancia correspondiente a Class usando la literal class, por ejemplo int.class, float.class o boolean.class. También es usada para representar una instancia de un arreglo en Java. Todos los arreglos con el mismo tipo y la misma dimensión comparten la misma instancia de la clase Class.

Otro uso de java.lang.Class es mientras se implementa el método equals() para verificar si dos objetos son del mismo tipo o no.


java.lang.Class en Java


Cada vez que la JVM crea un objeto, también se crea un objeto de la clase java.lang.Class que describe el tipo de objeto. Todas las instancias del la misma clase comparten el mismo objecto de la clase Class y así puedes obtener el objecto Class llamando el método getClass() de cualquier objeto. Además, este método es heredado de la clase java.lang.Object.

Imagina que tu creas dos instancias de una clase llamada Persona por ejemplo



En este caso, se imprimirá "A y B son instancias de la misma clase" porque ambas son instancias de la clase Persona.

Necesitamos forName() y newInstance() porque varias veces no sabemos el nombre de la clase que hay que inicializar mientras escribimos el código, podría ser que estamos obteniéndolo desde archivos de configuración, bases de datos, red o desde algún flujo de información de una aplicación Java externa.

Es por eso que llamamos de forma reflectiva la creación del objeto, la cual es una de las más poderosas características en Java y que es utilizada por muchos frameworks, por ejemplo Spring, Struts utilizan Java reflection


***El Artículo fue obtenido de JavaRevisited y fue modificado ligeramente para su traducción. Para revisar el contenido original dar clic aquí.

viernes, 21 de octubre de 2016

¿Por qué String es Inmutable en JAVA?

El tipo de dato String es Inmutable(es decir que no puede ser modificada) porque cualquier objeto String creado es almacenado en un espacio de memoria llamado String pool. Y ya que las literales tipo String son compartidas entre múltiples clientes siempre existe un riesgo donde alguna de las acciones de un cliente puede afectar a otro.
Por ejemplo, si uno de los clientes cambia el valor del String "Test" a "TEST", el resto de los clientes también verían ese valor como se explicó anteriormente.

Debido a que mantener en memoria los objetos de tipo String es importante por razones de performance, este riesgo se evita haciendo la clase String Inmutable. Al mismo tiempo, String es de tipo final así nadie puede comprometer la inmutabilidad ya sea extendiendo o sobreescribiendo sus comportamientos. Otra razón por la que la clase String es inmutable puede ser debido al uso de HasdMap.

Ya que las variables de tipo String son muy populares como llaves al usar HashMap, es importante que estas sean inmutables de esta manera esas llaves pueden devolver el valor del objeto que se ha almacenado en el HashMap. Ya que HashMap trabaja bajo el principio de Hashing, el cual requiere que el valor se mantenga para funcionar adecuadamente. Un tipo String Mutable, produciría dos diferentes hashcodes al tiempo de la inserción y retorno si el contenido de los Strings fuera modificado después de la inserción, lo que llevaría potencialmente a la pérdida de los objetos valor en el Map.

Si eres un fan del cricket, entonces serás capaz de relacionar mi siguiente frase. El string es VVS Laxman de Java, o sea una clase muy muy especial. No he visto un solo programa de Java que sea escrito sin usar String, Esa es la razón por la cual un sólido conocimiento de String es muy importante para un Desarrollador Java.

La importancia y popularidad de String como tipo de dato, objeto de transferencia y mediador ha lo ha hecho tan popular en entrevistas de Java. ¿Por qué String es inmutable en Java? es una de las preguntas más frecuentemente utilizadas en las entrevistas, lo que inicia con una discusión sobre, qué es String, cómo es la String en Java diferente de String en C y C++, y luego cambiando hacia qué es un objeto inmutable en Java, cuáles son los beneficios de los objetos inmutables, por qué los usarías y en cuáles escenarios los usarías. Entre estas preguntas algunas veces se pregunta, ¿Por qué String es final en Java?.

En una nota similar, si tu te estás preparando para hacer entrevistas sobre Java, te recomiendo que eches un vistazo al libro Java Programming Intervied exposed, un excelente recurso para programadores Java Senior y nivel medio. Ya que contiene preguntas de todos los temas más importantes en Java como multithreading, collections, GC, JVM internals y frameworks como Spring y Hibernate,


¿Por qué String es Final en Java?


Como dije, puede haber múltiples posibles respuestas a esta pregunta, y el único diseñador de esta clase puede responderla con seguridad. Esperaba alguna pista en el libro de Joshua Bloch's Effective Java, pero el tampoco lo mencionó. Yo creo en las siguientes dos razones que tienen mucho sentido de por qué String es una clase hecha Inmutable o fina en Java:

1) Imagina el String pool sin hacer String inmutable, no es posible del todo porque en el caso de que un objeto string contenido en el pool esté referenciado a diferentes referencias de variable, entonces si alguna de ellas cambia el valor, entonces las otras de manera automática se ven affectadas.

Digamos

String A = "Test"
String B = "Test"

Ahora la llamada a String B, "Test".toUpperCase() cambiará el mismo objeto a "TEST". entonces A también será "TEST" lo que no es deseable. Aquí hay un diagrama que muestra como las literales String son creadas en el espacio de memoria y el String literal pool.


Why String is Immutable or Final in Java


2)String ha sido ampliamente utilizado como parámetro para muchas clases de Java, por ejemplo para abrir conexiones de red, tú puedes pasar el hostname y el número de puerto como String, puedes pasar la URL de la base de datos para abrir una conexión o puedes abrir un archivo en Java pasando el nombre del archivo como argumento a las clases I/O de Java.

En el caso de que String no fuera inmutable, esta sería una seria amenaza a la seguridad, quiero decir que alguien podría acceder a cualquier archivo para el cual el tiene autorización y entonces cambiar el nombre del archivo ya sea deliberada o accidentalmente y obtener acceso a ese archivo. Debido a la inmutabilidad, no necesitas preocuparte de ese tipo de amenazas. Esta razón también responde a ¿Por qué String es final en Java? Haciendo final a String, el diseñador de Java se asegura que nadie puede sobreescribir ningún comportamiento en la clase String.

3) Ya que String es inmutable puede ser compartido de forma segura entre varios hilos lo cual es muy importante en la programación multihilos, y para evitar cualquier problema de sincronización en Java. Inmutabilidad, también hace que las instancias String sean thread-safe en Java, eso significa que no necesitas sincronizar las operaciones con String externamente. Otro punto importante sobre String es la pérdida de memoria por Substring, el cual no es un problema relacionado a los hilos, pero es algo de lo que hay que tener cuidado.

4) Otra razón de ¿Por qué String es inmutable en Java? es permitir a String mantener en cache su hashcode, siendo inmutable String en Java mantiene su hashcode en cache, y esto no se calcula cada vez que llamamos al método hashcode de String, lo que lo hace muy rápido de usar como llave en el hashmap de Java. Esto es también sugerido por Jaroslav Sedlacek en los comentarios. En resumen debido a que String es inmutable, nadie puede cambiar su contenido una vez creado lo cual garantiza que el hashcode sea el mismo en diferentes invocaciones.

5) Otra buena razón de Por qué es String Inmutable en Java es la sugerida por Dan Bergh Johnsson en los comentarios: La razón más importante es que es usada por el mecanismo de carga de clases, y de ahí que

***El Artículo fue obtenido de JavaRevisited y fue modificado ligeramente para su traducción. Para revisar el contenido original dar clic aquí.



domingo, 1 de marzo de 2015

Reportes dinámicos con PrimeFaces y JasperReports [Java]

Qué tal, bienvenido a esta nueva publicación, el día de hoy les mostraré como crear reportes dinámicos con Primefaces y JasperReports.

La historia comienza con una necesidad que tenía para mis proyectos de aplicación web, en los cuales tenía que mostrar reportes en ciertas secciones de una pantalla que constantemente cambiarían de información, es decir dependían de ciertos valores para su generación.

La idea inicial era que pudiera ser capaz de mostrar un pdf que a lo largo del ciclo de vida de la aplicación siempre estaría cambiando de forma, por lo que se me vino a la cabeza que podía generar un archivo .pdf y después mostrarlo en pantalla, pero, ¿cómo podría hacer esto?.

Después de investigar un poco me di cuenta que PrimeFaces nos proporciona un componente para mostrar todo tipo de contenidos entre estos un pdf, hablo del Componente Media que hablando en términos más técnicos de programación hace uso de un objeto StreamedContent para renderizar contenidos.

Ahora, la idea había evolucionado, si con el método exportReportToPdfStream de JasperExportManager puedo guardar el pdf generado en un OutputStream entonces este lo podría utilizar para crear un StreamedContent y aquí la prueba:

Country.java


Esta es la clase que utilizaré para mantener la información del reporte, el archivo .jasper ya te imaginarás que el diseño solo consta de 2 columnas id y name.

report.xhtml

Lo siento, solo mostraré lo necesario de este archivo, se conforma de un formulario que contiene un inputText, un commandButton que llama al método generateReport, el commandButton Descargar que llama al método downloadFile, el componente Media y algunas condiciones de renderizado.
Nota: el componente media debe tener en false la propiedad cache, de otra forma te dará un buen dolor de cabeza.

JasperReportUtil.java


La clase de utilería JasperReportUtil contiene 3 métodos:

  • getOutputStreamFromReport que retorna un ByteArrayOutputStream a partir de la lista de elementos que deseas renderizar en tu reporte, algún mapa con parámetros y el path del archivo .jasper,
  • getStreamContentFromOutputStream que retorna un StreamedContent a partir de un objeto ByteArrayOutputStream, una cadena con el tipo de contenido a generar y el nombre del archivo. 
  • getStreamContentReport este método es el camino corto (fusiona los 2 métodos anteriores [lo pensaba utilizar en un caso especial, no necesito explicarlo]).

ReportTestController.java


De esta clase seré breve, los 2 métodos que se llaman son generateReport y downloadFile.

El primero genera datos dummys y haciendo uso de la clase de utilería antes mencionada genera el StreamedContent  para que el componente media lo utilice y muestre el pdf.

El segundo método permite descargar el archivo pdf, observar que PrimeFaces ya provee un componente para descargar pero si intentas guardar el pdf o utilizar el componente FileDownload el archivo se descargar corrupto, desconozco la razón.

Una captura de lo que obtienes:


lunes, 2 de febrero de 2015

CRUD con Web SQL [JavaScript]

¿Qué tal amigos? En la publicación de hoy les mostraré como hacer una aplicación sencilla que permita almacenar en una tablita registros de Integrandes.

El tema es: ¿qué tecnología usar para guardar la información?. Tenemos distintas opciones:
  • Realizar una conexión a una base de datos relacional (según tu gusto), a MySQL, PostgreSQL, etc.
  • Usar una base de datos con documentos, con mayor popularidad tenemos a MongoDB.
  • Utilizar archivos para almacenar el contenido.
  • Etcétera.

Me agrada mucho la primera opción, porque es algo que manejo mucho y sería sencillo de realizar, pero requiero de una tecnología del lado del servidor que me apoye (PHP, Java, Python) por lo que en esta ocasión me abstengo de comenzar...

El segundo caso si utilizo base de datos documentales me llevaría demasiado tiempo hacer algo bien estructurado debido a mi falta de experiencia.

El tercer caso en un caso particular ni me agrada, así que ni lo menciono jajaja.

¿Pero todo lo anterior a que viene? Sucede que en esta ocasión me preparo para generar una pequeña aplicación personal y requiero almacenar información, para ser exactos usaré PhoneGap [Ya sabrán por donde va este asunto]. Leyendo por aquí y por allá llegue a conocer Web SQL.

Web SQL es una base de datos que podemos usar de forma nativa desde nuestro navegador, esto significa que para mi caso personal no requiero guardar o tener un concentrado de información de varios nodos en una misma base de datos, necesito una base de datos para uso "local". Web SQL si lo vemos de esta forma trabaja del lado del cliente, no requiero utilizar un "servidor". Web SQL se apoya [o vive] desde JavaScript, por lo tanto para nuestro ejemplo de hoy no necesitas mas que un navegador y un bloc de notas.

A continuación muestro un pequeño ejemplo de como guardar, actualizar, eliminar y consultar registros de una tabla usando HTML + JavaScript +  Web SQL. El objetivo del Post como es costumbre como los demás no es explicar la API de Web SQL [solo es un pequeño ejemplito para iluminar tu camino] por lo que si deseas conocer detalles da clic al siguiente link.

index.html

Como te darás cuenta solo hago uso de 2 archivos de JavaScript [Ni siquiera uso CSS jeje] para el funcionamiento de nuestra aplicación, un archivo index.js y el famoso jquery.js. jQuery básicamente lo uso para modificar el DOM a mi gusto, si deseas en tu caso puedes usar puro JavaScript y te quedará más limpio y liviano tu código.

El HTML se compone de 2 divisiones o secciones, la primera contiene una lista sin elementos la cual usaremos para mostrar a nuestros Integrantes, para ser exactos sus nombres, apellidos y sus respectivos botones de editar y eliminar. La segunda división es exclusiva para el formulario de creación y edición. El formulario se compone de 3 elementos para visualizar e ingresar información: ID, nombres y apellidos de los cuales ID solo es para lectura y no permite ser editado.

index.js



Del archivo anterior lo más relevante es lo siguiente:

  • Para abrir conexión con una base de datos usamos openDatabase() que retorna un objeto con el cual podemos hacer lo que necesitemos. Los valores que recibe son: un nombre, una versión, descripción y el tamaño.
  • Con la función transaction() generamos una transacción en la cual podemos incluir un grupo de instrucciones como creación de tablas, altas, actualizaciones, ediciones, etc. Claro está que no lo hace sola, utiliza la función executeSql() del objeto que retorna transaction().
  • Para usar executeSql() hay muchas formas, un caso es para cuando se desea ejecutar intrucciones SQL sin parámetros (como el de la función init()) que recibe: instruncción sql, función de error, función de éxito. Para el caso de la función listarIntegrantes() son 4 los parámetros recibidos: instrucción sql, una lista con parámetros que serán remplazados en la instrucción sql [se remplazan por los "?"], función de éxito, función de error.
  • Algo interesante para tomar nota es que la función readTransaction() esta destinada para incluir instrucciones de consulta, aunque en ningún momento dudo que dejará de funcionar si se usan otro tipo de instrucciones dentro de ella.
Para terminar, como breve conclusión si lo que necesitas es guardar información en una aplicación Web de forma local que sea persistente Web SQL es una buena solución, para mi caso este señor se lleva bien con PhoneGap así que en lugar de usar un SQLite ya saben que usar.

Una captura de la aplicación:


Es una pena que cada año que pasa mi forma de redactar empeora, aún así espero les sea de utilidad esta publicación...
Nos vemos hasta la próxima entrega :D donde posiblemente les muestre como generar reportes totalmente dinámicos con PrimeFaces y JasperReports. 

Nota: Firefox no soporta Web SQL jajajajaja

domingo, 7 de diciembre de 2014

Tablas en PrimeFaces no se refrescan al usar filtros [Java]

Qué tal amigo, nuevamente me encuentro de regreso por aquí, el día de hoy de mostraré una forma de resetear los filtros de las tablas en PrimeFaces.

Lo anterior se me hace algo interesante y útil cuando te sucede como a mi. Me encuentro realizando un proyecto de la Universidad y consta de algunas pantallas que para mostrar registros previamente guardados utilizo una tabla <p:table> que contiene filtros en cada columna <p:column>.

Para comenzar proporciono un archivo .xhtml en el cual tengo una tabla con tan solo 3 columnas.

aula.xhtml



Mi archivo anterior tiene asociado un Bean que funge como Controlador para todas las funcionas que desempeña este, por lo cual también muestro su contenido.

AulaController.java



Bueno y tu dirás, ¿Y para que quiero ver todo ese código?, bueno es básicamente para mostrarte el funcionamiento completo de la pantalla.

Cuando desde el navegador se despliega el proyecto y se tiene acceso a la pantalla lo primero que sucederá es que cargará la lista de aulas y las renderiza en la tabla con id tabla-aulas.

Dicha tabla se compone de 3 columnas: Aula, Descripción y Opciones, las 2 primeras cuentan con filtros (identificar los atributos filterMatchMode y filterBy).

Ahora, si vemos más adelante tenemos un formulario con id frm-creacion el cual permite crear nuevas aulas.

Observa con atención un commandButton que tiene un actionListener que llama a un método del Bean guardarAula().

El problema que tenía era el siguiente: Se muestra la página, ingreso datos para una nueva aula, doy clic en guardar [refresco la tabla y se muestra mi nuevo registro] y hasta aquí todo bien. Utilizo mi filtro de la columna de aula, busco algo, limpio el filtro, ingreso nuevos datos para un aula y doy clic en guardar [refresco la tabla] y ¡Boom! no aparece por ningún lado mi registro, mis logs me dicen que se hizo bien el alta del aula pero mi tabla jamás los muestra. La solución fue la siguiente:

Si buscas en AulaController el método guardarAula() te darás cuenta que hago uso de otro método más:

resetearFitrosTabla("frm-aulas:tabla-aulas");

Bien, este método es de la clase padre AbstractController pero para no publicar completa esta clase te comparto que es lo que hace realmente el método:



Listo, a partir del findComponent() obtengo la tabla del xhtml pasando como parámetro el id de la tabla (En el ejemplo  del método guardarAula como la tabla no se encuentra en el mismo formulario que el botón desde donde llamo el método el parametro esformulario:tabla y equivale a frm-aulas:tabla-aulas) para después únicamente con la instancia obtenida y guardada en el objeto table usar el método reset(), y con estas 2 sencillas líneas logro que mi tabla se refresque aún cuando halla utilizado los filtros.

Bueno, espero lo anterior te sea de ayuda, aquí una captura de la pantallita por si te da curiosidad, saludos y nuevamente bienvenido.